summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-02-27 17:15:29 +0100
committerGitHub <noreply@github.com>2019-02-27 17:15:29 +0100
commit4b151b71320bbee1549afcbad5554a40d90d63b4 (patch)
tree58313bc1f5c2e941a39a5073073da4b0aa381ca6 /src
parentanalyze security: check for ProtectHostname=yes (diff)
parenttest-network: add test for MTUBytes= in vlan or macvlan devices (diff)
downloadsystemd-4b151b71320bbee1549afcbad5554a40d90d63b4.tar.xz
systemd-4b151b71320bbee1549afcbad5554a40d90d63b4.zip
Merge pull request #11807 from yuwata/test-vlan-mtu
network: increase MTU if VLAN= or MACVLAN= requests higher value
Diffstat (limited to 'src')
-rw-r--r--src/network/networkd-dhcp4.c4
-rw-r--r--src/network/networkd-link.c15
-rw-r--r--src/network/networkd-link.h2
-rw-r--r--src/network/networkd-network.c30
-rw-r--r--src/network/networkd-network.h1
5 files changed, 41 insertions, 11 deletions
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index c8eca66545..85685d6df7 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -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);
}
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 22b639bad6..1738a0d944 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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);
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 8b88d3de5d..b6b7c92b4f 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -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);
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 75dd8b9e4e..034fa43999 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -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;
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 6b9b155b67..63d0328750 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -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;