From cb1ab5fc8b993f23924385ebee42d52ff45e4e8a Mon Sep 17 00:00:00 2001 From: Jamie Bainbridge Date: Thu, 10 Mar 2016 16:12:05 +1000 Subject: [PATCH 3/6] libndp: add option flags to send messages Within NA and RA message types, there are flags such as Solicited and Override (RFC-4861 Section 4). RA flags are currently implemented but not NA flags, so add remaining NA flag getters/setters. Set Solicited/Override flag on NA when appropriate, add a flags interface to the send API, and implement ability to send Unsolicited NA. Signed-off-by: Jamie Bainbridge Signed-off-by: Jiri Pirko --- include/ndp.h | 13 ++++++- libndp/libndp.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 124 insertions(+), 3 deletions(-) diff --git a/include/ndp.h b/include/ndp.h index 4ca33b8..09b234f 100644 --- a/include/ndp.h +++ b/include/ndp.h @@ -53,6 +53,9 @@ enum ndp_msg_type { NDP_MSG_ALL, /* Matches all */ }; +#define ND_OPT_NORMAL 0x0000 /* default, no change to ND message */ +#define ND_OPT_NA_UNSOL 0x0001 /* Unsolicited Neighbour Advertisement */ + enum ndp_route_preference { NDP_ROUTE_PREF_LOW = 3, NDP_ROUTE_PREF_MEDIUM = 0, @@ -76,7 +79,7 @@ enum ndp_msg_type ndp_msg_type(struct ndp_msg *msg); struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg); uint32_t ndp_msg_ifindex(struct ndp_msg *msg); void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex); -int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg); +int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags); uint8_t ndp_msgra_curhoplimit(struct ndp_msgra *msgra); void ndp_msgra_curhoplimit_set(struct ndp_msgra *msgra, uint8_t curhoplimit); @@ -100,6 +103,14 @@ uint32_t ndp_msgra_retransmit_time(struct ndp_msgra *msgra); void ndp_msgra_retransmit_time_set(struct ndp_msgra *msgra, uint32_t retransmit_time); +bool ndp_msgna_flag_router(struct ndp_msgna *msgna); +void ndp_msgna_flag_router_set(struct ndp_msgna *msgna, bool flag_router); +bool ndp_msgna_flag_solicited(struct ndp_msgna *msgna); +void ndp_msgna_flag_solicited_set(struct ndp_msgna *msgna, + bool flag_solicited); +bool ndp_msgna_flag_override(struct ndp_msgna *msgna); +void ndp_msgna_flag_override_set(struct ndp_msgna *msgna, bool flag_override); + enum ndp_msg_opt_type { NDP_MSG_OPT_SLLADDR, /* Source Link-layer Address */ NDP_MSG_OPT_TLLADDR, /* Target Link-layer Address */ diff --git a/libndp/libndp.c b/libndp/libndp.c index e75f4f7..899c2b0 100644 --- a/libndp/libndp.c +++ b/libndp/libndp.c @@ -676,7 +676,7 @@ struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg) * * Get interface index of message. * - * Returns: Inteface index + * Returns: Interface index **/ NDP_EXPORT uint32_t ndp_msg_ifindex(struct ndp_msg *msg) @@ -700,18 +700,34 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex) * ndp_msg_send: * @ndp: libndp library context * @msg: message structure + * @flags: option flags within message type * * Send message. * * Returns: zero on success or negative number in case of an error. **/ NDP_EXPORT -int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg) +int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags) { enum ndp_msg_type msg_type = ndp_msg_type(msg); if (ndp_msg_type_info(msg_type)->addrto_adjust) ndp_msg_type_info(msg_type)->addrto_adjust(&msg->addrto); + + switch (msg_type) { + case NDP_MSG_NA: + if (flags & ND_OPT_NA_UNSOL) { + ndp_msgna_flag_override_set((struct ndp_msgna*)&msg->nd_msg, true); + ndp_msgna_flag_solicited_set((struct ndp_msgna*)&msg->nd_msg, false); + ndp_msg_addrto_adjust_all_nodes(&msg->addrto); + } else { + ndp_msgna_flag_solicited_set((struct ndp_msgna*)&msg->nd_msg, true); + } + break; + default: + break; + } + return mysendto6(ndp->sock, msg->buf, msg->len, 0, &msg->addrto, msg->ifindex); } @@ -958,6 +974,100 @@ void ndp_msgra_retransmit_time_set(struct ndp_msgra *msgra, /** + * SECTION: msgna getters/setters + * @short_description: Getters and setters for NA message + */ + +/** + * ndp_msgna_flag_router: + * @msgna: NA message structure + * + * Get NA router flag. + * + * Returns: router flag. + **/ +NDP_EXPORT +bool ndp_msgna_flag_router(struct ndp_msgna *msgna) +{ + return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER; +} + +/** + * ndp_msgna_flag_router_set: + * @msgna: NA message structure + * + * Set NA router flag. + **/ +NDP_EXPORT +void ndp_msgna_flag_router_set(struct ndp_msgna *msgna, bool flag_router) +{ + if (flag_router) + msgna->na->nd_na_flags_reserved |= ND_NA_FLAG_ROUTER; + else + msgna->na->nd_na_flags_reserved &= ~ND_NA_FLAG_ROUTER; +} + +/** + * ndp_msgna_flag_solicited: + * @msgna: NA message structure + * + * Get NA solicited flag. + * + * Returns: solicited flag. + **/ +NDP_EXPORT +bool ndp_msgna_flag_solicited(struct ndp_msgna *msgna) +{ + return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED; +} + +/** + * ndp_msgna_flag_solicited_set: + * @msgna: NA message structure + * + * Set NA managed flag. + **/ +NDP_EXPORT +void ndp_msgna_flag_solicited_set(struct ndp_msgna *msgna, bool flag_solicited) +{ + if (flag_solicited) + msgna->na->nd_na_flags_reserved |= ND_NA_FLAG_SOLICITED; + else + msgna->na->nd_na_flags_reserved &= ~ND_NA_FLAG_SOLICITED; +} + +/** + * ndp_msgna_flag_override: + * @msgna: NA message structure + * + * Get NA override flag. + * + * Returns: override flag. + **/ +NDP_EXPORT +bool ndp_msgna_flag_override(struct ndp_msgna *msgna) +{ + return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_OVERRIDE; +} + +/** + * ndp_msgna_flag_override_set: + * @msgra: NA message structure + * + * Set NA override flag. + */ + +NDP_EXPORT +void ndp_msgna_flag_override_set(struct ndp_msgna *msgna, bool flag_override) +{ + if (flag_override) + msgna->na->nd_na_flags_reserved |= ND_NA_FLAG_OVERRIDE; + else + msgna->na->nd_na_flags_reserved &= ~ND_NA_FLAG_OVERRIDE; +} + + +/** * SECTION: msg_opt infrastructure * @short_description: Infrastructure for options */ -- 2.5.5