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 <[email protected]> --- 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 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
