From 6aa5773bfff0a92d64da70426cae833df6f84daf Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 5 Dec 2018 21:49:35 +1100
Subject: [PATCH] Install routes after addresses are ready

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>

Origin: upstream, https://github.com/systemd/systemd/commit/6aa5773bfff0a92d64da70426cae833df6f84daf
Bug-Ubuntu: https://launchpad.net/bugs/1812760
---
 src/network/networkd-link.c | 18 ++++++++++++------
 src/network/networkd-link.h |  1 +
 2 files changed, 13 insertions(+), 6 deletions(-)

--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -855,6 +855,15 @@
         if (!link->addresses_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;
 
@@ -886,10 +895,6 @@
                                 return;
         }
 
-        SET_FOREACH(a, link->addresses, i)
-                if (!address_is_ready(a))
-                        return;
-
         if (link->state != LINK_STATE_CONFIGURED)
                 link_enter_configured(link);
 
@@ -940,7 +945,7 @@
         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;
@@ -1097,6 +1102,7 @@
 
         /* Reset all *_configured flags we are configuring. */
         link->addresses_configured = false;
+        link->addresses_ready = false;
         link->static_routes_configured = false;
         link->routing_policy_rules_configured = false;
 
@@ -1248,7 +1254,7 @@
 
         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");
 
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -98,6 +98,8 @@
 
         bool addresses_configured;
 
+        bool addresses_ready;
+
         sd_dhcp_client *dhcp_client;
         sd_dhcp_lease *dhcp_lease;
         char *lease_file;
