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