]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: bump mtu if stacked vlan or macvlan requests larger size
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 27 Feb 2019 00:57:16 +0000 (09:57 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 27 Feb 2019 01:04:56 +0000 (10:04 +0900)
Closes #5972.

src/network/networkd-dhcp4.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-network.c
src/network/networkd-network.h

index c8eca6654582390d3b199bc14a403c54009d9acf..85685d6df7eb899a085fd86de75932fce8c21ce4 100644 (file)
@@ -261,7 +261,7 @@ static int dhcp_lease_lost(Link *link) {
 
                 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
                 if (r >= 0 && link->original_mtu != mtu) {
-                        r = link_set_mtu(link, link->original_mtu);
+                        r = link_set_mtu(link, link->original_mtu, true);
                         if (r < 0) {
                                 log_link_warning(link,
                                                  "DHCP error: could not reset MTU");
@@ -451,7 +451,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
 
                 r = sd_dhcp_lease_get_mtu(lease, &mtu);
                 if (r >= 0) {
-                        r = link_set_mtu(link, mtu);
+                        r = link_set_mtu(link, mtu, true);
                         if (r < 0)
                                 log_link_error_errno(link, r, "Failed to set MTU to %" PRIu16 ": %m", mtu);
                 }
index 22b639bad6a882ef08d094a737348b74bc206e64..1738a0d944ab1d6df44631a48087642fb20402ed 100644 (file)
@@ -1427,7 +1427,7 @@ static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
         return 1;
 }
 
-int link_set_mtu(Link *link, uint32_t mtu) {
+int link_set_mtu(Link *link, uint32_t mtu, bool force) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
@@ -1435,7 +1435,10 @@ int link_set_mtu(Link *link, uint32_t mtu) {
         assert(link->manager);
         assert(link->manager->rtnl);
 
-        if (link->mtu == mtu || link->setting_mtu)
+        if (mtu == 0 || link->setting_mtu)
+                return 0;
+
+        if (force ? link->mtu == mtu : link->mtu >= mtu)
                 return 0;
 
         log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
@@ -3118,11 +3121,9 @@ static int link_configure(Link *link) {
                         return r;
         }
 
-        if (link->network->mtu > 0) {
-                r = link_set_mtu(link, link->network->mtu);
-                if (r < 0)
-                        return r;
-        }
+        r = link_set_mtu(link, link->network->mtu, link->network->mtu_is_set);
+        if (r < 0)
+                return r;
 
         if (socket_ipv6_is_supported()) {
                 r = link_configure_addrgen_mode(link);
index 8b88d3de5db2c97e4edf6c02934daddd8aa17f7f..b6b7c92b4f48d4a11f22e98f27d9b2340963252a 100644 (file)
@@ -166,7 +166,7 @@ bool link_has_carrier(Link *link);
 
 int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
 
-int link_set_mtu(Link *link, uint32_t mtu);
+int link_set_mtu(Link *link, uint32_t mtu, bool force);
 
 int ipv4ll_configure(Link *link);
 int dhcp4_configure(Link *link);
index 7826ba2140ca7afa70e7572989b69269f272a15d..338137f348394a6e06ae0c4c7043d219b3d9d9b5 100644 (file)
@@ -174,9 +174,28 @@ static int network_resolve_stacked_netdevs(Network *network) {
         return 0;
 }
 
+static uint32_t network_get_stacked_netdevs_mtu(Network *network) {
+        uint32_t mtu = 0;
+        NetDev *dev;
+        Iterator i;
+
+        HASHMAP_FOREACH(dev, network->stacked_netdevs, i)
+                if (dev->kind == NETDEV_KIND_VLAN && dev->mtu > 0)
+                        /* See vlan_dev_change_mtu() in kernel.
+                         * Note that the additional 4bytes may not be necessary for all devices. */
+                        mtu = MAX(mtu, dev->mtu + 4);
+
+                else if (dev->kind == NETDEV_KIND_MACVLAN && dev->mtu > mtu)
+                        /* See macvlan_change_mtu() in kernel. */
+                        mtu = dev->mtu;
+
+        return mtu;
+}
+
 static int network_verify(Network *network) {
         Address *address;
         Route *route;
+        uint32_t mtu;
 
         assert(network);
         assert(network->filename);
@@ -246,7 +265,16 @@ static int network_verify(Network *network) {
         if (network->ip_masquerade)
                 network->ip_forward |= ADDRESS_FAMILY_IPV4;
 
-        if (network->mtu > 0 && network->dhcp_use_mtu) {
+        network->mtu_is_set = network->mtu > 0;
+        mtu = network_get_stacked_netdevs_mtu(network);
+        if (network->mtu < mtu) {
+                if (network->mtu_is_set)
+                        log_notice("%s: Bumping MTUBytes= from %"PRIu32" to %"PRIu32" because of stacked device",
+                                   network->filename, network->mtu, mtu);
+                network->mtu = mtu;
+        }
+
+        if (network->mtu_is_set && network->dhcp_use_mtu) {
                 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
                             "Disabling UseMTU=.", network->filename);
                 network->dhcp_use_mtu = false;
index 6b9b155b679dde03ec83c345e6e58f645d670a6b..63d0328750f37e85acf89f1c649c1f2dd01cc11a 100644 (file)
@@ -227,6 +227,7 @@ struct Network {
 
         struct ether_addr *mac;
         uint32_t mtu;
+        bool mtu_is_set; /* Indicate MTUBytes= is specified. */
         int arp;
         int multicast;
         int allmulticast;