diff mbox series

[net] ip6_tunnel: Fix encapsulation layout

Message ID f5f6a69915694976b6feec7ae64a89e1da4e551f.1539890448.git.sbrivio@redhat.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net] ip6_tunnel: Fix encapsulation layout | expand

Commit Message

Stefano Brivio Oct. 18, 2018, 7:25 p.m. UTC
Commit 058214a4d1df ("ip6_tun: Add infrastructure for doing
encapsulation") added the ip6_tnl_encap() call in ip6_tnl_xmit(), before
the call to ipv6_push_frag_opts() to append the IPv6 Tunnel Encapsulation
Limit option (option 4, RFC 2473, par. 5.1) to the outer IPv6 header.

As long as the option didn't actually end up in generated packets, this
wasn't an issue. Then commit 89a23c8b528b ("ip6_tunnel: Fix missing tunnel
encapsulation limit option") fixed sending of this option, and the
resulting layout, e.g. for FoU, is:

.-------------------.------------.----------.-------------------.----- - -
| Outer IPv6 Header | UDP header | Option 4 | Inner IPv6 Header | Payload
'-------------------'------------'----------'-------------------'----- - -

Needless to say, FoU and GUE (at least) won't work over IPv6. The option
is appended by default, and I couldn't find a way to disable it with the
current iproute2.

Turn this into a more reasonable:

.-------------------.----------.------------.-------------------.----- - -
| Outer IPv6 Header | Option 4 | UDP header | Inner IPv6 Header | Payload
'-------------------'----------'------------'-------------------'----- - -

With this, and with 84dad55951b0 ("udp6: fix encap return code for
resubmitting"), FoU and GUE work again over IPv6.

Fixes: 058214a4d1df ("ip6_tun: Add infrastructure for doing encapsulation")
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 net/ipv6/ip6_tunnel.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

David Miller Oct. 18, 2018, 11:55 p.m. UTC | #1
From: Stefano Brivio <sbrivio@redhat.com>
Date: Thu, 18 Oct 2018 21:25:07 +0200

> Commit 058214a4d1df ("ip6_tun: Add infrastructure for doing
> encapsulation") added the ip6_tnl_encap() call in ip6_tnl_xmit(), before
> the call to ipv6_push_frag_opts() to append the IPv6 Tunnel Encapsulation
> Limit option (option 4, RFC 2473, par. 5.1) to the outer IPv6 header.
> 
> As long as the option didn't actually end up in generated packets, this
> wasn't an issue. Then commit 89a23c8b528b ("ip6_tunnel: Fix missing tunnel
> encapsulation limit option") fixed sending of this option, and the
> resulting layout, e.g. for FoU, is:
> 
> .-------------------.------------.----------.-------------------.----- - -
> | Outer IPv6 Header | UDP header | Option 4 | Inner IPv6 Header | Payload
> '-------------------'------------'----------'-------------------'----- - -
> 
> Needless to say, FoU and GUE (at least) won't work over IPv6. The option
> is appended by default, and I couldn't find a way to disable it with the
> current iproute2.
> 
> Turn this into a more reasonable:
> 
> .-------------------.----------.------------.-------------------.----- - -
> | Outer IPv6 Header | Option 4 | UDP header | Inner IPv6 Header | Payload
> '-------------------'----------'------------'-------------------'----- - -
> 
> With this, and with 84dad55951b0 ("udp6: fix encap return code for
> resubmitting"), FoU and GUE work again over IPv6.
> 
> Fixes: 058214a4d1df ("ip6_tun: Add infrastructure for doing encapsulation")
> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>

This goes back to v4.7 then, I can't believe this has been broken for
so long. :-/

Applied and queued up for -stable, thanks.
diff mbox series

Patch

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 6f05e0f74bdf..77b3593e7f76 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1185,11 +1185,6 @@  int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
 	}
 	skb_dst_set(skb, dst);
 
-	if (encap_limit >= 0) {
-		init_tel_txopt(&opt, encap_limit);
-		ipv6_push_frag_opts(skb, &opt.ops, &proto);
-	}
-
 	if (hop_limit == 0) {
 		if (skb->protocol == htons(ETH_P_IP))
 			hop_limit = ip_hdr(skb)->ttl;
@@ -1211,6 +1206,11 @@  int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
 	if (err)
 		return err;
 
+	if (encap_limit >= 0) {
+		init_tel_txopt(&opt, encap_limit);
+		ipv6_push_frag_opts(skb, &opt.ops, &proto);
+	}
+
 	skb_push(skb, sizeof(struct ipv6hdr));
 	skb_reset_network_header(skb);
 	ipv6h = ipv6_hdr(skb);