]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: drop old ndisc configurations after new ones are configured
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Jul 2021 11:15:10 +0000 (20:15 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Jul 2021 11:59:38 +0000 (20:59 +0900)
Previously, `ndisc_remove_old_one()` checked `ndisc_{addresses,routes}_configured`
flags, but they are not unset when all addresses or routes are already
assigned.
After the request queue is implemented, the address or route requests
are not processed within the same event of ndisc handler is called, but
will processed later when they are ready. So, calling `ndisc_remove_old()`
in the event of ndisc handler will remove all addresses and routes
previously assigned even they are requested to be updated.

This makes `ndisc_remove_old()` do nothing when there exist some
requests to configure addresses and routes, thus previously assigned
addresses and routes are kept until all requests are processed.

Fixes #20050.

src/network/networkd-ndisc.c

index 444147c305af2456f914cc70fa46f985e13c9652..eebcea1a690cf13f057361cc03d4a9b1c3717586 100644 (file)
@@ -128,9 +128,6 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool
         if (!force) {
                 bool set_callback = false;
 
-                if (!link->ndisc_addresses_configured || !link->ndisc_routes_configured)
-                        return 0;
-
                 SET_FOREACH(na, link->ndisc_addresses)
                         if (!na->marked && in6_addr_equal(&na->router, router)) {
                                 set_callback = true;
@@ -212,6 +209,10 @@ static int ndisc_remove_old(Link *link) {
 
         assert(link);
 
+        if (link->ndisc_addresses_messages > 0 ||
+            link->ndisc_routes_messages > 0)
+                return 0;
+
         routers = set_new(&in6_addr_hash_ops);
         if (!routers)
                 return -ENOMEM;