1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# This test is designed for testing the new VRF strict_mode functionality. 5 6source lib.sh 7ret=0 8 9# identifies the "init" network namespace which is often called root network 10# namespace. 11INIT_NETNS_NAME="init" 12 13PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} 14 15TESTS="init testns mix" 16 17log_test() 18{ 19 local rc=$1 20 local expected=$2 21 local msg="$3" 22 23 if [ ${rc} -eq ${expected} ]; then 24 nsuccess=$((nsuccess+1)) 25 printf "\n TEST: %-60s [ OK ]\n" "${msg}" 26 else 27 ret=1 28 nfail=$((nfail+1)) 29 printf "\n TEST: %-60s [FAIL]\n" "${msg}" 30 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 31 echo 32 echo "hit enter to continue, 'q' to quit" 33 read a 34 [ "$a" = "q" ] && exit 1 35 fi 36 fi 37} 38 39print_log_test_results() 40{ 41 if [ "$TESTS" != "none" ]; then 42 printf "\nTests passed: %3d\n" ${nsuccess} 43 printf "Tests failed: %3d\n" ${nfail} 44 fi 45} 46 47log_section() 48{ 49 echo 50 echo "################################################################################" 51 echo "TEST SECTION: $*" 52 echo "################################################################################" 53} 54 55ip_expand_args() 56{ 57 local nsname=$1 58 local nsarg="" 59 60 if [ "${nsname}" != "${INIT_NETNS_NAME}" ]; then 61 nsarg="-netns ${nsname}" 62 fi 63 64 echo "${nsarg}" 65} 66 67vrf_count() 68{ 69 local nsname=$1 70 local nsarg="$(ip_expand_args ${nsname})" 71 72 ip ${nsarg} -o link show type vrf | wc -l 73} 74 75count_vrf_by_table_id() 76{ 77 local nsname=$1 78 local tableid=$2 79 local nsarg="$(ip_expand_args ${nsname})" 80 81 ip ${nsarg} -d -o link show type vrf | grep "table ${tableid}" | wc -l 82} 83 84add_vrf() 85{ 86 local nsname=$1 87 local vrfname=$2 88 local vrftable=$3 89 local nsarg="$(ip_expand_args ${nsname})" 90 91 ip ${nsarg} link add ${vrfname} type vrf table ${vrftable} &>/dev/null 92} 93 94add_vrf_and_check() 95{ 96 local nsname=$1 97 local vrfname=$2 98 local vrftable=$3 99 local cnt 100 local rc 101 102 add_vrf ${nsname} ${vrfname} ${vrftable}; rc=$? 103 104 cnt=$(count_vrf_by_table_id ${nsname} ${vrftable}) 105 106 log_test ${rc} 0 "${nsname}: add vrf ${vrfname}, ${cnt} vrfs for table ${vrftable}" 107} 108 109add_vrf_and_check_fail() 110{ 111 local nsname=$1 112 local vrfname=$2 113 local vrftable=$3 114 local cnt 115 local rc 116 117 add_vrf ${nsname} ${vrfname} ${vrftable}; rc=$? 118 119 cnt=$(count_vrf_by_table_id ${nsname} ${vrftable}) 120 121 log_test ${rc} 2 "${nsname}: CANNOT add vrf ${vrfname}, ${cnt} vrfs for table ${vrftable}" 122} 123 124del_vrf_and_check() 125{ 126 local nsname=$1 127 local vrfname=$2 128 local nsarg="$(ip_expand_args ${nsname})" 129 130 ip ${nsarg} link del ${vrfname} 131 log_test $? 0 "${nsname}: remove vrf ${vrfname}" 132} 133 134config_vrf_and_check() 135{ 136 local nsname=$1 137 local addr=$2 138 local vrfname=$3 139 local nsarg="$(ip_expand_args ${nsname})" 140 141 ip ${nsarg} link set dev ${vrfname} up && \ 142 ip ${nsarg} addr add ${addr} dev ${vrfname} 143 log_test $? 0 "${nsname}: vrf ${vrfname} up, addr ${addr}" 144} 145 146read_strict_mode() 147{ 148 local nsname=$1 149 local rval 150 local rc=0 151 local nsexec="" 152 153 if [ "${nsname}" != "${INIT_NETNS_NAME}" ]; then 154 # a custom network namespace is provided 155 nsexec="ip netns exec ${nsname}" 156 fi 157 158 rval="$(${nsexec} bash -c "cat /proc/sys/net/vrf/strict_mode" | \ 159 grep -E "^[0-1]$")" &> /dev/null 160 if [ $? -ne 0 ]; then 161 # set errors 162 rval=255 163 rc=1 164 fi 165 166 # on success, rval can be only 0 or 1; on error, rval is equal to 255 167 echo ${rval} 168 return ${rc} 169} 170 171read_strict_mode_compare_and_check() 172{ 173 local nsname=$1 174 local expected=$2 175 local res 176 177 res="$(read_strict_mode ${nsname})" 178 log_test ${res} ${expected} "${nsname}: check strict_mode=${res}" 179} 180 181set_strict_mode() 182{ 183 local nsname=$1 184 local val=$2 185 local nsexec="" 186 187 if [ "${nsname}" != "${INIT_NETNS_NAME}" ]; then 188 # a custom network namespace is provided 189 nsexec="ip netns exec ${nsname}" 190 fi 191 192 ${nsexec} bash -c "echo ${val} >/proc/sys/net/vrf/strict_mode" &>/dev/null 193} 194 195enable_strict_mode() 196{ 197 local nsname=$1 198 199 set_strict_mode ${nsname} 1 200} 201 202disable_strict_mode() 203{ 204 local nsname=$1 205 206 set_strict_mode ${nsname} 0 207} 208 209disable_strict_mode_and_check() 210{ 211 local nsname=$1 212 213 disable_strict_mode ${nsname} 214 log_test $? 0 "${nsname}: disable strict_mode (=0)" 215} 216 217enable_strict_mode_and_check() 218{ 219 local nsname=$1 220 221 enable_strict_mode ${nsname} 222 log_test $? 0 "${nsname}: enable strict_mode (=1)" 223} 224 225enable_strict_mode_and_check_fail() 226{ 227 local nsname=$1 228 229 enable_strict_mode ${nsname} 230 log_test $? 1 "${nsname}: CANNOT enable strict_mode" 231} 232 233strict_mode_check_default() 234{ 235 local nsname=$1 236 local strictmode 237 local vrfcnt 238 239 vrfcnt=$(vrf_count ${nsname}) 240 strictmode=$(read_strict_mode ${nsname}) 241 log_test ${strictmode} 0 "${nsname}: strict_mode=0 by default, ${vrfcnt} vrfs" 242} 243 244setup() 245{ 246 modprobe vrf 247 248 setup_ns testns 249} 250 251cleanup() 252{ 253 ip netns del $testns 2>/dev/null 254 255 ip link del vrf100 2>/dev/null 256 ip link del vrf101 2>/dev/null 257 ip link del vrf102 2>/dev/null 258 259 echo 0 >/proc/sys/net/vrf/strict_mode 2>/dev/null 260} 261 262vrf_strict_mode_tests_init() 263{ 264 log_section "VRF strict_mode test on init network namespace" 265 266 vrf_strict_mode_check_support init 267 268 strict_mode_check_default init 269 270 add_vrf_and_check init vrf100 100 271 config_vrf_and_check init 172.16.100.1/24 vrf100 272 273 enable_strict_mode_and_check init 274 275 add_vrf_and_check_fail init vrf101 100 276 277 disable_strict_mode_and_check init 278 279 add_vrf_and_check init vrf101 100 280 config_vrf_and_check init 172.16.101.1/24 vrf101 281 282 enable_strict_mode_and_check_fail init 283 284 del_vrf_and_check init vrf101 285 286 enable_strict_mode_and_check init 287 288 add_vrf_and_check init vrf102 102 289 config_vrf_and_check init 172.16.102.1/24 vrf102 290 291 # the strict_modle is enabled in the init 292} 293 294vrf_strict_mode_tests_testns() 295{ 296 log_section "VRF strict_mode test on testns network namespace" 297 298 vrf_strict_mode_check_support $testns 299 300 strict_mode_check_default $testns 301 302 enable_strict_mode_and_check $testns 303 304 add_vrf_and_check $testns vrf100 100 305 config_vrf_and_check $testns 10.0.100.1/24 vrf100 306 307 add_vrf_and_check_fail $testns vrf101 100 308 309 add_vrf_and_check_fail $testns vrf102 100 310 311 add_vrf_and_check $testns vrf200 200 312 313 disable_strict_mode_and_check $testns 314 315 add_vrf_and_check $testns vrf101 100 316 317 add_vrf_and_check $testns vrf102 100 318 319 #the strict_mode is disabled in the $testns 320} 321 322vrf_strict_mode_tests_mix() 323{ 324 log_section "VRF strict_mode test mixing init and testns network namespaces" 325 326 read_strict_mode_compare_and_check init 1 327 328 read_strict_mode_compare_and_check $testns 0 329 330 del_vrf_and_check $testns vrf101 331 332 del_vrf_and_check $testns vrf102 333 334 disable_strict_mode_and_check init 335 336 enable_strict_mode_and_check $testns 337 338 enable_strict_mode_and_check init 339 enable_strict_mode_and_check init 340 341 disable_strict_mode_and_check $testns 342 disable_strict_mode_and_check $testns 343 344 read_strict_mode_compare_and_check init 1 345 346 read_strict_mode_compare_and_check $testns 0 347} 348 349################################################################################ 350# usage 351 352usage() 353{ 354 cat <<EOF 355usage: ${0##*/} OPTS 356 357 -t <test> Test(s) to run (default: all) 358 (options: $TESTS) 359EOF 360} 361 362################################################################################ 363# main 364 365while getopts ":t:h" opt; do 366 case $opt in 367 t) TESTS=$OPTARG;; 368 h) usage; exit 0;; 369 *) usage; exit 1;; 370 esac 371done 372 373vrf_strict_mode_check_support() 374{ 375 local nsname=$1 376 local output 377 local rc 378 379 output="$(lsmod | grep '^vrf' | awk '{print $1}')" 380 if [ -z "${output}" ]; then 381 modinfo vrf || return $? 382 fi 383 384 # we do not care about the value of the strict_mode; we only check if 385 # the strict_mode parameter is available or not. 386 read_strict_mode ${nsname} &>/dev/null; rc=$? 387 log_test ${rc} 0 "${nsname}: net.vrf.strict_mode is available" 388 389 return ${rc} 390} 391 392if [ "$(id -u)" -ne 0 ];then 393 echo "SKIP: Need root privileges" 394 exit $ksft_skip 395fi 396 397if [ ! -x "$(command -v ip)" ]; then 398 echo "SKIP: Could not run test without ip tool" 399 exit $ksft_skip 400fi 401 402modprobe vrf &>/dev/null 403if [ ! -e /proc/sys/net/vrf/strict_mode ]; then 404 echo "SKIP: vrf sysctl does not exist" 405 exit $ksft_skip 406fi 407 408cleanup &> /dev/null 409 410setup 411for t in $TESTS 412do 413 case $t in 414 vrf_strict_mode_tests_init|init) vrf_strict_mode_tests_init;; 415 vrf_strict_mode_tests_testns|testns) vrf_strict_mode_tests_testns;; 416 vrf_strict_mode_tests_mix|mix) vrf_strict_mode_tests_mix;; 417 418 help) echo "Test names: $TESTS"; exit 0;; 419 420 esac 421done 422cleanup 423 424print_log_test_results 425 426exit $ret 427