ipneigh: neigh get support

This patch adds support to lookup a neigh entry
using recently added support in the kernel using RTM_GETNEIGH

example:
$ip neigh get 10.0.2.4 dev test-dummy0
10.0.2.4 dev test-dummy0 lladdr de:ad:be:ef:13:37 PERMANENT

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Tested-by: Ivan Vecera <ivecera@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
Roopa Prabhu 2019-09-30 21:52:23 -07:00 committed by David Ahern
parent 4ed5ad7bd3
commit 6284236237
2 changed files with 108 additions and 4 deletions

View File

@ -55,6 +55,7 @@ static void usage(void)
"\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 ]\n" " [ vrf NAME ]\n"
" ip neigh get { ADDR | proxy ADDR } dev DEV\n"
"\n" "\n"
"STATE := { permanent | noarp | stale | reachable | none |\n" "STATE := { permanent | noarp | stale | reachable | none |\n"
" incomplete | delay | probe | failed }\n"); " incomplete | delay | probe | failed }\n");
@ -599,6 +600,82 @@ static int do_show_or_flush(int argc, char **argv, int flush)
return 0; return 0;
} }
static int ipneigh_get(int argc, char **argv)
{
struct {
struct nlmsghdr n;
struct ndmsg ndm;
char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = RTM_GETNEIGH,
.ndm.ndm_family = preferred_family,
};
struct nlmsghdr *answer;
char *d = NULL;
int dst_ok = 0;
int dev_ok = 0;
inet_prefix dst;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
d = *argv;
dev_ok = 1;
} else if (matches(*argv, "proxy") == 0) {
NEXT_ARG();
if (matches(*argv, "help") == 0)
usage();
if (dst_ok)
duparg("address", *argv);
get_addr(&dst, *argv, preferred_family);
dst_ok = 1;
dev_ok = 1;
req.ndm.ndm_flags |= NTF_PROXY;
} else {
if (strcmp(*argv, "to") == 0)
NEXT_ARG();
if (matches(*argv, "help") == 0)
usage();
if (dst_ok)
duparg2("to", *argv);
get_addr(&dst, *argv, preferred_family);
dst_ok = 1;
}
argc--; argv++;
}
if (!dev_ok || !dst_ok || dst.family == AF_UNSPEC) {
fprintf(stderr, "Device and address are required arguments.\n");
return -1;
}
req.ndm.ndm_family = dst.family;
if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0)
return -1;
if (d) {
req.ndm.ndm_ifindex = ll_name_to_index(d);
if (!req.ndm.ndm_ifindex) {
fprintf(stderr, "Cannot find device \"%s\"\n", d);
return -1;
}
}
if (rtnl_talk(&rth, &req.n, &answer) < 0)
return -2;
ipneigh_reset_filter(0);
if (print_neigh(answer, stdout) < 0) {
fprintf(stderr, "An error :-)\n");
return -1;
}
return 0;
}
int do_ipneigh(int argc, char **argv) int do_ipneigh(int argc, char **argv)
{ {
if (argc > 0) { if (argc > 0) {
@ -611,10 +688,8 @@ int do_ipneigh(int argc, char **argv)
return ipneigh_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); return ipneigh_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
if (matches(*argv, "delete") == 0) if (matches(*argv, "delete") == 0)
return ipneigh_modify(RTM_DELNEIGH, 0, argc-1, argv+1); return ipneigh_modify(RTM_DELNEIGH, 0, argc-1, argv+1);
if (matches(*argv, "get") == 0) { if (matches(*argv, "get") == 0)
fprintf(stderr, "Sorry, \"neigh get\" is not implemented :-(\n"); return ipneigh_get(argc-1, argv+1);
return -1;
}
if (matches(*argv, "show") == 0 || if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 || matches(*argv, "lst") == 0 ||
matches(*argv, "list") == 0) matches(*argv, "list") == 0)

View File

@ -37,6 +37,12 @@ ip-neighbour \- neighbour/arp tables management.
.B vrf .B vrf
.IR NAME " ] " .IR NAME " ] "
.ti -8
.B ip neigh get
.IR ADDR
.B dev
.IR DEV
.ti -8 .ti -8
.IR STATE " := {" .IR STATE " := {"
.BR permanent " | " noarp " | " stale " | " reachable " | " none " |" .BR permanent " | " noarp " | " stale " | " reachable " | " none " |"
@ -231,6 +237,23 @@ twice,
also dumps all the deleted neighbours. also dumps all the deleted neighbours.
.RE .RE
.TP
ip neigh get
lookup a neighbour entry to a destination given a device
.RS
.TP
.BI proxy
indicates whether we should lookup a proxy neigbour entry
.TP
.BI to " ADDRESS " (default)
the prefix selecting the neighbour to query.
.TP
.BI dev " NAME"
get neighbour entry attached to this device.
.SH EXAMPLES .SH EXAMPLES
.PP .PP
ip neighbour ip neighbour
@ -242,6 +265,12 @@ ip neigh flush dev eth0
.RS .RS
Removes entries in the neighbour table on device eth0. Removes entries in the neighbour table on device eth0.
.RE .RE
.PP
ip neigh get 10.0.1.10 dev eth0
.RS
Performs a neighbour lookup in the kernel and returns
a neighbour entry.
.RE
.SH SEE ALSO .SH SEE ALSO
.br .br