]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: configure non-dhcp configs earlier even DUID-UUID is used by DHCP clients
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 10 Apr 2021 02:47:50 +0000 (11:47 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 21 Apr 2021 12:00:45 +0000 (21:00 +0900)
Previously, if DUID-UUID is used, all configurations are configured
after networkd gets product uuid of machine.

This makes only DHCP clients are delayed, and other configs are
configured earlier.

12 files changed:
src/network/networkd-dhcp-common.c
src/network/networkd-dhcp-common.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp4.h
src/network/networkd-dhcp6.c
src/network/networkd-dhcp6.h
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-ndisc.c
src/network/networkd-ndisc.h
src/network/networkd-network.c

index cbe2f67c94c1f2462c643fbbce75257aa8ba7296..b311dce49093562e9a781dfa664ec41ae66d0b1e 100644 (file)
@@ -86,19 +86,42 @@ DUID* link_get_duid(Link *link, int family) {
         return duid;
 }
 
-static int duid_set_uuid(DUID *duid, sd_id128_t uuid) {
-        assert(duid);
+static int link_configure_and_start_dhcp_delayed(Link *link) {
+        int r;
 
-        if (duid->raw_data_len > 0)
+        assert(link);
+
+        if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                 return 0;
 
-        if (duid->type != DUID_TYPE_UUID)
-                return -EINVAL;
+        if (!link->dhcp_client) {
+                r = dhcp4_configure(link);
+                if (r < 0)
+                        return r;
+        }
+
+        if (!link->dhcp6_client) {
+                r = dhcp6_configure(link);
+                if (r < 0)
+                        return r;
+        }
 
-        memcpy(&duid->raw_data, &uuid, sizeof(sd_id128_t));
-        duid->raw_data_len = sizeof(sd_id128_t);
+        if (!link_has_carrier(link))
+                return 0;
 
-        return 1;
+        r = dhcp4_start(link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
+
+        r = ndisc_start(link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
+
+        r = dhcp6_start(link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
+
+        return 0;
 }
 
 static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
@@ -106,7 +129,6 @@ static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_er
         const sd_bus_error *e;
         const void *a;
         size_t sz;
-        DUID *duid;
         Link *link;
         int r;
 
@@ -133,26 +155,22 @@ static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_er
         }
 
         memcpy(&manager->product_uuid, a, sz);
-        while ((duid = set_steal_first(manager->duids_requesting_uuid)))
-                (void) duid_set_uuid(duid, manager->product_uuid);
-
-        manager->duids_requesting_uuid = set_free(manager->duids_requesting_uuid);
 
 configure:
-        while ((link = set_steal_first(manager->links_requesting_uuid))) {
-                link_unref(link);
+        /* To avoid calling GetProductUUID() bus method so frequently, set the flag below
+         * even if the method fails. */
+        manager->has_product_uuid = true;
 
-                r = link_configure(link);
+        while ((link = set_steal_first(manager->links_requesting_uuid))) {
+                r = link_configure_and_start_dhcp_delayed(link);
                 if (r < 0)
                         link_enter_failed(link);
+
+                link_unref(link);
         }
 
         manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
 
-        /* To avoid calling GetProductUUID() bus method so frequently, set the flag below
-         * even if the method fails. */
-        manager->has_product_uuid = true;
-
         return 1;
 }
 
@@ -190,66 +208,22 @@ int manager_request_product_uuid(Manager *m) {
         return 0;
 }
 
-static bool dhcp4_requires_uuid(Link *link) {
-        const DUID *duid;
-
-        assert(link);
-
-        if (!link_dhcp4_enabled(link))
-                return false;
-
-        if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
-                return false;
-
-        duid = link_get_dhcp4_duid(link);
-        if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
-                return false;
-
-        return true;
-}
-
-static bool dhcp6_requires_uuid(Link *link) {
-        const DUID *duid;
-
-        assert(link);
-
-        if (!link_dhcp6_enabled(link) && !link_ipv6_accept_ra_enabled(link))
-                return false;
-
-        duid = link_get_dhcp6_duid(link);
-        if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
-                return false;
-
-        return true;
-}
-
-static bool link_requires_uuid(Link *link) {
-        return dhcp4_requires_uuid(link) || dhcp6_requires_uuid(link);
-}
-
-int link_configure_duid(Link *link) {
+int dhcp_configure_duid(Link *link, DUID *duid) {
         Manager *m;
-        DUID *duid;
         int r;
 
         assert(link);
         assert(link->manager);
-        assert(link->network);
+        assert(duid);
 
         m = link->manager;
 
-        if (!link_requires_uuid(link))
+        if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
                 return 1;
 
         if (m->has_product_uuid) {
-                if (dhcp4_requires_uuid(link)) {
-                        duid = link_get_dhcp4_duid(link);
-                        (void) duid_set_uuid(duid, m->product_uuid);
-                }
-                if (dhcp6_requires_uuid(link)) {
-                        duid = link_get_dhcp6_duid(link);
-                        (void) duid_set_uuid(duid, m->product_uuid);
-                }
+                memcpy(&duid->raw_data, &m->product_uuid, sizeof(sd_id128_t));
+                duid->raw_data_len = sizeof(sd_id128_t);
                 return 1;
         }
 
@@ -266,20 +240,6 @@ int link_configure_duid(Link *link) {
         if (r > 0)
                 link_ref(link);
 
-        if (dhcp4_requires_uuid(link)) {
-                duid = link_get_dhcp4_duid(link);
-                r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
-                if (r < 0)
-                        return log_oom();
-        }
-
-        if (dhcp6_requires_uuid(link)) {
-                duid = link_get_dhcp6_duid(link);
-                r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
-                if (r < 0)
-                        return log_oom();
-        }
-
         return 0;
 }
 
index 6b462b3bd23b68fb0bf04367ba4852568de3b0ff..fc85fb4706d519788bf1d9a52433d5b5bb2265cb 100644 (file)
@@ -60,7 +60,7 @@ static inline DUID *link_get_dhcp6_duid(Link *link) {
         return link_get_duid(link, AF_INET6);
 }
 
-int link_configure_duid(Link *link);
+int dhcp_configure_duid(Link *link, DUID *duid);
 int manager_request_product_uuid(Manager *m);
 
 const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
index 5c4e1d789c73727187724bbcf58aa43996b80ead..4987c8fc531bfe7a3528c2d5787dd12d732d1c1e 100644 (file)
@@ -1284,6 +1284,15 @@ static int dhcp4_set_client_identifier(Link *link) {
         return 0;
 }
 
+static int dhcp4_configure_duid(Link *link) {
+        assert(link);
+
+        if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
+                return 1;
+
+        return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
+}
+
 static int dhcp4_set_request_address(Link *link) {
         Address *a;
 
@@ -1323,6 +1332,10 @@ int dhcp4_configure(Link *link) {
         if (link->dhcp_client)
                 return -EBUSY; /* Already configured. */
 
+        r = dhcp4_configure_duid(link);
+        if (r <= 0)
+                return r;
+
         r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
         if (r < 0)
                 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m");
@@ -1505,6 +1518,20 @@ int dhcp4_update_mac(Link *link) {
         return 0;
 }
 
+int dhcp4_start(Link *link) {
+        assert(link);
+
+        if (!link->dhcp_client)
+                return 0;
+
+        if (sd_dhcp_client_is_running(link->dhcp_client) > 0)
+                return 0;
+
+        log_link_debug(link, "Acquiring DHCPv4 lease");
+
+        return sd_dhcp_client_start(link->dhcp_client);
+}
+
 int config_parse_dhcp_max_attempts(
                 const char *unit,
                 const char *filename,
index cfad656c3d74a7f562af1f4102b6af2538887c4d..a33fe403be87003aaab7c9d662ffdbabcf27490c 100644 (file)
@@ -20,6 +20,7 @@ typedef enum DHCPClientIdentifier {
 void network_adjust_dhcp4(Network *network);
 int dhcp4_configure(Link *link);
 int dhcp4_update_mac(Link *link);
+int dhcp4_start(Link *link);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address);
index 4cd479c584082c1237473dc9dbaec75866896f56..617bf6b07c7a4d1200ee7676a9cef56fe4ca9c83 100644 (file)
@@ -1290,6 +1290,31 @@ int dhcp6_request_address(Link *link, int ir) {
         return 0;
 }
 
+int dhcp6_start(Link *link) {
+        assert(link);
+
+        if (!link->dhcp6_client)
+                return 0;
+
+        if (!link_dhcp6_enabled(link))
+                return 0;
+
+        if (link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_NO)
+                return 0;
+
+        if (!in6_addr_is_link_local(&link->ipv6ll_address)) {
+                log_link_debug(link, "IPv6 link-local address is not set, delaying to start DHCPv6 client.");
+                return 0;
+        }
+
+        if (sd_dhcp6_client_is_running(link->dhcp6_client) > 0)
+                return 0;
+
+        log_link_debug(link, "Acquiring DHCPv6 lease");
+
+        return dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
+}
+
 int dhcp6_request_prefix_delegation(Link *link) {
         Link *l;
 
@@ -1460,6 +1485,10 @@ int dhcp6_configure(Link *link) {
         if (link->dhcp6_client)
                 return -EBUSY;
 
+        r = dhcp_configure_duid(link, link_get_dhcp6_duid(link));
+        if (r <= 0)
+                return r;
+
         r = sd_dhcp6_client_new(&client);
         if (r == -ENOMEM)
                 return log_oom();
index a8028a95abd8838dbbebf042fe251bbf60526719..025bbb6188185572ba4bbce3feb9f5f1c648f1c1 100644 (file)
@@ -31,6 +31,7 @@ bool link_dhcp6_pd_is_enabled(Link *link);
 int dhcp6_pd_remove(Link *link);
 int dhcp6_configure(Link *link);
 int dhcp6_update_mac(Link *link);
+int dhcp6_start(Link *link);
 int dhcp6_request_address(Link *link, int ir);
 int dhcp6_request_prefix_delegation(Link *link);
 
index 5143502745291ccea66766c928666be1cf259600..2c8c8cd4143ad75784f4577040bed869c151f6bb 100644 (file)
@@ -1177,14 +1177,6 @@ static int link_acquire_ipv6_conf(Link *link) {
 
         assert(link);
 
-        if (link->ndisc) {
-                log_link_debug(link, "Discovering IPv6 routers");
-
-                r = sd_ndisc_start(link->ndisc);
-                if (r < 0 && r != -EBUSY)
-                        return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
-        }
-
         if (link->radv) {
                 assert(link->radv);
                 assert(in6_addr_is_link_local(&link->ipv6ll_address));
@@ -1200,18 +1192,13 @@ static int link_acquire_ipv6_conf(Link *link) {
                         return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
         }
 
-        if (link_dhcp6_enabled(link) && IN_SET(link->network->dhcp6_without_ra,
-                                               DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST,
-                                               DHCP6_CLIENT_START_MODE_SOLICIT)) {
-                assert(link->dhcp6_client);
-                assert(in6_addr_is_link_local(&link->ipv6ll_address));
+        r = ndisc_start(link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
 
-                r = dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
-                if (r < 0 && r != -EBUSY)
-                        return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
-                else
-                        log_link_debug(link, "Acquiring DHCPv6 lease");
-        }
+        r = dhcp6_start(link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
 
         r = dhcp6_request_prefix_delegation(link);
         if (r < 0)
@@ -1228,11 +1215,9 @@ static int link_acquire_ipv4_conf(Link *link) {
         assert(link->manager->event);
 
         if (link->dhcp_client) {
-                log_link_debug(link, "Acquiring DHCPv4 lease");
-
-                r = sd_dhcp_client_start(link->dhcp_client);
+                r = dhcp4_start(link);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
+                        return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
 
         } else if (link->ipv4ll) {
                 log_link_debug(link, "Acquiring IPv4 link-local address");
@@ -2252,12 +2237,6 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
         link_set_state(link, LINK_STATE_INITIALIZED);
         link->activated = false;
 
-        /* link_configure_duid() returns 0 if it requests product UUID. In that case,
-         * link_configure() is called later asynchronously. */
-        r = link_configure_duid(link);
-        if (r <= 0)
-                return r;
-
         r = link_configure(link);
         if (r < 0)
                 return r;
@@ -2372,12 +2351,6 @@ static int link_initialized_and_synced(Link *link) {
         if (r < 0)
                 return r;
 
-        /* link_configure_duid() returns 0 if it requests product UUID. In that case,
-         * link_configure() is called later asynchronously. */
-        r = link_configure_duid(link);
-        if (r <= 0)
-                return r;
-
         r = link_configure(link);
         if (r < 0)
                 return r;
index 7beabf7e6fbbc77ad8aeb4926535fbc5ee6ff5d5..fce1d03de5e2e99b320ca0c2edd351dacdf63ba7 100644 (file)
@@ -452,7 +452,6 @@ Manager* manager_free(Manager *m) {
         m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
         m->links = hashmap_free_with_destructor(m->links, link_unref);
 
-        m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
         m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
 
         m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
index bb2cad188306fb07361c1fa11396a64bf59671d9..9cb99325db129e2da9fe9581367ba7fe804c4503 100644 (file)
@@ -58,7 +58,6 @@ struct Manager {
         bool has_product_uuid;
         bool product_uuid_requested;
         Set *links_requesting_uuid;
-        Set *duids_requesting_uuid;
 
         char* dynamic_hostname;
         char* dynamic_timezone;
index b02f67c7708c33313c91cad4e84cf706d16e05b3..af2d6a3ef7b17c7ac9f824bdbd841c806a76c76a 100644 (file)
@@ -1341,6 +1341,17 @@ int ndisc_configure(Link *link) {
         return 0;
 }
 
+int ndisc_start(Link *link) {
+        assert(link);
+
+        if (!link->ndisc || !link->dhcp6_client)
+                return 0;
+
+        log_link_debug(link, "Discovering IPv6 routers");
+
+        return sd_ndisc_start(link->ndisc);
+}
+
 void ndisc_vacuum(Link *link) {
         NDiscRDNSS *r;
         NDiscDNSSL *d;
index 13e954731173aa776c656a7ab4ce5dfe536e2674..2ff9a8969d6bc8a0eb512825bb5897c1b131191c 100644 (file)
@@ -73,6 +73,7 @@ bool link_ipv6_accept_ra_enabled(Link *link);
 void network_adjust_ipv6_accept_ra(Network *network);
 
 int ndisc_configure(Link *link);
+int ndisc_start(Link *link);
 void ndisc_vacuum(Link *link);
 void ndisc_flush(Link *link);
 
index 736f0d593b8647e5405b17ac07d5e01a613cb28f..239cb1e7cba7dc3d0ffb2673e67731e031647a2e 100644 (file)
@@ -600,11 +600,6 @@ static Network *network_free(Network *network) {
         ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
         ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
 
-        if (network->manager) {
-                set_remove(network->manager->duids_requesting_uuid, &network->dhcp_duid);
-                set_remove(network->manager->duids_requesting_uuid, &network->dhcp6_duid);
-        }
-
         free(network->name);
 
         free(network->dhcp_server_timezone);