From: Yu Watanabe Date: Wed, 10 Apr 2024 01:13:07 +0000 (+0900) Subject: network/ndisc: set IPv6 MTU through sysctl X-Git-Tag: v256-rc1~232^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8c9ef90b19a1fc4ca2a9c2d28895bef19030b861;p=thirdparty%2Fsystemd.git network/ndisc: set IPv6 MTU through sysctl Closes #31496. --- diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 9d15b4acce9..e56ee4f4197 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -167,6 +167,7 @@ typedef struct Link { Set *ndisc_captive_portals; Set *ndisc_pref64; Set *ndisc_redirects; + uint32_t ndisc_mtu; unsigned ndisc_messages; bool ndisc_configured:1; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index e1853bb31cc..2c21a1ce6c6 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -1027,6 +1027,37 @@ static int ndisc_router_process_hop_limit(Link *link, sd_ndisc_router *rt) { return 0; } +static int ndisc_router_process_mtu(Link *link, sd_ndisc_router *rt) { + uint32_t mtu; + int r; + + assert(link); + assert(link->network); + assert(rt); + + if (!link->network->ndisc_use_mtu) + return 0; + + /* Ignore the MTU option if the lifetime is zero. */ + r = sd_ndisc_router_get_lifetime(rt, NULL); + if (r <= 0) + return r; + + r = sd_ndisc_router_get_mtu(rt, &mtu); + if (r == -ENODATA) + return 0; + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get MTU from RA: %m"); + + link->ndisc_mtu = mtu; + + r = link_set_ipv6_mtu(link, LOG_DEBUG); + if (r < 0) + log_link_warning_errno(link, r, "Failed to apply IPv6 MTU (%"PRIu32"), ignoring: %m", mtu); + + return 0; +} + static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) { usec_t lifetime_valid_usec, lifetime_preferred_usec; _cleanup_set_free_ Set *addresses = NULL; @@ -2098,6 +2129,10 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { if (r < 0) return r; + r = ndisc_router_process_mtu(link, rt); + if (r < 0) + return r; + r = ndisc_router_process_options(link, rt); if (r < 0) return r; @@ -2432,6 +2467,7 @@ void ndisc_flush(Link *link) { link->ndisc_captive_portals = set_free(link->ndisc_captive_portals); link->ndisc_pref64 = set_free(link->ndisc_pref64); link->ndisc_redirects = set_free(link->ndisc_redirects); + link->ndisc_mtu = 0; } static const char* const ndisc_start_dhcp6_client_table[_IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX] = { diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 66ee2afeed2..68c23e0eb79 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -251,7 +251,7 @@ static int link_set_ipv6_proxy_ndp(Link *link) { } int link_set_ipv6_mtu(Link *link, int log_level) { - uint32_t mtu; + uint32_t mtu = 0; assert(link); @@ -260,7 +260,10 @@ int link_set_ipv6_mtu(Link *link, int log_level) { assert(link->network); - mtu = link->network->ipv6_mtu; + if (link->network->ndisc_use_mtu) + mtu = link->ndisc_mtu; + if (mtu == 0) + mtu = link->network->ipv6_mtu; if (mtu == 0) return 0;