Merge pull request #17474 from yuwata/network-drop-link-deserialization-logic

network: drop link deserialization logic
This commit is contained in:
Yu Watanabe 2020-11-27 09:08:01 +09:00 committed by GitHub
commit dca63b5b46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 86 additions and 434 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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)