]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/setlink: adjust requested MTU when it is ready to set
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 10 Apr 2024 02:35:21 +0000 (11:35 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 10 Apr 2024 03:15:33 +0000 (12:15 +0900)
This should not change any effective behavior.
Just for safety, and making the logic consistent with others, e.g.
setting master ifindex.

src/network/networkd-setlink.c

index eb65429a783ff0b6d31b5931baf8cbb1dc5d7f78..a7e04dde2e7882be6b2e074460dde621c6d733af 100644 (file)
@@ -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,