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 if [ $trap_name == "ingress_flow_action_drop" ] || 107 [ $trap_name == "egress_flow_action_drop" ]; then 108 devlink_trap_metadata_test $trap_name "flow_action_cookie" 109 check_err $? "Flow action cookie not reported as metadata of trap $trap_name" 110 fi 111 done 112 113 log_test "Trap metadata" 114} 115 116bad_trap_test() 117{ 118 RET=0 119 120 devlink_trap_action_set "made_up_trap" "drop" 121 check_fail $? "Did not get an error for non-existing trap" 122 123 log_test "Non-existing trap" 124} 125 126bad_trap_action_test() 127{ 128 local traps_arr 129 local trap_name 130 131 RET=0 132 133 # Pick first trap. 134 traps_arr=($(devlink_traps_get)) 135 trap_name=${traps_arr[0]} 136 137 devlink_trap_action_set $trap_name "made_up_action" 138 check_fail $? "Did not get an error for non-existing trap action" 139 140 log_test "Non-existing trap action" 141} 142 143trap_stats_test() 144{ 145 local trap_name 146 147 RET=0 148 149 for trap_name in $(devlink_traps_get); do 150 devlink_trap_stats_idle_test $trap_name 151 check_err $? "Stats of trap $trap_name not idle when netdev down" 152 153 ip link set dev $NETDEV up 154 155 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then 156 devlink_trap_action_set $trap_name "trap" 157 devlink_trap_stats_idle_test $trap_name 158 check_fail $? "Stats of trap $trap_name idle when action is trap" 159 160 devlink_trap_action_set $trap_name "drop" 161 devlink_trap_stats_idle_test $trap_name 162 check_err $? "Stats of trap $trap_name not idle when action is drop" 163 else 164 devlink_trap_stats_idle_test $trap_name 165 check_fail $? "Stats of non-drop trap $trap_name idle when should not" 166 fi 167 168 ip link set dev $NETDEV down 169 done 170 171 log_test "Trap statistics" 172} 173 174trap_group_action_test() 175{ 176 local curr_group group_name 177 local trap_name 178 local trap_type 179 local action 180 181 RET=0 182 183 for group_name in $(devlink_trap_groups_get); do 184 devlink_trap_group_action_set $group_name "trap" 185 186 for trap_name in $(devlink_traps_get); do 187 curr_group=$(devlink_trap_group_get $trap_name) 188 if [ $curr_group != $group_name ]; then 189 continue 190 fi 191 192 trap_type=$(devlink_trap_type_get $trap_name) 193 if [ $trap_type != "drop" ]; then 194 continue 195 fi 196 197 action=$(devlink_trap_action_get $trap_name) 198 if [ $action != "trap" ]; then 199 check_err 1 "Trap $trap_name did not change action to trap" 200 fi 201 done 202 203 devlink_trap_group_action_set $group_name "drop" 204 205 for trap_name in $(devlink_traps_get); do 206 curr_group=$(devlink_trap_group_get $trap_name) 207 if [ $curr_group != $group_name ]; then 208 continue 209 fi 210 211 trap_type=$(devlink_trap_type_get $trap_name) 212 if [ $trap_type != "drop" ]; then 213 continue 214 fi 215 216 action=$(devlink_trap_action_get $trap_name) 217 if [ $action != "drop" ]; then 218 check_err 1 "Trap $trap_name did not change action to drop" 219 fi 220 done 221 done 222 223 log_test "Trap group action" 224} 225 226bad_trap_group_test() 227{ 228 RET=0 229 230 devlink_trap_group_action_set "made_up_trap_group" "drop" 231 check_fail $? "Did not get an error for non-existing trap group" 232 233 log_test "Non-existing trap group" 234} 235 236trap_group_stats_test() 237{ 238 local group_name 239 240 RET=0 241 242 for group_name in $(devlink_trap_groups_get); do 243 devlink_trap_group_stats_idle_test $group_name 244 check_err $? "Stats of trap group $group_name not idle when netdev down" 245 246 ip link set dev $NETDEV up 247 248 devlink_trap_group_action_set $group_name "trap" 249 devlink_trap_group_stats_idle_test $group_name 250 check_fail $? "Stats of trap group $group_name idle when action is trap" 251 252 devlink_trap_group_action_set $group_name "drop" 253 ip link set dev $NETDEV down 254 done 255 256 log_test "Trap group statistics" 257} 258 259port_del_test() 260{ 261 local group_name 262 local i 263 264 # The test never fails. It is meant to exercise different code paths 265 # and make sure we properly dismantle a port while packets are 266 # in-flight. 267 RET=0 268 269 devlink_traps_enable_all 270 271 for i in $(seq 1 10); do 272 ip link set dev $NETDEV up 273 274 sleep $SLEEP_TIME 275 276 netdevsim_port_destroy 277 netdevsim_port_create 278 udevadm settle 279 done 280 281 devlink_traps_disable_all 282 283 log_test "Port delete" 284} 285 286dev_del_test() 287{ 288 local group_name 289 local i 290 291 # The test never fails. It is meant to exercise different code paths 292 # and make sure we properly unregister traps while packets are 293 # in-flight. 294 RET=0 295 296 devlink_traps_enable_all 297 298 for i in $(seq 1 10); do 299 ip link set dev $NETDEV up 300 301 sleep $SLEEP_TIME 302 303 cleanup 304 setup_prepare 305 done 306 307 devlink_traps_disable_all 308 309 log_test "Device delete" 310} 311 312netdevsim_dev_create() 313{ 314 echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device 315} 316 317netdevsim_dev_destroy() 318{ 319 echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device 320} 321 322netdevsim_port_create() 323{ 324 echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port 325} 326 327netdevsim_port_destroy() 328{ 329 echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port 330} 331 332setup_prepare() 333{ 334 local netdev 335 336 netdevsim_dev_create 337 338 if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then 339 echo "Failed to create netdevsim device" 340 exit 1 341 fi 342 343 netdevsim_port_create 344 345 if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then 346 echo "Failed to create netdevsim port" 347 exit 1 348 fi 349 350 # Wait for udev to rename newly created netdev. 351 udevadm settle 352 353 NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/) 354} 355 356cleanup() 357{ 358 pre_cleanup 359 netdevsim_port_destroy 360 netdevsim_dev_destroy 361} 362 363trap cleanup EXIT 364 365setup_prepare 366 367tests_run 368 369exit $EXIT_STATUS 370