-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests: netfilter: add packetdrill based conntrack tests
Add a new test script that uses packetdrill tool to exercise conntrack state machine. Needs ip/ip6tables and conntrack tool (to check if we have an entry in the expected state). Test cases added here cover following scenarios: 1. already-acked (retransmitted) packets are not tagged as INVALID 2. RST packet coming when conntrack is already closing (FIN/CLOSE_WAIT) transitions conntrack to CLOSE even if the RST is not an exact match 3. RST packets with out-of-window sequence numbers are marked as INVALID 4. SYN+Challenge ACK: check that challenge ack is allowed to pass 5. Old SYN/ACK: check conntrack handles the case where SYN is answered with SYN/ACK for an old, previous connection attempt 6. Check SYN reception while in ESTABLISHED state generates a challenge ack, RST response clears 'outdated' state + next SYN retransmit gets us into 'SYN_RECV' conntrack state. Tests get run twice, once with ipv4 and once with ipv6. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
- Loading branch information
Showing
10 changed files
with
475 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,3 +86,4 @@ CONFIG_VLAN_8021Q=m | |
CONFIG_XFRM_USER=m | ||
CONFIG_XFRM_STATISTICS=y | ||
CONFIG_NET_PKTGEN=m | ||
CONFIG_TUN=m |
71 changes: 71 additions & 0 deletions
71
tools/testing/selftests/net/netfilter/nf_conntrack_packetdrill.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#!/bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
source lib.sh | ||
|
||
checktool "conntrack --version" "run test without conntrack" | ||
checktool "iptables --version" "run test without iptables" | ||
checktool "ip6tables --version" "run test without ip6tables" | ||
|
||
modprobe -q tun | ||
modprobe -q nf_conntrack | ||
# echo 1 > /proc/sys/net/netfilter/nf_log_all_netns | ||
|
||
PDRILL_TIMEOUT=10 | ||
|
||
files=" | ||
conntrack_ack_loss_stall.pkt | ||
conntrack_inexact_rst.pkt | ||
conntrack_syn_challenge_ack.pkt | ||
conntrack_synack_old.pkt | ||
conntrack_synack_reuse.pkt | ||
conntrack_rst_invalid.pkt | ||
" | ||
|
||
if ! packetdrill --dry_run --verbose "packetdrill/conntrack_ack_loss_stall.pkt";then | ||
echo "SKIP: packetdrill not installed" | ||
exit ${ksft_skip} | ||
fi | ||
|
||
ret=0 | ||
|
||
run_packetdrill() | ||
{ | ||
filename="$1" | ||
ipver="$2" | ||
local mtu=1500 | ||
|
||
export NFCT_IP_VERSION="$ipver" | ||
|
||
if [ "$ipver" = "ipv4" ];then | ||
export xtables="iptables" | ||
elif [ "$ipver" = "ipv6" ];then | ||
export xtables="ip6tables" | ||
mtu=1520 | ||
fi | ||
|
||
timeout "$PDRILL_TIMEOUT" unshare -n packetdrill --ip_version="$ipver" --mtu=$mtu \ | ||
--tolerance_usecs=1000000 --non_fatal packet "$filename" | ||
} | ||
|
||
run_one_test_file() | ||
{ | ||
filename="$1" | ||
|
||
for v in ipv4 ipv6;do | ||
printf "%-50s(%s)%-20s" "$filename" "$v" "" | ||
if run_packetdrill packetdrill/"$f" "$v";then | ||
echo OK | ||
else | ||
echo FAIL | ||
ret=1 | ||
fi | ||
done | ||
} | ||
|
||
echo "Replaying packetdrill test cases:" | ||
for f in $files;do | ||
run_one_test_file packetdrill/"$f" | ||
done | ||
|
||
exit $ret |
33 changes: 33 additions & 0 deletions
33
tools/testing/selftests/net/netfilter/packetdrill/common.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
# for debugging set net.netfilter.nf_log_all_netns=1 in init_net | ||
# or do not use net namespaces. | ||
modprobe -q nf_conntrack | ||
sysctl -q net.netfilter.nf_conntrack_log_invalid=6 | ||
|
||
# Flush old cached data (fastopen cookies). | ||
ip tcp_metrics flush all > /dev/null 2>&1 | ||
|
||
# TCP min, default, and max receive and send buffer sizes. | ||
sysctl -q net.ipv4.tcp_rmem="4096 540000 $((15*1024*1024))" | ||
sysctl -q net.ipv4.tcp_wmem="4096 $((256*1024)) 4194304" | ||
|
||
# TCP congestion control. | ||
sysctl -q net.ipv4.tcp_congestion_control=cubic | ||
|
||
# TCP slow start after idle. | ||
sysctl -q net.ipv4.tcp_slow_start_after_idle=0 | ||
|
||
# TCP Explicit Congestion Notification (ECN) | ||
sysctl -q net.ipv4.tcp_ecn=0 | ||
|
||
sysctl -q net.ipv4.tcp_notsent_lowat=4294967295 > /dev/null 2>&1 | ||
|
||
# Override the default qdisc on the tun device. | ||
# Many tests fail with timing errors if the default | ||
# is FQ and that paces their flows. | ||
tc qdisc add dev tun0 root pfifo | ||
|
||
# Enable conntrack | ||
$xtables -A INPUT -m conntrack --ctstate NEW -p tcp --syn |
118 changes: 118 additions & 0 deletions
118
tools/testing/selftests/net/netfilter/packetdrill/conntrack_ack_loss_stall.pkt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// check that already-acked (retransmitted) packet is let through rather | ||
// than tagged as INVALID. | ||
|
||
`packetdrill/common.sh` | ||
|
||
// should set -P DROP but it disconnects VM w.o. extra netns | ||
+0 `$xtables -A INPUT -m conntrack --ctstate INVALID -j DROP` | ||
|
||
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 | ||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 | ||
+0 bind(3, ..., ...) = 0 | ||
+0 listen(3, 10) = 0 | ||
|
||
+0 < S 0:0(0) win 32792 <mss 1000> | ||
+0 > S. 0:0(0) ack 1 <mss 1460> | ||
+.01 < . 1:1(0) ack 1 win 65535 | ||
+0 accept(3, ..., ...) = 4 | ||
|
||
+0.0001 < P. 1:1461(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 1461 win 65535 | ||
+0.0001 < P. 1461:2921(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 2921 win 65535 | ||
+0.0001 < P. 2921:4381(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 4381 win 65535 | ||
+0.0001 < P. 4381:5841(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 5841 win 65535 | ||
+0.0001 < P. 5841:7301(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 7301 win 65535 | ||
+0.0001 < P. 7301:8761(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 8761 win 65535 | ||
+0.0001 < P. 8761:10221(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 10221 win 65535 | ||
+0.0001 < P. 10221:11681(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 11681 win 65535 | ||
+0.0001 < P. 11681:13141(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 13141 win 65535 | ||
+0.0001 < P. 13141:14601(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 14601 win 65535 | ||
+0.0001 < P. 14601:16061(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 16061 win 65535 | ||
+0.0001 < P. 16061:17521(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 17521 win 65535 | ||
+0.0001 < P. 17521:18981(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 18981 win 65535 | ||
+0.0001 < P. 18981:20441(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 20441 win 65535 | ||
+0.0001 < P. 20441:21901(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 21901 win 65535 | ||
+0.0001 < P. 21901:23361(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 23361 win 65535 | ||
+0.0001 < P. 23361:24821(1460) ack 1 win 257 | ||
0.055 > . 1:1(0) ack 24821 win 65535 | ||
+0.0001 < P. 24821:26281(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 26281 win 65535 | ||
+0.0001 < P. 26281:27741(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 27741 win 65535 | ||
+0.0001 < P. 27741:29201(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 29201 win 65535 | ||
+0.0001 < P. 29201:30661(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 30661 win 65535 | ||
+0.0001 < P. 30661:32121(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 32121 win 65535 | ||
+0.0001 < P. 32121:33581(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 33581 win 65535 | ||
+0.0001 < P. 33581:35041(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 35041 win 65535 | ||
+0.0001 < P. 35041:36501(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 36501 win 65535 | ||
+0.0001 < P. 36501:37961(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 37961 win 65535 | ||
+0.0001 < P. 37961:39421(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 39421 win 65535 | ||
+0.0001 < P. 39421:40881(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 40881 win 65535 | ||
+0.0001 < P. 40881:42341(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 42341 win 65535 | ||
+0.0001 < P. 42341:43801(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 43801 win 65535 | ||
+0.0001 < P. 43801:45261(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 45261 win 65535 | ||
+0.0001 < P. 45261:46721(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 46721 win 65535 | ||
+0.0001 < P. 46721:48181(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 48181 win 65535 | ||
+0.0001 < P. 48181:49641(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 49641 win 65535 | ||
+0.0001 < P. 49641:51101(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 51101 win 65535 | ||
+0.0001 < P. 51101:52561(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 52561 win 65535 | ||
+0.0001 < P. 52561:54021(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 54021 win 65535 | ||
+0.0001 < P. 54021:55481(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 55481 win 65535 | ||
+0.0001 < P. 55481:56941(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 56941 win 65535 | ||
+0.0001 < P. 56941:58401(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 58401 win 65535 | ||
+0.0001 < P. 58401:59861(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 59861 win 65535 | ||
+0.0001 < P. 59861:61321(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 61321 win 65535 | ||
+0.0001 < P. 61321:62781(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 62781 win 65535 | ||
+0.0001 < P. 62781:64241(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 64241 win 65535 | ||
+0.0001 < P. 64241:65701(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 65701 win 65535 | ||
+0.0001 < P. 65701:67161(1460) ack 1 win 257 | ||
+.0 > . 1:1(0) ack 67161 win 65535 | ||
|
||
// nf_ct_proto_6: SEQ is under the lower bound (already ACKed data retransmitted) IN=tun0 OUT= MAC= SRC=192.0.2.1 DST=192.168.24.72 LEN=1500 TOS=0x00 PREC=0x00 TTL=255 ID=0 PROTO=TCP SPT=34375 DPT=8080 SEQ=1 ACK=4162510439 WINDOW=257 RES=0x00 ACK PSH URGP=0 | ||
+0.0001 < P. 1:1461(1460) ack 1 win 257 | ||
|
||
// only sent if above packet isn't flagged as invalid | ||
+.0 > . 1:1(0) ack 67161 win 65535 | ||
|
||
+0 `$xtables -D INPUT -m conntrack --ctstate INVALID -j DROP` |
62 changes: 62 additions & 0 deletions
62
tools/testing/selftests/net/netfilter/packetdrill/conntrack_inexact_rst.pkt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// check RST packet that doesn't exactly match expected next sequence | ||
// number still transitions conntrack state to CLOSE iff its already in | ||
// FIN/CLOSE_WAIT. | ||
|
||
`packetdrill/common.sh` | ||
|
||
// 5.771921 server_ip > client_ip TLSv1.2 337 [Packet size limited during capture] | ||
// 5.771994 server_ip > client_ip TLSv1.2 337 [Packet size limited during capture] | ||
// 5.772212 client_ip > server_ip TCP 66 45020 > 443 [ACK] Seq=1905874048 Ack=781810658 Win=36352 Len=0 TSval=3317842872 TSecr=675936334 | ||
// 5.787924 server_ip > client_ip TLSv1.2 1300 [Packet size limited during capture] | ||
// 5.788126 server_ip > client_ip TLSv1.2 90 Application Data | ||
// 5.788207 server_ip > client_ip TCP 66 443 > 45020 [FIN, ACK] Seq=781811916 Ack=1905874048 Win=31104 Len=0 TSval=675936350 TSecr=3317842872 | ||
// 5.788447 client_ip > server_ip TLSv1.2 90 Application Data | ||
// 5.788479 client_ip > server_ip TCP 66 45020 > 443 [RST, ACK] Seq=1905874072 Ack=781811917 Win=39040 Len=0 TSval=3317842889 TSecr=675936350 | ||
// 5.788581 server_ip > client_ip TCP 54 8443 > 45020 [RST] Seq=781811892 Win=0 Len=0 | ||
|
||
+0 `iptables -A INPUT -p tcp -m conntrack --ctstate INVALID -j DROP` | ||
+0 `iptables -A OUTPUT -p tcp -m conntrack --ctstate INVALID -j DROP` | ||
|
||
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 | ||
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 | ||
|
||
0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) | ||
|
||
0.1 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 8> | ||
|
||
+0.1 < S. 1:1(0) ack 1 win 65535 <mss 1460> | ||
|
||
+0 > . 1:1(0) ack 1 win 65535 | ||
+0 < . 1:1001(1000) ack 1 win 65535 | ||
+0 < . 1001:2001(1000) ack 1 win 65535 | ||
+0 < . 2001:3001(1000) ack 1 win 65535 | ||
|
||
+0 > . 1:1(0) ack 1001 win 65535 | ||
+0 > . 1:1(0) ack 2001 win 65535 | ||
+0 > . 1:1(0) ack 3001 win 65535 | ||
|
||
+0 write(3, ..., 1000) = 1000 | ||
|
||
+0.0 > P. 1:1001(1000) ack 3001 win 65535 | ||
|
||
+0.1 read(3, ..., 1000) = 1000 | ||
|
||
// Conntrack should move to FIN_WAIT, then CLOSE_WAIT. | ||
+0 < F. 3001:3001(0) ack 1001 win 65535 | ||
+0 > . 1001:1001(0) ack 3002 win 65535 | ||
|
||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q CLOSE_WAIT` | ||
|
||
+1 close(3) = 0 | ||
// RST: unread data. FIN was seen, hence ack + 1 | ||
+0 > R. 1001:1001(0) ack 3002 win 65535 | ||
// ... and then, CLOSE. | ||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q CLOSE\ ` | ||
|
||
// Spurious RST from peer -- no sk state. Should NOT get | ||
// marked INVALID, because conntrack is already closing. | ||
+0.1 < R 2001:2001(0) win 0 | ||
|
||
// No packets should have been marked INVALID | ||
+0 `iptables -v -S INPUT | grep INVALID | grep -q -- "-c 0 0"` | ||
+0 `iptables -v -S OUTPUT | grep INVALID | grep -q -- "-c 0 0"` |
59 changes: 59 additions & 0 deletions
59
tools/testing/selftests/net/netfilter/packetdrill/conntrack_rst_invalid.pkt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// check that out of window resets are marked as INVALID and conntrack remains | ||
// in ESTABLISHED state. | ||
|
||
`packetdrill/common.sh` | ||
|
||
+0 `$xtables -A INPUT -p tcp -m conntrack --ctstate INVALID -j DROP` | ||
+0 `$xtables -A OUTPUT -p tcp -m conntrack --ctstate INVALID -j DROP` | ||
|
||
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 | ||
+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 | ||
|
||
0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) | ||
|
||
0.1 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 8> | ||
|
||
+0.1 < S. 1:1(0) ack 1 win 65535 <mss 1460> | ||
|
||
+0 > . 1:1(0) ack 1 win 65535 | ||
+0 < . 1:1001(1000) ack 1 win 65535 | ||
+0 < . 1001:2001(1000) ack 1 win 65535 | ||
+0 < . 2001:3001(1000) ack 1 win 65535 | ||
|
||
+0 > . 1:1(0) ack 1001 win 65535 | ||
+0 > . 1:1(0) ack 2001 win 65535 | ||
+0 > . 1:1(0) ack 3001 win 65535 | ||
|
||
+0 write(3, ..., 1000) = 1000 | ||
|
||
// out of window | ||
+0.0 < R 0:0(0) win 0 | ||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q ESTABLISHED` | ||
|
||
// out of window | ||
+0.0 < R 1000000:1000000(0) win 0 | ||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q ESTABLISHED` | ||
|
||
// in-window but not exact match | ||
+0.0 < R 42:42(0) win 0 | ||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q ESTABLISHED` | ||
|
||
+0.0 > P. 1:1001(1000) ack 3001 win 65535 | ||
|
||
+0.1 read(3, ..., 1000) = 1000 | ||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q ESTABLISHED` | ||
|
||
+0 < . 3001:3001(0) ack 1001 win 65535 | ||
|
||
+0.0 < R. 3000:3000(0) ack 1001 win 0 | ||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q ESTABLISHED` | ||
|
||
// exact next sequence | ||
+0.0 < R. 3001:3001(0) ack 1001 win 0 | ||
// Conntrack should move to CLOSE | ||
|
||
// Expect four invalid RSTs | ||
+0 `$xtables -v -S INPUT | grep INVALID | grep -q -- "-c 4 "` | ||
+0 `$xtables -v -S OUTPUT | grep INVALID | grep -q -- "-c 0 0"` | ||
|
||
+0 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null |grep -q CLOSE\ ` |
Oops, something went wrong.