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# Kselftest framework requirement - SKIP code is 4. 22ksft_skip=4 23ret=0 24policy_checks_ok=1 25 26KEY_SHA=0xdeadbeef1234567890abcdefabcdefabcdefabcd 27KEY_AES=0x0123456789abcdef0123456789012345 28SPI1=0x1 29SPI2=0x2 30 31do_esp() { 32 local ns=$1 33 local me=$2 34 local remote=$3 35 local lnet=$4 36 local rnet=$5 37 local spi_out=$6 38 local spi_in=$7 39 40 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 41 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 42 43 # to encrypt packets as they go out (includes forwarded packets that need encapsulation) 44 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 45 # to fwd decrypted packets after esp processing: 46 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 47} 48 49do_esp_policy_get_check() { 50 local ns=$1 51 local lnet=$2 52 local rnet=$3 53 54 ip -net $ns xfrm policy get src $lnet dst $rnet dir out > /dev/null 55 if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then 56 policy_checks_ok=0 57 echo "FAIL: ip -net $ns xfrm policy get src $lnet dst $rnet dir out" 58 ret=1 59 fi 60 61 ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd > /dev/null 62 if [ $? -ne 0 ] && [ $policy_checks_ok -eq 1 ] ;then 63 policy_checks_ok=0 64 echo "FAIL: ip -net $ns xfrm policy get src $rnet dst $lnet dir fwd" 65 ret=1 66 fi 67} 68 69do_exception() { 70 local ns=$1 71 local me=$2 72 local remote=$3 73 local encryptip=$4 74 local plain=$5 75 76 # network $plain passes without tunnel 77 ip -net $ns xfrm policy add dst $plain dir out priority 10 action allow 78 79 # direct policy for $encryptip, use tunnel, higher prio takes precedence 80 ip -net $ns xfrm policy add dst $encryptip dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow 81} 82 83# policies that are not supposed to match any packets generated in this test. 84do_dummies4() { 85 local ns=$1 86 87 for i in $(seq 10 16);do 88 # dummy policy with wildcard src/dst. 89 echo netns exec $ns ip xfrm policy add src 0.0.0.0/0 dst 10.$i.99.0/30 dir out action block 90 echo netns exec $ns ip xfrm policy add src 10.$i.99.0/30 dst 0.0.0.0/0 dir out action block 91 for j in $(seq 32 64);do 92 echo netns exec $ns ip xfrm policy add src 10.$i.1.0/30 dst 10.$i.$j.0/30 dir out action block 93 # silly, as it encompasses the one above too, but its allowed: 94 echo netns exec $ns ip xfrm policy add src 10.$i.1.0/29 dst 10.$i.$j.0/29 dir out action block 95 # and yet again, even more broad one. 96 echo netns exec $ns ip xfrm policy add src 10.$i.1.0/24 dst 10.$i.$j.0/24 dir out action block 97 echo netns exec $ns ip xfrm policy add src 10.$i.$j.0/24 dst 10.$i.1.0/24 dir fwd action block 98 done 99 done | ip -batch /dev/stdin 100} 101 102do_dummies6() { 103 local ns=$1 104 105 for i in $(seq 10 16);do 106 for j in $(seq 32 64);do 107 echo netns exec $ns ip xfrm policy add src dead:$i::/64 dst dead:$i:$j::/64 dir out action block 108 echo netns exec $ns ip xfrm policy add src dead:$i:$j::/64 dst dead:$i::/24 dir fwd action block 109 done 110 done | ip -batch /dev/stdin 111} 112 113check_ipt_policy_count() 114{ 115 ns=$1 116 117 ip netns exec $ns iptables-save -c |grep policy | ( read c rest 118 ip netns exec $ns iptables -Z 119 if [ x"$c" = x'[0:0]' ]; then 120 exit 0 121 elif [ x"$c" = x ]; then 122 echo "ERROR: No counters" 123 ret=1 124 exit 111 125 else 126 exit 1 127 fi 128 ) 129} 130 131check_xfrm() { 132 # 0: iptables -m policy rule count == 0 133 # 1: iptables -m policy rule count != 0 134 rval=$1 135 ip=$2 136 lret=0 137 138 ip netns exec ns1 ping -q -c 1 10.0.2.$ip > /dev/null 139 140 check_ipt_policy_count ns3 141 if [ $? -ne $rval ] ; then 142 lret=1 143 fi 144 check_ipt_policy_count ns4 145 if [ $? -ne $rval ] ; then 146 lret=1 147 fi 148 149 ip netns exec ns2 ping -q -c 1 10.0.1.$ip > /dev/null 150 151 check_ipt_policy_count ns3 152 if [ $? -ne $rval ] ; then 153 lret=1 154 fi 155 check_ipt_policy_count ns4 156 if [ $? -ne $rval ] ; then 157 lret=1 158 fi 159 160 return $lret 161} 162 163#check for needed privileges 164if [ "$(id -u)" -ne 0 ];then 165 echo "SKIP: Need root privileges" 166 exit $ksft_skip 167fi 168 169ip -Version 2>/dev/null >/dev/null 170if [ $? -ne 0 ];then 171 echo "SKIP: Could not run test without the ip tool" 172 exit $ksft_skip 173fi 174 175# needed to check if policy lookup got valid ipsec result 176iptables --version 2>/dev/null >/dev/null 177if [ $? -ne 0 ];then 178 echo "SKIP: Could not run test without iptables tool" 179 exit $ksft_skip 180fi 181 182for i in 1 2 3 4; do 183 ip netns add ns$i 184 ip -net ns$i link set lo up 185done 186 187DEV=veth0 188ip link add $DEV netns ns1 type veth peer name eth1 netns ns3 189ip link add $DEV netns ns2 type veth peer name eth1 netns ns4 190 191ip link add $DEV netns ns3 type veth peer name veth0 netns ns4 192 193DEV=veth0 194for i in 1 2; do 195 ip -net ns$i link set $DEV up 196 ip -net ns$i addr add 10.0.$i.2/24 dev $DEV 197 ip -net ns$i addr add dead:$i::2/64 dev $DEV 198 199 ip -net ns$i addr add 10.0.$i.253 dev $DEV 200 ip -net ns$i addr add 10.0.$i.254 dev $DEV 201 ip -net ns$i addr add dead:$i::fd dev $DEV 202 ip -net ns$i addr add dead:$i::fe dev $DEV 203done 204 205for i in 3 4; do 206ip -net ns$i link set eth1 up 207ip -net ns$i link set veth0 up 208done 209 210ip -net ns1 route add default via 10.0.1.1 211ip -net ns2 route add default via 10.0.2.1 212 213ip -net ns3 addr add 10.0.1.1/24 dev eth1 214ip -net ns3 addr add 10.0.3.1/24 dev veth0 215ip -net ns3 addr add 2001:1::1/64 dev eth1 216ip -net ns3 addr add 2001:3::1/64 dev veth0 217 218ip -net ns3 route add default via 10.0.3.10 219 220ip -net ns4 addr add 10.0.2.1/24 dev eth1 221ip -net ns4 addr add 10.0.3.10/24 dev veth0 222ip -net ns4 addr add 2001:2::1/64 dev eth1 223ip -net ns4 addr add 2001:3::10/64 dev veth0 224ip -net ns4 route add default via 10.0.3.1 225 226for j in 4 6; do 227 for i in 3 4;do 228 ip netns exec ns$i sysctl net.ipv$j.conf.eth1.forwarding=1 > /dev/null 229 ip netns exec ns$i sysctl net.ipv$j.conf.veth0.forwarding=1 > /dev/null 230 done 231done 232 233# abuse iptables rule counter to check if ping matches a policy 234ip netns exec ns3 iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec 235ip netns exec ns4 iptables -p icmp -A FORWARD -m policy --dir out --pol ipsec 236if [ $? -ne 0 ];then 237 echo "SKIP: Could not insert iptables rule" 238 for i in 1 2 3 4;do ip netns del ns$i;done 239 exit $ksft_skip 240fi 241 242# localip remoteip localnet remotenet 243do_esp ns3 10.0.3.1 10.0.3.10 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2 244do_esp ns3 dead:3::1 dead:3::10 dead:1::/64 dead:2::/64 $SPI1 $SPI2 245do_esp ns4 10.0.3.10 10.0.3.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1 246do_esp ns4 dead:3::10 dead:3::1 dead:2::/64 dead:1::/64 $SPI2 $SPI1 247 248do_dummies4 ns3 249do_dummies6 ns4 250 251do_esp_policy_get_check ns3 10.0.1.0/24 10.0.2.0/24 252do_esp_policy_get_check ns4 10.0.2.0/24 10.0.1.0/24 253do_esp_policy_get_check ns3 dead:1::/64 dead:2::/64 254do_esp_policy_get_check ns4 dead:2::/64 dead:1::/64 255 256# ping to .254 should use ipsec, exception is not installed. 257check_xfrm 1 254 258if [ $? -ne 0 ]; then 259 echo "FAIL: expected ping to .254 to use ipsec tunnel" 260 ret=1 261else 262 echo "PASS: policy before exception matches" 263fi 264 265# installs exceptions 266# localip remoteip encryptdst plaindst 267do_exception ns3 10.0.3.1 10.0.3.10 10.0.2.253 10.0.2.240/28 268do_exception ns4 10.0.3.10 10.0.3.1 10.0.1.253 10.0.1.240/28 269 270do_exception ns3 dead:3::1 dead:3::10 dead:2::fd dead:2:f0::/96 271do_exception ns4 dead:3::10 dead:3::1 dead:1::fd dead:1:f0::/96 272 273# ping to .254 should now be excluded from the tunnel 274check_xfrm 0 254 275if [ $? -ne 0 ]; then 276 echo "FAIL: expected ping to .254 to fail" 277 ret=1 278else 279 echo "PASS: ping to .254 bypassed ipsec tunnel" 280fi 281 282# ping to .253 should use use ipsec due to direct policy exception. 283check_xfrm 1 253 284if [ $? -ne 0 ]; then 285 echo "FAIL: expected ping to .253 to use ipsec tunnel" 286 ret=1 287else 288 echo "PASS: direct policy matches" 289fi 290 291# ping to .2 should use ipsec. 292check_xfrm 1 2 293if [ $? -ne 0 ]; then 294 echo "FAIL: expected ping to .2 to use ipsec tunnel" 295 ret=1 296else 297 echo "PASS: policy matches" 298fi 299 300for i in 1 2 3 4;do ip netns del ns$i;done 301 302exit $ret 303