On Thu, May 21, 2026 at 08:01:45PM +0200, Stefano Brivio wrote: > ...instead of the one dedicated to the neighbour monitor, because, if > neighbour notifications start coming in before or while we send the > initial request to read out the neighbour tables, messages and > sequence numbers will collide. > > For example, if nl_neigh_sync() sends a RTM_GETNEIGH request with > sequence 20, we expect a corresponding reply with sequence 20. But > given that we already used the same socket to subscribe to > notifications, and notifications don't correspond to any specific > request we sent, we might now get a message with sequence 0. Heh. Called it, kinda. Nice job tracking this down. > The collision between messages wouldn't actually matter, as we'll > handle anyway any RTM_NEWNEIGH message in the same fashion, but we > need to validate sequence numbers for robustness, and that will fail. > > At the same time, we have to subscribe to neighbour notifications > before calling nl_neigh_sync(), because we'll have a race condition > otherwise, as we might miss neighbours that were added before the > notifier is registered. > > Use the regular nl_sock for nl_neigh_sync(). > > Drop the interface index from the request: we won't get any entry > otherwise, because the Linux kernel (as of version 7.0) is unable to > filter on it. Results are now filtered by interface index as we read > them. > > Passing along an interface index used to work when nl_neigh_sync() > used the notifier socket, because NETLINK_GET_STRICT_CHK is not set > on it, meaning that results weren't filtered at all (interface and > IP version passed in the request were ignored altogether). > > To reproduce the issue fixed here: > > * detach a network and user namespace: > > [terminal 0] > $ unshare -rUn > # echo $$ > 1543307 > > * attach pasta to it: > > [terminal 1] > $ ./pasta -f --config-net 1543307 -I enp9s0 > > * enter that namespace from yet another terminal: > > [terminal 2] > $ nsenter --preserve-credentials -U -n -t 1543307 > > * start flooding the MAC address table of this namespace: > > [terminal 1] > # for i in $(seq 10 99); do for j in $(seq 10 99); do for k in $(seq 10 99); do ip ne add dev enp9s0 10.$i.$j.$k lladdr 00:11:22:$i:$j:$k; done; done; done > > * and now start another instance of pasta in this namespace: > > [terminal 2] > # ./pasta -d --config-net > > which will eventually result in pasta exiting with a message like: > > 0.0253: netlink: Unexpected sequence number (0 != 34) > > Reported-by: Paul Holzinger > Link: https://bugs.passt.top/show_bug.cgi?id=203 > Fixes: 3c469013cfaa ("netlink: add subscription on changes in NDP/ARP table") > Signed-off-by: Stefano Brivio Reviewed-by: David Gibson > --- > netlink.c | 15 +++++++-------- > 1 file changed, 7 insertions(+), 8 deletions(-) > > diff --git a/netlink.c b/netlink.c > index c3c830e..0863734 100644 > --- a/netlink.c > +++ b/netlink.c > @@ -1206,24 +1206,23 @@ static void nl_neigh_msg_read(const struct ctx *c, struct nlmsghdr *nh) > * @proto: Protocol, AF_INET or AF_INET6 > * @ifi: Interface index > */ > -static void nl_neigh_sync(const struct ctx *c, int proto, int ifi) > +static void nl_neigh_sync(const struct ctx *c, int proto) > { > struct { > struct nlmsghdr nlh; > struct ndmsg ndm; > } req = { > - .ndm.ndm_family = proto, > - .ndm.ndm_ifindex = ifi, > + .ndm.ndm_family = proto, > }; > struct nlmsghdr *nh; > char buf[NLBUFSIZ]; > ssize_t status; > uint32_t seq; > > - seq = nl_send(nl_sock_neigh, &req, RTM_GETNEIGH, > - NLM_F_DUMP, sizeof(req)); > - nl_foreach_oftype(nh, status, nl_sock_neigh, buf, seq, RTM_NEWNEIGH) > + seq = nl_send(nl_sock, &req, RTM_GETNEIGH, NLM_F_DUMP, sizeof(req)); > + nl_foreach_oftype(nh, status, nl_sock, buf, seq, RTM_NEWNEIGH) > nl_neigh_msg_read(c, nh); > + > if (status < 0) > warn("netlink: RTM_GETNEIGH failed: %s", strerror_(-status)); > } > @@ -1298,8 +1297,8 @@ int nl_neigh_notify_init(const struct ctx *c) > return -1; > } > > - nl_neigh_sync(c, AF_INET, c->ifi4); > - nl_neigh_sync(c, AF_INET6, c->ifi6); > + nl_neigh_sync(c, AF_INET); > + nl_neigh_sync(c, AF_INET6); > > return 0; > } > -- > 2.43.0 > -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson