| From 3f82a30c00731f0f5e46312fd449d79a025c8bff Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 21 Jun 2021 18:52:54 -0700 |
| Subject: ip6_tunnel: fix GRE6 segmentation |
| |
| From: Jakub Kicinski <kuba@kernel.org> |
| |
| [ Upstream commit a6e3f2985a80ef6a45a17d2d9d9151f17ea3ce07 ] |
| |
| Commit 6c11fbf97e69 ("ip6_tunnel: add MPLS transmit support") |
| moved assiging inner_ipproto down from ipxip6_tnl_xmit() to |
| its callee ip6_tnl_xmit(). The latter is also used by GRE. |
| |
| Since commit 38720352412a ("gre: Use inner_proto to obtain inner |
| header protocol") GRE had been depending on skb->inner_protocol |
| during segmentation. It sets it in gre_build_header() and reads |
| it in gre_gso_segment(). Changes to ip6_tnl_xmit() overwrite |
| the protocol, resulting in GSO skbs getting dropped. |
| |
| Note that inner_protocol is a union with inner_ipproto, |
| GRE uses the former while the change switched it to the latter |
| (always setting it to just IPPROTO_GRE). |
| |
| Restore the original location of skb_set_inner_ipproto(), |
| it is unclear why it was moved in the first place. |
| |
| Fixes: 6c11fbf97e69 ("ip6_tunnel: add MPLS transmit support") |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Tested-by: Vadim Fedorenko <vfedorenko@novek.ru> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/ipv6/ip6_tunnel.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c |
| index 42ca2d05c480..08441f06afd4 100644 |
| --- a/net/ipv6/ip6_tunnel.c |
| +++ b/net/ipv6/ip6_tunnel.c |
| @@ -1270,8 +1270,6 @@ route_lookup: |
| if (max_headroom > dev->needed_headroom) |
| dev->needed_headroom = max_headroom; |
| |
| - skb_set_inner_ipproto(skb, proto); |
| - |
| err = ip6_tnl_encap(skb, t, &proto, fl6); |
| if (err) |
| return err; |
| @@ -1408,6 +1406,8 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, |
| if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) |
| return -1; |
| |
| + skb_set_inner_ipproto(skb, protocol); |
| + |
| err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
| protocol); |
| if (err != 0) { |
| -- |
| 2.30.2 |
| |