[ovs-dev] [PATCH v2 1/1] userspace: Add IPv6 extension header parsing for tunnels

Eelco Chaudron echaudro at redhat.com
Thu Feb 8 15:40:38 UTC 2018


While OVS userspace datapath (OVS-DPDK) supports GREv6, it does not
inter-operate with a native Linux ip6gretap tunnel. This is because
the Linux driver uses IPv6 optional headers for the Tunnel
Encapsulation Limit (RFC 2473, section 6.6).

OVS userspace simply does not parse these IPv6 extension headers
inside netdev_tnl_ip_extract_tnl_md(), as such popping the tunnel
leaves extra bytes resulting in a mangled decapsulated frame.

The change below will parse the IPv6 "next header" chain and return
the offset to the upper layer protocol.

v1->v2
 - Remove netdev_tnl_ip6_get_upperlayer_offset() and reused existing
   parse_ipv6_ext_hdrs() function.

Signed-off-by: Eelco Chaudron <echaudro at redhat.com>
---
 lib/netdev-native-tnl.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
index fb5eab033..4f520a0f9 100644
--- a/lib/netdev-native-tnl.c
+++ b/lib/netdev-native-tnl.c
@@ -115,6 +115,10 @@ netdev_tnl_ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl,
         *hlen += IP_HEADER_LEN;
 
     } else if (IP_VER(ip->ip_ihl_ver) == 6) {
+        const void *ip6_data;
+        size_t ip6_size;
+        uint8_t nw_proto;
+        uint8_t nw_frag;
         ovs_be32 tc_flow = get_16aligned_be32(&ip6->ip6_flow);
 
         memcpy(tnl->ipv6_src.s6_addr, ip6->ip6_src.be16, sizeof ip6->ip6_src);
@@ -125,6 +129,20 @@ netdev_tnl_ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl,
 
         *hlen += IPV6_HEADER_LEN;
 
+        ip6_data = ip6 + 1;
+        ip6_size = l3_size - IPV6_HEADER_LEN;
+        nw_proto = ip6->ip6_nxt;
+        nw_frag = 0;
+
+        if (!parse_ipv6_ext_hdrs(&ip6_data, &ip6_size, &nw_proto, &nw_frag) ||
+            nw_frag != 0) {
+            VLOG_WARN_RL(&err_rl,
+                         "ipv6 packet has unsupported extension headers");
+            return NULL;
+        }
+
+        *hlen += l3_size - IPV6_HEADER_LEN - ip6_size;
+
     } else {
         VLOG_WARN_RL(&err_rl, "ipv4 packet has invalid version (%d)",
                      IP_VER(ip->ip_ihl_ver));
-- 
2.14.3



More information about the dev mailing list