aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/netfilter/nft_conntrack_helper.sh
blob: bf6b9626c7dd2749547cb13062188d4bb834c5b6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/bash
#
# This tests connection tracking helper assignment:
# 1. can attach ftp helper to a connection from nft ruleset.
# 2. auto-assign still works.
#
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
ret=0

sfx=$(mktemp -u "XXXXXXXX")
ns1="ns1-$sfx"
ns2="ns2-$sfx"
testipv6=1

cleanup()
{
	ip netns del ${ns1}
	ip netns del ${ns2}
}

nft --version > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without nft tool"
	exit $ksft_skip
fi

ip -Version > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without ip tool"
	exit $ksft_skip
fi

conntrack -V > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without conntrack tool"
	exit $ksft_skip
fi

which nc >/dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without netcat tool"
	exit $ksft_skip
fi

trap cleanup EXIT

ip netns add ${ns1}
ip netns add ${ns2}

ip link add veth0 netns ${ns1} type veth peer name veth0 netns ${ns2} > /dev/null 2>&1
if [ $? -ne 0 ];then
    echo "SKIP: No virtual ethernet pair device support in kernel"
    exit $ksft_skip
fi

ip -net ${ns1} link set lo up
ip -net ${ns1} link set veth0 up

ip -net ${ns2} link set lo up
ip -net ${ns2} link set veth0 up

ip -net ${ns1} addr add 10.0.1.1/24 dev veth0
ip -net ${ns1} addr add dead:1::1/64 dev veth0

ip -net ${ns2} addr add 10.0.1.2/24 dev veth0
ip -net ${ns2} addr add dead:1::2/64 dev veth0

load_ruleset_family() {
	local family=$1
	local ns=$2

ip netns exec ${ns} nft -f - <<EOF
table $family raw {
	ct helper ftp {
             type "ftp" protocol tcp
        }
	chain pre {
		type filter hook prerouting priority 0; policy accept;
		tcp dport 2121 ct helper set "ftp"
	}
	chain output {
		type filter hook output priority 0; policy accept;
		tcp dport 2121 ct helper set "ftp"
	}
}
EOF
	return $?
}

check_for_helper()
{
	local netns=$1
	local message=$2
	local port=$3

	if echo $message |grep -q 'ipv6';then
		local family="ipv6"
	else
		local family="ipv4"
	fi

	ip netns exec ${netns} conntrack -L -f $family -p tcp --dport $port 2> /dev/null |grep -q 'helper=ftp'
	if [ $? -ne 0 ] ; then
		echo "FAIL: ${netns} did not show attached helper $message" 1>&2
		ret=1
	fi

	echo "PASS: ${netns} connection on port $port has ftp helper attached" 1>&2
	return 0
}

test_helper()
{
	local port=$1
	local msg=$2

	sleep 3 | ip netns exec ${ns2} nc -w 2 -l -p $port > /dev/null &

	sleep 1 | ip netns exec ${ns1} nc -w 2 10.0.1.2 $port > /dev/null &
	sleep 1

	check_for_helper "$ns1" "ip $msg" $port
	check_for_helper "$ns2" "ip $msg" $port

	wait

	if [ $testipv6 -eq 0 ] ;then
		return 0
	fi

	ip netns exec ${ns1} conntrack -F 2> /dev/null
	ip netns exec ${ns2} conntrack -F 2> /dev/null

	sleep 3 | ip netns exec ${ns2} nc -w 2 -6 -l -p $port > /dev/null &

	sleep 1 | ip netns exec ${ns1} nc -w 2 -6 dead:1::2 $port > /dev/null &
	sleep 1

	check_for_helper "$ns1" "ipv6 $msg" $port
	check_for_helper "$ns2" "ipv6 $msg" $port

	wait
}

load_ruleset_family ip ${ns1}
if [ $? -ne 0 ];then
	echo "FAIL: ${ns1} cannot load ip ruleset" 1>&2
	exit 1
fi

load_ruleset_family ip6 ${ns1}
if [ $? -ne 0 ];then
	echo "SKIP: ${ns1} cannot load ip6 ruleset" 1>&2
	testipv6=0
fi

load_ruleset_family inet ${ns2}
if [ $? -ne 0 ];then
	echo "SKIP: ${ns1} cannot load inet ruleset" 1>&2
	load_ruleset_family ip ${ns2}
	if [ $? -ne 0 ];then
		echo "FAIL: ${ns2} cannot load ip ruleset" 1>&2
		exit 1
	fi

	if [ $testipv6 -eq 1 ] ;then
		load_ruleset_family ip6 ${ns2}
		if [ $? -ne 0 ];then
			echo "FAIL: ${ns2} cannot load ip6 ruleset" 1>&2
			exit 1
		fi
	fi
fi

test_helper 2121 "set via ruleset"
ip netns exec ${ns1} sysctl -q 'net.netfilter.nf_conntrack_helper=1'
ip netns exec ${ns2} sysctl -q 'net.netfilter.nf_conntrack_helper=1'
test_helper 21 "auto-assign"

exit $ret