|
|
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 |
|