From 3def88503a623334febdd213c1121a66fd6bb222 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 14:16:22 +0900 Subject: [PATCH 01/11] network: set previous DHCP4 address in link->addresses_foreign Previously, the address was taken from the state file, but DHCP4_ADDRESS= entry was dropped by 46986251d6eb4c78bb56c080ce310fd2b1f9439f. Moreover, the link state file is always removed when networkd is stopping. Let's take the address from the list of enumerated addresses. --- src/network/networkd-address.c | 2 +- src/network/networkd-address.h | 1 + src/network/networkd-dhcp4.c | 51 ++++++++++++++++++---------------- src/network/networkd-dhcp4.h | 2 -- src/network/networkd-link.c | 6 ---- 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 9130fae778..1bf6514a29 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -528,7 +528,7 @@ static bool link_is_static_address_configured(const Link *link, const Address *a return false; } -static bool link_address_is_dynamic(const Link *link, const Address *address) { +bool link_address_is_dynamic(const Link *link, const Address *address) { Route *route; assert(link); diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 0104747d9a..8b0fb9b0df 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -64,6 +64,7 @@ int link_drop_addresses(Link *link); int link_drop_foreign_addresses(Link *link); int link_serialize_addresses(Link *link, FILE *f); int link_deserialize_addresses(Link *link, const char *addresses); +bool link_address_is_dynamic(const Link *link, const Address *address); void ipv4_dad_unref(Link *link); int ipv4_dad_stop(Link *link); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index bb8c34f7cc..eba6c3e16b 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1286,6 +1286,29 @@ static int dhcp4_set_client_identifier(Link *link) { return 0; } +static int dhcp4_set_request_address(Link *link) { + Address *a; + + assert(link); + assert(link->network); + assert(link->dhcp_client); + + if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) + return 0; + + SET_FOREACH(a, link->addresses_foreign) { + if (a->family != AF_INET) + continue; + if (link_address_is_dynamic(link, a)) + break; + } + + if (!a) + return 0; + + return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in); +} + static int dhcp4_init(Link *link) { int r; @@ -1469,6 +1492,10 @@ int dhcp4_configure(Link *link) { return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed set to lease lifetime: %m"); } + r = dhcp4_set_request_address(link); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set initial DHCPv4 address: %m"); + r = dhcp4_configure_dad(link); if (r < 0) return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to configure service type: %m"); @@ -1499,30 +1526,6 @@ int dhcp4_update_mac(Link *link) { return 0; } -int link_deserialize_dhcp4(Link *link, const char *dhcp4_address) { - union in_addr_union address; - int r; - - assert(link); - - if (isempty(dhcp4_address)) - return 0; - - r = in_addr_from_string(AF_INET, dhcp4_address, &address); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to parse DHCPv4 address: %s", dhcp4_address); - - r = dhcp4_init(link); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to initialize DHCPv4 client: %m"); - - r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to set initial DHCPv4 address %s: %m", dhcp4_address); - - return 0; -} - int config_parse_dhcp_max_attempts( const char *unit, const char *filename, diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h index 8aa6ac9453..b8476bb38c 100644 --- a/src/network/networkd-dhcp4.h +++ b/src/network/networkd-dhcp4.h @@ -20,8 +20,6 @@ typedef enum DHCPClientIdentifier { int dhcp4_configure(Link *link); int dhcp4_update_mac(Link *link); -int link_deserialize_dhcp4(Link *link, const char *dhcp4_address); - CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9dd29bb203..735dee8083 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2415,7 +2415,6 @@ static int link_load(Link *link) { _cleanup_free_ char *network_file = NULL, *addresses = NULL, *routes = NULL, - *dhcp4_address = NULL, *ipv4ll_address = NULL; int r; @@ -2425,7 +2424,6 @@ static int link_load(Link *link) { "NETWORK_FILE", &network_file, "ADDRESSES", &addresses, "ROUTES", &routes, - "DHCP4_ADDRESS", &dhcp4_address, "IPV4LL_ADDRESS", &ipv4ll_address); if (r < 0 && r != -ENOENT) return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file); @@ -2463,10 +2461,6 @@ network_file_fail: if (r < 0) log_link_warning_errno(link, r, "Failed to load routes from %s, ignoring: %m", link->state_file); - r = link_deserialize_dhcp4(link, dhcp4_address); - if (r < 0) - log_link_warning_errno(link, r, "Failed to load DHCPv4 address from %s, ignoring: %m", link->state_file); - r = link_deserialize_ipv4ll(link, ipv4ll_address); if (r < 0) log_link_warning_errno(link, r, "Failed to load IPv4LL address from %s, ignoring: %m", link->state_file); From 5360b089e1f2a18e6ea79eea1c63171e86809c8c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 14:22:09 +0900 Subject: [PATCH 02/11] network: drop dhcp4_init() It is now called by only dhcp4_configure(). Let's merge them. --- src/network/networkd-dhcp4.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index eba6c3e16b..a605a9c7d6 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1309,25 +1309,6 @@ static int dhcp4_set_request_address(Link *link) { return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in); } -static int dhcp4_init(Link *link) { - int r; - - assert(link); - - if (link->dhcp_client) - return 0; - - r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); - if (r < 0) - return r; - - r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0); - if (r < 0) - return r; - - return 0; -} - int dhcp4_configure(Link *link) { sd_dhcp_option *send_option; void *request_options; @@ -1343,9 +1324,15 @@ int dhcp4_configure(Link *link) { if (r < 0) return r; - r = dhcp4_init(link); - if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to initialize DHCP4 client: %m"); + if (!link->dhcp_client) { + r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m"); + + r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m"); + } r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, From e69642dccc19598017abf9223e3b2e5e4c92664a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 14:24:29 +0900 Subject: [PATCH 03/11] network: mention that the error will be ignored --- src/network/networkd-dhcp4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index a605a9c7d6..b9a98a56a8 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1220,7 +1220,7 @@ static int dhcp4_set_promote_secondaries(Link *link) { promote_secondaries_path = strjoina("net/ipv4/conf/", link->ifname, "/promote_secondaries"); r = sysctl_write(promote_secondaries_path, "1"); if (r < 0) - log_link_warning_errno(link, r, "cannot set sysctl %s to 1", promote_secondaries_path); + log_link_warning_errno(link, r, "Failed to set sysctl %s to 1, ignoring", promote_secondaries_path); return r > 0; } From a41768533f2517a1d4c4a1df483ff0a462b4604a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:07:06 +0900 Subject: [PATCH 04/11] network: always enable sysctl property promote_secondaries systemd-sysctl already enables promote_secondaries for all interface. So, networkd also enables it unconditionally. --- src/network/networkd-dhcp4.c | 55 ----------------------------------- src/network/networkd-sysctl.c | 9 ++++++ 2 files changed, 9 insertions(+), 55 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index b9a98a56a8..55526b107c 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1176,57 +1176,6 @@ static int dhcp4_set_hostname(Link *link) { return 0; } -static bool promote_secondaries_enabled(const char *ifname) { - _cleanup_free_ char *promote_secondaries_sysctl = NULL; - char *promote_secondaries_path; - int r; - - promote_secondaries_path = strjoina("net/ipv4/conf/", ifname, "/promote_secondaries"); - r = sysctl_read(promote_secondaries_path, &promote_secondaries_sysctl); - if (r < 0) { - log_debug_errno(r, "Cannot read sysctl %s", promote_secondaries_path); - return false; - } - - truncate_nl(promote_secondaries_sysctl); - r = parse_boolean(promote_secondaries_sysctl); - if (r < 0) - log_warning_errno(r, "Cannot parse sysctl %s with content %s as boolean", promote_secondaries_path, promote_secondaries_sysctl); - return r > 0; -} - -/* dhcp4_set_promote_secondaries will ensure this interface has - * the "promote_secondaries" option in the kernel set. If this sysctl - * is not set DHCP will work only as long as the IP address does not - * changes between leases. The kernel will remove all secondary IP - * addresses of an interface otherwise. The way systemd-network works - * is that the new IP of a lease is added as a secondary IP and when - * the primary one expires it relies on the kernel to promote the - * secondary IP. See also https://github.com/systemd/systemd/issues/7163 - */ -static int dhcp4_set_promote_secondaries(Link *link) { - int r; - - assert(link); - - /* check if the kernel has promote_secondaries enabled for our - * interface. If it is not globally enabled or enabled for the - * specific interface we must either enable it. - */ - if (!(promote_secondaries_enabled("all") || promote_secondaries_enabled(link->ifname))) { - char *promote_secondaries_path = NULL; - - log_link_debug(link, "promote_secondaries is unset, setting it"); - promote_secondaries_path = strjoina("net/ipv4/conf/", link->ifname, "/promote_secondaries"); - r = sysctl_write(promote_secondaries_path, "1"); - if (r < 0) - log_link_warning_errno(link, r, "Failed to set sysctl %s to 1, ignoring", promote_secondaries_path); - return r > 0; - } - - return 0; -} - static int dhcp4_set_client_identifier(Link *link) { int r; @@ -1320,10 +1269,6 @@ int dhcp4_configure(Link *link) { if (!link_dhcp4_enabled(link)) return 0; - r = dhcp4_set_promote_secondaries(link); - if (r < 0) - return r; - if (!link->dhcp_client) { r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); if (r < 0) diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index b6839f86ee..dc95d01934 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -212,6 +212,15 @@ int link_set_sysctl(Link *link) { if (r < 0) log_link_warning_errno(link, r, "Cannot set IPv4 accept_local flag for interface, ignoring: %m"); + /* If promote_secondaries is not set, DHCP will work only as long as the IP address does not + * changes between leases. The kernel will remove all secondary IP addresses of an interface + * otherwise. The way systemd-networkd works is that the new IP of a lease is added as a + * secondary IP and when the primary one expires it relies on the kernel to promote the + * secondary IP. See also https://github.com/systemd/systemd/issues/7163 */ + r = sysctl_write_ip_property_boolean(AF_INET, link->ifname, "promote_secondaries", true); + if (r < 0) + log_link_warning_errno(link, r, "Cannot enable promote_secondaries for interface, ignoring: %m"); + return 0; } From 62f12d757c414be9657437eae2b6a9d09c264a7f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:18:23 +0900 Subject: [PATCH 05/11] network: downgrade log level in dhcp4_configure() --- src/network/networkd-dhcp4.c | 83 +++++++++++++++++------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 55526b107c..c20e2e2b0a 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1161,7 +1161,7 @@ static int dhcp4_set_hostname(Link *link) { else { r = gethostname_strict(&hostname); if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */ - return r; + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to get hostname: %m"); hn = hostname; } @@ -1169,9 +1169,9 @@ static int dhcp4_set_hostname(Link *link) { r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); if (r == -EINVAL && hostname) /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */ - log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m"); + log_link_debug_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m"); else if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); return 0; } @@ -1201,7 +1201,7 @@ static int dhcp4_set_client_identifier(Link *link) { duid->raw_data_len > 0 ? duid->raw_data : NULL, duid->raw_data_len); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set IAID+DUID: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set IAID+DUID: %m"); break; } case DHCP_CLIENT_ID_DUID_ONLY: { @@ -1217,7 +1217,7 @@ static int dhcp4_set_client_identifier(Link *link) { duid->raw_data_len > 0 ? duid->raw_data : NULL, duid->raw_data_len); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set DUID: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set DUID: %m"); break; } case DHCP_CLIENT_ID_MAC: @@ -1226,7 +1226,7 @@ static int dhcp4_set_client_identifier(Link *link) { (const uint8_t *) &link->mac, sizeof(link->mac)); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m"); break; default: assert_not_reached("Unknown client identifier type."); @@ -1272,43 +1272,41 @@ int dhcp4_configure(Link *link) { if (!link->dhcp_client) { r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m"); r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m"); } r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m"); r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set ifindex: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set ifindex: %m"); r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set callback: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set callback: %m"); - r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, - link->network->dhcp_broadcast); + r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m"); - if (link->mtu) { + if (link->mtu > 0) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MTU: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MTU: %m"); } if (link->network->dhcp_use_mtu) { - r = sd_dhcp_client_set_request_option(link->dhcp_client, - SD_DHCP_OPTION_INTERFACE_MTU); + r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_INTERFACE_MTU); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for MTU: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for MTU: %m"); } /* NOTE: even if this variable is called "use", it also "sends" PRL @@ -1317,39 +1315,37 @@ int dhcp4_configure(Link *link) { /* NOTE: when using Anonymize=yes, routes PRL options are sent * by default, so they don't need to be added here. */ if (link->network->dhcp_use_routes && !link->network->dhcp_anonymize) { - r = sd_dhcp_client_set_request_option(link->dhcp_client, - SD_DHCP_OPTION_STATIC_ROUTE); + r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for static route: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for static route: %m"); - r = sd_dhcp_client_set_request_option(link->dhcp_client, - SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE); + r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for classless static route: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for classless static route: %m"); } if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO && !link->network->dhcp_anonymize) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for domain search list: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for domain search list: %m"); } if (link->network->dhcp_use_ntp) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m"); } if (link->network->dhcp_use_sip) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_SIP_SERVER); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m"); } if (link->network->dhcp_use_timezone) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m"); } SET_FOREACH(request_options, link->network->dhcp_request_options) { @@ -1357,7 +1353,7 @@ int dhcp4_configure(Link *link) { r = sd_dhcp_client_set_request_option(link->dhcp_client, option); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option); } ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options) { @@ -1365,7 +1361,7 @@ int dhcp4_configure(Link *link) { if (r == -EEXIST) continue; if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m"); } ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_vendor_options) { @@ -1373,7 +1369,7 @@ int dhcp4_configure(Link *link) { if (r == -EEXIST) continue; if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m"); } r = dhcp4_set_hostname(link); @@ -1384,53 +1380,52 @@ int dhcp4_configure(Link *link) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, link->network->dhcp_vendor_class_identifier); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m"); } if (link->network->dhcp_mudurl) { - r = sd_dhcp_client_set_mud_url(link->dhcp_client, - link->network->dhcp_mudurl); + r = sd_dhcp_client_set_mud_url(link->dhcp_client, link->network->dhcp_mudurl); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MUD URL: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MUD URL: %m"); } if (link->network->dhcp_user_class) { r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m"); } - if (link->network->dhcp_client_port) { + if (link->network->dhcp_client_port > 0) { r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m"); } if (link->network->dhcp_max_attempts > 0) { r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m"); } if (link->network->dhcp_ip_service_type > 0) { r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->dhcp_ip_service_type); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m"); } if (link->network->dhcp_fallback_lease_lifetime > 0) { r = sd_dhcp_client_set_fallback_lease_lifetime(link->dhcp_client, link->network->dhcp_fallback_lease_lifetime); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed set to lease lifetime: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed set to lease lifetime: %m"); } r = dhcp4_set_request_address(link); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set initial DHCPv4 address: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set initial DHCPv4 address: %m"); r = dhcp4_configure_dad(link); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to configure service type: %m"); + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to configure service type: %m"); return dhcp4_set_client_identifier(link); } From 31a9a27d4c211768098540b0461eacaca2d68287 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 14:43:39 +0900 Subject: [PATCH 06/11] sysctl-util: truncate newline in read value --- src/shared/sysctl-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/sysctl-util.c b/src/shared/sysctl-util.c index 8543dbd2d0..d06174eed4 100644 --- a/src/shared/sysctl-util.c +++ b/src/shared/sysctl-util.c @@ -122,6 +122,7 @@ int sysctl_read_ip_property(int af, const char *ifname, const char *property, ch if (r < 0) return r; + truncate_nl(value); if (ret) *ret = TAKE_PTR(value); From 778c879533af090e691a67f64f251686a9dbd155 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:22:47 +0900 Subject: [PATCH 07/11] network: use sysctl_read_ip_property() where applicable --- src/network/networkd-route.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index cd0f0aa707..4c3704b328 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -152,25 +152,19 @@ static const char *format_route_protocol(int protocol, char *buf, size_t size) { static unsigned routes_max(void) { static thread_local unsigned cached = 0; - _cleanup_free_ char *s4 = NULL, *s6 = NULL; unsigned val4 = ROUTES_DEFAULT_MAX_PER_FAMILY, val6 = ROUTES_DEFAULT_MAX_PER_FAMILY; if (cached > 0) return cached; - if (sysctl_read("net/ipv4/route/max_size", &s4) >= 0) { - truncate_nl(s4); - if (safe_atou(s4, &val4) >= 0 && - val4 == 2147483647U) + if (sysctl_read_ip_property(AF_INET, NULL, "route/max_size", &s4) >= 0) + if (safe_atou(s4, &val4) >= 0 && val4 == 2147483647U) /* This is the default "no limit" value in the kernel */ val4 = ROUTES_DEFAULT_MAX_PER_FAMILY; - } - if (sysctl_read("net/ipv6/route/max_size", &s6) >= 0) { - truncate_nl(s6); + if (sysctl_read_ip_property(AF_INET6, NULL, "route/max_size", &s6) >= 0) (void) safe_atou(s6, &val6); - } cached = MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val4) + MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val6); From ca97e7cda0fb3c00b96a1f1979d15cccd0f8b669 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:30:25 +0900 Subject: [PATCH 08/11] network: do not serialize/deserialize ipv4ll address The link state file is always removed on stop. So, we cannot deserialize the address from the file. Moreover, currently the IPv4 link-local address is always dropped by link_drop_foreign_addresses() on restart. Let's drop the serialize/deserialize logic for IPv4 LL address. --- src/network/networkd-ipv4ll.c | 77 ++++------------------------------- src/network/networkd-ipv4ll.h | 2 - src/network/networkd-link.c | 14 +------ 3 files changed, 11 insertions(+), 82 deletions(-) diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 3be395e1ad..e4a20aeae1 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -142,25 +142,6 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) { } } -static int ipv4ll_init(Link *link) { - int r; - - assert(link); - - if (link->ipv4ll) - return 0; - - r = sd_ipv4ll_new(&link->ipv4ll); - if (r < 0) - return r; - - r = sd_ipv4ll_attach_event(link->ipv4ll, link->manager->event, 0); - if (r < 0) - return r; - - return 0; -} - int ipv4ll_configure(Link *link) { uint64_t seed; int r; @@ -170,9 +151,15 @@ int ipv4ll_configure(Link *link) { if (!link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) return 0; - r = ipv4ll_init(link); - if (r < 0) - return r; + if (!link->ipv4ll) { + r = sd_ipv4ll_new(&link->ipv4ll); + if (r < 0) + return r; + + r = sd_ipv4ll_attach_event(link->ipv4ll, link->manager->event, 0); + if (r < 0) + return r; + } if (link->sd_device && net_get_unique_predictable_data(link->sd_device, true, &seed) >= 0) { @@ -224,52 +211,6 @@ int ipv4ll_update_mac(Link *link) { return 0; } -int link_serialize_ipv4ll(Link *link, FILE *f) { - struct in_addr address; - int r; - - assert(link); - - if (!link->ipv4ll) - return 0; - - r = sd_ipv4ll_get_address(link->ipv4ll, &address); - if (r == -ENOENT) - return 0; - if (r < 0) - return r; - - fputs("IPV4LL_ADDRESS=", f); - serialize_in_addrs(f, &address, 1, false, NULL); - fputc('\n', f); - - return 0; -} - -int link_deserialize_ipv4ll(Link *link, const char *ipv4ll_address) { - union in_addr_union address; - int r; - - assert(link); - - if (isempty(ipv4ll_address)) - return 0; - - r = in_addr_from_string(AF_INET, ipv4ll_address, &address); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to parse IPv4LL address: %s", ipv4ll_address); - - r = ipv4ll_init(link); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to initialize IPv4LL client: %m"); - - r = sd_ipv4ll_set_address(link->ipv4ll, &address.in); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to set initial IPv4LL address %s: %m", ipv4ll_address); - - return 0; -} - int config_parse_ipv4ll( const char* unit, const char *filename, diff --git a/src/network/networkd-ipv4ll.h b/src/network/networkd-ipv4ll.h index 4833e304b6..c5df691dcc 100644 --- a/src/network/networkd-ipv4ll.h +++ b/src/network/networkd-ipv4ll.h @@ -9,7 +9,5 @@ typedef struct Link Link; int ipv4ll_configure(Link *link); int ipv4ll_update_mac(Link *link); -int link_serialize_ipv4ll(Link *link, FILE *f); -int link_deserialize_ipv4ll(Link *link, const char *ipv4ll_address); CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 735dee8083..31f292043d 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2414,8 +2414,7 @@ int link_initialized(Link *link, sd_device *device) { static int link_load(Link *link) { _cleanup_free_ char *network_file = NULL, *addresses = NULL, - *routes = NULL, - *ipv4ll_address = NULL; + *routes = NULL; int r; assert(link); @@ -2423,8 +2422,7 @@ static int link_load(Link *link) { r = parse_env_file(NULL, link->state_file, "NETWORK_FILE", &network_file, "ADDRESSES", &addresses, - "ROUTES", &routes, - "IPV4LL_ADDRESS", &ipv4ll_address); + "ROUTES", &routes); if (r < 0 && r != -ENOENT) return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file); @@ -2461,10 +2459,6 @@ network_file_fail: if (r < 0) log_link_warning_errno(link, r, "Failed to load routes from %s, ignoring: %m", link->state_file); - r = link_deserialize_ipv4ll(link, ipv4ll_address); - if (r < 0) - log_link_warning_errno(link, r, "Failed to load IPv4LL address from %s, ignoring: %m", link->state_file); - return 0; } @@ -3170,10 +3164,6 @@ int link_save(Link *link) { } else (void) unlink(link->lease_file); - r = link_serialize_ipv4ll(link, f); - if (r < 0) - goto fail; - r = link_serialize_dhcp6_client(link, f); if (r < 0) goto fail; From 7b829a7b3b79ef0c1e2e06537b9850bdcf27827e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:38:29 +0900 Subject: [PATCH 09/11] network: do not serialize/deserialize addresses The link state file is always removed when networkd is stopping. So, the deserialization logic does not work. Moreover, the ADDRESSES= entry is not used by sd-network, so serialization is also not necessary. --- src/network/networkd-address.c | 54 --------------------- src/network/networkd-address.h | 2 - src/network/networkd-link.c | 12 ----- test/test-network/systemd-networkd-tests.py | 1 - 4 files changed, 69 deletions(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 1bf6514a29..bf3c7b39a0 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1248,60 +1248,6 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, return 1; } -int link_serialize_addresses(Link *link, FILE *f) { - bool space = false; - Address *a; - - assert(link); - - fputs("ADDRESSES=", f); - SET_FOREACH(a, link->addresses) { - _cleanup_free_ char *address_str = NULL; - - if (in_addr_to_string(a->family, &a->in_addr, &address_str) < 0) - continue; - - fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen); - space = true; - } - fputc('\n', f); - - return 0; -} - -int link_deserialize_addresses(Link *link, const char *addresses) { - int r; - - assert(link); - - for (const char *p = addresses;; ) { - _cleanup_(address_freep) Address *tmp = NULL; - _cleanup_free_ char *address_str = NULL; - - r = extract_first_word(&p, &address_str, NULL, 0); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to parse ADDRESSES=: %m"); - if (r == 0) - return 0; - - r = address_new(&tmp); - if (r < 0) - return log_oom(); - - r = in_addr_prefix_from_string_auto(address_str, &tmp->family, &tmp->in_addr, &tmp->prefixlen); - if (r < 0) { - log_link_debug_errno(link, r, "Failed to parse address, ignoring: %s", address_str); - continue; - } - - r = address_add(link, tmp, NULL); - if (r < 0) - log_link_debug_errno(link, r, "Failed to add address %s, ignoring: %m", address_str); - } - - return 0; -} - static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) { _cleanup_free_ char *pretty = NULL; Address *address; diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 8b0fb9b0df..22dcd081e7 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -62,8 +62,6 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free); int link_set_addresses(Link *link); int link_drop_addresses(Link *link); int link_drop_foreign_addresses(Link *link); -int link_serialize_addresses(Link *link, FILE *f); -int link_deserialize_addresses(Link *link, const char *addresses); bool link_address_is_dynamic(const Link *link, const Address *address); void ipv4_dad_unref(Link *link); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 31f292043d..5db118e77e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2413,7 +2413,6 @@ int link_initialized(Link *link, sd_device *device) { static int link_load(Link *link) { _cleanup_free_ char *network_file = NULL, - *addresses = NULL, *routes = NULL; int r; @@ -2421,7 +2420,6 @@ static int link_load(Link *link) { r = parse_env_file(NULL, link->state_file, "NETWORK_FILE", &network_file, - "ADDRESSES", &addresses, "ROUTES", &routes); if (r < 0 && r != -ENOENT) return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file); @@ -2451,10 +2449,6 @@ static int link_load(Link *link) { network_file_fail: - r = link_deserialize_addresses(link, addresses); - if (r < 0) - log_link_warning_errno(link, r, "Failed to load addresses from %s, ignoring: %m", link->state_file); - r = link_deserialize_routes(link, routes); if (r < 0) log_link_warning_errno(link, r, "Failed to load routes from %s, ignoring: %m", link->state_file); @@ -3139,12 +3133,6 @@ int link_save(Link *link) { /************************************************************/ - r = link_serialize_addresses(link, f); - if (r < 0) - goto fail; - - /************************************************************/ - r = link_serialize_routes(link, f); if (r < 0) goto fail; diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 46c4bb7a95..bfc135a041 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2891,7 +2891,6 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities): self.assertRegex(data, r'LLMNR=no') self.assertRegex(data, r'MDNS=yes') self.assertRegex(data, r'DNSSEC=no') - self.assertRegex(data, r'ADDRESSES=192.168.(10.10|12.12)/24 192.168.(12.12|10.10)/24') check_output(*resolvectl_cmd, 'dns', 'dummy98', '10.10.10.12#ccc.com', '10.10.10.13', '1111:2222::3333', env=env) check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env) From 6fdcef2174cb372bbc66050761e22f6b17139617 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:41:33 +0900 Subject: [PATCH 10/11] network: do not serialize/deserialize routes The same as the previous commit. These are not used. --- src/network/networkd-link.c | 22 ++-------- src/network/networkd-route.c | 78 ------------------------------------ src/network/networkd-route.h | 2 - 3 files changed, 4 insertions(+), 98 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 5db118e77e..6b6f772c88 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2412,15 +2412,13 @@ int link_initialized(Link *link, sd_device *device) { } static int link_load(Link *link) { - _cleanup_free_ char *network_file = NULL, - *routes = NULL; + _cleanup_free_ char *network_file = NULL; int r; assert(link); r = parse_env_file(NULL, link->state_file, - "NETWORK_FILE", &network_file, - "ROUTES", &routes); + "NETWORK_FILE", &network_file); if (r < 0 && r != -ENOENT) return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file); @@ -2432,14 +2430,14 @@ static int link_load(Link *link) { suffix = strrchr(network_file, '.'); if (!suffix) { log_link_debug(link, "Failed to get network name from %s", network_file); - goto network_file_fail; + return 0; } *suffix = '\0'; r = network_get_by_name(link->manager, basename(network_file), &network); if (r < 0) { log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file)); - goto network_file_fail; + return 0; } r = network_apply(network, link); @@ -2447,12 +2445,6 @@ static int link_load(Link *link) { return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file)); } -network_file_fail: - - r = link_deserialize_routes(link, routes); - if (r < 0) - log_link_warning_errno(link, r, "Failed to load routes from %s, ignoring: %m", link->state_file); - return 0; } @@ -3130,12 +3122,6 @@ int link_save(Link *link) { fputs_with_space(f, n, NULL, &space); fputc('\n', f); } - - /************************************************************/ - - r = link_serialize_routes(link, f); - if (r < 0) - goto fail; } print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 4c3704b328..2408981b6b 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1591,84 +1591,6 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma return 1; } -int link_serialize_routes(const Link *link, FILE *f) { - bool space = false; - Route *route; - - assert(link); - assert(link->network); - assert(f); - - fputs("ROUTES=", f); - SET_FOREACH(route, link->routes) { - _cleanup_free_ char *route_str = NULL; - - if (in_addr_to_string(route->family, &route->dst, &route_str) < 0) - continue; - - fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%"PRIu32"/"USEC_FMT, - space ? " " : "", route_str, - route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime); - space = true; - } - fputc('\n', f); - - return 0; -} - -int link_deserialize_routes(Link *link, const char *routes) { - int r; - - assert(link); - - for (const char *p = routes;; ) { - _cleanup_(route_freep) Route *tmp = NULL; - _cleanup_free_ char *route_str = NULL; - char *prefixlen_str; - - r = extract_first_word(&p, &route_str, NULL, 0); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to parse ROUTES=: %m"); - if (r == 0) - return 0; - - prefixlen_str = strchr(route_str, '/'); - if (!prefixlen_str) { - log_link_debug(link, "Failed to parse route, ignoring: %s", route_str); - continue; - } - *prefixlen_str++ = '\0'; - - r = route_new(&tmp); - if (r < 0) - return log_oom(); - - r = sscanf(prefixlen_str, - "%hhu/%hhu/%"SCNu32"/%"PRIu32"/"USEC_FMT, - &tmp->dst_prefixlen, - &tmp->tos, - &tmp->priority, - &tmp->table, - &tmp->lifetime); - if (r != 5) { - log_link_debug(link, - "Failed to parse destination prefix length, tos, priority, table or expiration: %s", - prefixlen_str); - continue; - } - - r = in_addr_from_string_auto(route_str, &tmp->family, &tmp->dst); - if (r < 0) { - log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str); - continue; - } - - r = route_add_and_setup_timer(link, tmp, NULL, NULL); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to add route: %m"); - } -} - int network_add_ipv4ll_route(Network *network) { _cleanup_(route_free_or_set_invalidp) Route *n = NULL; unsigned section_line; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index e896719e13..b5193383c0 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -75,8 +75,6 @@ int route_remove(const Route *route, Manager *manager, Link *link, link_netlink_ int link_set_routes(Link *link); int link_drop_routes(Link *link); int link_drop_foreign_routes(Link *link); -int link_serialize_routes(const Link *link, FILE *f); -int link_deserialize_routes(Link *link, const char *routes); uint32_t link_get_dhcp_route_table(const Link *link); uint32_t link_get_ipv6_accept_ra_route_table(const Link *link); From 61eb77c4b6784ca3244dbbc0f292e051f18eab71 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 28 Oct 2020 15:48:34 +0900 Subject: [PATCH 11/11] network: drop link_load() The link state file does not exist, as it is always removed on stop. --- src/network/networkd-link.c | 41 ------------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 6b6f772c88..d224842c09 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2411,43 +2411,6 @@ int link_initialized(Link *link, sd_device *device) { return 0; } -static int link_load(Link *link) { - _cleanup_free_ char *network_file = NULL; - int r; - - assert(link); - - r = parse_env_file(NULL, link->state_file, - "NETWORK_FILE", &network_file); - if (r < 0 && r != -ENOENT) - return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file); - - if (network_file) { - Network *network; - char *suffix; - - /* drop suffix */ - suffix = strrchr(network_file, '.'); - if (!suffix) { - log_link_debug(link, "Failed to get network name from %s", network_file); - return 0; - } - *suffix = '\0'; - - r = network_get_by_name(link->manager, basename(network_file), &network); - if (r < 0) { - log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file)); - return 0; - } - - r = network_apply(network, link); - if (r < 0) - return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file)); - } - - return 0; -} - int link_add(Manager *m, sd_netlink_message *message, Link **ret) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; char ifindex_str[2 + DECIMAL_STR_MAX(int)]; @@ -2467,10 +2430,6 @@ int link_add(Manager *m, sd_netlink_message *message, Link **ret) { log_link_debug(link, "Link %d added", link->ifindex); - r = link_load(link); - if (r < 0) - return r; - if (path_is_read_only_fs("/sys") <= 0) { /* udev should be around */ sprintf(ifindex_str, "n%d", link->ifindex);