diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index fc33f89a388..416874fbaff 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -691,6 +691,15 @@
The valid range is 0-1048575.
+
+
+ IPDoNotFragment=
+
+ Allows to set the IPv4 Do not Fragment (DF) bit in outgoing packets, or to inherit its
+ value from the IPv4 inner header. Takes a boolean value, or inherit. Set
+ to inherit if the encapsulated protocol is IPv6. When unset, the kernel's
+ default will be used.
+
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index fe5e53f2a83..e2c994e9717 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -124,6 +124,7 @@ VXLAN.MaximumFDBEntries, config_parse_unsigned,
VXLAN.PortRange, config_parse_port_range, 0, 0
VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port)
VXLAN.FlowLabel, config_parse_flow_label, 0, 0
+VXLAN.IPDoNotFragment, config_parse_df, 0, offsetof(VxLan, df)
GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id)
GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote)
GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos)
diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c
index 56c97cb6865..126f6138a36 100644
--- a/src/network/netdev/vxlan.c
+++ b/src/network/netdev/vxlan.c
@@ -7,6 +7,7 @@
#include "conf-parser.h"
#include "alloc-util.h"
#include "extract-word.h"
+#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "parse-util.h"
@@ -15,6 +16,15 @@
#include "networkd-link.h"
#include "netdev/vxlan.h"
+static const char* const df_table[_NETDEV_VXLAN_DF_MAX] = {
+ [NETDEV_VXLAN_DF_NO] = "no",
+ [NETDEV_VXLAN_DF_YES] = "yes",
+ [NETDEV_VXLAN_DF_INHERIT] = "inherit",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(df, VxLanDF, NETDEV_VXLAN_DF_YES);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_df, df, VxLanDF, "Failed to parse VXLAN IPDoNotFragment= setting");
+
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
VxLan *v;
int r;
@@ -150,6 +160,12 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GPE attribute: %m");
}
+ if (v->df != _NETDEV_VXLAN_DF_INVALID) {
+ r = sd_netlink_message_append_u8(m, IFLA_VXLAN_DF, v->df);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_DF attribute: %m");
+ }
+
return r;
}
@@ -305,6 +321,7 @@ static void vxlan_init(NetDev *netdev) {
assert(v);
v->vni = VXLAN_VID_MAX + 1;
+ v->df = _NETDEV_VXLAN_DF_INVALID;
v->learning = true;
v->udpcsum = false;
v->udp6zerocsumtx = false;
diff --git a/src/network/netdev/vxlan.h b/src/network/netdev/vxlan.h
index ad72a10b2fd..d448e3ccfe2 100644
--- a/src/network/netdev/vxlan.h
+++ b/src/network/netdev/vxlan.h
@@ -3,12 +3,22 @@
typedef struct VxLan VxLan;
+#include
+
#include "in-addr-util.h"
#include "netdev/netdev.h"
#define VXLAN_VID_MAX (1u << 24) - 1
#define VXLAN_FLOW_LABEL_MAX_MASK 0xFFFFFU
+typedef enum VxLanDF {
+ NETDEV_VXLAN_DF_NO = VXLAN_DF_UNSET,
+ NETDEV_VXLAN_DF_YES = VXLAN_DF_SET,
+ NETDEV_VXLAN_DF_INHERIT = VXLAN_DF_INHERIT,
+ _NETDEV_VXLAN_DF_MAX,
+ _NETDEV_VXLAN_DF_INVALID = -1
+} VxLanDF;
+
struct VxLan {
NetDev meta;
@@ -18,6 +28,8 @@ struct VxLan {
int local_family;
int group_family;
+ VxLanDF df;
+
union in_addr_union remote;
union in_addr_union local;
union in_addr_union group;
@@ -50,6 +62,10 @@ struct VxLan {
DEFINE_NETDEV_CAST(VXLAN, VxLan);
extern const NetDevVTable vxlan_vtable;
+const char *df_to_string(VxLanDF d) _const_;
+VxLanDF df_from_string(const char *d) _pure_;
+
CONFIG_PARSER_PROTOTYPE(config_parse_vxlan_address);
CONFIG_PARSER_PROTOTYPE(config_parse_port_range);
CONFIG_PARSER_PROTOTYPE(config_parse_flow_label);
+CONFIG_PARSER_PROTOTYPE(config_parse_df);
diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev
index 56d41834720..f2189e1ccf2 100644
--- a/test/fuzz/fuzz-netdev-parser/directives.netdev
+++ b/test/fuzz/fuzz-netdev-parser/directives.netdev
@@ -109,6 +109,7 @@ ReduceARPProxy=
PortRange=
UDPChecksum=
UDP6ZeroCheckSumTx=
+IPDoNotFragment=
[VXCAN]
Peer=
[Bond]