~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/xfrm_policy.sh

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/bin/bash
  2 # SPDX-License-Identifier: GPL-2.0
  3 #
  4 # Check xfrm policy resolution.  Topology:
  5 #
  6 # 1.2   1.1   3.1  3.10    2.1   2.2
  7 # eth1  eth1 veth0 veth0 eth1   eth1
  8 # ns1 ---- ns3 ----- ns4 ---- ns2
  9 #
 10 # ns3 and ns4 are connected via ipsec tunnel.
 11 # pings from ns1 to ns2 (and vice versa) are supposed to work like this:
 12 # ns1: ping 10.0.2.2: passes via ipsec tunnel.
 13 # ns2: ping 10.0.1.2: passes via ipsec tunnel.
 14 
 15 # ns1: ping 10.0.1.253: passes via ipsec tunnel (direct policy)
 16 # ns2: ping 10.0.2.253: passes via ipsec tunnel (direct policy)
 17 #
 18 # ns1: ping 10.0.2.254: does NOT pass via ipsec tunnel (exception)
 19 # ns2: ping 10.0.1.254: does NOT pass via ipsec tunnel (exception)
 20 
 21 source lib.sh
 22 ret=0
 23 policy_checks_ok=1
 24 
 25 KEY_SHA=0xdeadbeef1234567890abcdefabcdefabcdefabcd
 26 KEY_AES=0x0123456789abcdef0123456789012345
 27 SPI1=0x1
 28 SPI2=0x2
 29 
 30 do_esp_policy() {
 31     local ns=$1
 32     local me=$2
 33     local remote=$3
 34     local lnet=$4
 35     local rnet=$5
 36 
 37     # to encrypt packets as they go out (includes forwarded packets that need encapsulation)
 38     ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 100 action allow
 39     # to fwd decrypted packets after esp processing:
 40     ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 100 action allow
 41 }
 42 
 43 do_esp() {
 44     local ns=$1
 45     local me=$2
 46     local remote=$3
 47     local lnet=$4
 48     local rnet=$5
 49     local spi_out=$6
 50     local spi_in=$7
 51 
 52     ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in  enc aes $KEY_AES  auth sha1 $KEY_SHA  mode tunnel sel src $rnet dst $lnet
 53     ip -net $ns xfrm state add src $me  dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet
 54 
 55     do_esp_policy $ns $me $remote $lnet $rnet
 56 }
 57 
 58 # add policies with different netmasks, to make sure kernel carries
 59 # the policies contained within new netmask over when search tree is
 60 # re-built.
 61 # peer netns that are supposed to be encapsulated via esp have addresses
 62 # in the 10.0.1.0/24 and 10.0.2.0/24 subnets, respectively.
 63 #
 64 # Adding a policy for '10.0.1.0/23' will make it necessary to
 65 # alter the prefix of 10.0.1.0 subnet.
 66 # In case new prefix overlaps with existing node, the node and all
 67 # policies it carries need to be merged with the existing one(s).
 68 #
 69 # Do that here.
 70 do_overlap()
 71 {
 72     local ns=$1
 73 
 74     # adds new nodes to tree (neither network exists yet in policy database).
 75     ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/24 dir fwd priority 200 action block
 76 
 77     # adds a new node in the 10.0.0.0/24 tree (dst node exists).
 78     ip -net $ns xfrm policy add src 10.2.0.0/24 dst 10.0.0.0/24 dir fwd priority 200 action block
 79 
 80     # adds a 10.2.0.0/23 node, but for different dst.
 81     ip -net $ns xfrm policy add src 10.2.0.0/23 dst 10.0.1.0/24 dir fwd priority 200 action block
 82 
 83     # dst now overlaps with the 10.0.1.0/24 ESP policy in fwd.
 84     # kernel must 'promote' existing one (10.0.0.0/24) to 10.0.0.0/23.
 85     # But 10.0.0.0/23 also includes existing 10.0.1.0/24, so that node
 86     # also has to be merged too, including source-sorted subtrees.
 87     # old:
 88     # 10.0.0.0/24 (node 1 in dst tree of the bin)
 89     #    10.1.0.0/24 (node in src tree of dst node 1)
 90     #    10.2.0.0/24 (node in src tree of dst node 1)
 91     # 10.0.1.0/24 (node 2 in dst tree of the bin)
 92     #    10.0.2.0/24 (node in src tree of dst node 2)
 93     #    10.2.0.0/24 (node in src tree of dst node 2)
 94     #
 95     # The next 'policy add' adds dst '10.0.0.0/23', which means
 96     # that dst node 1 and dst node 2 have to be merged including
 97     # the sub-tree.  As no duplicates are allowed, policies in
 98     # the two '10.0.2.0/24' are also merged.
 99     #
100     # after the 'add', internal search tree should look like this:
101     # 10.0.0.0/23 (node in dst tree of bin)
102     #     10.0.2.0/24 (node in src tree of dst node)
103     #     10.1.0.0/24 (node in src tree of dst node)
104     #     10.2.0.0/24 (node in src tree of dst node)
105     #
106     # 10.0.0.0/24 and 10.0.1.0/24 nodes have been merged as 10.0.0.0/23.
107     ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/23 dir fwd priority 200 action block
108 
109     # similar to above: add policies (with partially random address), with shrinking prefixes.
110     for p in 29 28 27;do
111       for k in $(seq 1 32); do
112        ip -net $ns xfrm policy add src 10.253.1.$((RANDOM%255))/$p dst 10.254.1.$((RANDOM%255))/$p dir fwd priority $((200+k)) action block 2>/dev/null
113       done
114     done
115 }
116 
117 do_esp_policy_get_check() {
118     local ns=$1
119     local lnet=$2
120     local rnet=$3
121 
122     ip -net $ns xfrm policy get src $lnet dst $rnet dir out > /dev/null
123     if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then
124         policy_checks_ok=0
125         echo "FAIL: ip -net $ns xfrm policy get src $lnet dst $rnet dir out"
126         ret=1
127     fi
128 
129     ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd > /dev/null
130     if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then
131         policy_checks_ok=0
132         echo "FAIL: ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd"
133         ret=1
134     fi
135 }
136 
137 do_exception() {
138     local ns=$1
139     local me=$2
140     local remote=$3
141     local encryptip=$4
142     local plain=$5
143 
144     # network $plain passes without tunnel
145     ip -net $ns xfrm policy add dst $plain dir out priority 10 action allow
146 
147     # direct policy for $encryptip, use tunnel, higher prio takes precedence
148     ip -net $ns xfrm policy add dst $encryptip dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow
149 }
150 
151 # policies that are not supposed to match any packets generated in this test.
152 do_dummies4() {
153     local ns=$1
154 
155     for i in $(seq 10 16);do
156       # dummy policy with wildcard src/dst.
157       echo netns exec $ns ip xfrm policy add src 0.0.0.0/0 dst 10.$i.99.0/30 dir out action block
158       echo netns exec $ns ip xfrm policy add src 10.$i.99.0/30 dst 0.0.0.0/0 dir out action block
159       for j in $(seq 32 64);do
160         echo netns exec $ns ip xfrm policy add src 10.$i.1.0/30 dst 10.$i.$j.0/30 dir out action block
161         # silly, as it encompasses the one above too, but its allowed:
162         echo netns exec $ns ip xfrm policy add src 10.$i.1.0/29 dst 10.$i.$j.0/29 dir out action block
163         # and yet again, even more broad one.
164         echo netns exec $ns ip xfrm policy add src 10.$i.1.0/24 dst 10.$i.$j.0/24 dir out action block
165         echo netns exec $ns ip xfrm policy add src 10.$i.$j.0/24 dst 10.$i.1.0/24 dir fwd action block
166       done
167     done | ip -batch /dev/stdin
168 }
169 
170 do_dummies6() {
171     local ns=$1
172 
173     for i in $(seq 10 16);do
174       for j in $(seq 32 64);do
175        echo netns exec $ns ip xfrm policy add src dead:$i::/64 dst dead:$i:$j::/64 dir out action block
176        echo netns exec $ns ip xfrm policy add src dead:$i:$j::/64 dst dead:$i::/24 dir fwd action block
177       done
178     done | ip -batch /dev/stdin
179 }
180 
181 check_ipt_policy_count()
182 {
183         ns=$1
184 
185         ip netns exec $ns iptables-save -c |grep policy | ( read c rest
186                 ip netns exec $ns iptables -Z
187                 if [ x"$c" = x'[0:0]' ]; then
188                         exit 0
189                 elif [ x"$c" = x ]; then
190                         echo "ERROR: No counters"
191                         ret=1
192                         exit 111
193                 else
194                         exit 1
195                 fi
196         )
197 }
198 
199 check_xfrm() {
200         # 0: iptables -m policy rule count == 0
201         # 1: iptables -m policy rule count != 0
202         rval=$1
203         ip=$2
204         local lret=0
205 
206         ip netns exec ${ns[1]} ping -q -c 1 10.0.2.$ip > /dev/null
207 
208         check_ipt_policy_count ${ns[3]}
209         if [ $? -ne $rval ] ; then
210                 lret=1
211         fi
212         check_ipt_policy_count ${ns[4]}
213         if [ $? -ne $rval ] ; then
214                 lret=1
215         fi
216 
217         ip netns exec ${ns[2]} ping -q -c 1 10.0.1.$ip > /dev/null
218 
219         check_ipt_policy_count ${ns[3]}
220         if [ $? -ne $rval ] ; then
221                 lret=1
222         fi
223         check_ipt_policy_count ${ns[4]}
224         if [ $? -ne $rval ] ; then
225                 lret=1
226         fi
227 
228         return $lret
229 }
230 
231 check_exceptions()
232 {
233         logpostfix="$1"
234         local lret=0
235 
236         # ping to .254 should be excluded from the tunnel (exception is in place).
237         check_xfrm 0 254
238         if [ $? -ne 0 ]; then
239                 echo "FAIL: expected ping to .254 to fail ($logpostfix)"
240                 lret=1
241         else
242                 echo "PASS: ping to .254 bypassed ipsec tunnel ($logpostfix)"
243         fi
244 
245         # ping to .253 should use use ipsec due to direct policy exception.
246         check_xfrm 1 253
247         if [ $? -ne 0 ]; then
248                 echo "FAIL: expected ping to .253 to use ipsec tunnel ($logpostfix)"
249                 lret=1
250         else
251                 echo "PASS: direct policy matches ($logpostfix)"
252         fi
253 
254         # ping to .2 should use ipsec.
255         check_xfrm 1 2
256         if [ $? -ne 0 ]; then
257                 echo "FAIL: expected ping to .2 to use ipsec tunnel ($logpostfix)"
258                 lret=1
259         else
260                 echo "PASS: policy matches ($logpostfix)"
261         fi
262 
263         return $lret
264 }
265 
266 check_hthresh_repeat()
267 {
268         local log=$1
269         i=0
270 
271         for i in $(seq 1 10);do
272                 ip -net ${ns[1]} xfrm policy update src e000:0001::0000 dst ff01::0014:0000:0001 dir in tmpl src :: dst :: proto esp mode tunnel priority 100 action allow || break
273                 ip -net ${ns[1]} xfrm policy set hthresh6 0 28 || break
274 
275                 ip -net ${ns[1]} xfrm policy update src e000:0001::0000 dst ff01::01 dir in tmpl src :: dst :: proto esp mode tunnel priority 100 action allow || break
276                 ip -net ${ns[1]} xfrm policy set hthresh6 0 28 || break
277         done
278 
279         if [ $i -ne 10 ] ;then
280                 echo "FAIL: $log" 1>&2
281                 ret=1
282                 return 1
283         fi
284 
285         echo "PASS: $log"
286         return 0
287 }
288 
289 # insert non-overlapping policies in a random order and check that
290 # all of them can be fetched using the traffic selectors.
291 check_random_order()
292 {
293         local ns=$1
294         local log=$2
295 
296         for i in $(seq 50); do
297                 ip -net $ns xfrm policy flush
298                 for j in $(seq 0 16 255 | sort -R); do
299                         ip -net $ns xfrm policy add dst $j.0.0.0/24 dir out priority 10 action allow
300                 done
301                 for j in $(seq 0 16 255); do
302                         if ! ip -net $ns xfrm policy get dst $j.0.0.0/24 dir out > /dev/null; then
303                                 echo "FAIL: $log" 1>&2
304                                 return 1
305                         fi
306                 done
307         done
308 
309         for i in $(seq 50); do
310                 ip -net $ns xfrm policy flush
311                 for j in $(seq 0 16 255 | sort -R); do
312                         local addr=$(printf "e000:0000:%02x00::/56" $j)
313                         ip -net $ns xfrm policy add dst $addr dir out priority 10 action allow
314                 done
315                 for j in $(seq 0 16 255); do
316                         local addr=$(printf "e000:0000:%02x00::/56" $j)
317                         if ! ip -net $ns xfrm policy get dst $addr dir out > /dev/null; then
318                                 echo "FAIL: $log" 1>&2
319                                 return 1
320                         fi
321                 done
322         done
323 
324         ip -net $ns xfrm policy flush
325 
326         echo "PASS: $log"
327         return 0
328 }
329 
330 #check for needed privileges
331 if [ "$(id -u)" -ne 0 ];then
332         echo "SKIP: Need root privileges"
333         exit $ksft_skip
334 fi
335 
336 ip -Version 2>/dev/null >/dev/null
337 if [ $? -ne 0 ];then
338         echo "SKIP: Could not run test without the ip tool"
339         exit $ksft_skip
340 fi
341 
342 # needed to check if policy lookup got valid ipsec result
343 iptables --version 2>/dev/null >/dev/null
344 if [ $? -ne 0 ];then
345         echo "SKIP: Could not run test without iptables tool"
346         exit $ksft_skip
347 fi
348 
349 setup_ns ns1 ns2 ns3 ns4
350 ns[1]=$ns1
351 ns[2]=$ns2
352 ns[3]=$ns3
353 ns[4]=$ns4
354 
355 DEV=veth0
356 ip link add $DEV netns ${ns[1]} type veth peer name eth1 netns ${ns[3]}
357 ip link add $DEV netns ${ns[2]} type veth peer name eth1 netns ${ns[4]}
358 
359 ip link add $DEV netns ${ns[3]} type veth peer name veth0 netns ${ns[4]}
360 
361 DEV=veth0
362 for i in 1 2; do
363     ip -net ${ns[$i]} link set $DEV up
364     ip -net ${ns[$i]} addr add 10.0.$i.2/24 dev $DEV
365     ip -net ${ns[$i]} addr add dead:$i::2/64 dev $DEV
366 
367     ip -net ${ns[$i]} addr add 10.0.$i.253 dev $DEV
368     ip -net ${ns[$i]} addr add 10.0.$i.254 dev $DEV
369     ip -net ${ns[$i]} addr add dead:$i::fd dev $DEV
370     ip -net ${ns[$i]} addr add dead:$i::fe dev $DEV
371 done
372 
373 for i in 3 4; do
374     ip -net ${ns[$i]} link set eth1 up
375     ip -net ${ns[$i]} link set veth0 up
376 done
377 
378 ip -net ${ns[1]} route add default via 10.0.1.1
379 ip -net ${ns[2]} route add default via 10.0.2.1
380 
381 ip -net ${ns[3]} addr add 10.0.1.1/24 dev eth1
382 ip -net ${ns[3]} addr add 10.0.3.1/24 dev veth0
383 ip -net ${ns[3]} addr add 2001:1::1/64 dev eth1
384 ip -net ${ns[3]} addr add 2001:3::1/64 dev veth0
385 
386 ip -net ${ns[3]} route add default via 10.0.3.10
387 
388 ip -net ${ns[4]} addr add 10.0.2.1/24 dev eth1
389 ip -net ${ns[4]} addr add 10.0.3.10/24 dev veth0
390 ip -net ${ns[4]} addr add 2001:2::1/64 dev eth1
391 ip -net ${ns[4]} addr add 2001:3::10/64 dev veth0
392 ip -net ${ns[4]} route add default via 10.0.3.1
393 
394 for j in 4 6; do
395         for i in 3 4;do
396                 ip netns exec ${ns[$i]} sysctl net.ipv$j.conf.eth1.forwarding=1 > /dev/null
397                 ip netns exec ${ns[$i]} sysctl net.ipv$j.conf.veth0.forwarding=1 > /dev/null
398         done
399 done
400 
401 # abuse iptables rule counter to check if ping matches a policy
402 ip netns exec ${ns[3]} iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec
403 ip netns exec ${ns[4]} iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec
404 if [ $? -ne 0 ];then
405         echo "SKIP: Could not insert iptables rule"
406         cleanup_ns $ns1 $ns2 $ns3 $ns4
407         exit $ksft_skip
408 fi
409 
410 #          localip  remoteip  localnet    remotenet
411 do_esp ${ns[3]} 10.0.3.1 10.0.3.10 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2
412 do_esp ${ns[3]} dead:3::1 dead:3::10 dead:1::/64 dead:2::/64 $SPI1 $SPI2
413 do_esp ${ns[4]} 10.0.3.10 10.0.3.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1
414 do_esp ${ns[4]} dead:3::10 dead:3::1 dead:2::/64 dead:1::/64 $SPI2 $SPI1
415 
416 do_dummies4 ${ns[3]}
417 do_dummies6 ${ns[4]}
418 
419 do_esp_policy_get_check ${ns[3]} 10.0.1.0/24 10.0.2.0/24
420 do_esp_policy_get_check ${ns[4]} 10.0.2.0/24 10.0.1.0/24
421 do_esp_policy_get_check ${ns[3]} dead:1::/64 dead:2::/64
422 do_esp_policy_get_check ${ns[4]} dead:2::/64 dead:1::/64
423 
424 # ping to .254 should use ipsec, exception is not installed.
425 check_xfrm 1 254
426 if [ $? -ne 0 ]; then
427         echo "FAIL: expected ping to .254 to use ipsec tunnel"
428         ret=1
429 else
430         echo "PASS: policy before exception matches"
431 fi
432 
433 # installs exceptions
434 #                localip  remoteip   encryptdst  plaindst
435 do_exception ${ns[3]} 10.0.3.1 10.0.3.10 10.0.2.253 10.0.2.240/28
436 do_exception ${ns[4]} 10.0.3.10 10.0.3.1 10.0.1.253 10.0.1.240/28
437 
438 do_exception ${ns[3]} dead:3::1 dead:3::10 dead:2::fd  dead:2:f0::/96
439 do_exception ${ns[4]} dead:3::10 dead:3::1 dead:1::fd  dead:1:f0::/96
440 
441 check_exceptions "exceptions"
442 if [ $? -ne 0 ]; then
443         ret=1
444 fi
445 
446 # insert block policies with adjacent/overlapping netmasks
447 do_overlap ${ns[3]}
448 
449 check_exceptions "exceptions and block policies"
450 if [ $? -ne 0 ]; then
451         ret=1
452 fi
453 
454 for n in ${ns[3]} ${ns[4]};do
455         ip -net $n xfrm policy set hthresh4 28 24 hthresh6 126 125
456         sleep $((RANDOM%5))
457 done
458 
459 check_exceptions "exceptions and block policies after hresh changes"
460 
461 # full flush of policy db, check everything gets freed incl. internal meta data
462 ip -net ${ns[3]} xfrm policy flush
463 
464 do_esp_policy ${ns[3]} 10.0.3.1 10.0.3.10 10.0.1.0/24 10.0.2.0/24
465 do_exception ${ns[3]} 10.0.3.1 10.0.3.10 10.0.2.253 10.0.2.240/28
466 
467 # move inexact policies to hash table
468 ip -net ${ns[3]} xfrm policy set hthresh4 16 16
469 
470 sleep $((RANDOM%5))
471 check_exceptions "exceptions and block policies after hthresh change in ns3"
472 
473 # restore original hthresh settings -- move policies back to tables
474 for n in ${ns[3]} ${ns[4]};do
475         ip -net $n xfrm policy set hthresh4 32 32 hthresh6 128 128
476         sleep $((RANDOM%5))
477 done
478 check_exceptions "exceptions and block policies after htresh change to normal"
479 
480 check_hthresh_repeat "policies with repeated htresh change"
481 
482 check_random_order ${ns[3]} "policies inserted in random order"
483 
484 cleanup_ns $ns1 $ns2 $ns3 $ns4
485 
486 exit $ret

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php