lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Wed, 28 Oct 2020 00:45:32 +0300 From: Alexander Ovechkin <ovov@...dex-team.ru> To: Vadim Fedorenko <vfedorenko@...ek.ru> Cc: Willem de Bruijn <willemdebruijn.kernel@...il.com>, Network Development <netdev@...r.kernel.org> Subject: Re: [PATCH net] ip6_tunnel: set inner ipproto before ip6_tnl_encap. But ip6_tnl_encap assigns to proto number of outer protocol (i.e. = protocol that encapsulates our original packet). Setting inner_ipproto = to this value makes no sense.=20 For example in case of ipv6 inside MPLS inside fou6 encapsulation we = have following packet structure: +--------------+ <---+ | ipv6 | | +--------------+ +- fou6-encap | udp | | +--------------+ <---+ | mpls | <--- mpls-enacp +--------------+ <---+ | inner-ipv6 | | +--------------+ +- original packet | ... | | +--------------+ <---+ After ip6_tnl_encap proto will be equal to IPPROTO_UDP, that is = obviously is not inner ipproto. Actually if pproto =3D=3D IPPROTO_MPLS than we have two layers of = encapsulation and it is meaningless to set inner ipproto, cause = currently there is no support for segmentation of packets with two = layers of encapsulation. > On 17 Oct 2020, at 03:59, Vadim Fedorenko <vfedorenko@...ek.ru> wrote: > > On 16.10.2020 18:55, Willem de Bruijn wrote: >> On Fri, Oct 16, 2020 at 7:14 AM Alexander Ovechkin <ovov@...dex-team.ru> wrote: >>> ip6_tnl_encap assigns to proto transport protocol which >>> encapsulates inner packet, but we must pass to set_inner_ipproto >>> protocol of that inner packet. >>> >>> Calling set_inner_ipproto after ip6_tnl_encap might break gso. >>> For example, in case of encapsulating ipv6 packet in fou6 packet, inner_ipproto >>> would be set to IPPROTO_UDP instead of IPPROTO_IPV6. This would lead to >>> incorrect calling sequence of gso functions: >>> ipv6_gso_segment -> udp6_ufo_fragment -> skb_udp_tunnel_segment -> udp6_ufo_fragment >>> instead of: >>> ipv6_gso_segment -> udp6_ufo_fragment -> skb_udp_tunnel_segment -> ip6ip6_gso_segment >>> >>> Signed-off-by: Alexander Ovechkin <ovov@...dex-team.ru> >> Commit 6c11fbf97e69 ("ip6_tunnel: add MPLS transmit support") moved >> the call from ip6_tnl_encap's caller to inside ip6_tnl_encap. >> >> It makes sense that that likely broke this behavior for UDP (L4) tunnels. >> >> But it was moved on purpose to avoid setting the inner protocol to >> IPPROTO_MPLS. That needs to use skb->inner_protocol to further >> segment. >> >> I suspect we need to set this before or after conditionally to avoid >> breaking that use case. > I hope it could be fixed with something like this: > > diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c > index a0217e5..87368b0 100644 > --- a/net/ipv6/ip6_tunnel.c > +++ b/net/ipv6/ip6_tunnel.c > @@ -1121,6 +1121,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, > bool use_cache = false; > u8 hop_limit; > int err = -1; > + __u8 pproto = proto; > > if (t->parms.collect_md) { > hop_limit = skb_tunnel_info(skb)->key.ttl; > @@ -1280,7 +1281,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, > ipv6_push_frag_opts(skb, &opt.ops, &proto); > } > > - skb_set_inner_ipproto(skb, proto); > + skb_set_inner_ipproto(skb, pproto == IPPROTO_MPLS ? proto : pproto); > > skb_push(skb, sizeof(struct ipv6hdr)); > skb_reset_network_header(skb); >
Powered by blists - more mailing lists