From 1c8b0eccc788e94a9ff1987948e9af35efc246cd Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 8 May 2019 20:09:42 +0530 Subject: [PATCH 1/3] networkd: Assign VXLAN destination port to when GPE is set When VXLAN destination port is unset and GPE is set then assign 4790 to destination port. Kernel does the same as well as iproute. IANA VXLAN-GPE port is 4790 --- man/systemd.netdev.xml | 3 ++- src/network/netdev/vxlan.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 7fddedf6e8..fc33f89a38 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -661,7 +661,8 @@ Takes a boolean. When true, Generic Protocol Extension extends the existing VXLAN protocol to provide protocol typing, OAM, and versioning capabilities. For details about the VXLAN GPE Header, see the - Generic Protocol Extension for VXLAN document. Defaults to false. + Generic Protocol Extension for VXLAN document. If destination port is not specified and + Generic Protocol Extension is set then default port of 4790 is used. Defaults to false. diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c index 86403696a0..56c97cb686 100644 --- a/src/network/netdev/vxlan.c +++ b/src/network/netdev/vxlan.c @@ -289,6 +289,9 @@ static int netdev_vxlan_verify(NetDev *netdev, const char *filename) { "%s: VXLAN TTL must be <= 255. Ignoring.", filename); + if (!v->dest_port && v->generic_protocol_extension) + v->dest_port = 4790; + return 0; } From 2a36d4006d195203d92c679037bf4bb981900914 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 8 May 2019 22:29:40 +0530 Subject: [PATCH 2/3] sd-netlink: Add VXLAN netlink properties Add IFLA_VXLAN_DF and IFLA_VXLAN_TTL_INHERIT --- src/libsystemd/sd-netlink/netlink-types.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 118f319a20..192033fd69 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -170,6 +170,8 @@ static const NLType rtnl_link_info_data_vxlan_types[] = { [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 }, [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 }, [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_TTL_INHERIT] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_DF] = { .type = NETLINK_TYPE_U8 }, }; static const NLType rtnl_bond_arp_target_types[] = { From 1189c00a3c41e0982fb598909911f5a58c278adc Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 8 May 2019 22:31:08 +0530 Subject: [PATCH 3/3] networkd: VXLAN add support to configure IP Don't fragment. Allow users to set the IPv4 DF bit in outgoing packets, or to inherit its value from the IPv4 inner header. If the encapsulated protocol is IPv6 and DF is configured to be inherited, always set it. --- man/systemd.netdev.xml | 9 +++++++++ src/network/netdev/netdev-gperf.gperf | 1 + src/network/netdev/vxlan.c | 17 +++++++++++++++++ src/network/netdev/vxlan.h | 16 ++++++++++++++++ test/fuzz/fuzz-netdev-parser/directives.netdev | 1 + 5 files changed, 44 insertions(+) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index fc33f89a38..416874fbaf 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 fe5e53f2a8..e2c994e971 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 56c97cb686..126f6138a3 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 ad72a10b2f..d448e3ccfe 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 56d4183472..f2189e1ccf 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]