diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index bc09e3c403..92237c4e0f 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -537,7 +537,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); @@ -1257,60 +1257,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 56e81da822..036ac7a564 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -62,8 +62,7 @@ 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); int ipv4_dad_stop(Link *link); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 3983b33527..a521822a50 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,60 +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 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, "cannot set sysctl %s to 1", promote_secondaries_path); - return r > 0; - } + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); return 0; } @@ -1252,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: { @@ -1268,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: { @@ -1286,7 +1235,7 @@ static int dhcp4_set_client_identifier(Link *link) { hw_addr, hw_addr_len); 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: @@ -1296,23 +1245,27 @@ static int dhcp4_set_client_identifier(Link *link) { return 0; } -static int dhcp4_init(Link *link) { - int r; +static int dhcp4_set_request_address(Link *link) { + Address *a; assert(link); + assert(link->network); + assert(link->dhcp_client); - if (link->dhcp_client) + if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) return 0; - r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); - if (r < 0) - return r; + SET_FOREACH(a, link->addresses_foreign) { + if (a->family != AF_INET) + continue; + if (link_address_is_dynamic(link, a)) + break; + } - r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0); - if (r < 0) - return r; + if (!a) + return 0; - return 0; + return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in); } int dhcp4_configure(Link *link) { @@ -1326,45 +1279,45 @@ 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) + return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m"); - r = dhcp4_init(link); - if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to initialize DHCP4 client: %m"); + r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0); + if (r < 0) + 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, link->hw_addr.addr.bytes, link->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL, link->hw_addr.length, link->iftype); 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 @@ -1373,39 +1326,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) { @@ -1413,7 +1364,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) { @@ -1421,7 +1372,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) { @@ -1429,7 +1380,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); @@ -1440,49 +1391,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_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); } @@ -1512,30 +1466,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 daab5b1d7d..7500a23c3b 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-ipv4ll.c b/src/network/networkd-ipv4ll.c index 295abe866e..598af25de6 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 fae48cd921..82acc2ec70 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 ced18de425..4feda54c70 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2415,69 +2415,6 @@ int link_initialized(Link *link, sd_device *device) { return 0; } -static int link_load(Link *link) { - _cleanup_free_ char *network_file = NULL, - *addresses = NULL, - *routes = NULL, - *dhcp4_address = NULL, - *ipv4ll_address = NULL; - int r; - - assert(link); - - r = parse_env_file(NULL, link->state_file, - "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); - - 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); - goto network_file_fail; - } - *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; - } - - r = network_apply(network, link); - if (r < 0) - return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file)); - } - -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); - - 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); - - 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)]; @@ -2497,10 +2434,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); @@ -3146,18 +3079,6 @@ int link_save(Link *link) { fputs_with_space(f, n, NULL, &space); fputc('\n', f); } - - /************************************************************/ - - r = link_serialize_addresses(link, f); - if (r < 0) - goto fail; - - /************************************************************/ - - r = link_serialize_routes(link, f); - if (r < 0) - goto fail; } print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links); @@ -3174,10 +3095,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; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 10f30c1a7e..f477db1902 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); @@ -1597,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 f59369392f..82ef4ee2a0 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); diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 518fe8e131..add069e470 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; } diff --git a/src/shared/sysctl-util.c b/src/shared/sysctl-util.c index 670c33108b..a835a8bd0a 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); diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 1062f93e55..688238777d 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)