summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-11-27 09:08:01 +0900
committerGitHub <noreply@github.com>2020-11-27 09:08:01 +0900
commitdca63b5b46f36989f69b154d7af3b4da433ae59e (patch)
tree9ce43d3630e029a3a53a1fb3821bc337523b4d3f
parent0d5eb02134c6420a7b929915df5a1b18ba841911 (diff)
parent61eb77c4b6784ca3244dbbc0f292e051f18eab71 (diff)
downloadsystemd-dca63b5b46f36989f69b154d7af3b4da433ae59e.tar.gz
Merge pull request #17474 from yuwata/network-drop-link-deserialization-logic
network: drop link deserialization logic
-rw-r--r--src/network/networkd-address.c56
-rw-r--r--src/network/networkd-address.h3
-rw-r--r--src/network/networkd-dhcp4.c194
-rw-r--r--src/network/networkd-dhcp4.h2
-rw-r--r--src/network/networkd-ipv4ll.c77
-rw-r--r--src/network/networkd-ipv4ll.h2
-rw-r--r--src/network/networkd-link.c83
-rw-r--r--src/network/networkd-route.c90
-rw-r--r--src/network/networkd-route.h2
-rw-r--r--src/network/networkd-sysctl.c9
-rw-r--r--src/shared/sysctl-util.c1
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py1
12 files changed, 86 insertions, 434 deletions
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)