Blame SOURCES/0005-ndptool-add-D-dest-support.patch

f9401c
From e9a35fba03ec3670586fba7debd2e0cb3cd4341e Mon Sep 17 00:00:00 2001
f9401c
From: Hangbin Liu <haliu@redhat.com>
f9401c
Date: Mon, 2 Sep 2019 19:39:12 +0800
f9401c
Subject: [PATCH 05/06] ndptool: add -D dest support
f9401c
f9401c
This patch add -D dest option, with this option a user could set the dest
f9401c
address in IPv6 header for solicited NS/NA message
f9401c
f9401c
For function ndp_msg_addrto_adjust_solicit_multi(), I moved the check
f9401c
in ndp_msg_target_set() instead of in the function itself.
f9401c
f9401c
I also use reverse christmas tree variable order in the main() function
f9401c
of ndptool.c.
f9401c
f9401c
Signed-off-by: Hangbin Liu <haliu@redhat.com>
f9401c
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
f9401c
---
f9401c
 include/ndp.h   |  1 +
f9401c
 libndp/libndp.c | 42 ++++++++++++++++++++++++++++++++----------
f9401c
 man/ndptool.8   |  6 +++++-
f9401c
 utils/ndptool.c | 49 +++++++++++++++++++++++++++++++++++--------------
f9401c
 4 files changed, 73 insertions(+), 25 deletions(-)
f9401c
f9401c
diff --git a/include/ndp.h b/include/ndp.h
f9401c
index 698bba7..7bf8794 100644
f9401c
--- a/include/ndp.h
f9401c
+++ b/include/ndp.h
f9401c
@@ -80,6 +80,7 @@ struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg);
f9401c
 uint32_t ndp_msg_ifindex(struct ndp_msg *msg);
f9401c
 void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex);
f9401c
 void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target);
f9401c
+void ndp_msg_dest_set(struct ndp_msg *msg, struct in6_addr *dest);
f9401c
 void ndp_msg_opt_set(struct ndp_msg *msg);
f9401c
 int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg);
f9401c
 int ndp_msg_send_with_flags(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags);
f9401c
diff --git a/libndp/libndp.c b/libndp/libndp.c
f9401c
index 8b7de6b..283de77 100644
f9401c
--- a/libndp/libndp.c
f9401c
+++ b/libndp/libndp.c
f9401c
@@ -318,11 +318,6 @@ static void ndp_msg_addrto_adjust_all_routers(struct in6_addr *addr)
f9401c
 static void ndp_msg_addrto_adjust_solicit_multi(struct in6_addr *addr,
f9401c
 						struct in6_addr *target)
f9401c
 {
f9401c
-	struct in6_addr any = IN6ADDR_ANY_INIT;
f9401c
-
f9401c
-	/* Don't set addr to target if target is default IN6ADDR_ANY_INIT */
f9401c
-	if (!memcmp(target, &any, sizeof(any)))
f9401c
-		return;
f9401c
 	addr->s6_addr32[0] = htonl(0xFF020000);
f9401c
 	addr->s6_addr32[1] = 0;
f9401c
 	addr->s6_addr32[2] = htonl(0x1);
f9401c
@@ -700,17 +695,41 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex)
f9401c
 	msg->ifindex = ifindex;
f9401c
 }
f9401c
 
f9401c
+/**
f9401c
+ * ndp_msg_dest_set:
f9401c
+ * @msg: message structure
f9401c
+ * @dest: ns,na dest
f9401c
+ *
f9401c
+ * Set dest address in IPv6 header for NS and NA.
f9401c
+ **/
f9401c
+NDP_EXPORT
f9401c
+void ndp_msg_dest_set(struct ndp_msg *msg, struct in6_addr *dest)
f9401c
+{
f9401c
+	enum ndp_msg_type msg_type = ndp_msg_type(msg);
f9401c
+	switch (msg_type) {
f9401c
+		case NDP_MSG_NS:
f9401c
+			/* fall through */
f9401c
+		case NDP_MSG_NA:
f9401c
+			msg->addrto = *dest;
f9401c
+			/* fall through */
f9401c
+		default:
f9401c
+			break;
f9401c
+	}
f9401c
+}
f9401c
+
f9401c
 /**
f9401c
  * ndp_msg_target_set:
f9401c
  * @msg: message structure
f9401c
  * @target: ns,na target
f9401c
  *
f9401c
- * Set target address for NS and NA.
f9401c
+ * Set target address in ICMPv6 header for NS and NA.
f9401c
  **/
f9401c
 NDP_EXPORT
f9401c
 void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
f9401c
 {
f9401c
+	struct in6_addr any = IN6ADDR_ANY_INIT;
f9401c
 	enum ndp_msg_type msg_type = ndp_msg_type(msg);
f9401c
+
f9401c
 	switch (msg_type) {
f9401c
 		case NDP_MSG_NS:
f9401c
 			((struct ndp_msgns*)&msg->nd_msg)->ns->nd_ns_target = *target;
f9401c
@@ -720,11 +739,14 @@ void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
f9401c
 			 * node seeks to verify the reachability of a
f9401c
 			 * neighbor.
f9401c
 			 *
f9401c
-			 * In this case we don't know if we have a cache of
f9401c
-			 * target, so we use multicast to resolve the target
f9401c
-			 * address.
f9401c
+			 * In this case we need to update the dest address in
f9401c
+			 * IPv6 header when
f9401c
+			 * a) IPv6 dest address is not set
f9401c
+			 * b) ICMPv6 target address is supplied
f9401c
 			 * */
f9401c
-			ndp_msg_addrto_adjust_solicit_multi(&msg->addrto, target);
f9401c
+			if (!memcmp(&msg->addrto, &any, sizeof(any)) &&
f9401c
+			    memcmp(target, &any, sizeof(any)))
f9401c
+				ndp_msg_addrto_adjust_solicit_multi(&msg->addrto, target);
f9401c
 			break;
f9401c
 		case NDP_MSG_NA:
f9401c
 			((struct ndp_msgna*)&msg->nd_msg)->na->nd_na_target = *target;
f9401c
diff --git a/man/ndptool.8 b/man/ndptool.8
f9401c
index dd6ddee..fb0dd63 100644
f9401c
--- a/man/ndptool.8
f9401c
+++ b/man/ndptool.8
f9401c
@@ -41,9 +41,13 @@ Neighbor Advertisement.
f9401c
 .B "\-i ifname, \-\-ifname ifname"
f9401c
 Specified interface name.
f9401c
 
f9401c
+.TP
f9401c
+.B "\-D dest, \-\-dest dest"
f9401c
+Specified dest address in IPv6 header for NS/NA message.
f9401c
+
f9401c
 .TP
f9401c
 .B "\-T target, \-\-target target"
f9401c
-Specified target address for NS/NA message.
f9401c
+Specified target address in ICMPv6 header for NS/NA message.
f9401c
 
f9401c
 .TP
f9401c
 .B "\-U, \-\-unsolicited"
f9401c
diff --git a/utils/ndptool.c b/utils/ndptool.c
f9401c
index afa516f..1131462 100644
f9401c
--- a/utils/ndptool.c
f9401c
+++ b/utils/ndptool.c
f9401c
@@ -135,7 +135,8 @@ static void print_help(const char *argv0) {
f9401c
             "\t-v --verbose             Increase output verbosity\n"
f9401c
             "\t-t --msg-type=TYPE       Specify message type\n"
f9401c
 	    "\t                         (\"rs\", \"ra\", \"ns\", \"na\")\n"
f9401c
-            "\t-T --target=TARGET       Target address for NS or NA\n"
f9401c
+            "\t-D --dest=DEST           Dest address in IPv6 header for NS or NA\n"
f9401c
+            "\t-T --target=TARGET       Target address in ICMPv6 header for NS or NA\n"
f9401c
             "\t-i --ifname=IFNAME       Specify interface name\n"
f9401c
             "\t-U --unsolicited         Send Unsolicited NA\n"
f9401c
 	    "Available commands:\n"
f9401c
@@ -334,7 +335,8 @@ static int run_cmd_monitor(struct ndp *ndp, enum ndp_msg_type msg_type,
f9401c
 }
f9401c
 
f9401c
 static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type,
f9401c
-			uint32_t ifindex, struct in6_addr *target)
f9401c
+			uint32_t ifindex, struct in6_addr *dest,
f9401c
+			struct in6_addr *target)
f9401c
 {
f9401c
 	struct ndp_msg *msg;
f9401c
 	int err;
f9401c
@@ -345,6 +347,7 @@ static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type,
f9401c
 		return err;
f9401c
 	}
f9401c
 	ndp_msg_ifindex_set(msg, ifindex);
f9401c
+	ndp_msg_dest_set(msg, dest);
f9401c
 	ndp_msg_target_set(msg, target);
f9401c
 	ndp_msg_opt_set(msg);
f9401c
 
f9401c
@@ -387,23 +390,27 @@ int main(int argc, char **argv)
f9401c
 		{ "verbose",	no_argument,		NULL, 'v' },
f9401c
 		{ "msg-type",	required_argument,	NULL, 't' },
f9401c
 		{ "ifname",	required_argument,	NULL, 'i' },
f9401c
+		{ "dest",	required_argument,	NULL, 'D' },
f9401c
 		{ "target",	required_argument,	NULL, 'T' },
f9401c
 		{ "unsolicited",no_argument,		NULL, 'U' },
f9401c
 		{ NULL, 0, NULL, 0 }
f9401c
 	};
f9401c
-	int opt;
f9401c
-	struct ndp *ndp;
f9401c
-	char *msgtypestr = NULL;
f9401c
+
f9401c
+	struct in6_addr target = IN6ADDR_ANY_INIT;
f9401c
+	struct in6_addr dest = IN6ADDR_ANY_INIT;
f9401c
 	enum ndp_msg_type msg_type;
f9401c
+	char *msgtypestr = NULL;
f9401c
+	int res = EXIT_FAILURE;
f9401c
 	char *ifname = NULL;
f9401c
-	char *addr = NULL;
f9401c
-	struct in6_addr target = IN6ADDR_ANY_INIT;
f9401c
+	char *daddr = NULL;
f9401c
+	char *taddr = NULL;
f9401c
 	uint32_t ifindex;
f9401c
+	struct ndp *ndp;
f9401c
 	char *cmd_name;
f9401c
+	int opt;
f9401c
 	int err;
f9401c
-	int res = EXIT_FAILURE;
f9401c
 
f9401c
-	while ((opt = getopt_long(argc, argv, "hvt:T:i:U",
f9401c
+	while ((opt = getopt_long(argc, argv, "hvt:D:T:i:U",
f9401c
 				  long_options, NULL)) >= 0) {
f9401c
 
f9401c
 		switch(opt) {
f9401c
@@ -421,9 +428,13 @@ int main(int argc, char **argv)
f9401c
 			free(ifname);
f9401c
 			ifname = strdup(optarg);
f9401c
 			break;
f9401c
+		case 'D':
f9401c
+			free(daddr);
f9401c
+			daddr = strdup(optarg);
f9401c
+			break;
f9401c
 		case 'T':
f9401c
-			free(addr);
f9401c
-			addr = strdup(optarg);
f9401c
+			free(taddr);
f9401c
+			taddr = strdup(optarg);
f9401c
 			break;
f9401c
 		case 'U':
f9401c
 			flags |= ND_OPT_NA_UNSOL;
f9401c
@@ -458,8 +469,18 @@ int main(int argc, char **argv)
f9401c
 		}
f9401c
 	}
f9401c
 
f9401c
-	if (addr && inet_pton(AF_INET6, addr, &target) <= 0) {
f9401c
-		pr_err("Invalid target address \"%s\"\n", addr);
f9401c
+	if (daddr && (flags & ND_OPT_NA_UNSOL)) {
f9401c
+		pr_err("Conflicts for both setting dest address and unsolicited flag\n");
f9401c
+		goto errout;
f9401c
+	}
f9401c
+
f9401c
+	if (daddr && inet_pton(AF_INET6, daddr, &dest) <= 0) {
f9401c
+		pr_err("Invalid dest address \"%s\"\n", daddr);
f9401c
+		goto errout;
f9401c
+	}
f9401c
+
f9401c
+	if (taddr && inet_pton(AF_INET6, taddr, &target) <= 0) {
f9401c
+		pr_err("Invalid target address \"%s\"\n", taddr);
f9401c
 		goto errout;
f9401c
 	}
f9401c
 
f9401c
@@ -493,7 +514,7 @@ int main(int argc, char **argv)
f9401c
 			print_help(argv0);
f9401c
 			goto errout;
f9401c
 		}
f9401c
-		err = run_cmd_send(ndp, msg_type, ifindex, &target);
f9401c
+		err = run_cmd_send(ndp, msg_type, ifindex, &dest, &target);
f9401c
 	} else {
f9401c
 		pr_err("Unknown command \"%s\"\n", cmd_name);
f9401c
 		goto ndp_close;
f9401c
-- 
f9401c
2.19.2
f9401c