GNU Linux-libre 4.19.245-gnu1
[releases.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 ipv4() {
39     echo -n 192.168.$1.2
40 }
41
42 ipv6 () {
43     echo -n dead:$1::2
44 }
45
46 check_counter()
47 {
48         ns=$1
49         name=$2
50         expect=$3
51         local lret=0
52
53         cnt=$(ip netns exec $ns nft list counter inet filter "$name" | grep -q "$expect")
54         if [ $? -ne 0 ]; then
55                 echo "ERROR: counter $name in $ns has unexpected value (expected $expect)" 1>&2
56                 ip netns exec $ns nft list counter inet filter "$name" 1>&2
57                 lret=1
58         fi
59
60         return $lret
61 }
62
63 check_unknown()
64 {
65         expect="packets 0 bytes 0"
66         for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
67                 check_counter $n "unknown" "$expect"
68                 if [ $? -ne 0 ] ;then
69                         return 1
70                 fi
71         done
72
73         return 0
74 }
75
76 for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do
77   ip netns add $n
78   ip -net $n link set lo up
79 done
80
81 DEV=veth0
82 ip link add $DEV netns nsclient1 type veth peer name eth1 netns nsrouter1
83 DEV=veth0
84 ip link add $DEV netns nsclient2 type veth peer name eth1 netns nsrouter2
85
86 DEV=veth0
87 ip link add $DEV netns nsrouter1 type veth peer name eth2 netns nsrouter2
88
89 DEV=veth0
90 for i in 1 2; do
91     ip -net nsclient$i link set $DEV up
92     ip -net nsclient$i addr add $(ipv4 $i)/24 dev $DEV
93     ip -net nsclient$i addr add $(ipv6 $i)/64 dev $DEV
94 done
95
96 ip -net nsrouter1 link set eth1 up
97 ip -net nsrouter1 link set veth0 up
98
99 ip -net nsrouter2 link set eth1 up
100 ip -net nsrouter2 link set eth2 up
101
102 ip -net nsclient1 route add default via 192.168.1.1
103 ip -net nsclient1 -6 route add default via dead:1::1
104
105 ip -net nsclient2 route add default via 192.168.2.1
106 ip -net nsclient2 route add default via dead:2::1
107
108 i=3
109 ip -net nsrouter1 addr add 192.168.1.1/24 dev eth1
110 ip -net nsrouter1 addr add 192.168.3.1/24 dev veth0
111 ip -net nsrouter1 addr add dead:1::1/64 dev eth1
112 ip -net nsrouter1 addr add dead:3::1/64 dev veth0
113 ip -net nsrouter1 route add default via 192.168.3.10
114 ip -net nsrouter1 -6 route add default via dead:3::10
115
116 ip -net nsrouter2 addr add 192.168.2.1/24 dev eth1
117 ip -net nsrouter2 addr add 192.168.3.10/24 dev eth2
118 ip -net nsrouter2 addr add dead:2::1/64 dev eth1
119 ip -net nsrouter2 addr add dead:3::10/64 dev eth2
120 ip -net nsrouter2 route add default via 192.168.3.1
121 ip -net nsrouter2 route add default via dead:3::1
122
123 sleep 2
124 for i in 4 6; do
125         ip netns exec nsrouter1 sysctl -q net.ipv$i.conf.all.forwarding=1
126         ip netns exec nsrouter2 sysctl -q net.ipv$i.conf.all.forwarding=1
127 done
128
129 for netns in nsrouter1 nsrouter2; do
130 ip netns exec $netns nft -f - <<EOF
131 table inet filter {
132         counter unknown { }
133         counter related { }
134         chain forward {
135                 type filter hook forward priority 0; policy accept;
136                 meta l4proto icmpv6 icmpv6 type "packet-too-big" ct state "related" counter name "related" accept
137                 meta l4proto icmp icmp type "destination-unreachable" ct state "related" counter name "related" accept
138                 meta l4proto { icmp, icmpv6 } ct state new,established accept
139                 counter name "unknown" drop
140         }
141 }
142 EOF
143 done
144
145 ip netns exec nsclient1 nft -f - <<EOF
146 table inet filter {
147         counter unknown { }
148         counter related { }
149         chain input {
150                 type filter hook input priority 0; policy accept;
151                 meta l4proto { icmp, icmpv6 } ct state established,untracked accept
152
153                 meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
154                 counter name "unknown" drop
155         }
156 }
157 EOF
158
159 ip netns exec nsclient2 nft -f - <<EOF
160 table inet filter {
161         counter unknown { }
162         counter new { }
163         counter established { }
164
165         chain input {
166                 type filter hook input priority 0; policy accept;
167                 meta l4proto { icmp, icmpv6 } ct state established,untracked accept
168
169                 meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" accept
170                 meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" accept
171                 counter name "unknown" drop
172         }
173         chain output {
174                 type filter hook output 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"
178                 meta l4proto { icmp, icmpv6 } ct state "established" counter name "established"
179                 counter name "unknown" drop
180         }
181 }
182 EOF
183
184
185 # make sure NAT core rewrites adress of icmp error if nat is used according to
186 # conntrack nat information (icmp error will be directed at nsrouter1 address,
187 # but it needs to be routed to nsclient1 address).
188 ip netns exec nsrouter1 nft -f - <<EOF
189 table ip nat {
190         chain postrouting {
191                 type nat hook postrouting priority 0; policy accept;
192                 ip protocol icmp oifname "veth0" counter masquerade
193         }
194 }
195 table ip6 nat {
196         chain postrouting {
197                 type nat hook postrouting priority 0; policy accept;
198                 ip6 nexthdr icmpv6 oifname "veth0" counter masquerade
199         }
200 }
201 EOF
202
203 ip netns exec nsrouter2 ip link set eth1  mtu 1280
204 ip netns exec nsclient2 ip link set veth0 mtu 1280
205 sleep 1
206
207 ip netns exec nsclient1 ping -c 1 -s 1000 -q -M do 192.168.2.2 >/dev/null
208 if [ $? -ne 0 ]; then
209         echo "ERROR: netns ip routing/connectivity broken" 1>&2
210         cleanup
211         exit 1
212 fi
213 ip netns exec nsclient1 ping6 -q -c 1 -s 1000 dead:2::2 >/dev/null
214 if [ $? -ne 0 ]; then
215         echo "ERROR: netns ipv6 routing/connectivity broken" 1>&2
216         cleanup
217         exit 1
218 fi
219
220 check_unknown
221 if [ $? -ne 0 ]; then
222         ret=1
223 fi
224
225 expect="packets 0 bytes 0"
226 for netns in nsrouter1 nsrouter2 nsclient1;do
227         check_counter "$netns" "related" "$expect"
228         if [ $? -ne 0 ]; then
229                 ret=1
230         fi
231 done
232
233 expect="packets 2 bytes 2076"
234 check_counter nsclient2 "new" "$expect"
235 if [ $? -ne 0 ]; then
236         ret=1
237 fi
238
239 ip netns exec nsclient1 ping -q -c 1 -s 1300 -M do 192.168.2.2 > /dev/null
240 if [ $? -eq 0 ]; then
241         echo "ERROR: ping should have failed with PMTU too big error" 1>&2
242         ret=1
243 fi
244
245 # nsrouter2 should have generated the icmp error, so
246 # related counter should be 0 (its in forward).
247 expect="packets 0 bytes 0"
248 check_counter "nsrouter2" "related" "$expect"
249 if [ $? -ne 0 ]; then
250         ret=1
251 fi
252
253 # but nsrouter1 should have seen it, same for nsclient1.
254 expect="packets 1 bytes 576"
255 for netns in nsrouter1 nsclient1;do
256         check_counter "$netns" "related" "$expect"
257         if [ $? -ne 0 ]; then
258                 ret=1
259         fi
260 done
261
262 ip netns exec nsclient1 ping6 -c 1 -s 1300 dead:2::2 > /dev/null
263 if [ $? -eq 0 ]; then
264         echo "ERROR: ping6 should have failed with PMTU too big error" 1>&2
265         ret=1
266 fi
267
268 expect="packets 2 bytes 1856"
269 for netns in nsrouter1 nsclient1;do
270         check_counter "$netns" "related" "$expect"
271         if [ $? -ne 0 ]; then
272                 ret=1
273         fi
274 done
275
276 if [ $ret -eq 0 ];then
277         echo "PASS: icmp mtu error had RELATED state"
278 else
279         echo "ERROR: icmp error RELATED state test has failed"
280 fi
281
282 cleanup
283 exit $ret