Skip to content

Commit f1ed102

Browse files
NicolasDichtelklassert
authored andcommitted
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: 9522416 ("vti[6]: fix packet tx through bpf_redirect()") Signed-off-by: Nicolas Dichtel <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 03891f8 commit f1ed102

File tree

3 files changed

+56
-15
lines changed

3 files changed

+56
-15
lines changed

net/ipv4/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ config SYN_COOKIES
303303

304304
config NET_IPVTI
305305
tristate "Virtual (secure) IP: tunneling"
306+
depends on IPV6 || IPV6=n
306307
select INET_TUNNEL
307308
select NET_IP_TUNNEL
308309
select XFRM

net/ipv4/ip_vti.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,39 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
187187
int mtu;
188188

189189
if (!dst) {
190-
struct rtable *rt;
191-
192-
fl->u.ip4.flowi4_oif = dev->ifindex;
193-
fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
194-
rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
195-
if (IS_ERR(rt)) {
190+
switch (skb->protocol) {
191+
case htons(ETH_P_IP): {
192+
struct rtable *rt;
193+
194+
fl->u.ip4.flowi4_oif = dev->ifindex;
195+
fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
196+
rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
197+
if (IS_ERR(rt)) {
198+
dev->stats.tx_carrier_errors++;
199+
goto tx_error_icmp;
200+
}
201+
dst = &rt->dst;
202+
skb_dst_set(skb, dst);
203+
break;
204+
}
205+
#if IS_ENABLED(CONFIG_IPV6)
206+
case htons(ETH_P_IPV6):
207+
fl->u.ip6.flowi6_oif = dev->ifindex;
208+
fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
209+
dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
210+
if (dst->error) {
211+
dst_release(dst);
212+
dst = NULL;
213+
dev->stats.tx_carrier_errors++;
214+
goto tx_error_icmp;
215+
}
216+
skb_dst_set(skb, dst);
217+
break;
218+
#endif
219+
default:
196220
dev->stats.tx_carrier_errors++;
197221
goto tx_error_icmp;
198222
}
199-
dst = &rt->dst;
200-
skb_dst_set(skb, dst);
201223
}
202224

203225
dst_hold(dst);

net/ipv6/ip6_vti.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -450,15 +450,33 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
450450
int mtu;
451451

452452
if (!dst) {
453-
fl->u.ip6.flowi6_oif = dev->ifindex;
454-
fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
455-
dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
456-
if (dst->error) {
457-
dst_release(dst);
458-
dst = NULL;
453+
switch (skb->protocol) {
454+
case htons(ETH_P_IP): {
455+
struct rtable *rt;
456+
457+
fl->u.ip4.flowi4_oif = dev->ifindex;
458+
fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
459+
rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
460+
if (IS_ERR(rt))
461+
goto tx_err_link_failure;
462+
dst = &rt->dst;
463+
skb_dst_set(skb, dst);
464+
break;
465+
}
466+
case htons(ETH_P_IPV6):
467+
fl->u.ip6.flowi6_oif = dev->ifindex;
468+
fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
469+
dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
470+
if (dst->error) {
471+
dst_release(dst);
472+
dst = NULL;
473+
goto tx_err_link_failure;
474+
}
475+
skb_dst_set(skb, dst);
476+
break;
477+
default:
459478
goto tx_err_link_failure;
460479
}
461-
skb_dst_set(skb, dst);
462480
}
463481

464482
dst_hold(dst);

0 commit comments

Comments
 (0)