diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2020-02-04 19:00:27 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-04-02 17:34:32 +0300 |
commit | 27993a6ac82cd57e8fa8088315736bd4e5ba8a1a (patch) | |
tree | d1c687798ac0d280c02e878904aa4d66714934db /net/ipv6 | |
parent | a6001a07098525ada40c5c3e63c811e69a11c565 (diff) | |
download | linux-27993a6ac82cd57e8fa8088315736bd4e5ba8a1a.tar.xz |
vti[6]: fix packet tx through bpf_redirect() in XinY cases
commit f1ed10264ed6b66b9cd5e8461cffce69be482356 upstream.
I forgot the 4in6/6in4 cases in my previous patch. Let's fix them.
Fixes: 95224166a903 ("vti[6]: fix packet tx through bpf_redirect()")
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_vti.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 396a0f61f5f8..2f0217657ba2 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -454,15 +454,33 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) int mtu; if (!dst) { - fl->u.ip6.flowi6_oif = dev->ifindex; - fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; - dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); - if (dst->error) { - dst_release(dst); - dst = NULL; + switch (skb->protocol) { + case htons(ETH_P_IP): { + struct rtable *rt; + + fl->u.ip4.flowi4_oif = dev->ifindex; + fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); + if (IS_ERR(rt)) + goto tx_err_link_failure; + dst = &rt->dst; + skb_dst_set(skb, dst); + break; + } + case htons(ETH_P_IPV6): + fl->u.ip6.flowi6_oif = dev->ifindex; + fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; + dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); + if (dst->error) { + dst_release(dst); + dst = NULL; + goto tx_err_link_failure; + } + skb_dst_set(skb, dst); + break; + default: goto tx_err_link_failure; } - skb_dst_set(skb, dst); } dst_hold(dst); |