]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Install routes after addresses are ready
authorDaniel Axtens <dja@axtens.net>
Wed, 5 Dec 2018 10:49:35 +0000 (21:49 +1100)
committerDaniel Axtens <dja@axtens.net>
Wed, 16 Jan 2019 01:54:06 +0000 (12:54 +1100)
If an IPv6 route is added with a source address that is still
tentative, the kernel will refuse to install it.

Previously, once we sent the messages to the kernel to add the
addresses, we would immediately proceed to add the routes. The
addresses would usually still be tentative at this point, so
adding static IPv6 routes was broken - see issue #5882.

Now, only begin to configure routes once the addresses are ready,
by restructuring the state machine, and tracking when addresses are
ready, not just added.

Fixes: #5882
Signed-off-by: Daniel Axtens <dja@axtens.net>
src/network/networkd-link.c
src/network/networkd-link.h

index 11dca0162b673a697281f1dfd39e37c7690d5b2a..f413e6191115865a08d89c62505bccd50f1c687e 100644 (file)
@@ -861,6 +861,15 @@ void link_check_ready(Link *link) {
         if (!link->neighbors_configured)
                 return;
 
+        SET_FOREACH(a, link->addresses, i)
+                if (!address_is_ready(a))
+                        return;
+
+        if (!link->addresses_ready) {
+                link->addresses_ready = true;
+                link_request_set_routes(link);
+        }
+
         if (!link->static_routes_configured)
                 return;
 
@@ -890,10 +899,6 @@ void link_check_ready(Link *link) {
                         return;
         }
 
-        SET_FOREACH(a, link->addresses, i)
-                if (!address_is_ready(a))
-                        return;
-
         if (link->state != LINK_STATE_CONFIGURED)
                 link_enter_configured(link);
 
@@ -954,7 +959,7 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
         if (link->address_messages == 0) {
                 log_link_debug(link, "Addresses set");
                 link->addresses_configured = true;
-                link_request_set_routes(link);
+                link_check_ready(link);
         }
 
         return 1;
@@ -1084,6 +1089,7 @@ static int link_request_set_addresses(Link *link) {
 
         /* Reset all *_configured flags we are configuring. */
         link->addresses_configured = false;
+        link->addresses_ready = false;
         link->neighbors_configured = false;
         link->static_routes_configured = false;
         link->routing_policy_rules_configured = false;
@@ -1238,7 +1244,7 @@ static int link_request_set_addresses(Link *link) {
 
         if (link->address_messages == 0) {
                 link->addresses_configured = true;
-                link_request_set_routes(link);
+                link_check_ready(link);
         } else
                 log_link_debug(link, "Setting addresses");
 
index 00e68fdfaab6975d753acc4eee9b52ec0f3368bb..e417ea26ef3089ca177635f20da7530dbb7e0820 100644 (file)
@@ -82,6 +82,7 @@ typedef struct Link {
         Set *routes_foreign;
 
         bool addresses_configured;
+        bool addresses_ready;
 
         sd_dhcp_client *dhcp_client;
         sd_dhcp_lease *dhcp_lease;