Skip to content

Commit fd31cb0

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net 1) Fix bogus compilter warning in nfnetlink_queue, from Florian Westphal. 2) Don't run conntrack on vrf with !dflt qdisc, from Nicolas Dichtel. 3) Fix nft_pipapo bucket load in AVX2 lookup routine for six 8-bit groups, from Stefano Brivio. 4) Break rule evaluation on malformed TCP options. 5) Use socat instead of nc in selftests/netfilter/nft_zones_many.sh, also from Florian 6) Fix KCSAN data-race in conntrack timeout updates, from Eric Dumazet. * git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf: netfilter: conntrack: annotate data-races around ct->timeout selftests: netfilter: switch zone stress to socat netfilter: nft_exthdr: break evaluation if setting TCP option fails selftests: netfilter: Add correctness test for mac,net set type nft_set_pipapo: Fix bucket load in AVX2 lookup routine for six 8-bit groups vrf: don't run conntrack on vrf with !dflt qdisc netfilter: nfnetlink_queue: silence bogus compiler warning ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents b5b6b6b + 802a7dc commit fd31cb0

File tree

11 files changed

+82
-32
lines changed

11 files changed

+82
-32
lines changed

drivers/net/vrf.c

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

771771
skb->dev = vrf_dev;
772772

773-
vrf_nf_set_untracked(skb);
774-
775773
err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk,
776774
skb, NULL, vrf_dev, vrf_ip6_out_direct_finish);
777775

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

793+
vrf_nf_set_untracked(skb);
794+
795795
if (qdisc_tx_is_default(vrf_dev) ||
796796
IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
797797
return vrf_ip6_out_direct(vrf_dev, sk, skb);
@@ -1000,8 +1000,6 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
10001000

10011001
skb->dev = vrf_dev;
10021002

1003-
vrf_nf_set_untracked(skb);
1004-
10051003
err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk,
10061004
skb, NULL, vrf_dev, vrf_ip_out_direct_finish);
10071005

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

1024+
vrf_nf_set_untracked(skb);
1025+
10261026
if (qdisc_tx_is_default(vrf_dev) ||
10271027
IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
10281028
return vrf_ip_out_direct(vrf_dev, sk, skb);

include/net/netfilter/nf_conntrack.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,14 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
276276
/* jiffies until ct expires, 0 if already expired */
277277
static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
278278
{
279-
s32 timeout = ct->timeout - nfct_time_stamp;
279+
s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
280280

281281
return timeout > 0 ? timeout : 0;
282282
}
283283

284284
static inline bool nf_ct_is_expired(const struct nf_conn *ct)
285285
{
286-
return (__s32)(ct->timeout - nfct_time_stamp) <= 0;
286+
return (__s32)(READ_ONCE(ct->timeout) - nfct_time_stamp) <= 0;
287287
}
288288

289289
/* use after obtaining a reference count */
@@ -302,7 +302,7 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
302302
static inline void nf_ct_offload_timeout(struct nf_conn *ct)
303303
{
304304
if (nf_ct_expires(ct) < NF_CT_DAY / 2)
305-
ct->timeout = nfct_time_stamp + NF_CT_DAY;
305+
WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);
306306
}
307307

308308
struct kernel_param;

net/netfilter/nf_conntrack_core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
684684

685685
tstamp = nf_conn_tstamp_find(ct);
686686
if (tstamp) {
687-
s32 timeout = ct->timeout - nfct_time_stamp;
687+
s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
688688

689689
tstamp->stop = ktime_get_real_ns();
690690
if (timeout < 0)
@@ -1036,7 +1036,7 @@ static int nf_ct_resolve_clash_harder(struct sk_buff *skb, u32 repl_idx)
10361036
}
10371037

10381038
/* We want the clashing entry to go away real soon: 1 second timeout. */
1039-
loser_ct->timeout = nfct_time_stamp + HZ;
1039+
WRITE_ONCE(loser_ct->timeout, nfct_time_stamp + HZ);
10401040

10411041
/* IPS_NAT_CLASH removes the entry automatically on the first
10421042
* reply. Also prevents UDP tracker from moving the entry to
@@ -1560,7 +1560,7 @@ __nf_conntrack_alloc(struct net *net,
15601560
/* save hash for reusing when confirming */
15611561
*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
15621562
ct->status = 0;
1563-
ct->timeout = 0;
1563+
WRITE_ONCE(ct->timeout, 0);
15641564
write_pnet(&ct->ct_net, net);
15651565
memset(&ct->__nfct_init_offset, 0,
15661566
offsetof(struct nf_conn, proto) -

net/netfilter/nf_conntrack_netlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1998,7 +1998,7 @@ static int ctnetlink_change_timeout(struct nf_conn *ct,
19981998

19991999
if (timeout > INT_MAX)
20002000
timeout = INT_MAX;
2001-
ct->timeout = nfct_time_stamp + (u32)timeout;
2001+
WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);
20022002

20032003
if (test_bit(IPS_DYING_BIT, &ct->status))
20042004
return -ETIME;

net/netfilter/nf_flow_table_core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ static void flow_offload_fixup_ct_timeout(struct nf_conn *ct)
201201
if (timeout < 0)
202202
timeout = 0;
203203

204-
if (nf_flow_timeout_delta(ct->timeout) > (__s32)timeout)
205-
ct->timeout = nfct_time_stamp + timeout;
204+
if (nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout)
205+
WRITE_ONCE(ct->timeout, nfct_time_stamp + timeout);
206206
}
207207

208208
static void flow_offload_fixup_ct_state(struct nf_conn *ct)

net/netfilter/nfnetlink_queue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
387387
struct net_device *indev;
388388
struct net_device *outdev;
389389
struct nf_conn *ct = NULL;
390-
enum ip_conntrack_info ctinfo;
390+
enum ip_conntrack_info ctinfo = 0;
391391
struct nfnl_ct_hook *nfnl_ct;
392392
bool csum_verify;
393393
char *secdata = NULL;

net/netfilter/nft_exthdr.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
236236

237237
tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len);
238238
if (!tcph)
239-
return;
239+
goto err;
240240

241241
opt = (u8 *)tcph;
242242
for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {
@@ -251,16 +251,16 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
251251
continue;
252252

253253
if (i + optl > tcphdr_len || priv->len + priv->offset > optl)
254-
return;
254+
goto err;
255255

256256
if (skb_ensure_writable(pkt->skb,
257257
nft_thoff(pkt) + i + priv->len))
258-
return;
258+
goto err;
259259

260260
tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff,
261261
&tcphdr_len);
262262
if (!tcph)
263-
return;
263+
goto err;
264264

265265
offset = i + priv->offset;
266266

@@ -303,6 +303,9 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
303303

304304
return;
305305
}
306+
return;
307+
err:
308+
regs->verdict.code = NFT_BREAK;
306309
}
307310

308311
static void nft_exthdr_sctp_eval(const struct nft_expr *expr,

net/netfilter/nft_set_pipapo_avx2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill,
886886
NFT_PIPAPO_AVX2_BUCKET_LOAD8(4, lt, 4, pkt[4], bsize);
887887

888888
NFT_PIPAPO_AVX2_AND(5, 0, 1);
889-
NFT_PIPAPO_AVX2_BUCKET_LOAD8(6, lt, 6, pkt[5], bsize);
889+
NFT_PIPAPO_AVX2_BUCKET_LOAD8(6, lt, 5, pkt[5], bsize);
890890
NFT_PIPAPO_AVX2_AND(7, 2, 3);
891891

892892
/* Stall */

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

tools/testing/selftests/netfilter/nft_concat_range.sh

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ TESTS="reported_issues correctness concurrency timeout"
2323

2424
# Set types, defined by TYPE_ variables below
2525
TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto
26-
net_port_net net_mac net_mac_icmp net6_mac_icmp net6_port_net6_port
27-
net_port_mac_proto_net"
26+
net_port_net net_mac mac_net net_mac_icmp net6_mac_icmp
27+
net6_port_net6_port net_port_mac_proto_net"
2828

2929
# Reported bugs, also described by TYPE_ variables below
3030
BUGS="flush_remove_add"
@@ -277,6 +277,23 @@ perf_entries 1000
277277
perf_proto ipv4
278278
"
279279

280+
TYPE_mac_net="
281+
display mac,net
282+
type_spec ether_addr . ipv4_addr
283+
chain_spec ether saddr . ip saddr
284+
dst
285+
src mac addr4
286+
start 1
287+
count 5
288+
src_delta 2000
289+
tools sendip nc bash
290+
proto udp
291+
292+
race_repeat 0
293+
294+
perf_duration 0
295+
"
296+
280297
TYPE_net_mac_icmp="
281298
display net,mac - ICMP
282299
type_spec ipv4_addr . ether_addr
@@ -984,7 +1001,8 @@ format() {
9841001
fi
9851002
done
9861003
for f in ${src}; do
987-
__expr="${__expr} . "
1004+
[ "${__expr}" != "{ " ] && __expr="${__expr} . "
1005+
9881006
__start="$(eval format_"${f}" "${srcstart}")"
9891007
__end="$(eval format_"${f}" "${srcend}")"
9901008

0 commit comments

Comments
 (0)