Blob Blame History Raw
From cb1ab5fc8b993f23924385ebee42d52ff45e4e8a Mon Sep 17 00:00:00 2001
From: Jamie Bainbridge <jamie.bainbridge@gmail.com>
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 <jamie.bainbridge@gmail.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 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