| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 |
|
| 7 | lib_dir=$(dirname $0)/../../../net/forwarding
|
| 8 |
|
| 9 | ALL_TESTS="
|
| 10 | init_test
|
| 11 | trap_action_test
|
| 12 | trap_metadata_test
|
| 13 | bad_trap_test
|
| 14 | bad_trap_action_test
|
| 15 | trap_stats_test
|
| 16 | trap_group_action_test
|
| 17 | bad_trap_group_test
|
| 18 | trap_group_stats_test
|
| 19 | trap_policer_test
|
| 20 | trap_policer_bind_test
|
| 21 | port_del_test
|
| 22 | dev_del_test
|
| 23 | "
|
| 24 | NETDEVSIM_PATH=/sys/bus/netdevsim/
|
| 25 | DEV_ADDR=1337
|
| 26 | DEV=netdevsim${DEV_ADDR}
|
| 27 | DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
|
| 28 | SLEEP_TIME=1
|
| 29 | NETDEV=""
|
| 30 | NUM_NETIFS=0
|
| 31 | source $lib_dir/lib.sh
|
| 32 |
|
| 33 | DEVLINK_DEV=
|
| 34 | source $lib_dir/devlink_lib.sh
|
| 35 | DEVLINK_DEV=netdevsim/${DEV}
|
| 36 |
|
| 37 | require_command udevadm
|
| 38 |
|
| 39 | modprobe netdevsim &> /dev/null
|
| 40 | if [ ! -d "$NETDEVSIM_PATH" ]; then
|
| 41 | echo "SKIP: No netdevsim support"
|
| 42 | exit 1
|
| 43 | fi
|
| 44 |
|
| 45 | if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then
|
| 46 | echo "SKIP: Device netdevsim${DEV_ADDR} already exists"
|
| 47 | exit 1
|
| 48 | fi
|
| 49 |
|
| 50 | check_netdev_down()
|
| 51 | {
|
| 52 | state=$(cat /sys/class/net/${NETDEV}/flags)
|
| 53 |
|
| 54 | if [ $((state & 1)) -ne 0 ]; then
|
| 55 | echo "WARNING: unexpected interface UP, disable NetworkManager?"
|
| 56 |
|
| 57 | ip link set dev $NETDEV down
|
| 58 | fi
|
| 59 | }
|
| 60 |
|
| 61 | init_test()
|
| 62 | {
|
| 63 | RET=0
|
| 64 |
|
| 65 | test $(devlink_traps_num_get) -ne 0
|
| 66 | check_err $? "No traps were registered"
|
| 67 |
|
| 68 | log_test "Initialization"
|
| 69 | }
|
| 70 |
|
| 71 | trap_action_test()
|
| 72 | {
|
| 73 | local orig_action
|
| 74 | local trap_name
|
| 75 | local action
|
| 76 |
|
| 77 | RET=0
|
| 78 |
|
| 79 | for trap_name in $(devlink_traps_get); do
|
| 80 | |
| 81 | if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
|
| 82 | devlink_trap_action_set $trap_name "trap"
|
| 83 | action=$(devlink_trap_action_get $trap_name)
|
| 84 | if [ $action != "trap" ]; then
|
| 85 | check_err 1 "Trap $trap_name did not change action to trap"
|
| 86 | fi
|
| 87 |
|
| 88 | devlink_trap_action_set $trap_name "drop"
|
| 89 | action=$(devlink_trap_action_get $trap_name)
|
| 90 | if [ $action != "drop" ]; then
|
| 91 | check_err 1 "Trap $trap_name did not change action to drop"
|
| 92 | fi
|
| 93 | else
|
| 94 | orig_action=$(devlink_trap_action_get $trap_name)
|
| 95 |
|
| 96 | devlink_trap_action_set $trap_name "trap"
|
| 97 | action=$(devlink_trap_action_get $trap_name)
|
| 98 | if [ $action != $orig_action ]; then
|
| 99 | check_err 1 "Trap $trap_name changed action when should not"
|
| 100 | fi
|
| 101 |
|
| 102 | devlink_trap_action_set $trap_name "drop"
|
| 103 | action=$(devlink_trap_action_get $trap_name)
|
| 104 | if [ $action != $orig_action ]; then
|
| 105 | check_err 1 "Trap $trap_name changed action when should not"
|
| 106 | fi
|
| 107 | fi
|
| 108 | done
|
| 109 |
|
| 110 | log_test "Trap action"
|
| 111 | }
|
| 112 |
|
| 113 | trap_metadata_test()
|
| 114 | {
|
| 115 | local trap_name
|
| 116 |
|
| 117 | RET=0
|
| 118 |
|
| 119 | for trap_name in $(devlink_traps_get); do
|
| 120 | devlink_trap_metadata_test $trap_name "input_port"
|
| 121 | check_err $? "Input port not reported as metadata of trap $trap_name"
|
| 122 | if [ $trap_name == "ingress_flow_action_drop" ] ||
|
| 123 | [ $trap_name == "egress_flow_action_drop" ]; then
|
| 124 | devlink_trap_metadata_test $trap_name "flow_action_cookie"
|
| 125 | check_err $? "Flow action cookie not reported as metadata of trap $trap_name"
|
| 126 | fi
|
| 127 | done
|
| 128 |
|
| 129 | log_test "Trap metadata"
|
| 130 | }
|
| 131 |
|
| 132 | bad_trap_test()
|
| 133 | {
|
| 134 | RET=0
|
| 135 |
|
| 136 | devlink_trap_action_set "made_up_trap" "drop"
|
| 137 | check_fail $? "Did not get an error for non-existing trap"
|
| 138 |
|
| 139 | log_test "Non-existing trap"
|
| 140 | }
|
| 141 |
|
| 142 | bad_trap_action_test()
|
| 143 | {
|
| 144 | local traps_arr
|
| 145 | local trap_name
|
| 146 |
|
| 147 | RET=0
|
| 148 |
|
| 149 | |
| 150 | traps_arr=($(devlink_traps_get))
|
| 151 | trap_name=${traps_arr[0]}
|
| 152 |
|
| 153 | devlink_trap_action_set $trap_name "made_up_action"
|
| 154 | check_fail $? "Did not get an error for non-existing trap action"
|
| 155 |
|
| 156 | log_test "Non-existing trap action"
|
| 157 | }
|
| 158 |
|
| 159 | trap_stats_test()
|
| 160 | {
|
| 161 | local trap_name
|
| 162 |
|
| 163 | RET=0
|
| 164 |
|
| 165 | check_netdev_down
|
| 166 | for trap_name in $(devlink_traps_get); do
|
| 167 | devlink_trap_stats_idle_test $trap_name
|
| 168 | check_err $? "Stats of trap $trap_name not idle when netdev down"
|
| 169 |
|
| 170 | ip link set dev $NETDEV up
|
| 171 |
|
| 172 | if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
|
| 173 | devlink_trap_action_set $trap_name "trap"
|
| 174 | devlink_trap_stats_idle_test $trap_name
|
| 175 | check_fail $? "Stats of trap $trap_name idle when action is trap"
|
| 176 |
|
| 177 | devlink_trap_action_set $trap_name "drop"
|
| 178 | devlink_trap_stats_idle_test $trap_name
|
| 179 | check_err $? "Stats of trap $trap_name not idle when action is drop"
|
| 180 |
|
| 181 | echo "y"> $DEBUGFS_DIR/fail_trap_drop_counter_get
|
| 182 | devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
|
| 183 | check_fail $? "Managed to read trap (hard dropped) statistics when should not"
|
| 184 | echo "n"> $DEBUGFS_DIR/fail_trap_drop_counter_get
|
| 185 | devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
|
| 186 | check_err $? "Did not manage to read trap (hard dropped) statistics when should"
|
| 187 |
|
| 188 | devlink_trap_drop_stats_idle_test $trap_name
|
| 189 | check_fail $? "Drop stats of trap $trap_name idle when should not"
|
| 190 | else
|
| 191 | devlink_trap_stats_idle_test $trap_name
|
| 192 | check_fail $? "Stats of non-drop trap $trap_name idle when should not"
|
| 193 | fi
|
| 194 |
|
| 195 | ip link set dev $NETDEV down
|
| 196 | done
|
| 197 |
|
| 198 | log_test "Trap statistics"
|
| 199 | }
|
| 200 |
|
| 201 | trap_group_action_test()
|
| 202 | {
|
| 203 | local curr_group group_name
|
| 204 | local trap_name
|
| 205 | local trap_type
|
| 206 | local action
|
| 207 |
|
| 208 | RET=0
|
| 209 |
|
| 210 | for group_name in $(devlink_trap_groups_get); do
|
| 211 | devlink_trap_group_action_set $group_name "trap"
|
| 212 |
|
| 213 | for trap_name in $(devlink_traps_get); do
|
| 214 | curr_group=$(devlink_trap_group_get $trap_name)
|
| 215 | if [ $curr_group != $group_name ]; then
|
| 216 | continue
|
| 217 | fi
|
| 218 |
|
| 219 | trap_type=$(devlink_trap_type_get $trap_name)
|
| 220 | if [ $trap_type != "drop" ]; then
|
| 221 | continue
|
| 222 | fi
|
| 223 |
|
| 224 | action=$(devlink_trap_action_get $trap_name)
|
| 225 | if [ $action != "trap" ]; then
|
| 226 | check_err 1 "Trap $trap_name did not change action to trap"
|
| 227 | fi
|
| 228 | done
|
| 229 |
|
| 230 | devlink_trap_group_action_set $group_name "drop"
|
| 231 |
|
| 232 | for trap_name in $(devlink_traps_get); do
|
| 233 | curr_group=$(devlink_trap_group_get $trap_name)
|
| 234 | if [ $curr_group != $group_name ]; then
|
| 235 | continue
|
| 236 | fi
|
| 237 |
|
| 238 | trap_type=$(devlink_trap_type_get $trap_name)
|
| 239 | if [ $trap_type != "drop" ]; then
|
| 240 | continue
|
| 241 | fi
|
| 242 |
|
| 243 | action=$(devlink_trap_action_get $trap_name)
|
| 244 | if [ $action != "drop" ]; then
|
| 245 | check_err 1 "Trap $trap_name did not change action to drop"
|
| 246 | fi
|
| 247 | done
|
| 248 | done
|
| 249 |
|
| 250 | log_test "Trap group action"
|
| 251 | }
|
| 252 |
|
| 253 | bad_trap_group_test()
|
| 254 | {
|
| 255 | RET=0
|
| 256 |
|
| 257 | devlink_trap_group_action_set "made_up_trap_group" "drop"
|
| 258 | check_fail $? "Did not get an error for non-existing trap group"
|
| 259 |
|
| 260 | log_test "Non-existing trap group"
|
| 261 | }
|
| 262 |
|
| 263 | trap_group_stats_test()
|
| 264 | {
|
| 265 | local group_name
|
| 266 |
|
| 267 | RET=0
|
| 268 |
|
| 269 | check_netdev_down
|
| 270 | for group_name in $(devlink_trap_groups_get); do
|
| 271 | devlink_trap_group_stats_idle_test $group_name
|
| 272 | check_err $? "Stats of trap group $group_name not idle when netdev down"
|
| 273 |
|
| 274 | ip link set dev $NETDEV up
|
| 275 |
|
| 276 | devlink_trap_group_action_set $group_name "trap"
|
| 277 | devlink_trap_group_stats_idle_test $group_name
|
| 278 | check_fail $? "Stats of trap group $group_name idle when action is trap"
|
| 279 |
|
| 280 | devlink_trap_group_action_set $group_name "drop"
|
| 281 | ip link set dev $NETDEV down
|
| 282 | done
|
| 283 |
|
| 284 | log_test "Trap group statistics"
|
| 285 | }
|
| 286 |
|
| 287 | trap_policer_test()
|
| 288 | {
|
| 289 | local packets_t0
|
| 290 | local packets_t1
|
| 291 |
|
| 292 | RET=0
|
| 293 |
|
| 294 | if [ $(devlink_trap_policers_num_get) -eq 0 ]; then
|
| 295 | check_err 1 "Failed to dump policers"
|
| 296 | fi
|
| 297 |
|
| 298 | devlink trap policer set $DEVLINK_DEV policer 1337 &> /dev/null
|
| 299 | check_fail $? "Did not get an error for setting a non-existing policer"
|
| 300 | devlink trap policer show $DEVLINK_DEV policer 1337 &> /dev/null
|
| 301 | check_fail $? "Did not get an error for getting a non-existing policer"
|
| 302 |
|
| 303 | devlink trap policer set $DEVLINK_DEV policer 1 rate 2000 burst 16
|
| 304 | check_err $? "Failed to set valid parameters for a valid policer"
|
| 305 | if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
|
| 306 | check_err 1 "Policer rate was not changed"
|
| 307 | fi
|
| 308 | if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
|
| 309 | check_err 1 "Policer burst size was not changed"
|
| 310 | fi
|
| 311 |
|
| 312 | devlink trap policer set $DEVLINK_DEV policer 1 rate 0 &> /dev/null
|
| 313 | check_fail $? "Policer rate was changed to rate lower than limit"
|
| 314 | devlink trap policer set $DEVLINK_DEV policer 1 rate 9000 &> /dev/null
|
| 315 | check_fail $? "Policer rate was changed to rate higher than limit"
|
| 316 | devlink trap policer set $DEVLINK_DEV policer 1 burst 2 &> /dev/null
|
| 317 | check_fail $? "Policer burst size was changed to burst size lower than limit"
|
| 318 | devlink trap policer set $DEVLINK_DEV policer 1 rate 65537 &> /dev/null
|
| 319 | check_fail $? "Policer burst size was changed to burst size higher than limit"
|
| 320 | echo "y" > $DEBUGFS_DIR/fail_trap_policer_set
|
| 321 | devlink trap policer set $DEVLINK_DEV policer 1 rate 3000 &> /dev/null
|
| 322 | check_fail $? "Managed to set policer rate when should not"
|
| 323 | echo "n" > $DEBUGFS_DIR/fail_trap_policer_set
|
| 324 | if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
|
| 325 | check_err 1 "Policer rate was changed to an invalid value"
|
| 326 | fi
|
| 327 | if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
|
| 328 | check_err 1 "Policer burst size was changed to an invalid value"
|
| 329 | fi
|
| 330 |
|
| 331 | packets_t0=$(devlink_trap_policer_rx_dropped_get 1)
|
| 332 | sleep .5
|
| 333 | packets_t1=$(devlink_trap_policer_rx_dropped_get 1)
|
| 334 | if [ ! $packets_t1 -gt $packets_t0 ]; then
|
| 335 | check_err 1 "Policer drop counter was not incremented"
|
| 336 | fi
|
| 337 |
|
| 338 | echo "y"> $DEBUGFS_DIR/fail_trap_policer_counter_get
|
| 339 | devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
|
| 340 | check_fail $? "Managed to read policer drop counter when should not"
|
| 341 | echo "n"> $DEBUGFS_DIR/fail_trap_policer_counter_get
|
| 342 | devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
|
| 343 | check_err $? "Did not manage to read policer drop counter when should"
|
| 344 |
|
| 345 | log_test "Trap policer"
|
| 346 | }
|
| 347 |
|
| 348 | trap_group_check_policer()
|
| 349 | {
|
| 350 | local group_name=$1; shift
|
| 351 |
|
| 352 | devlink -j -p trap group show $DEVLINK_DEV group $group_name \
|
| 353 | | jq -e '.[][][]["policer"]' &> /dev/null
|
| 354 | }
|
| 355 |
|
| 356 | trap_policer_bind_test()
|
| 357 | {
|
| 358 | RET=0
|
| 359 |
|
| 360 | devlink trap group set $DEVLINK_DEV group l2_drops policer 1
|
| 361 | check_err $? "Failed to bind a valid policer"
|
| 362 | if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
|
| 363 | check_err 1 "Bound policer was not changed"
|
| 364 | fi
|
| 365 |
|
| 366 | devlink trap group set $DEVLINK_DEV group l2_drops policer 1337 \
|
| 367 | &> /dev/null
|
| 368 | check_fail $? "Did not get an error for binding a non-existing policer"
|
| 369 | if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
|
| 370 | check_err 1 "Bound policer was changed when should not"
|
| 371 | fi
|
| 372 |
|
| 373 | devlink trap group set $DEVLINK_DEV group l2_drops policer 0
|
| 374 | check_err $? "Failed to unbind a policer when using ID 0"
|
| 375 | trap_group_check_policer "l2_drops"
|
| 376 | check_fail $? "Trap group has a policer after unbinding with ID 0"
|
| 377 |
|
| 378 | devlink trap group set $DEVLINK_DEV group l2_drops policer 1
|
| 379 | check_err $? "Failed to bind a valid policer"
|
| 380 |
|
| 381 | devlink trap group set $DEVLINK_DEV group l2_drops nopolicer
|
| 382 | check_err $? "Failed to unbind a policer when using 'nopolicer' keyword"
|
| 383 | trap_group_check_policer "l2_drops"
|
| 384 | check_fail $? "Trap group has a policer after unbinding with 'nopolicer' keyword"
|
| 385 |
|
| 386 | devlink trap group set $DEVLINK_DEV group l2_drops policer 1
|
| 387 | check_err $? "Failed to bind a valid policer"
|
| 388 |
|
| 389 | echo "y"> $DEBUGFS_DIR/fail_trap_group_set
|
| 390 | devlink trap group set $DEVLINK_DEV group l2_drops policer 2 \
|
| 391 | &> /dev/null
|
| 392 | check_fail $? "Managed to bind a policer when should not"
|
| 393 | echo "n"> $DEBUGFS_DIR/fail_trap_group_set
|
| 394 | devlink trap group set $DEVLINK_DEV group l2_drops policer 2
|
| 395 | check_err $? "Did not manage to bind a policer when should"
|
| 396 |
|
| 397 | devlink trap group set $DEVLINK_DEV group l2_drops action drop \
|
| 398 | policer 1337 &> /dev/null
|
| 399 | check_fail $? "Did not get an error for partially modified trap group"
|
| 400 |
|
| 401 | log_test "Trap policer binding"
|
| 402 | }
|
| 403 |
|
| 404 | port_del_test()
|
| 405 | {
|
| 406 | local group_name
|
| 407 | local i
|
| 408 |
|
| 409 | |
| 410 | |
| 411 | |
| 412 | RET=0
|
| 413 |
|
| 414 | devlink_traps_enable_all
|
| 415 |
|
| 416 | for i in $(seq 1 10); do
|
| 417 | ip link set dev $NETDEV up
|
| 418 |
|
| 419 | sleep $SLEEP_TIME
|
| 420 |
|
| 421 | netdevsim_port_destroy
|
| 422 | netdevsim_port_create
|
| 423 | udevadm settle
|
| 424 | done
|
| 425 |
|
| 426 | devlink_traps_disable_all
|
| 427 |
|
| 428 | log_test "Port delete"
|
| 429 | }
|
| 430 |
|
| 431 | dev_del_test()
|
| 432 | {
|
| 433 | local group_name
|
| 434 | local i
|
| 435 |
|
| 436 | |
| 437 | |
| 438 | |
| 439 | RET=0
|
| 440 |
|
| 441 | devlink_traps_enable_all
|
| 442 |
|
| 443 | for i in $(seq 1 10); do
|
| 444 | ip link set dev $NETDEV up
|
| 445 |
|
| 446 | sleep $SLEEP_TIME
|
| 447 |
|
| 448 | cleanup
|
| 449 | setup_prepare
|
| 450 | done
|
| 451 |
|
| 452 | devlink_traps_disable_all
|
| 453 |
|
| 454 | log_test "Device delete"
|
| 455 | }
|
| 456 |
|
| 457 | netdevsim_dev_create()
|
| 458 | {
|
| 459 | echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device
|
| 460 | }
|
| 461 |
|
| 462 | netdevsim_dev_destroy()
|
| 463 | {
|
| 464 | echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
|
| 465 | }
|
| 466 |
|
| 467 | netdevsim_port_create()
|
| 468 | {
|
| 469 | echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port
|
| 470 | }
|
| 471 |
|
| 472 | netdevsim_port_destroy()
|
| 473 | {
|
| 474 | echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port
|
| 475 | }
|
| 476 |
|
| 477 | setup_prepare()
|
| 478 | {
|
| 479 | local netdev
|
| 480 |
|
| 481 | netdevsim_dev_create
|
| 482 |
|
| 483 | if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then
|
| 484 | echo "Failed to create netdevsim device"
|
| 485 | exit 1
|
| 486 | fi
|
| 487 |
|
| 488 | netdevsim_port_create
|
| 489 |
|
| 490 | if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then
|
| 491 | echo "Failed to create netdevsim port"
|
| 492 | exit 1
|
| 493 | fi
|
| 494 |
|
| 495 | |
| 496 | udevadm settle
|
| 497 |
|
| 498 | NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/)
|
| 499 | }
|
| 500 |
|
| 501 | cleanup()
|
| 502 | {
|
| 503 | pre_cleanup
|
| 504 | netdevsim_port_destroy
|
| 505 | netdevsim_dev_destroy
|
| 506 | }
|
| 507 |
|
| 508 | trap cleanup EXIT
|
| 509 |
|
| 510 | setup_prepare
|
| 511 |
|
| 512 | tests_run
|
| 513 |
|
| 514 | exit $EXIT_STATUS
|