]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip, neigh: Add NTF_EXT_MANAGED support
authorDaniel Borkmann <daniel@iogearbox.net>
Mon, 25 Oct 2021 15:47:28 +0000 (17:47 +0200)
committerDavid Ahern <dsahern@kernel.org>
Thu, 28 Oct 2021 14:59:03 +0000 (08:59 -0600)
Currently, ip neigh does not support the NTF_EXT_MANAGED flag. Add cmdline
support.

Usage example:

  # ./ip/ip n replace 192.168.178.30 dev enp5s0 managed extern_learn
  # ./ip/ip n
  192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a managed extern_learn REACHABLE
  [...]

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David Ahern <dsahern@kernel.org>
ip/ipneigh.c
man/man8/ip-neighbour.8

index 874c90335208c30026129777011d31f40b2f7ea2..7facc399fc41236d8dfb49255870d098bf70d97f 100644 (file)
@@ -51,7 +51,8 @@ static void usage(void)
        fprintf(stderr,
                "Usage: ip neigh { add | del | change | replace }\n"
                "                { ADDR [ lladdr LLADDR ] [ nud STATE ] proxy ADDR }\n"
-               "                [ dev DEV ] [ router ] [ use ] [ extern_learn ] [ protocol PROTO ]\n"
+               "                [ dev DEV ] [ router ] [ use ] [ managed ] [ extern_learn ]\n"
+               "                [ protocol PROTO ]\n"
                "\n"
                "       ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n"
                "                                 [ vrf NAME ] [ nomaster ]\n"
@@ -115,6 +116,7 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
                .ndm.ndm_family = preferred_family,
                .ndm.ndm_state = NUD_PERMANENT,
        };
+       __u32 ext_flags = 0;
        char  *dev = NULL;
        int dst_ok = 0;
        int dev_ok = 0;
@@ -150,6 +152,9 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
                        req.ndm.ndm_flags |= NTF_ROUTER;
                } else if (strcmp(*argv, "use") == 0) {
                        req.ndm.ndm_flags |= NTF_USE;
+               } else if (strcmp(*argv, "managed") == 0) {
+                       ext_flags |= NTF_EXT_MANAGED;
+                       req.ndm.ndm_state = NUD_NONE;
                } else if (matches(*argv, "extern_learn") == 0) {
                        req.ndm.ndm_flags |= NTF_EXT_LEARNED;
                } else if (strcmp(*argv, "dev") == 0) {
@@ -185,7 +190,10 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
        req.ndm.ndm_family = dst.family;
        if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0)
                return -1;
-
+       if (ext_flags &&
+           addattr_l(&req.n, sizeof(req), NDA_FLAGS_EXT, &ext_flags,
+                     sizeof(ext_flags)) < 0)
+               return -1;
        if (lla && strcmp(lla, "null")) {
                char llabuf[20];
                int l;
@@ -305,6 +313,7 @@ int print_neigh(struct nlmsghdr *n, void *arg)
        int len = n->nlmsg_len;
        struct rtattr *tb[NDA_MAX+1];
        static int logit = 1;
+       __u32 ext_flags = 0;
        __u8 protocol = 0;
 
        if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH &&
@@ -348,6 +357,8 @@ int print_neigh(struct nlmsghdr *n, void *arg)
 
        if (tb[NDA_PROTOCOL])
                protocol = rta_getattr_u8(tb[NDA_PROTOCOL]);
+       if (tb[NDA_FLAGS_EXT])
+               ext_flags = rta_getattr_u32(tb[NDA_FLAGS_EXT]);
 
        if (filter.protocol && filter.protocol != protocol)
                return 0;
@@ -430,13 +441,12 @@ int print_neigh(struct nlmsghdr *n, void *arg)
 
        if (r->ndm_flags & NTF_ROUTER)
                print_null(PRINT_ANY, "router", "%s ", "router");
-
        if (r->ndm_flags & NTF_PROXY)
                print_null(PRINT_ANY, "proxy", "%s ", "proxy");
-
+       if (ext_flags & NTF_EXT_MANAGED)
+               print_null(PRINT_ANY, "managed", "%s ", "managed");
        if (r->ndm_flags & NTF_EXT_LEARNED)
                print_null(PRINT_ANY, "extern_learn", "%s ", "extern_learn");
-
        if (r->ndm_flags & NTF_OFFLOADED)
                print_null(PRINT_ANY, "offload", "%s ", "offload");
 
index 3001cd010c5a0628ea6a351dd66efc1557c6f9f7..6fed47ced85798ff9d90cc73fd04a1dbfa08c87f 100644 (file)
@@ -26,6 +26,7 @@ ip-neighbour \- neighbour/arp tables management.
 .IR DEV " ] [ "
 .BR router " ] [ "
 .BR use " ] [ "
+.BR managed " ] [ "
 .BR extern_learn " ]"
 
 .ti -8
@@ -100,6 +101,14 @@ the kernel that a controller is using this dynamic entry. If the entry
 does not exist, the kernel will resolve it. If it exists, an attempt
 to refresh the neighbor entry will be triggered.
 
+.TP
+.BI managed
+this neigh entry is "managed". This option can be used to indicate to
+the kernel that a controller is using this dynamic entry. In contrast
+to "use", if the entry does not exist, the kernel will resolve it and
+periodically attempt to auto-refresh the neighbor entry such that it
+remains in resolved state when possible.
+
 .TP
 .BI extern_learn
 this neigh entry was learned externally. This option can be used to