Skip to content

Commit d43b75f

Browse files
NicolasDichtelummakynes
authored andcommitted
vrf: don't run conntrack on vrf with !dflt qdisc
After the below patch, the conntrack attached to skb is set to "notrack" in the context of vrf device, for locally generated packets. But this is true only when the default qdisc is set to the vrf device. When changing the qdisc, notrack is not set anymore. In fact, there is a shortcut in the vrf driver, when the default qdisc is set, see commit dcdd43c ("net: vrf: performance improvements for IPv4") for more details. This patch ensures that the behavior is always the same, whatever the qdisc is. To demonstrate the difference, a new test is added in conntrack_vrf.sh. Fixes: 8c9c296 ("vrf: run conntrack only in context of lower/physdev for locally generated packets") Signed-off-by: Nicolas Dichtel <[email protected]> Acked-by: Florian Westphal <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent b43c279 commit d43b75f

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

drivers/net/vrf.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -768,8 +768,6 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
768768

769769
skb->dev = vrf_dev;
770770

771-
vrf_nf_set_untracked(skb);
772-
773771
err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk,
774772
skb, NULL, vrf_dev, vrf_ip6_out_direct_finish);
775773

@@ -790,6 +788,8 @@ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
790788
if (rt6_need_strict(&ipv6_hdr(skb)->daddr))
791789
return skb;
792790

791+
vrf_nf_set_untracked(skb);
792+
793793
if (qdisc_tx_is_default(vrf_dev) ||
794794
IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
795795
return vrf_ip6_out_direct(vrf_dev, sk, skb);
@@ -998,8 +998,6 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
998998

999999
skb->dev = vrf_dev;
10001000

1001-
vrf_nf_set_untracked(skb);
1002-
10031001
err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk,
10041002
skb, NULL, vrf_dev, vrf_ip_out_direct_finish);
10051003

@@ -1021,6 +1019,8 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
10211019
ipv4_is_lbcast(ip_hdr(skb)->daddr))
10221020
return skb;
10231021

1022+
vrf_nf_set_untracked(skb);
1023+
10241024
if (qdisc_tx_is_default(vrf_dev) ||
10251025
IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
10261026
return vrf_ip_out_direct(vrf_dev, sk, skb);

tools/testing/selftests/netfilter/conntrack_vrf.sh

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,27 @@ EOF
150150
# oifname is the vrf device.
151151
test_masquerade_vrf()
152152
{
153+
local qdisc=$1
154+
155+
if [ "$qdisc" != "default" ]; then
156+
tc -net $ns0 qdisc add dev tvrf root $qdisc
157+
fi
158+
153159
ip netns exec $ns0 conntrack -F 2>/dev/null
154160

155161
ip netns exec $ns0 nft -f - <<EOF
156162
flush ruleset
157163
table ip nat {
164+
chain rawout {
165+
type filter hook output priority raw;
166+
167+
oif tvrf ct state untracked counter
168+
}
169+
chain postrouting2 {
170+
type filter hook postrouting priority mangle;
171+
172+
oif tvrf ct state untracked counter
173+
}
158174
chain postrouting {
159175
type nat hook postrouting priority 0;
160176
# NB: masquerade should always be combined with 'oif(name) bla',
@@ -171,13 +187,18 @@ EOF
171187
fi
172188

173189
# must also check that nat table was evaluated on second (lower device) iteration.
174-
ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2'
190+
ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2' &&
191+
ip netns exec $ns0 nft list table ip nat |grep -q 'untracked counter packets [1-9]'
175192
if [ $? -eq 0 ]; then
176-
echo "PASS: iperf3 connect with masquerade + sport rewrite on vrf device"
193+
echo "PASS: iperf3 connect with masquerade + sport rewrite on vrf device ($qdisc qdisc)"
177194
else
178-
echo "FAIL: vrf masq rule has unexpected counter value"
195+
echo "FAIL: vrf rules have unexpected counter value"
179196
ret=1
180197
fi
198+
199+
if [ "$qdisc" != "default" ]; then
200+
tc -net $ns0 qdisc del dev tvrf root
201+
fi
181202
}
182203

183204
# add masq rule that gets evaluated w. outif set to veth device.
@@ -213,7 +234,8 @@ EOF
213234
}
214235

215236
test_ct_zone_in
216-
test_masquerade_vrf
237+
test_masquerade_vrf "default"
238+
test_masquerade_vrf "pfifo"
217239
test_masquerade_veth
218240

219241
exit $ret

0 commit comments

Comments
 (0)