1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Various combinations of VRF with xfrms and qdisc. 5 6# Kselftest framework requirement - SKIP code is 4. 7ksft_skip=4 8 9PAUSE_ON_FAIL=no 10VERBOSE=0 11ret=0 12 13HOST1_4=192.168.1.1 14HOST2_4=192.168.1.2 15HOST1_6=2001:db8:1::1 16HOST2_6=2001:db8:1::2 17 18XFRM1_4=10.0.1.1 19XFRM2_4=10.0.1.2 20XFRM1_6=fc00:1000::1 21XFRM2_6=fc00:1000::2 22IF_ID=123 23 24VRF=red 25TABLE=300 26 27AUTH_1=0xd94fcfea65fddf21dc6e0d24a0253508 28AUTH_2=0xdc6e0d24a0253508d94fcfea65fddf21 29ENC_1=0xfc46c20f8048be9725930ff3fb07ac2a91f0347dffeacf62 30ENC_2=0x3fb07ac2a91f0347dffeacf62fc46c20f8048be9725930ff 31SPI_1=0x02122b77 32SPI_2=0x2b770212 33 34which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) 35 36################################################################################ 37# 38log_test() 39{ 40 local rc=$1 41 local expected=$2 42 local msg="$3" 43 44 if [ ${rc} -eq ${expected} ]; then 45 printf "TEST: %-60s [ OK ]\n" "${msg}" 46 nsuccess=$((nsuccess+1)) 47 else 48 ret=1 49 nfail=$((nfail+1)) 50 printf "TEST: %-60s [FAIL]\n" "${msg}" 51 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 52 echo 53 echo "hit enter to continue, 'q' to quit" 54 read a 55 [ "$a" = "q" ] && exit 1 56 fi 57 fi 58} 59 60run_cmd_host1() 61{ 62 local cmd="$*" 63 local out 64 local rc 65 66 if [ "$VERBOSE" = "1" ]; then 67 printf " COMMAND: $cmd\n" 68 fi 69 70 out=$(eval ip netns exec host1 $cmd 2>&1) 71 rc=$? 72 if [ "$VERBOSE" = "1" ]; then 73 if [ -n "$out" ]; then 74 echo 75 echo " $out" 76 fi 77 echo 78 fi 79 80 return $rc 81} 82 83################################################################################ 84# create namespaces for hosts and sws 85 86create_vrf() 87{ 88 local ns=$1 89 local vrf=$2 90 local table=$3 91 92 if [ -n "${ns}" ]; then 93 ns="-netns ${ns}" 94 fi 95 96 ip ${ns} link add ${vrf} type vrf table ${table} 97 ip ${ns} link set ${vrf} up 98 ip ${ns} route add vrf ${vrf} unreachable default metric 8192 99 ip ${ns} -6 route add vrf ${vrf} unreachable default metric 8192 100 101 ip ${ns} addr add 127.0.0.1/8 dev ${vrf} 102 ip ${ns} -6 addr add ::1 dev ${vrf} nodad 103 104 ip ${ns} ru del pref 0 105 ip ${ns} ru add pref 32765 from all lookup local 106 ip ${ns} -6 ru del pref 0 107 ip ${ns} -6 ru add pref 32765 from all lookup local 108} 109 110create_ns() 111{ 112 local ns=$1 113 local addr=$2 114 local addr6=$3 115 116 [ -z "${addr}" ] && addr="-" 117 [ -z "${addr6}" ] && addr6="-" 118 119 ip netns add ${ns} 120 121 ip -netns ${ns} link set lo up 122 if [ "${addr}" != "-" ]; then 123 ip -netns ${ns} addr add dev lo ${addr} 124 fi 125 if [ "${addr6}" != "-" ]; then 126 ip -netns ${ns} -6 addr add dev lo ${addr6} 127 fi 128 129 ip -netns ${ns} ro add unreachable default metric 8192 130 ip -netns ${ns} -6 ro add unreachable default metric 8192 131 132 ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1 133 ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1 134 ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1 135 ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1 136 ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.accept_dad=0 137} 138 139# create veth pair to connect namespaces and apply addresses. 140connect_ns() 141{ 142 local ns1=$1 143 local ns1_dev=$2 144 local ns1_addr=$3 145 local ns1_addr6=$4 146 local ns2=$5 147 local ns2_dev=$6 148 local ns2_addr=$7 149 local ns2_addr6=$8 150 local ns1arg 151 local ns2arg 152 153 if [ -n "${ns1}" ]; then 154 ns1arg="-netns ${ns1}" 155 fi 156 if [ -n "${ns2}" ]; then 157 ns2arg="-netns ${ns2}" 158 fi 159 160 ip ${ns1arg} li add ${ns1_dev} type veth peer name tmp 161 ip ${ns1arg} li set ${ns1_dev} up 162 ip ${ns1arg} li set tmp netns ${ns2} name ${ns2_dev} 163 ip ${ns2arg} li set ${ns2_dev} up 164 165 if [ "${ns1_addr}" != "-" ]; then 166 ip ${ns1arg} addr add dev ${ns1_dev} ${ns1_addr} 167 ip ${ns2arg} addr add dev ${ns2_dev} ${ns2_addr} 168 fi 169 170 if [ "${ns1_addr6}" != "-" ]; then 171 ip ${ns1arg} addr add dev ${ns1_dev} ${ns1_addr6} nodad 172 ip ${ns2arg} addr add dev ${ns2_dev} ${ns2_addr6} nodad 173 fi 174} 175 176################################################################################ 177 178cleanup() 179{ 180 ip netns del host1 181 ip netns del host2 182} 183 184setup() 185{ 186 create_ns "host1" 187 create_ns "host2" 188 189 connect_ns "host1" eth0 ${HOST1_4}/24 ${HOST1_6}/64 \ 190 "host2" eth0 ${HOST2_4}/24 ${HOST2_6}/64 191 192 create_vrf "host1" ${VRF} ${TABLE} 193 ip -netns host1 link set dev eth0 master ${VRF} 194} 195 196cleanup_xfrm() 197{ 198 for ns in host1 host2 199 do 200 for x in state policy 201 do 202 ip -netns ${ns} xfrm ${x} flush 203 ip -6 -netns ${ns} xfrm ${x} flush 204 done 205 done 206} 207 208setup_xfrm() 209{ 210 local h1_4=$1 211 local h2_4=$2 212 local h1_6=$3 213 local h2_6=$4 214 local devarg="$5" 215 216 # 217 # policy 218 # 219 220 # host1 - IPv4 out 221 ip -netns host1 xfrm policy add \ 222 src ${h1_4} dst ${h2_4} ${devarg} dir out \ 223 tmpl src ${HOST1_4} dst ${HOST2_4} proto esp mode tunnel 224 225 # host2 - IPv4 in 226 ip -netns host2 xfrm policy add \ 227 src ${h1_4} dst ${h2_4} dir in \ 228 tmpl src ${HOST1_4} dst ${HOST2_4} proto esp mode tunnel 229 230 # host1 - IPv4 in 231 ip -netns host1 xfrm policy add \ 232 src ${h2_4} dst ${h1_4} ${devarg} dir in \ 233 tmpl src ${HOST2_4} dst ${HOST1_4} proto esp mode tunnel 234 235 # host2 - IPv4 out 236 ip -netns host2 xfrm policy add \ 237 src ${h2_4} dst ${h1_4} dir out \ 238 tmpl src ${HOST2_4} dst ${HOST1_4} proto esp mode tunnel 239 240 241 # host1 - IPv6 out 242 ip -6 -netns host1 xfrm policy add \ 243 src ${h1_6} dst ${h2_6} ${devarg} dir out \ 244 tmpl src ${HOST1_6} dst ${HOST2_6} proto esp mode tunnel 245 246 # host2 - IPv6 in 247 ip -6 -netns host2 xfrm policy add \ 248 src ${h1_6} dst ${h2_6} dir in \ 249 tmpl src ${HOST1_6} dst ${HOST2_6} proto esp mode tunnel 250 251 # host1 - IPv6 in 252 ip -6 -netns host1 xfrm policy add \ 253 src ${h2_6} dst ${h1_6} ${devarg} dir in \ 254 tmpl src ${HOST2_6} dst ${HOST1_6} proto esp mode tunnel 255 256 # host2 - IPv6 out 257 ip -6 -netns host2 xfrm policy add \ 258 src ${h2_6} dst ${h1_6} dir out \ 259 tmpl src ${HOST2_6} dst ${HOST1_6} proto esp mode tunnel 260 261 # 262 # state 263 # 264 ip -netns host1 xfrm state add src ${HOST1_4} dst ${HOST2_4} \ 265 proto esp spi ${SPI_1} reqid 0 mode tunnel \ 266 replay-window 4 replay-oseq 0x4 \ 267 auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \ 268 enc 'cbc(aes)' ${ENC_1} \ 269 sel src ${h1_4} dst ${h2_4} ${devarg} 270 271 ip -netns host2 xfrm state add src ${HOST1_4} dst ${HOST2_4} \ 272 proto esp spi ${SPI_1} reqid 0 mode tunnel \ 273 replay-window 4 replay-oseq 0x4 \ 274 auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \ 275 enc 'cbc(aes)' ${ENC_1} \ 276 sel src ${h1_4} dst ${h2_4} 277 278 279 ip -netns host1 xfrm state add src ${HOST2_4} dst ${HOST1_4} \ 280 proto esp spi ${SPI_2} reqid 0 mode tunnel \ 281 replay-window 4 replay-oseq 0x4 \ 282 auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \ 283 enc 'cbc(aes)' ${ENC_2} \ 284 sel src ${h2_4} dst ${h1_4} ${devarg} 285 286 ip -netns host2 xfrm state add src ${HOST2_4} dst ${HOST1_4} \ 287 proto esp spi ${SPI_2} reqid 0 mode tunnel \ 288 replay-window 4 replay-oseq 0x4 \ 289 auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \ 290 enc 'cbc(aes)' ${ENC_2} \ 291 sel src ${h2_4} dst ${h1_4} 292 293 294 ip -6 -netns host1 xfrm state add src ${HOST1_6} dst ${HOST2_6} \ 295 proto esp spi ${SPI_1} reqid 0 mode tunnel \ 296 replay-window 4 replay-oseq 0x4 \ 297 auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \ 298 enc 'cbc(aes)' ${ENC_1} \ 299 sel src ${h1_6} dst ${h2_6} ${devarg} 300 301 ip -6 -netns host2 xfrm state add src ${HOST1_6} dst ${HOST2_6} \ 302 proto esp spi ${SPI_1} reqid 0 mode tunnel \ 303 replay-window 4 replay-oseq 0x4 \ 304 auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \ 305 enc 'cbc(aes)' ${ENC_1} \ 306 sel src ${h1_6} dst ${h2_6} 307 308 309 ip -6 -netns host1 xfrm state add src ${HOST2_6} dst ${HOST1_6} \ 310 proto esp spi ${SPI_2} reqid 0 mode tunnel \ 311 replay-window 4 replay-oseq 0x4 \ 312 auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \ 313 enc 'cbc(aes)' ${ENC_2} \ 314 sel src ${h2_6} dst ${h1_6} ${devarg} 315 316 ip -6 -netns host2 xfrm state add src ${HOST2_6} dst ${HOST1_6} \ 317 proto esp spi ${SPI_2} reqid 0 mode tunnel \ 318 replay-window 4 replay-oseq 0x4 \ 319 auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \ 320 enc 'cbc(aes)' ${ENC_2} \ 321 sel src ${h2_6} dst ${h1_6} 322} 323 324cleanup_xfrm_dev() 325{ 326 ip -netns host1 li del xfrm0 327 ip -netns host2 addr del ${XFRM2_4}/24 dev eth0 328 ip -netns host2 addr del ${XFRM2_6}/64 dev eth0 329} 330 331setup_xfrm_dev() 332{ 333 local vrfarg="vrf ${VRF}" 334 335 ip -netns host1 li add type xfrm dev eth0 if_id ${IF_ID} 336 ip -netns host1 li set xfrm0 ${vrfarg} up 337 ip -netns host1 addr add ${XFRM1_4}/24 dev xfrm0 338 ip -netns host1 addr add ${XFRM1_6}/64 dev xfrm0 339 340 ip -netns host2 addr add ${XFRM2_4}/24 dev eth0 341 ip -netns host2 addr add ${XFRM2_6}/64 dev eth0 342 343 setup_xfrm ${XFRM1_4} ${XFRM2_4} ${XFRM1_6} ${XFRM2_6} "if_id ${IF_ID}" 344} 345 346run_tests() 347{ 348 cleanup_xfrm 349 350 # no IPsec 351 run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4} 352 log_test $? 0 "IPv4 no xfrm policy" 353 run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6} 354 log_test $? 0 "IPv6 no xfrm policy" 355 356 # xfrm without VRF in sel 357 setup_xfrm ${HOST1_4} ${HOST2_4} ${HOST1_6} ${HOST2_6} 358 run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4} 359 log_test $? 0 "IPv4 xfrm policy based on address" 360 run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6} 361 log_test $? 0 "IPv6 xfrm policy based on address" 362 cleanup_xfrm 363 364 # xfrm with VRF in sel 365 # Known failure: ipv4 resets the flow oif after the lookup. Fix is 366 # not straightforward. 367 # setup_xfrm ${HOST1_4} ${HOST2_4} ${HOST1_6} ${HOST2_6} "dev ${VRF}" 368 # run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4} 369 # log_test $? 0 "IPv4 xfrm policy with VRF in selector" 370 run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6} 371 log_test $? 0 "IPv6 xfrm policy with VRF in selector" 372 cleanup_xfrm 373 374 # xfrm with enslaved device in sel 375 # Known failures: combined with the above, __xfrm{4,6}_selector_match 376 # needs to consider both l3mdev and enslaved device index. 377 # setup_xfrm ${HOST1_4} ${HOST2_4} ${HOST1_6} ${HOST2_6} "dev eth0" 378 # run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4} 379 # log_test $? 0 "IPv4 xfrm policy with enslaved device in selector" 380 # run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6} 381 # log_test $? 0 "IPv6 xfrm policy with enslaved device in selector" 382 # cleanup_xfrm 383 384 # xfrm device 385 setup_xfrm_dev 386 run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${XFRM2_4} 387 log_test $? 0 "IPv4 xfrm policy with xfrm device" 388 run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${XFRM2_6} 389 log_test $? 0 "IPv6 xfrm policy with xfrm device" 390 cleanup_xfrm_dev 391} 392 393################################################################################ 394# usage 395 396usage() 397{ 398 cat <<EOF 399usage: ${0##*/} OPTS 400 401 -p Pause on fail 402 -v verbose mode (show commands and output) 403 404done 405EOF 406} 407 408################################################################################ 409# main 410 411while getopts :pv o 412do 413 case $o in 414 p) PAUSE_ON_FAIL=yes;; 415 v) VERBOSE=$(($VERBOSE + 1));; 416 h) usage; exit 0;; 417 *) usage; exit 1;; 418 esac 419done 420 421cleanup 2>/dev/null 422setup 423 424echo 425echo "No qdisc on VRF device" 426run_tests 427 428run_cmd_host1 tc qdisc add dev ${VRF} root netem delay 100ms 429echo 430echo "netem qdisc on VRF device" 431run_tests 432 433printf "\nTests passed: %3d\n" ${nsuccess} 434printf "Tests failed: %3d\n" ${nfail} 435 436exit $ret 437