Commit f1ed1026 authored by Nicolas Dichtel's avatar Nicolas Dichtel Committed by Steffen Klassert
Browse files

vti[6]: fix packet tx through bpf_redirect() in XinY cases



I forgot the 4in6/6in4 cases in my previous patch. Let's fix them.

Fixes: 95224166 ("vti[6]: fix packet tx through bpf_redirect()")
Signed-off-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 03891f82
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -303,6 +303,7 @@ config SYN_COOKIES

config NET_IPVTI
	tristate "Virtual (secure) IP: tunneling"
	depends on IPV6 || IPV6=n
	select INET_TUNNEL
	select NET_IP_TUNNEL
	select XFRM
+30 −8
Original line number Diff line number Diff line
@@ -187,6 +187,8 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
	int mtu;

	if (!dst) {
		switch (skb->protocol) {
		case htons(ETH_P_IP): {
			struct rtable *rt;

			fl->u.ip4.flowi4_oif = dev->ifindex;
@@ -198,6 +200,26 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
			}
			dst = &rt->dst;
			skb_dst_set(skb, dst);
			break;
		}
#if IS_ENABLED(CONFIG_IPV6)
		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;
				dev->stats.tx_carrier_errors++;
				goto tx_error_icmp;
			}
			skb_dst_set(skb, dst);
			break;
#endif
		default:
			dev->stats.tx_carrier_errors++;
			goto tx_error_icmp;
		}
	}

	dst_hold(dst);
+25 −7
Original line number Diff line number Diff line
@@ -450,6 +450,20 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
	int mtu;

	if (!dst) {
		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);
@@ -459,6 +473,10 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
				goto tx_err_link_failure;
			}
			skb_dst_set(skb, dst);
			break;
		default:
			goto tx_err_link_failure;
		}
	}

	dst_hold(dst);