diff --git a/man/systemd.network.xml b/man/systemd.network.xml index cbf53f323a..31af7cfa98 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1167,6 +1167,7 @@ When true, the interface maximum transmission unit from the DHCP server will be used on the current link. + If MTUBytes= is set, then this setting is ignored. Defaults to false. diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index c169ffa160..9b55598482 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1263,6 +1263,8 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userd return 0; } +static int link_configure_after_setting_mtu(Link *link); + static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_(link_unrefp) Link *link = userdata; int r; @@ -1271,12 +1273,21 @@ static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda assert(link); assert(link->ifname); + link->setting_mtu = false; + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; r = sd_netlink_message_get_errno(m); - if (r < 0) + if (r < 0) { log_link_warning_errno(link, r, "Could not set MTU: %m"); + return 1; + } + + log_link_debug(link, "Setting MTU done."); + + if (link->state == LINK_STATE_PENDING) + (void) link_configure_after_setting_mtu(link); return 1; } @@ -1289,6 +1300,9 @@ int link_set_mtu(Link *link, uint32_t mtu) { assert(link->manager); assert(link->manager->rtnl); + if (link->mtu == mtu || link->setting_mtu) + return 0; + log_link_debug(link, "Setting MTU: %" PRIu32, mtu); r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); @@ -1296,23 +1310,19 @@ int link_set_mtu(Link *link, uint32_t mtu) { return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); /* If IPv6 not configured (no static IPv6 address and IPv6LL autoconfiguration is disabled) - for this interface, or if it is a bridge slave, then disable IPv6 else enable it. */ + * for this interface, or if it is a bridge slave, then disable IPv6 else enable it. */ (void) link_enable_ipv6(link); /* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes - on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */ - if (link_ipv6_enabled(link) && link->network->mtu < IPV6_MIN_MTU) { + * on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */ + if (link_ipv6_enabled(link) && mtu < IPV6_MIN_MTU) { log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as " "IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes: %m"); - link->network->mtu = IPV6_MIN_MTU; + mtu = IPV6_MIN_MTU; } - r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu); - if (r < 0) - return log_link_error_errno(link, r, "Could not set MTU: %m"); - r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu); if (r < 0) return log_link_error_errno(link, r, "Could not append MTU: %m"); @@ -1691,11 +1701,6 @@ static int link_acquire_conf(Link *link) { assert(link); - if (link->setting_mtu) { - link->setting_mtu = false; - return 0; - } - r = link_acquire_ipv4_conf(link); if (r < 0) return r; @@ -2859,6 +2864,19 @@ static int link_configure(Link *link) { return r; } + return link_configure_after_setting_mtu(link); +} + +static int link_configure_after_setting_mtu(Link *link) { + int r; + + assert(link); + assert(link->network); + assert(link->state == LINK_STATE_PENDING); + + if (link->setting_mtu) + return 0; + if (link_has_carrier(link) || link->network->configure_without_carrier) { r = link_acquire_conf(link); if (r < 0) @@ -3406,8 +3424,8 @@ static int link_carrier_lost(Link *link) { assert(link); /* Some devices reset itself while setting the MTU. This causes the DHCP client fall into a loop. - setting_mtu keep track whether the device got reset because of setting MTU and does not drop the - configuration and stop the clients as well. */ + * setting_mtu keep track whether the device got reset because of setting MTU and does not drop the + * configuration and stop the clients as well. */ if (link->setting_mtu) return 0; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index c7d162de67..107762d519 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -281,6 +281,12 @@ static int network_load_one(Manager *manager, const char *filename) { if (network->ip_masquerade) network->ip_forward |= ADDRESS_FAMILY_IPV4; + if (network->mtu > 0 && network->dhcp_use_mtu) { + log_warning("MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set in %s. " + "Disabling UseMTU=.", filename); + network->dhcp_use_mtu = false; + } + LIST_PREPEND(networks, manager->networks, network); r = hashmap_ensure_allocated(&manager->networks_by_name, &string_hash_ops);