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