From: Yu Watanabe Date: Wed, 10 Apr 2024 02:35:21 +0000 (+0900) Subject: network/setlink: adjust requested MTU when it is ready to set X-Git-Tag: v256-rc1~232^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4386dd1c84ecb0c6eff0160f64849d24a1cf989;p=thirdparty%2Fsystemd.git network/setlink: adjust requested MTU when it is ready to set This should not change any effective behavior. Just for safety, and making the logic consistent with others, e.g. setting master ifindex. --- diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index eb65429a783..a7e04dde2e7 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -453,6 +453,43 @@ static bool netdev_is_ready(NetDev *netdev) { return true; } +static uint32_t link_adjust_mtu(Link *link, uint32_t mtu) { + const char *origin; + uint32_t min_mtu; + + assert(link); + assert(link->network); + + min_mtu = link->min_mtu; + origin = "the minimum MTU of the interface"; + if (link_ipv6_enabled(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 (min_mtu < IPV6_MIN_MTU) { + min_mtu = IPV6_MIN_MTU; + origin = "the minimum IPv6 MTU"; + } + if (min_mtu < link->network->ipv6_mtu) { + min_mtu = link->network->ipv6_mtu; + origin = "the requested IPv6 MTU in IPv6MTUBytes="; + } + } + + if (mtu < min_mtu) { + log_link_warning(link, "Bumping the requested MTU %"PRIu32" to %s (%"PRIu32")", + mtu, origin, min_mtu); + mtu = min_mtu; + } + + if (mtu > link->max_mtu) { + log_link_warning(link, "Reducing the requested MTU %"PRIu32" to the interface's maximum MTU %"PRIu32".", + mtu, link->max_mtu); + mtu = link->max_mtu; + } + + return mtu; +} + static int link_is_ready_to_set_link(Link *link, Request *req) { int r; @@ -570,13 +607,24 @@ static int link_is_ready_to_set_link(Link *link, Request *req) { })) return false; - /* Changing FD mode may affect MTU. */ + /* Changing FD mode may affect MTU. + * See https://docs.kernel.org/networking/can.html#can-fd-flexible-data-rate-driver-support + * MTU = 16 (CAN_MTU) => Classical CAN device + * MTU = 72 (CANFD_MTU) => CAN FD capable device */ if (ordered_set_contains(link->manager->request_queue, &(const Request) { .link = link, .type = REQUEST_TYPE_SET_LINK_CAN, })) return false; + + /* Now, it is ready to set MTU, but before setting, adjust requested MTU. */ + uint32_t mtu = link_adjust_mtu(link, PTR_TO_UINT32(req->userdata)); + if (mtu == link->mtu) + return -EALREADY; /* Not necessary to set the same value. */ + + req->userdata = UINT32_TO_PTR(mtu); + return true; } default: break; @@ -865,51 +913,12 @@ int link_request_to_set_master(Link *link) { } int link_request_to_set_mtu(Link *link, uint32_t mtu) { - const char *origin; - uint32_t min_mtu, max_mtu; Request *req; int r; assert(link); - assert(link->network); - - min_mtu = link->min_mtu; - origin = "the minimum MTU of the interface"; - if (link_ipv6_enabled(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 (min_mtu < IPV6_MIN_MTU) { - min_mtu = IPV6_MIN_MTU; - origin = "the minimum IPv6 MTU"; - } - if (min_mtu < link->network->ipv6_mtu) { - min_mtu = link->network->ipv6_mtu; - origin = "the requested IPv6 MTU in IPv6MTUBytes="; - } - } - - if (mtu < min_mtu) { - log_link_warning(link, "Bumping the requested MTU %"PRIu32" to %s (%"PRIu32")", - mtu, origin, min_mtu); - mtu = min_mtu; - } - - max_mtu = link->max_mtu; - if (link->iftype == ARPHRD_CAN) - /* The maximum MTU may be changed when FD mode is changed. - * See https://docs.kernel.org/networking/can.html#can-fd-flexible-data-rate-driver-support - * MTU = 16 (CAN_MTU) => Classical CAN device - * MTU = 72 (CANFD_MTU) => CAN FD capable device - * So, even if the current maximum is 16, we should not reduce the requested value now. */ - max_mtu = MAX(max_mtu, 72u); - - if (mtu > max_mtu) { - log_link_warning(link, "Reducing the requested MTU %"PRIu32" to the interface's maximum MTU %"PRIu32".", - mtu, max_mtu); - mtu = max_mtu; - } - if (link->mtu == mtu) + if (mtu == 0) return 0; r = link_request_set_link(link, REQUEST_TYPE_SET_LINK_MTU,