1becf2319SFlorian Westphal#!/bin/bash
2becf2319SFlorian Westphal#
3becf2319SFlorian Westphal# check that ICMP df-needed/pkttoobig icmp are set are set as related
4becf2319SFlorian Westphal# state
5becf2319SFlorian Westphal#
6becf2319SFlorian Westphal# Setup is:
7becf2319SFlorian Westphal#
8becf2319SFlorian Westphal# nsclient1 -> nsrouter1 -> nsrouter2 -> nsclient2
9becf2319SFlorian Westphal# MTU 1500, except for nsrouter2 <-> nsclient2 link (1280).
10becf2319SFlorian Westphal# ping nsclient2 from nsclient1, checking that conntrack did set RELATED
11becf2319SFlorian Westphal# 'fragmentation needed' icmp packet.
12becf2319SFlorian Westphal#
13becf2319SFlorian Westphal# In addition, nsrouter1 will perform IP masquerading, i.e. also
14becf2319SFlorian Westphal# check the icmp errors are propagated to the correct host as per
15becf2319SFlorian Westphal# nat of "established" icmp-echo "connection".
16becf2319SFlorian Westphal
17becf2319SFlorian Westphal# Kselftest framework requirement - SKIP code is 4.
18becf2319SFlorian Westphalksft_skip=4
19becf2319SFlorian Westphalret=0
20becf2319SFlorian Westphal
21becf2319SFlorian Westphalnft --version > /dev/null 2>&1
22becf2319SFlorian Westphalif [ $? -ne 0 ];then
23becf2319SFlorian Westphal	echo "SKIP: Could not run test without nft tool"
24becf2319SFlorian Westphal	exit $ksft_skip
25becf2319SFlorian Westphalfi
26becf2319SFlorian Westphal
27becf2319SFlorian Westphalip -Version > /dev/null 2>&1
28becf2319SFlorian Westphalif [ $? -ne 0 ];then
29becf2319SFlorian Westphal	echo "SKIP: Could not run test without ip tool"
30becf2319SFlorian Westphal	exit $ksft_skip
31becf2319SFlorian Westphalfi
32becf2319SFlorian Westphal
33becf2319SFlorian Westphalcleanup() {
34becf2319SFlorian Westphal	for i in 1 2;do ip netns del nsclient$i;done
35becf2319SFlorian Westphal	for i in 1 2;do ip netns del nsrouter$i;done
36becf2319SFlorian Westphal}
37becf2319SFlorian Westphal
38*7d7cfb48SFlorian Westphaltrap cleanup EXIT
39*7d7cfb48SFlorian Westphal
40becf2319SFlorian Westphalipv4() {
41becf2319SFlorian Westphal    echo -n 192.168.$1.2
42becf2319SFlorian Westphal}
43becf2319SFlorian Westphal
44becf2319SFlorian Westphalipv6 () {
45becf2319SFlorian Westphal    echo -n dead:$1::2
46becf2319SFlorian Westphal}
47becf2319SFlorian Westphal
48becf2319SFlorian Westphalcheck_counter()
49becf2319SFlorian Westphal{
50becf2319SFlorian Westphal	ns=$1
51becf2319SFlorian Westphal	name=$2
52becf2319SFlorian Westphal	expect=$3
53becf2319SFlorian Westphal	local lret=0
54becf2319SFlorian Westphal
55becf2319SFlorian Westphal	cnt=$(ip netns exec $ns nft list counter inet filter "$name" | grep -q "$expect")
56becf2319SFlorian Westphal	if [ $? -ne 0 ]; then
57becf2319SFlorian Westphal		echo "ERROR: counter $name in $ns has unexpected value (expected $expect)" 1>&2
58becf2319SFlorian Westphal		ip netns exec $ns nft list counter inet filter "$name" 1>&2
59becf2319SFlorian Westphal		lret=1
60becf2319SFlorian Westphal	fi
61becf2319SFlorian Westphal
62becf2319SFlorian Westphal	return $lret
63becf2319SFlorian Westphal}
64becf2319SFlorian Westphal
65becf2319SFlorian Westphalcheck_unknown()
66becf2319SFlorian Westphal{
67becf2319SFlorian Westphal	expect="packets 0 bytes 0"
68becf2319SFlorian Westphal	for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
69becf2319SFlorian Westphal		check_counter $n "unknown" "$expect"
70becf2319SFlorian Westphal		if [ $? -ne 0 ] ;then
71becf2319SFlorian Westphal			return 1
72becf2319SFlorian Westphal		fi
73becf2319SFlorian Westphal	done
74becf2319SFlorian Westphal
75becf2319SFlorian Westphal	return 0
76becf2319SFlorian Westphal}
77becf2319SFlorian Westphal
78becf2319SFlorian Westphalfor n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
79becf2319SFlorian Westphal  ip netns add $n
80becf2319SFlorian Westphal  ip -net $n link set lo up
81becf2319SFlorian Westphaldone
82becf2319SFlorian Westphal
83becf2319SFlorian WestphalDEV=veth0
84becf2319SFlorian Westphalip link add $DEV netns nsclient1 type veth peer name eth1 netns nsrouter1
85becf2319SFlorian WestphalDEV=veth0
86becf2319SFlorian Westphalip link add $DEV netns nsclient2 type veth peer name eth1 netns nsrouter2
87becf2319SFlorian Westphal
88becf2319SFlorian WestphalDEV=veth0
89becf2319SFlorian Westphalip link add $DEV netns nsrouter1 type veth peer name eth2 netns nsrouter2
90becf2319SFlorian Westphal
91becf2319SFlorian WestphalDEV=veth0
92becf2319SFlorian Westphalfor i in 1 2; do
93becf2319SFlorian Westphal    ip -net nsclient$i link set $DEV up
94becf2319SFlorian Westphal    ip -net nsclient$i addr add $(ipv4 $i)/24 dev $DEV
95becf2319SFlorian Westphal    ip -net nsclient$i addr add $(ipv6 $i)/64 dev $DEV
96becf2319SFlorian Westphaldone
97becf2319SFlorian Westphal
98becf2319SFlorian Westphalip -net nsrouter1 link set eth1 up
99becf2319SFlorian Westphalip -net nsrouter1 link set veth0 up
100becf2319SFlorian Westphal
101becf2319SFlorian Westphalip -net nsrouter2 link set eth1 up
102becf2319SFlorian Westphalip -net nsrouter2 link set eth2 up
103becf2319SFlorian Westphal
104becf2319SFlorian Westphalip -net nsclient1 route add default via 192.168.1.1
105becf2319SFlorian Westphalip -net nsclient1 -6 route add default via dead:1::1
106becf2319SFlorian Westphal
107becf2319SFlorian Westphalip -net nsclient2 route add default via 192.168.2.1
108becf2319SFlorian Westphalip -net nsclient2 route add default via dead:2::1
109becf2319SFlorian Westphal
110becf2319SFlorian Westphali=3
111becf2319SFlorian Westphalip -net nsrouter1 addr add 192.168.1.1/24 dev eth1
112becf2319SFlorian Westphalip -net nsrouter1 addr add 192.168.3.1/24 dev veth0
113becf2319SFlorian Westphalip -net nsrouter1 addr add dead:1::1/64 dev eth1
114becf2319SFlorian Westphalip -net nsrouter1 addr add dead:3::1/64 dev veth0
115becf2319SFlorian Westphalip -net nsrouter1 route add default via 192.168.3.10
116becf2319SFlorian Westphalip -net nsrouter1 -6 route add default via dead:3::10
117becf2319SFlorian Westphal
118becf2319SFlorian Westphalip -net nsrouter2 addr add 192.168.2.1/24 dev eth1
119becf2319SFlorian Westphalip -net nsrouter2 addr add 192.168.3.10/24 dev eth2
120becf2319SFlorian Westphalip -net nsrouter2 addr add dead:2::1/64 dev eth1
121becf2319SFlorian Westphalip -net nsrouter2 addr add dead:3::10/64 dev eth2
122becf2319SFlorian Westphalip -net nsrouter2 route add default via 192.168.3.1
123becf2319SFlorian Westphalip -net nsrouter2 route add default via dead:3::1
124becf2319SFlorian Westphal
125becf2319SFlorian Westphalsleep 2
126becf2319SFlorian Westphalfor i in 4 6; do
127becf2319SFlorian Westphal	ip netns exec nsrouter1 sysctl -q net.ipv$i.conf.all.forwarding=1
128becf2319SFlorian Westphal	ip netns exec nsrouter2 sysctl -q net.ipv$i.conf.all.forwarding=1
129becf2319SFlorian Westphaldone
130becf2319SFlorian Westphal
131becf2319SFlorian Westphalfor netns in nsrouter1 nsrouter2; do
132becf2319SFlorian Westphalip netns exec $netns nft -f - <<EOF
133becf2319SFlorian Westphaltable inet filter {
134becf2319SFlorian Westphal	counter unknown { }
135becf2319SFlorian Westphal	counter related { }
136becf2319SFlorian Westphal	chain forward {
137becf2319SFlorian Westphal		type filter hook forward priority 0; policy accept;
138becf2319SFlorian Westphal		meta l4proto icmpv6 icmpv6 type "packet-too-big" ct state "related" counter name "related" accept
139becf2319SFlorian Westphal		meta l4proto icmp icmp type "destination-unreachable" ct state "related" counter name "related" accept
140becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state new,established accept
141becf2319SFlorian Westphal		counter name "unknown" drop
142becf2319SFlorian Westphal	}
143becf2319SFlorian Westphal}
144becf2319SFlorian WestphalEOF
145becf2319SFlorian Westphaldone
146becf2319SFlorian Westphal
147becf2319SFlorian Westphalip netns exec nsclient1 nft -f - <<EOF
148becf2319SFlorian Westphaltable inet filter {
149becf2319SFlorian Westphal	counter unknown { }
150becf2319SFlorian Westphal	counter related { }
151*7d7cfb48SFlorian Westphal	counter redir4 { }
152*7d7cfb48SFlorian Westphal	counter redir6 { }
153becf2319SFlorian Westphal	chain input {
154becf2319SFlorian Westphal		type filter hook input priority 0; policy accept;
155becf2319SFlorian Westphal
156*7d7cfb48SFlorian Westphal		icmp type "redirect" ct state "related" counter name "redir4" accept
157*7d7cfb48SFlorian Westphal		icmpv6 type "nd-redirect" ct state "related" counter name "redir6" accept
158*7d7cfb48SFlorian Westphal
159*7d7cfb48SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state established,untracked accept
160becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
161*7d7cfb48SFlorian Westphal
162becf2319SFlorian Westphal		counter name "unknown" drop
163becf2319SFlorian Westphal	}
164becf2319SFlorian Westphal}
165becf2319SFlorian WestphalEOF
166becf2319SFlorian Westphal
167becf2319SFlorian Westphalip netns exec nsclient2 nft -f - <<EOF
168becf2319SFlorian Westphaltable inet filter {
169becf2319SFlorian Westphal	counter unknown { }
170becf2319SFlorian Westphal	counter new { }
171becf2319SFlorian Westphal	counter established { }
172becf2319SFlorian Westphal
173becf2319SFlorian Westphal	chain input {
174becf2319SFlorian Westphal		type filter hook input priority 0; policy accept;
175becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state established,untracked accept
176becf2319SFlorian Westphal
177becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" accept
178becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" accept
179becf2319SFlorian Westphal		counter name "unknown" drop
180becf2319SFlorian Westphal	}
181becf2319SFlorian Westphal	chain output {
182becf2319SFlorian Westphal		type filter hook output priority 0; policy accept;
183becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state established,untracked accept
184becf2319SFlorian Westphal
185becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state "new" counter name "new"
186becf2319SFlorian Westphal		meta l4proto { icmp, icmpv6 } ct state "established" counter name "established"
187becf2319SFlorian Westphal		counter name "unknown" drop
188becf2319SFlorian Westphal	}
189becf2319SFlorian Westphal}
190becf2319SFlorian WestphalEOF
191becf2319SFlorian Westphal
192becf2319SFlorian Westphal
193becf2319SFlorian Westphal# make sure NAT core rewrites adress of icmp error if nat is used according to
194becf2319SFlorian Westphal# conntrack nat information (icmp error will be directed at nsrouter1 address,
195becf2319SFlorian Westphal# but it needs to be routed to nsclient1 address).
196becf2319SFlorian Westphalip netns exec nsrouter1 nft -f - <<EOF
197becf2319SFlorian Westphaltable ip nat {
198becf2319SFlorian Westphal	chain postrouting {
199becf2319SFlorian Westphal		type nat hook postrouting priority 0; policy accept;
200becf2319SFlorian Westphal		ip protocol icmp oifname "veth0" counter masquerade
201becf2319SFlorian Westphal	}
202becf2319SFlorian Westphal}
203becf2319SFlorian Westphaltable ip6 nat {
204becf2319SFlorian Westphal	chain postrouting {
205becf2319SFlorian Westphal		type nat hook postrouting priority 0; policy accept;
206becf2319SFlorian Westphal		ip6 nexthdr icmpv6 oifname "veth0" counter masquerade
207becf2319SFlorian Westphal	}
208becf2319SFlorian Westphal}
209becf2319SFlorian WestphalEOF
210becf2319SFlorian Westphal
211becf2319SFlorian Westphalip netns exec nsrouter2 ip link set eth1  mtu 1280
212becf2319SFlorian Westphalip netns exec nsclient2 ip link set veth0 mtu 1280
213becf2319SFlorian Westphalsleep 1
214becf2319SFlorian Westphal
215becf2319SFlorian Westphalip netns exec nsclient1 ping -c 1 -s 1000 -q -M do 192.168.2.2 >/dev/null
216becf2319SFlorian Westphalif [ $? -ne 0 ]; then
217becf2319SFlorian Westphal	echo "ERROR: netns ip routing/connectivity broken" 1>&2
218becf2319SFlorian Westphal	cleanup
219becf2319SFlorian Westphal	exit 1
220becf2319SFlorian Westphalfi
221becf2319SFlorian Westphalip netns exec nsclient1 ping6 -q -c 1 -s 1000 dead:2::2 >/dev/null
222becf2319SFlorian Westphalif [ $? -ne 0 ]; then
223becf2319SFlorian Westphal	echo "ERROR: netns ipv6 routing/connectivity broken" 1>&2
224becf2319SFlorian Westphal	cleanup
225becf2319SFlorian Westphal	exit 1
226becf2319SFlorian Westphalfi
227becf2319SFlorian Westphal
228becf2319SFlorian Westphalcheck_unknown
229becf2319SFlorian Westphalif [ $? -ne 0 ]; then
230becf2319SFlorian Westphal	ret=1
231becf2319SFlorian Westphalfi
232becf2319SFlorian Westphal
233becf2319SFlorian Westphalexpect="packets 0 bytes 0"
234becf2319SFlorian Westphalfor netns in nsrouter1 nsrouter2 nsclient1;do
235becf2319SFlorian Westphal	check_counter "$netns" "related" "$expect"
236becf2319SFlorian Westphal	if [ $? -ne 0 ]; then
237becf2319SFlorian Westphal		ret=1
238becf2319SFlorian Westphal	fi
239becf2319SFlorian Westphaldone
240becf2319SFlorian Westphal
241becf2319SFlorian Westphalexpect="packets 2 bytes 2076"
242becf2319SFlorian Westphalcheck_counter nsclient2 "new" "$expect"
243becf2319SFlorian Westphalif [ $? -ne 0 ]; then
244becf2319SFlorian Westphal	ret=1
245becf2319SFlorian Westphalfi
246becf2319SFlorian Westphal
247becf2319SFlorian Westphalip netns exec nsclient1 ping -q -c 1 -s 1300 -M do 192.168.2.2 > /dev/null
248becf2319SFlorian Westphalif [ $? -eq 0 ]; then
249becf2319SFlorian Westphal	echo "ERROR: ping should have failed with PMTU too big error" 1>&2
250becf2319SFlorian Westphal	ret=1
251becf2319SFlorian Westphalfi
252becf2319SFlorian Westphal
253becf2319SFlorian Westphal# nsrouter2 should have generated the icmp error, so
254becf2319SFlorian Westphal# related counter should be 0 (its in forward).
255becf2319SFlorian Westphalexpect="packets 0 bytes 0"
256becf2319SFlorian Westphalcheck_counter "nsrouter2" "related" "$expect"
257becf2319SFlorian Westphalif [ $? -ne 0 ]; then
258becf2319SFlorian Westphal	ret=1
259becf2319SFlorian Westphalfi
260becf2319SFlorian Westphal
261becf2319SFlorian Westphal# but nsrouter1 should have seen it, same for nsclient1.
262becf2319SFlorian Westphalexpect="packets 1 bytes 576"
263becf2319SFlorian Westphalfor netns in nsrouter1 nsclient1;do
264becf2319SFlorian Westphal	check_counter "$netns" "related" "$expect"
265becf2319SFlorian Westphal	if [ $? -ne 0 ]; then
266becf2319SFlorian Westphal		ret=1
267becf2319SFlorian Westphal	fi
268becf2319SFlorian Westphaldone
269becf2319SFlorian Westphal
270becf2319SFlorian Westphalip netns exec nsclient1 ping6 -c 1 -s 1300 dead:2::2 > /dev/null
271becf2319SFlorian Westphalif [ $? -eq 0 ]; then
272becf2319SFlorian Westphal	echo "ERROR: ping6 should have failed with PMTU too big error" 1>&2
273becf2319SFlorian Westphal	ret=1
274becf2319SFlorian Westphalfi
275becf2319SFlorian Westphal
276becf2319SFlorian Westphalexpect="packets 2 bytes 1856"
277becf2319SFlorian Westphalfor netns in nsrouter1 nsclient1;do
278becf2319SFlorian Westphal	check_counter "$netns" "related" "$expect"
279becf2319SFlorian Westphal	if [ $? -ne 0 ]; then
280becf2319SFlorian Westphal		ret=1
281becf2319SFlorian Westphal	fi
282becf2319SFlorian Westphaldone
283becf2319SFlorian Westphal
284becf2319SFlorian Westphalif [ $ret -eq 0 ];then
285becf2319SFlorian Westphal	echo "PASS: icmp mtu error had RELATED state"
286becf2319SFlorian Westphalelse
287becf2319SFlorian Westphal	echo "ERROR: icmp error RELATED state test has failed"
288becf2319SFlorian Westphalfi
289becf2319SFlorian Westphal
290*7d7cfb48SFlorian Westphal# add 'bad' route,  expect icmp REDIRECT to be generated
291*7d7cfb48SFlorian Westphalip netns exec nsclient1 ip route add 192.168.1.42 via 192.168.1.1
292*7d7cfb48SFlorian Westphalip netns exec nsclient1 ip route add dead:1::42 via dead:1::1
293*7d7cfb48SFlorian Westphal
294*7d7cfb48SFlorian Westphalip netns exec "nsclient1" ping -q -c 2 192.168.1.42 > /dev/null
295*7d7cfb48SFlorian Westphal
296*7d7cfb48SFlorian Westphalexpect="packets 1 bytes 112"
297*7d7cfb48SFlorian Westphalcheck_counter nsclient1 "redir4" "$expect"
298*7d7cfb48SFlorian Westphalif [ $? -ne 0 ];then
299*7d7cfb48SFlorian Westphal	ret=1
300*7d7cfb48SFlorian Westphalfi
301*7d7cfb48SFlorian Westphal
302*7d7cfb48SFlorian Westphalip netns exec "nsclient1" ping -c 1 dead:1::42 > /dev/null
303*7d7cfb48SFlorian Westphalexpect="packets 1 bytes 192"
304*7d7cfb48SFlorian Westphalcheck_counter nsclient1 "redir6" "$expect"
305*7d7cfb48SFlorian Westphalif [ $? -ne 0 ];then
306*7d7cfb48SFlorian Westphal	ret=1
307*7d7cfb48SFlorian Westphalfi
308*7d7cfb48SFlorian Westphal
309*7d7cfb48SFlorian Westphalif [ $ret -eq 0 ];then
310*7d7cfb48SFlorian Westphal	echo "PASS: icmp redirects had RELATED state"
311*7d7cfb48SFlorian Westphalelse
312*7d7cfb48SFlorian Westphal	echo "ERROR: icmp redirect RELATED state test has failed"
313*7d7cfb48SFlorian Westphalfi
314*7d7cfb48SFlorian Westphal
315becf2319SFlorian Westphalexit $ret
316