Skip to content

Commit 87f78f2

Browse files
committed
Merge branch 'vrf-looping'
David Ahern says: ==================== net: Fix looping with vrf, xfrms and qdisc on VRF Trev reported that use of VRFs with xfrms is looping when a qdisc is added to the VRF device. The combination of xfrm + qdisc is not handled by the VRF driver which lost track that it has already seen the packet. The XFRM_TRANSFORMED flag is used by the netfilter code for a similar purpose, so re-use for VRF. Patch 1 drops the #ifdef around setting the flag in the xfrm output functions. Patch 2 adds a check to the VRF driver for flag; if set the packet has already passed through the VRF driver once and does not need to recirculated a second time. This is a day 1 bug with VRFs; stable wise, I would only take this back to 4.14. I have a set of test cases which I will submit to net-next. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 9175d3f + 16b9db1 commit 87f78f2

File tree

3 files changed

+4
-6
lines changed

3 files changed

+4
-6
lines changed

drivers/net/vrf.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,8 @@ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
474474
if (rt6_need_strict(&ipv6_hdr(skb)->daddr))
475475
return skb;
476476

477-
if (qdisc_tx_is_default(vrf_dev))
477+
if (qdisc_tx_is_default(vrf_dev) ||
478+
IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
478479
return vrf_ip6_out_direct(vrf_dev, sk, skb);
479480

480481
return vrf_ip6_out_redirect(vrf_dev, skb);
@@ -686,7 +687,8 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
686687
ipv4_is_lbcast(ip_hdr(skb)->daddr))
687688
return skb;
688689

689-
if (qdisc_tx_is_default(vrf_dev))
690+
if (qdisc_tx_is_default(vrf_dev) ||
691+
IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
690692
return vrf_ip_out_direct(vrf_dev, sk, skb);
691693

692694
return vrf_ip_out_redirect(vrf_dev, skb);

net/ipv4/xfrm4_output.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb)
5858
{
5959
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
6060

61-
#ifdef CONFIG_NETFILTER
6261
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
63-
#endif
6462

6563
return xfrm_output(sk, skb);
6664
}

net/ipv6/xfrm6_output.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb)
111111
{
112112
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
113113

114-
#ifdef CONFIG_NETFILTER
115114
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
116-
#endif
117115

118116
return xfrm_output(sk, skb);
119117
}

0 commit comments

Comments
 (0)