On Thu, Feb 08, 2018 at 04:40:38PM +0100, Eelco Chaudron wrote:
> 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).
Maybe worth noting that the kernel started adding these headers in
4.12. Specifically, it was introduced by 89a23c8b528b ("ip6_tunnel: Fix
missing tunnel encapsulation limit option")
>
> 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
>
Thanks Eelco. I tested this by applying it on top of a non-upstream gre6
test case I had previously written [0]. If this gets applied I can post
that testcase to the list.
Tested-by: Eric Garver <[email protected]>
[0]
https://github.com/erig0/ovs/commits/ff2e39278b66b3fe937dba63b32e341098901c50
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev