From 66409d1bccbdddd8833f74876a1e7ef250034d4e Mon Sep 17 00:00:00 2001 From: Andrew Evans Date: Fri, 29 Apr 2011 17:05:58 -0700 Subject: [PATCH] tunneling: Add df_default and df_inherit tunnel options. Split existing pmtud tunnel option's functionality into three. Existing pmtud option still exists, but now governs only whether datapath sends ICMP frag needed messages. New df_inherit option controls whether DF bit is copied from packet inner header to outer tunnel header. New df_default option controls whether DF bit is set if inner packet isn't IP or if df_inherit is disabled. Suggested-by: Jesse Gross Signed-off-by: Andrew Evans Feature #5456. --- datapath/tunnel.c | 14 ++++---- include/openvswitch/tunnel.h | 8 +++-- lib/netdev-vport.c | 16 ++++++++- vswitchd/vswitch.xml | 66 ++++++++++++++++++++++++++++-------- 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 899d1cdcb..70a4cd7ca 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -725,8 +725,9 @@ static bool check_mtu(struct sk_buff *skb, const struct tnl_mutable_config *mutable, const struct rtable *rt, __be16 *frag_offp) { + bool df_inherit = mutable->flags & TNL_F_DF_INHERIT; bool pmtud = mutable->flags & TNL_F_PMTUD; - __be16 frag_off = 0; + __be16 frag_off = mutable->flags & TNL_F_DF_DEFAULT ? htons(IP_DF) : 0; int mtu = 0; unsigned int packet_length = skb->len - ETH_HLEN; @@ -738,8 +739,6 @@ static bool check_mtu(struct sk_buff *skb, if (pmtud) { int vlan_header = 0; - frag_off = htons(IP_DF); - /* The tag needs to go in packet regardless of where it * currently is, so subtract it from the MTU. */ @@ -756,7 +755,8 @@ static bool check_mtu(struct sk_buff *skb, if (skb->protocol == htons(ETH_P_IP)) { struct iphdr *iph = ip_hdr(skb); - frag_off |= iph->frag_off & htons(IP_DF); + if (df_inherit) + frag_off = iph->frag_off & htons(IP_DF); if (pmtud && iph->frag_off & htons(IP_DF)) { mtu = max(mtu, IP_MIN_MTU); @@ -769,8 +769,10 @@ static bool check_mtu(struct sk_buff *skb, } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) else if (skb->protocol == htons(ETH_P_IPV6)) { - /* IPv6 requires PMTUD if the packet is above the minimum MTU. */ - if (packet_length > IPV6_MIN_MTU) + /* IPv6 requires end hosts to do fragmentation + * if the packet is above the minimum MTU. + */ + if (df_inherit && packet_length > IPV6_MIN_MTU) frag_off = htons(IP_DF); if (pmtud) { diff --git a/include/openvswitch/tunnel.h b/include/openvswitch/tunnel.h index a394f8a8d..5e2e91644 100644 --- a/include/openvswitch/tunnel.h +++ b/include/openvswitch/tunnel.h @@ -65,8 +65,10 @@ enum { #define TNL_F_CSUM (1 << 0) /* Checksum packets. */ #define TNL_F_TOS_INHERIT (1 << 1) /* Inherit the ToS from the inner packet. */ #define TNL_F_TTL_INHERIT (1 << 2) /* Inherit the TTL from the inner packet. */ -#define TNL_F_PMTUD (1 << 3) /* Enable path MTU discovery. */ -#define TNL_F_HDR_CACHE (1 << 4) /* Enable tunnel header caching. */ -#define TNL_F_IPSEC (1 << 5) /* Traffic is IPsec encrypted. */ +#define TNL_F_DF_INHERIT (1 << 3) /* Inherit the DF bit from the inner packet. */ +#define TNL_F_DF_DEFAULT (1 << 4) /* Set the DF bit if inherit off or not IP. */ +#define TNL_F_PMTUD (1 << 5) /* Enable path MTU discovery. */ +#define TNL_F_HDR_CACHE (1 << 6) /* Enable tunnel header caching. */ +#define TNL_F_IPSEC (1 << 7) /* Traffic is IPsec encrypted. */ #endif /* openvswitch/tunnel.h */ diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index be2694159..f31f85fd1 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -667,7 +667,7 @@ parse_tunnel_config(const char *name, const char *type, ovs_be32 daddr = htonl(0); uint32_t flags; - flags = TNL_F_PMTUD | TNL_F_HDR_CACHE; + flags = TNL_F_DF_DEFAULT | TNL_F_PMTUD | TNL_F_HDR_CACHE; if (!strcmp(type, "gre")) { is_gre = true; } else if (!strcmp(type, "ipsec_gre")) { @@ -709,6 +709,14 @@ parse_tunnel_config(const char *name, const char *type, if (!strcmp(node->data, "true")) { flags |= TNL_F_CSUM; } + } else if (!strcmp(node->name, "df_inherit")) { + if (!strcmp(node->data, "true")) { + flags |= TNL_F_DF_INHERIT; + } + } else if (!strcmp(node->name, "df_default")) { + if (!strcmp(node->data, "false")) { + flags &= ~TNL_F_DF_DEFAULT; + } } else if (!strcmp(node->name, "pmtud")) { if (!strcmp(node->data, "false")) { flags &= ~TNL_F_PMTUD; @@ -891,6 +899,12 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED, if (flags & TNL_F_CSUM) { smap_add(args, "csum", "true"); } + if (flags & TNL_F_DF_INHERIT) { + smap_add(args, "df_inherit", "true"); + } + if (!(flags & TNL_F_DF_DEFAULT)) { + smap_add(args, "df_default", "false"); + } if (!(flags & TNL_F_PMTUD)) { smap_add(args, "pmtud", "false"); } diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 48315fa9c..1db89dc5b 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -830,19 +830,31 @@ adds value for the GRE and encapsulated Ethernet headers. Default is disabled, set to true to enable. +
+
df_inherit
+
Optional. If enabled, the Don't Fragment bit will be copied + from the inner IP headers (those of the encapsulated traffic) + to the outer (tunnel) headers. Default is disabled; set to + true to enable.
+
+
+
df_default
+
Optional. If enabled, the Don't Fragment bit will be set by + default on tunnel headers if the df_inherit option + is not set, or if the encapsulated packet is not IP. Default + is enabled; set to false to disable.
+
pmtud
Optional. Enable tunnel path MTU discovery. If enabled - ``ICMP destination unreachable - fragmentation'' needed + ``ICMP Destination Unreachable - Fragmentation Needed'' messages will be generated for IPv4 packets with the DF bit set and IPv6 packets above the minimum MTU if the packet size - exceeds the path MTU minus the size of the tunnel headers. It - also forces the encapsulating packet DF bit to be set (it is - always set if the inner packet implies path MTU discovery). + exceeds the path MTU minus the size of the tunnel headers. Note that this option causes behavior that is typically reserved for routers and therefore is not entirely in compliance with the IEEE 802.1D specification for bridges. - Default is enabled, set to false to disable.
+ Default is enabled; set to false to disable.
header_cache
@@ -956,19 +968,31 @@ adds value for the GRE and encapsulated Ethernet headers. Default is disabled, set to true to enable.
+
+
df_inherit
+
Optional. If enabled, the Don't Fragment bit will be copied + from the inner IP headers (those of the encapsulated traffic) + to the outer (tunnel) headers. Default is disabled; set to + true to enable.
+
+
+
df_default
+
Optional. If enabled, the Don't Fragment bit will be set by + default on tunnel headers if the df_inherit option + is not set, or if the encapsulated packet is not IP. Default + is enabled; set to false to disable.
+
pmtud
Optional. Enable tunnel path MTU discovery. If enabled - ``ICMP destination unreachable - fragmentation'' needed + ``ICMP Destination Unreachable - Fragmentation Needed'' messages will be generated for IPv4 packets with the DF bit set and IPv6 packets above the minimum MTU if the packet size - exceeds the path MTU minus the size of the tunnel headers. It - also forces the encapsulating packet DF bit to be set (it is - always set if the inner packet implies path MTU discovery). + exceeds the path MTU minus the size of the tunnel headers. Note that this option causes behavior that is typically reserved for routers and therefore is not entirely in compliance with the IEEE 802.1D specification for bridges. - Default is enabled, set to false to disable.
+ Default is enabled; set to false to disable.
capwap
@@ -1011,19 +1035,31 @@ (otherwise it will be the system default, typically 64). Default is the system default TTL. +
+
df_inherit
+
Optional. If enabled, the Don't Fragment bit will be copied + from the inner IP headers (those of the encapsulated traffic) + to the outer (tunnel) headers. Default is disabled; set to + true to enable.
+
+
+
df_default
+
Optional. If enabled, the Don't Fragment bit will be set by + default on tunnel headers if the df_inherit option + is not set, or if the encapsulated packet is not IP. Default + is enabled; set to false to disable.
+
pmtud
Optional. Enable tunnel path MTU discovery. If enabled - ``ICMP destination unreachable - fragmentation'' needed + ``ICMP Destination Unreachable - Fragmentation Needed'' messages will be generated for IPv4 packets with the DF bit set and IPv6 packets above the minimum MTU if the packet size - exceeds the path MTU minus the size of the tunnel headers. It - also forces the encapsulating packet DF bit to be set (it is - always set if the inner packet implies path MTU discovery). + exceeds the path MTU minus the size of the tunnel headers. Note that this option causes behavior that is typically reserved for routers and therefore is not entirely in compliance with the IEEE 802.1D specification for bridges. - Default is enabled, set to false to disable.
+ Default is enabled; set to false to disable.
header_cache
-- 2.45.2