1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# This test is for checking devlink-trap functionality. It makes use of 5# netdevsim which implements the required callbacks. 6 7lib_dir=$(dirname $0)/../../../net/forwarding 8 9ALL_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 port_del_test 20 dev_del_test 21" 22NETDEVSIM_PATH=/sys/bus/netdevsim/ 23DEV_ADDR=1337 24DEV=netdevsim${DEV_ADDR} 25DEVLINK_DEV=netdevsim/${DEV} 26SLEEP_TIME=1 27NETDEV="" 28NUM_NETIFS=0 29source $lib_dir/lib.sh 30source $lib_dir/devlink_lib.sh 31 32require_command udevadm 33 34modprobe netdevsim &> /dev/null 35if [ ! -d "$NETDEVSIM_PATH" ]; then 36 echo "SKIP: No netdevsim support" 37 exit 1 38fi 39 40if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then 41 echo "SKIP: Device netdevsim${DEV_ADDR} already exists" 42 exit 1 43fi 44 45init_test() 46{ 47 RET=0 48 49 test $(devlink_traps_num_get) -ne 0 50 check_err $? "No traps were registered" 51 52 log_test "Initialization" 53} 54 55trap_action_test() 56{ 57 local orig_action 58 local trap_name 59 local action 60 61 RET=0 62 63 for trap_name in $(devlink_traps_get); do 64 # The action of non-drop traps cannot be changed. 65 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then 66 devlink_trap_action_set $trap_name "trap" 67 action=$(devlink_trap_action_get $trap_name) 68 if [ $action != "trap" ]; then 69 check_err 1 "Trap $trap_name did not change action to trap" 70 fi 71 72 devlink_trap_action_set $trap_name "drop" 73 action=$(devlink_trap_action_get $trap_name) 74 if [ $action != "drop" ]; then 75 check_err 1 "Trap $trap_name did not change action to drop" 76 fi 77 else 78 orig_action=$(devlink_trap_action_get $trap_name) 79 80 devlink_trap_action_set $trap_name "trap" 81 action=$(devlink_trap_action_get $trap_name) 82 if [ $action != $orig_action ]; then 83 check_err 1 "Trap $trap_name changed action when should not" 84 fi 85 86 devlink_trap_action_set $trap_name "drop" 87 action=$(devlink_trap_action_get $trap_name) 88 if [ $action != $orig_action ]; then 89 check_err 1 "Trap $trap_name changed action when should not" 90 fi 91 fi 92 done 93 94 log_test "Trap action" 95} 96 97trap_metadata_test() 98{ 99 local trap_name 100 101 RET=0 102 103 for trap_name in $(devlink_traps_get); do 104 devlink_trap_metadata_test $trap_name "input_port" 105 check_err $? "Input port not reported as metadata of trap $trap_name" 106 done 107 108 log_test "Trap metadata" 109} 110 111bad_trap_test() 112{ 113 RET=0 114 115 devlink_trap_action_set "made_up_trap" "drop" 116 check_fail $? "Did not get an error for non-existing trap" 117 118 log_test "Non-existing trap" 119} 120 121bad_trap_action_test() 122{ 123 local traps_arr 124 local trap_name 125 126 RET=0 127 128 # Pick first trap. 129 traps_arr=($(devlink_traps_get)) 130 trap_name=${traps_arr[0]} 131 132 devlink_trap_action_set $trap_name "made_up_action" 133 check_fail $? "Did not get an error for non-existing trap action" 134 135 log_test "Non-existing trap action" 136} 137 138trap_stats_test() 139{ 140 local trap_name 141 142 RET=0 143 144 for trap_name in $(devlink_traps_get); do 145 devlink_trap_stats_idle_test $trap_name 146 check_err $? "Stats of trap $trap_name not idle when netdev down" 147 148 ip link set dev $NETDEV up 149 150 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then 151 devlink_trap_action_set $trap_name "trap" 152 devlink_trap_stats_idle_test $trap_name 153 check_fail $? "Stats of trap $trap_name idle when action is trap" 154 155 devlink_trap_action_set $trap_name "drop" 156 devlink_trap_stats_idle_test $trap_name 157 check_err $? "Stats of trap $trap_name not idle when action is drop" 158 else 159 devlink_trap_stats_idle_test $trap_name 160 check_fail $? "Stats of non-drop trap $trap_name idle when should not" 161 fi 162 163 ip link set dev $NETDEV down 164 done 165 166 log_test "Trap statistics" 167} 168 169trap_group_action_test() 170{ 171 local curr_group group_name 172 local trap_name 173 local trap_type 174 local action 175 176 RET=0 177 178 for group_name in $(devlink_trap_groups_get); do 179 devlink_trap_group_action_set $group_name "trap" 180 181 for trap_name in $(devlink_traps_get); do 182 curr_group=$(devlink_trap_group_get $trap_name) 183 if [ $curr_group != $group_name ]; then 184 continue 185 fi 186 187 trap_type=$(devlink_trap_type_get $trap_name) 188 if [ $trap_type != "drop" ]; then 189 continue 190 fi 191 192 action=$(devlink_trap_action_get $trap_name) 193 if [ $action != "trap" ]; then 194 check_err 1 "Trap $trap_name did not change action to trap" 195 fi 196 done 197 198 devlink_trap_group_action_set $group_name "drop" 199 200 for trap_name in $(devlink_traps_get); do 201 curr_group=$(devlink_trap_group_get $trap_name) 202 if [ $curr_group != $group_name ]; then 203 continue 204 fi 205 206 trap_type=$(devlink_trap_type_get $trap_name) 207 if [ $trap_type != "drop" ]; then 208 continue 209 fi 210 211 action=$(devlink_trap_action_get $trap_name) 212 if [ $action != "drop" ]; then 213 check_err 1 "Trap $trap_name did not change action to drop" 214 fi 215 done 216 done 217 218 log_test "Trap group action" 219} 220 221bad_trap_group_test() 222{ 223 RET=0 224 225 devlink_trap_group_action_set "made_up_trap_group" "drop" 226 check_fail $? "Did not get an error for non-existing trap group" 227 228 log_test "Non-existing trap group" 229} 230 231trap_group_stats_test() 232{ 233 local group_name 234 235 RET=0 236 237 for group_name in $(devlink_trap_groups_get); do 238 devlink_trap_group_stats_idle_test $group_name 239 check_err $? "Stats of trap group $group_name not idle when netdev down" 240 241 ip link set dev $NETDEV up 242 243 devlink_trap_group_action_set $group_name "trap" 244 devlink_trap_group_stats_idle_test $group_name 245 check_fail $? "Stats of trap group $group_name idle when action is trap" 246 247 devlink_trap_group_action_set $group_name "drop" 248 ip link set dev $NETDEV down 249 done 250 251 log_test "Trap group statistics" 252} 253 254port_del_test() 255{ 256 local group_name 257 local i 258 259 # The test never fails. It is meant to exercise different code paths 260 # and make sure we properly dismantle a port while packets are 261 # in-flight. 262 RET=0 263 264 devlink_traps_enable_all 265 266 for i in $(seq 1 10); do 267 ip link set dev $NETDEV up 268 269 sleep $SLEEP_TIME 270 271 netdevsim_port_destroy 272 netdevsim_port_create 273 udevadm settle 274 done 275 276 devlink_traps_disable_all 277 278 log_test "Port delete" 279} 280 281dev_del_test() 282{ 283 local group_name 284 local i 285 286 # The test never fails. It is meant to exercise different code paths 287 # and make sure we properly unregister traps while packets are 288 # in-flight. 289 RET=0 290 291 devlink_traps_enable_all 292 293 for i in $(seq 1 10); do 294 ip link set dev $NETDEV up 295 296 sleep $SLEEP_TIME 297 298 cleanup 299 setup_prepare 300 done 301 302 devlink_traps_disable_all 303 304 log_test "Device delete" 305} 306 307netdevsim_dev_create() 308{ 309 echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device 310} 311 312netdevsim_dev_destroy() 313{ 314 echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device 315} 316 317netdevsim_port_create() 318{ 319 echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port 320} 321 322netdevsim_port_destroy() 323{ 324 echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port 325} 326 327setup_prepare() 328{ 329 local netdev 330 331 netdevsim_dev_create 332 333 if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then 334 echo "Failed to create netdevsim device" 335 exit 1 336 fi 337 338 netdevsim_port_create 339 340 if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then 341 echo "Failed to create netdevsim port" 342 exit 1 343 fi 344 345 # Wait for udev to rename newly created netdev. 346 udevadm settle 347 348 NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/) 349} 350 351cleanup() 352{ 353 pre_cleanup 354 netdevsim_port_destroy 355 netdevsim_dev_destroy 356} 357 358trap cleanup EXIT 359 360setup_prepare 361 362tests_run 363 364exit $EXIT_STATUS 365