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