@@ -31,7 +31,7 @@ modprobe -q sctp
31
31
32
32
trap cleanup EXIT
33
33
34
- setup_ns ns1 ns2 nsrouter
34
+ setup_ns ns1 ns2 ns3 nsrouter
35
35
36
36
TMPFILE0=$( mktemp)
37
37
TMPFILE1=$( mktemp)
@@ -48,6 +48,7 @@ if ! ip link add veth0 netns "$nsrouter" type veth peer name eth0 netns "$ns1" >
48
48
exit $ksft_skip
49
49
fi
50
50
ip link add veth1 netns " $nsrouter " type veth peer name eth0 netns " $ns2 "
51
+ ip link add veth2 netns " $nsrouter " type veth peer name eth0 netns " $ns3 "
51
52
52
53
ip -net " $nsrouter " link set veth0 up
53
54
ip -net " $nsrouter " addr add 10.0.1.1/24 dev veth0
@@ -57,8 +58,13 @@ ip -net "$nsrouter" link set veth1 up
57
58
ip -net " $nsrouter " addr add 10.0.2.1/24 dev veth1
58
59
ip -net " $nsrouter " addr add dead:2::1/64 dev veth1 nodad
59
60
61
+ ip -net " $nsrouter " link set veth2 up
62
+ ip -net " $nsrouter " addr add 10.0.3.1/24 dev veth2
63
+ ip -net " $nsrouter " addr add dead:3::1/64 dev veth2 nodad
64
+
60
65
ip -net " $ns1 " link set eth0 up
61
66
ip -net " $ns2 " link set eth0 up
67
+ ip -net " $ns3 " link set eth0 up
62
68
63
69
ip -net " $ns1 " addr add 10.0.1.99/24 dev eth0
64
70
ip -net " $ns1 " addr add dead:1::99/64 dev eth0 nodad
@@ -70,6 +76,11 @@ ip -net "$ns2" addr add dead:2::99/64 dev eth0 nodad
70
76
ip -net " $ns2 " route add default via 10.0.2.1
71
77
ip -net " $ns2 " route add default via dead:2::1
72
78
79
+ ip -net " $ns3 " addr add 10.0.3.99/24 dev eth0
80
+ ip -net " $ns3 " addr add dead:3::99/64 dev eth0 nodad
81
+ ip -net " $ns3 " route add default via 10.0.3.1
82
+ ip -net " $ns3 " route add default via dead:3::1
83
+
73
84
load_ruleset () {
74
85
local name=$1
75
86
local prio=$2
473
484
check_output_files " $TMPINPUT " " $TMPFILE1 " " sctp output"
474
485
}
475
486
487
+ udp_listener_ready ()
488
+ {
489
+ ss -S -N " $1 " -uln -o " sport = :12345" | grep -q 12345
490
+ }
491
+
492
+ output_files_written ()
493
+ {
494
+ test -s " $1 " && test -s " $2 "
495
+ }
496
+
497
+ test_udp_ct_race ()
498
+ {
499
+ ip netns exec " $nsrouter " nft -f /dev/stdin << EOF
500
+ flush ruleset
501
+ table inet udpq {
502
+ chain prerouting {
503
+ type nat hook prerouting priority dstnat - 5; policy accept;
504
+ ip daddr 10.6.6.6 udp dport 12345 counter dnat to numgen inc mod 2 map { 0 : 10.0.2.99, 1 : 10.0.3.99 }
505
+ }
506
+ chain postrouting {
507
+ type filter hook postrouting priority srcnat - 5; policy accept;
508
+ udp dport 12345 counter queue num 12
509
+ }
510
+ }
511
+ EOF
512
+ :> " $TMPFILE1 "
513
+ :> " $TMPFILE2 "
514
+
515
+ timeout 10 ip netns exec " $ns2 " socat UDP-LISTEN:12345,fork OPEN:" $TMPFILE1 " ,trunc &
516
+ local rpid1=$!
517
+
518
+ timeout 10 ip netns exec " $ns3 " socat UDP-LISTEN:12345,fork OPEN:" $TMPFILE2 " ,trunc &
519
+ local rpid2=$!
520
+
521
+ ip netns exec " $nsrouter " ./nf_queue -q 12 -d 1000 &
522
+ local nfqpid=$!
523
+
524
+ busywait " $BUSYWAIT_TIMEOUT " udp_listener_ready " $ns2 "
525
+ busywait " $BUSYWAIT_TIMEOUT " udp_listener_ready " $ns3 "
526
+ busywait " $BUSYWAIT_TIMEOUT " nf_queue_wait " $nsrouter " 12
527
+
528
+ # Send two packets, one should end up in ns1, other in ns2.
529
+ # This is because nfqueue will delay packet for long enough so that
530
+ # second packet will not find existing conntrack entry.
531
+ echo " Packet 1" | ip netns exec " $ns1 " socat STDIN UDP-DATAGRAM:10.6.6.6:12345,bind=0.0.0.0:55221
532
+ echo " Packet 2" | ip netns exec " $ns1 " socat STDIN UDP-DATAGRAM:10.6.6.6:12345,bind=0.0.0.0:55221
533
+
534
+ busywait 10000 output_files_written " $TMPFILE1 " " $TMPFILE2 "
535
+
536
+ kill " $nfqpid "
537
+
538
+ if ! ip netns exec " $nsrouter " bash -c ' conntrack -L -p udp --dport 12345 2>/dev/null | wc -l | grep -q "^1"' ; then
539
+ echo " FAIL: Expected One udp conntrack entry"
540
+ ip netns exec " $nsrouter " conntrack -L -p udp --dport 12345
541
+ ret=1
542
+ fi
543
+
544
+ if ! ip netns exec " $nsrouter " nft delete table inet udpq; then
545
+ echo " FAIL: Could not delete udpq table"
546
+ ret=1
547
+ return
548
+ fi
549
+
550
+ NUMLINES1=$( wc -l < " $TMPFILE1 " )
551
+ NUMLINES2=$( wc -l < " $TMPFILE2 " )
552
+
553
+ if [ " $NUMLINES1 " -ne 1 ] || [ " $NUMLINES2 " -ne 1 ]; then
554
+ ret=1
555
+ echo " FAIL: uneven udp packet distribution: $NUMLINES1 $NUMLINES2 "
556
+ echo -n " $TMPFILE1 : " ; cat " $TMPFILE1 "
557
+ echo -n " $TMPFILE2 : " ; cat " $TMPFILE2 "
558
+ return
559
+ fi
560
+
561
+ echo " PASS: both udp receivers got one packet each"
562
+ }
563
+
476
564
test_queue_removal ()
477
565
{
478
566
read tainted_then < /proc/sys/kernel/tainted
512
600
ip netns exec " $nsrouter " sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
513
601
ip netns exec " $nsrouter " sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
514
602
ip netns exec " $nsrouter " sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
603
+ ip netns exec " $nsrouter " sysctl net.ipv4.conf.veth2.forwarding=1 > /dev/null
515
604
516
605
load_ruleset " filter" 0
517
606
@@ -549,6 +638,7 @@ test_tcp_localhost_connectclose
549
638
test_tcp_localhost_requeue
550
639
test_sctp_forward
551
640
test_sctp_output
641
+ test_udp_ct_race
552
642
553
643
# should be last, adds vrf device in ns1 and changes routes
554
644
test_icmp_vrf
0 commit comments