1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4
5# Kselftest framework requirement - SKIP code is 4.
6ksft_skip=4
7ret=0
8
9rnd=$(mktemp -u XXXXXXXX)
10nsr="nsr-$rnd"	# synproxy machine
11ns1="ns1-$rnd"  # iperf client
12ns2="ns2-$rnd"  # iperf server
13
14checktool (){
15	if ! $1 > /dev/null 2>&1; then
16		echo "SKIP: Could not $2"
17		exit $ksft_skip
18	fi
19}
20
21checktool "nft --version" "run test without nft tool"
22checktool "ip -Version" "run test without ip tool"
23checktool "iperf3 --version" "run test without iperf3"
24checktool "ip netns add $nsr" "create net namespace"
25
26modprobe -q nf_conntrack
27
28ip netns add $ns1
29ip netns add $ns2
30
31cleanup() {
32	ip netns pids $ns1 | xargs kill 2>/dev/null
33	ip netns pids $ns2 | xargs kill 2>/dev/null
34	ip netns del $ns1
35	ip netns del $ns2
36
37	ip netns del $nsr
38}
39
40trap cleanup EXIT
41
42ip link add veth0 netns $nsr type veth peer name eth0 netns $ns1
43ip link add veth1 netns $nsr type veth peer name eth0 netns $ns2
44
45for dev in lo veth0 veth1; do
46ip -net $nsr link set $dev up
47done
48
49ip -net $nsr addr add 10.0.1.1/24 dev veth0
50ip -net $nsr addr add 10.0.2.1/24 dev veth1
51
52ip netns exec $nsr sysctl -q net.ipv4.conf.veth0.forwarding=1
53ip netns exec $nsr sysctl -q net.ipv4.conf.veth1.forwarding=1
54ip netns exec $nsr sysctl -q net.netfilter.nf_conntrack_tcp_loose=0
55
56for n in $ns1 $ns2; do
57  ip -net $n link set lo up
58  ip -net $n link set eth0 up
59done
60ip -net $ns1 addr add 10.0.1.99/24 dev eth0
61ip -net $ns2 addr add 10.0.2.99/24 dev eth0
62ip -net $ns1 route add default via 10.0.1.1
63ip -net $ns2 route add default via 10.0.2.1
64
65# test basic connectivity
66if ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then
67  echo "ERROR: $ns1 cannot reach $ns2" 1>&2
68  exit 1
69fi
70
71if ! ip netns exec $ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then
72  echo "ERROR: $ns2 cannot reach $ns1" 1>&2
73  exit 1
74fi
75
76ip netns exec $ns2 iperf3 -s > /dev/null 2>&1 &
77# ip netns exec $nsr tcpdump -vvv -n -i veth1 tcp | head -n 10 &
78
79sleep 1
80
81ip netns exec $nsr nft -f - <<EOF
82table inet filter {
83   chain prerouting {
84      type filter hook prerouting priority -300; policy accept;
85      meta iif veth0 tcp flags syn counter notrack
86   }
87
88  chain forward {
89      type filter hook forward priority 0; policy accept;
90
91      ct state new,established counter accept
92
93      meta iif veth0 meta l4proto tcp ct state untracked,invalid synproxy mss 1460 sack-perm timestamp
94
95      ct state invalid counter drop
96
97      # make ns2 unreachable w.o. tcp synproxy
98      tcp flags syn counter drop
99   }
100}
101EOF
102if [ $? -ne 0 ]; then
103	echo "SKIP: Cannot add nft synproxy"
104	exit $ksft_skip
105fi
106
107ip netns exec $ns1 timeout 5 iperf3 -c 10.0.2.99 -n $((1 * 1024 * 1024)) > /dev/null
108
109if [ $? -ne 0 ]; then
110	echo "FAIL: iperf3 returned an error" 1>&2
111	ret=$?
112	ip netns exec $nsr nft list ruleset
113else
114	echo "PASS: synproxy connection successful"
115fi
116
117exit $ret
118