]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/ndisc: set IPv6 MTU through sysctl
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 10 Apr 2024 01:13:07 +0000 (10:13 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 10 Apr 2024 03:22:43 +0000 (12:22 +0900)
Closes #31496.

src/network/networkd-link.h
src/network/networkd-ndisc.c
src/network/networkd-sysctl.c

index 9d15b4acce915266a6dca71858279c6020a97aee..e56ee4f41974d8c6825e25bf9f13a8c999bc747e 100644 (file)
@@ -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;
 
index e1853bb31ccf6b26437d4aae96c4d2c03354374f..2c21a1ce6c6100835b448fb96161a4644907fd8f 100644 (file)
@@ -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] = {
index 66ee2afeed2e97675b6fe96afb95a141b28966e9..68c23e0eb7962f51693bb0531c8d46cf7973892a 100644 (file)
@@ -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;