diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index ed765e1b9c..5b5536df90 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -1220,7 +1220,19 @@ DiscoverPathMTU= Takes a boolean. When true, enables Path MTU Discovery on - the tunnel. + the tunnel. + When IgnoreDontFragment= is enabled, + defaults to false. Otherwise, defaults to true. + + + + IgnoreDontFragment= + + Takes a boolean. When true, enables IPv4 Don't Fragment (DF) suppression on + the tunnel. Defaults to false. + Note that if IgnoreDontFragment= is set to true, + DiscoverPathMTU= cannot be set to true. + Only applicable to GRE, GRETAP, and ERSPAN tunnels. diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index ade5b1b919..d5aa522de8 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -77,7 +77,8 @@ Tunnel.TTL, config_parse_unsigned, Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key) Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey) Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey) -Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc) +Tunnel.DiscoverPathMTU, config_parse_tristate, 0, offsetof(Tunnel, pmtudisc) +Tunnel.IgnoreDontFragment, config_parse_bool, 0, offsetof(Tunnel, ignore_df) Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode) Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, 0 Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp) diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c index 2addfeecaa..881be3c405 100644 --- a/src/network/netdev/tunnel.c +++ b/src/network/netdev/tunnel.c @@ -378,6 +378,10 @@ static int netdev_gre_erspan_fill_message_create(NetDev *netdev, Link *link, sd_ if (r < 0) return r; + r = sd_netlink_message_append_u8(m, IFLA_GRE_IGNORE_DF, t->ignore_df); + if (r < 0) + return r; + if (t->key != 0) { ikey = okey = htobe32(t->key); iflags |= GRE_KEY; @@ -746,6 +750,11 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) { "The local address cannot be '%s' when Independent= or AssignToLoopback= is enabled, ignoring.", strna(netdev_local_address_type_to_string(t->local_type))); + if (t->pmtudisc > 0 && t->ignore_df) + return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL), + "IgnoreDontFragment= cannot be enabled when DiscoverPathMTU= is enabled"); + if (t->pmtudisc < 0) + t->pmtudisc = !t->ignore_df; return 0; } @@ -1189,7 +1198,7 @@ static void netdev_tunnel_init(NetDev *netdev) { assert(t); t->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID; - t->pmtudisc = true; + t->pmtudisc = -1; t->fou_encap_type = NETDEV_FOO_OVER_UDP_ENCAP_DIRECT; t->isatap = -1; t->gre_erspan_sequence = -1; diff --git a/src/network/netdev/tunnel.h b/src/network/netdev/tunnel.h index 7c81f22391..713f2fbf37 100644 --- a/src/network/netdev/tunnel.h +++ b/src/network/netdev/tunnel.h @@ -54,7 +54,8 @@ typedef struct Tunnel { Ip6TnlMode ip6tnl_mode; FooOverUDPEncapType fou_encap_type; - bool pmtudisc; + int pmtudisc; + bool ignore_df; bool copy_dscp; bool independent; bool fou_tunnel; diff --git a/test/test-network/conf/25-erspan0-tunnel.netdev b/test/test-network/conf/25-erspan0-tunnel.netdev index ee295d901f..0ed03803a6 100644 --- a/test/test-network/conf/25-erspan0-tunnel.netdev +++ b/test/test-network/conf/25-erspan0-tunnel.netdev @@ -13,3 +13,4 @@ Local = 172.16.1.200 Remote = 172.16.1.100 Key=101 SerializeTunneledPackets=true +IgnoreDontFragment=true diff --git a/test/test-network/conf/25-gretap-tunnel.netdev b/test/test-network/conf/25-gretap-tunnel.netdev index 86ac3f7c5b..af5ea2fb2b 100644 --- a/test/test-network/conf/25-gretap-tunnel.netdev +++ b/test/test-network/conf/25-gretap-tunnel.netdev @@ -8,3 +8,4 @@ Local=10.65.223.238 Remote=10.65.223.239 Key=106 SerializeTunneledPackets=true +IgnoreDontFragment=true diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index b5ef83a9c0..c068f37a8a 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1796,6 +1796,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): self.assertRegex(output, 'okey 0.0.0.106') self.assertRegex(output, 'iseq') self.assertRegex(output, 'oseq') + self.assertIn('nopmtudisc', output) + self.assertIn('ignore-df', output) output = check_output('ip -d link show gretap98') print(output) self.assertRegex(output, 'gretap remote 10.65.223.239 local any dev dummy98') @@ -1955,6 +1957,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): self.assertNotIn('erspan_hwid 1f', output) self.assertIn('ikey 0.0.0.101', output) self.assertIn('iseq', output) + self.assertIn('nopmtudisc', output) + self.assertIn('ignore-df', output) output = check_output('ip -d link show erspan98') print(output) self.assertIn('erspan remote 172.16.1.100 local any', output)