Merge branch 'managed-neighbor' into next

Daniel Borkmann  says:

====================

iproute2 patches to add support for managed neighbor entries as per recent
net-next commits:

  2ed08b5ead3c ("Merge branch 'Managed-Neighbor-Entries'")
  c47fedba94bc ("Merge branch 'minor-managed-neighbor-follow-ups'")

====================

Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
David Ahern 2021-10-28 09:00:26 -06:00
commit e2947f6fd8
2 changed files with 42 additions and 13 deletions

View File

@ -51,7 +51,8 @@ static void usage(void)
fprintf(stderr, fprintf(stderr,
"Usage: ip neigh { add | del | change | replace }\n" "Usage: ip neigh { add | del | change | replace }\n"
" { ADDR [ lladdr LLADDR ] [ nud STATE ] proxy ADDR }\n" " { ADDR [ lladdr LLADDR ] [ nud STATE ] proxy ADDR }\n"
" [ dev DEV ] [ router ] [ extern_learn ] [ protocol PROTO ]\n" " [ dev DEV ] [ router ] [ use ] [ managed ] [ extern_learn ]\n"
" [ protocol PROTO ]\n"
"\n" "\n"
" ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n" " ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n"
" [ vrf NAME ] [ nomaster ]\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_family = preferred_family,
.ndm.ndm_state = NUD_PERMANENT, .ndm.ndm_state = NUD_PERMANENT,
}; };
__u32 ext_flags = 0;
char *dev = NULL; char *dev = NULL;
int dst_ok = 0; int dst_ok = 0;
int dev_ok = 0; int dev_ok = 0;
@ -148,6 +150,11 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
req.ndm.ndm_flags |= NTF_PROXY; req.ndm.ndm_flags |= NTF_PROXY;
} else if (strcmp(*argv, "router") == 0) { } else if (strcmp(*argv, "router") == 0) {
req.ndm.ndm_flags |= NTF_ROUTER; 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) { } else if (matches(*argv, "extern_learn") == 0) {
req.ndm.ndm_flags |= NTF_EXT_LEARNED; req.ndm.ndm_flags |= NTF_EXT_LEARNED;
} else if (strcmp(*argv, "dev") == 0) { } else if (strcmp(*argv, "dev") == 0) {
@ -183,7 +190,10 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
req.ndm.ndm_family = dst.family; req.ndm.ndm_family = dst.family;
if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0) if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0)
return -1; 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")) { if (lla && strcmp(lla, "null")) {
char llabuf[20]; char llabuf[20];
int l; int l;
@ -235,7 +245,7 @@ static void print_neigh_state(unsigned int nud)
#define PRINT_FLAG(f) \ #define PRINT_FLAG(f) \
if (nud & NUD_##f) { \ if (nud & NUD_##f) { \
nud &= ~NUD_##f; \ nud &= ~NUD_##f; \
print_string(PRINT_ANY, NULL, " %s", #f); \ print_string(PRINT_ANY, NULL, "%s ", #f); \
} }
PRINT_FLAG(INCOMPLETE); PRINT_FLAG(INCOMPLETE);
@ -303,6 +313,7 @@ int print_neigh(struct nlmsghdr *n, void *arg)
int len = n->nlmsg_len; int len = n->nlmsg_len;
struct rtattr *tb[NDA_MAX+1]; struct rtattr *tb[NDA_MAX+1];
static int logit = 1; static int logit = 1;
__u32 ext_flags = 0;
__u8 protocol = 0; __u8 protocol = 0;
if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH && if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH &&
@ -346,6 +357,8 @@ int print_neigh(struct nlmsghdr *n, void *arg)
if (tb[NDA_PROTOCOL]) if (tb[NDA_PROTOCOL])
protocol = rta_getattr_u8(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) if (filter.protocol && filter.protocol != protocol)
return 0; return 0;
@ -423,27 +436,26 @@ int print_neigh(struct nlmsghdr *n, void *arg)
fprintf(fp, "lladdr "); fprintf(fp, "lladdr ");
print_color_string(PRINT_ANY, COLOR_MAC, print_color_string(PRINT_ANY, COLOR_MAC,
"lladdr", "%s", lladdr); "lladdr", "%s ", lladdr);
} }
if (r->ndm_flags & NTF_ROUTER) if (r->ndm_flags & NTF_ROUTER)
print_null(PRINT_ANY, "router", " %s", "router"); print_null(PRINT_ANY, "router", "%s ", "router");
if (r->ndm_flags & NTF_PROXY) if (r->ndm_flags & NTF_PROXY)
print_null(PRINT_ANY, "proxy", " %s", "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) if (r->ndm_flags & NTF_EXT_LEARNED)
print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn"); print_null(PRINT_ANY, "extern_learn", "%s ", "extern_learn");
if (r->ndm_flags & NTF_OFFLOADED) if (r->ndm_flags & NTF_OFFLOADED)
print_null(PRINT_ANY, "offload", " %s", "offload"); print_null(PRINT_ANY, "offload", "%s ", "offload");
if (show_stats) { if (show_stats) {
if (tb[NDA_CACHEINFO]) if (tb[NDA_CACHEINFO])
print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO])); print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO]));
if (tb[NDA_PROBES]) if (tb[NDA_PROBES])
print_uint(PRINT_ANY, "probes", " probes %u", print_uint(PRINT_ANY, "probes", "probes %u ",
rta_getattr_u32(tb[NDA_PROBES])); rta_getattr_u32(tb[NDA_PROBES]));
} }
@ -453,7 +465,7 @@ int print_neigh(struct nlmsghdr *n, void *arg)
if (protocol) { if (protocol) {
SPRINT_BUF(b1); SPRINT_BUF(b1);
print_string(PRINT_ANY, "protocol", " proto %s ", print_string(PRINT_ANY, "protocol", "proto %s ",
rtnl_rtprot_n2a(protocol, b1, sizeof(b1))); rtnl_rtprot_n2a(protocol, b1, sizeof(b1)));
} }

View File

@ -25,6 +25,8 @@ ip-neighbour \- neighbour/arp tables management.
.B dev .B dev
.IR DEV " ] [ " .IR DEV " ] [ "
.BR router " ] [ " .BR router " ] [ "
.BR use " ] [ "
.BR managed " ] [ "
.BR extern_learn " ]" .BR extern_learn " ]"
.ti -8 .ti -8
@ -92,6 +94,21 @@ indicates whether we are proxying for this neighbour entry
.BI router .BI router
indicates whether neighbour is a router indicates whether neighbour is a router
.TP
.BI use
this neigh entry is in "use". This option can be used to indicate to
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 .TP
.BI extern_learn .BI extern_learn
this neigh entry was learned externally. This option can be used to this neigh entry was learned externally. This option can be used to