1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4lib_dir=$(dirname $0)/../../../net/forwarding 5 6ALL_TESTS=" 7 l3_reporting_test 8 l3_fail_next_test 9 l3_counter_test 10 l3_rollback_test 11 l3_monitor_test 12" 13 14NETDEVSIM_PATH=/sys/bus/netdevsim/ 15DEV_ADDR_1=1337 16DEV_ADDR_2=1057 17DEV_ADDR_3=5417 18NUM_NETIFS=0 19source $lib_dir/lib.sh 20 21DUMMY_IFINDEX= 22 23DEV_ADDR() 24{ 25 local n=$1; shift 26 local var=DEV_ADDR_$n 27 28 echo ${!var} 29} 30 31DEV() 32{ 33 echo netdevsim$(DEV_ADDR $1) 34} 35 36DEVLINK_DEV() 37{ 38 echo netdevsim/$(DEV $1) 39} 40 41SYSFS_NET_DIR() 42{ 43 echo /sys/bus/netdevsim/devices/$(DEV $1)/net/ 44} 45 46DEBUGFS_DIR() 47{ 48 echo /sys/kernel/debug/netdevsim/$(DEV $1)/ 49} 50 51nsim_add() 52{ 53 local n=$1; shift 54 55 echo "$(DEV_ADDR $n) 1" > ${NETDEVSIM_PATH}/new_device 56 while [ ! -d $(SYSFS_NET_DIR $n) ] ; do :; done 57} 58 59nsim_reload() 60{ 61 local n=$1; shift 62 local ns=$1; shift 63 64 devlink dev reload $(DEVLINK_DEV $n) netns $ns 65 66 if [ $? -ne 0 ]; then 67 echo "Failed to reload $(DEV $n) into netns \"testns1\"" 68 exit 1 69 fi 70 71} 72 73nsim_del() 74{ 75 local n=$1; shift 76 77 echo "$(DEV_ADDR $n)" > ${NETDEVSIM_PATH}/del_device 78} 79 80nsim_hwstats_toggle() 81{ 82 local action=$1; shift 83 local instance=$1; shift 84 local netdev=$1; shift 85 local type=$1; shift 86 87 local ifindex=$($IP -j link show dev $netdev | jq '.[].ifindex') 88 89 echo $ifindex > $(DEBUGFS_DIR $instance)/hwstats/$type/$action 90} 91 92nsim_hwstats_enable() 93{ 94 nsim_hwstats_toggle enable_ifindex "$@" 95} 96 97nsim_hwstats_disable() 98{ 99 nsim_hwstats_toggle disable_ifindex "$@" 100} 101 102nsim_hwstats_fail_next_enable() 103{ 104 nsim_hwstats_toggle fail_next_enable "$@" 105} 106 107setup_prepare() 108{ 109 modprobe netdevsim &> /dev/null 110 nsim_add 1 111 nsim_add 2 112 nsim_add 3 113 114 ip netns add testns1 115 116 if [ $? -ne 0 ]; then 117 echo "Failed to add netns \"testns1\"" 118 exit 1 119 fi 120 121 nsim_reload 1 testns1 122 nsim_reload 2 testns1 123 nsim_reload 3 testns1 124 125 IP="ip -n testns1" 126 127 $IP link add name dummy1 type dummy 128 $IP link set dev dummy1 up 129 DUMMY_IFINDEX=$($IP -j link show dev dummy1 | jq '.[].ifindex') 130} 131 132cleanup() 133{ 134 pre_cleanup 135 136 $IP link del name dummy1 137 ip netns del testns1 138 nsim_del 3 139 nsim_del 2 140 nsim_del 1 141 modprobe -r netdevsim &> /dev/null 142} 143 144netdev_hwstats_used() 145{ 146 local netdev=$1; shift 147 local type=$1; shift 148 149 $IP -j stats show dev "$netdev" group offload subgroup hw_stats_info | 150 jq '.[].info.l3_stats.used' 151} 152 153netdev_check_used() 154{ 155 local netdev=$1; shift 156 local type=$1; shift 157 158 [[ $(netdev_hwstats_used $netdev $type) == "true" ]] 159} 160 161netdev_check_unused() 162{ 163 local netdev=$1; shift 164 local type=$1; shift 165 166 [[ $(netdev_hwstats_used $netdev $type) == "false" ]] 167} 168 169netdev_hwstats_request() 170{ 171 local netdev=$1; shift 172 local type=$1; shift 173 174 $IP -j stats show dev "$netdev" group offload subgroup hw_stats_info | 175 jq ".[].info.${type}_stats.request" 176} 177 178netdev_check_requested() 179{ 180 local netdev=$1; shift 181 local type=$1; shift 182 183 [[ $(netdev_hwstats_request $netdev $type) == "true" ]] 184} 185 186netdev_check_unrequested() 187{ 188 local netdev=$1; shift 189 local type=$1; shift 190 191 [[ $(netdev_hwstats_request $netdev $type) == "false" ]] 192} 193 194reporting_test() 195{ 196 local type=$1; shift 197 local instance=1 198 199 RET=0 200 201 [[ -n $(netdev_hwstats_used dummy1 $type) ]] 202 check_err $? "$type stats not reported" 203 204 netdev_check_unused dummy1 $type 205 check_err $? "$type stats reported as used before either device or netdevsim request" 206 207 nsim_hwstats_enable $instance dummy1 $type 208 netdev_check_unused dummy1 $type 209 check_err $? "$type stats reported as used before device request" 210 netdev_check_unrequested dummy1 $type 211 check_err $? "$type stats reported as requested before device request" 212 213 $IP stats set dev dummy1 ${type}_stats on 214 netdev_check_used dummy1 $type 215 check_err $? "$type stats reported as not used after both device and netdevsim request" 216 netdev_check_requested dummy1 $type 217 check_err $? "$type stats reported as not requested after device request" 218 219 nsim_hwstats_disable $instance dummy1 $type 220 netdev_check_unused dummy1 $type 221 check_err $? "$type stats reported as used after netdevsim request withdrawn" 222 223 nsim_hwstats_enable $instance dummy1 $type 224 netdev_check_used dummy1 $type 225 check_err $? "$type stats reported as not used after netdevsim request reenabled" 226 227 $IP stats set dev dummy1 ${type}_stats off 228 netdev_check_unused dummy1 $type 229 check_err $? "$type stats reported as used after device request withdrawn" 230 netdev_check_unrequested dummy1 $type 231 check_err $? "$type stats reported as requested after device request withdrawn" 232 233 nsim_hwstats_disable $instance dummy1 $type 234 netdev_check_unused dummy1 $type 235 check_err $? "$type stats reported as used after both requests withdrawn" 236 237 log_test "Reporting of $type stats usage" 238} 239 240l3_reporting_test() 241{ 242 reporting_test l3 243} 244 245__fail_next_test() 246{ 247 local instance=$1; shift 248 local type=$1; shift 249 250 RET=0 251 252 netdev_check_unused dummy1 $type 253 check_err $? "$type stats reported as used before either device or netdevsim request" 254 255 nsim_hwstats_enable $instance dummy1 $type 256 nsim_hwstats_fail_next_enable $instance dummy1 $type 257 netdev_check_unused dummy1 $type 258 check_err $? "$type stats reported as used before device request" 259 netdev_check_unrequested dummy1 $type 260 check_err $? "$type stats reported as requested before device request" 261 262 $IP stats set dev dummy1 ${type}_stats on 2>/dev/null 263 check_fail $? "$type stats request not bounced as it should have been" 264 netdev_check_unused dummy1 $type 265 check_err $? "$type stats reported as used after bounce" 266 netdev_check_unrequested dummy1 $type 267 check_err $? "$type stats reported as requested after bounce" 268 269 $IP stats set dev dummy1 ${type}_stats on 270 check_err $? "$type stats request failed when it shouldn't have" 271 netdev_check_used dummy1 $type 272 check_err $? "$type stats reported as not used after both device and netdevsim request" 273 netdev_check_requested dummy1 $type 274 check_err $? "$type stats reported as not requested after device request" 275 276 $IP stats set dev dummy1 ${type}_stats off 277 nsim_hwstats_disable $instance dummy1 $type 278 279 log_test "Injected failure of $type stats enablement (netdevsim #$instance)" 280} 281 282fail_next_test() 283{ 284 __fail_next_test 1 "$@" 285 __fail_next_test 2 "$@" 286 __fail_next_test 3 "$@" 287} 288 289l3_fail_next_test() 290{ 291 fail_next_test l3 292} 293 294get_hwstat() 295{ 296 local netdev=$1; shift 297 local type=$1; shift 298 local selector=$1; shift 299 300 $IP -j stats show dev $netdev group offload subgroup ${type}_stats | 301 jq ".[0].stats64.${selector}" 302} 303 304counter_test() 305{ 306 local type=$1; shift 307 local instance=1 308 309 RET=0 310 311 nsim_hwstats_enable $instance dummy1 $type 312 $IP stats set dev dummy1 ${type}_stats on 313 netdev_check_used dummy1 $type 314 check_err $? "$type stats reported as not used after both device and netdevsim request" 315 316 # Netdevsim counts 10pps on ingress. We should see maybe a couple 317 # packets, unless things take a reeealy long time. 318 local pkts=$(get_hwstat dummy1 l3 rx.packets) 319 ((pkts < 10)) 320 check_err $? "$type stats show >= 10 packets after first enablement" 321 322 sleep 2 323 324 local pkts=$(get_hwstat dummy1 l3 rx.packets) 325 ((pkts >= 20)) 326 check_err $? "$type stats show < 20 packets after 2s passed" 327 328 $IP stats set dev dummy1 ${type}_stats off 329 330 sleep 2 331 332 $IP stats set dev dummy1 ${type}_stats on 333 local pkts=$(get_hwstat dummy1 l3 rx.packets) 334 ((pkts < 10)) 335 check_err $? "$type stats show >= 10 packets after second enablement" 336 337 $IP stats set dev dummy1 ${type}_stats off 338 nsim_hwstats_fail_next_enable $instance dummy1 $type 339 $IP stats set dev dummy1 ${type}_stats on 2>/dev/null 340 check_fail $? "$type stats request not bounced as it should have been" 341 342 sleep 2 343 344 $IP stats set dev dummy1 ${type}_stats on 345 local pkts=$(get_hwstat dummy1 l3 rx.packets) 346 ((pkts < 10)) 347 check_err $? "$type stats show >= 10 packets after post-fail enablement" 348 349 $IP stats set dev dummy1 ${type}_stats off 350 351 log_test "Counter values in $type stats" 352} 353 354l3_counter_test() 355{ 356 counter_test l3 357} 358 359rollback_test() 360{ 361 local type=$1; shift 362 363 RET=0 364 365 nsim_hwstats_enable 1 dummy1 l3 366 nsim_hwstats_enable 2 dummy1 l3 367 nsim_hwstats_enable 3 dummy1 l3 368 369 # The three netdevsim instances are registered in order of their number 370 # one after another. It is reasonable to expect that whatever 371 # notifications take place hit no. 2 in between hitting nos. 1 and 3, 372 # whatever the actual order. This allows us to test that a fail caused 373 # by no. 2 does not leave the system in a partial state, and rolls 374 # everything back. 375 376 nsim_hwstats_fail_next_enable 2 dummy1 l3 377 $IP stats set dev dummy1 ${type}_stats on 2>/dev/null 378 check_fail $? "$type stats request not bounced as it should have been" 379 380 netdev_check_unused dummy1 $type 381 check_err $? "$type stats reported as used after bounce" 382 netdev_check_unrequested dummy1 $type 383 check_err $? "$type stats reported as requested after bounce" 384 385 sleep 2 386 387 $IP stats set dev dummy1 ${type}_stats on 388 check_err $? "$type stats request not upheld as it should have been" 389 390 local pkts=$(get_hwstat dummy1 l3 rx.packets) 391 ((pkts < 10)) 392 check_err $? "$type stats show $pkts packets after post-fail enablement" 393 394 $IP stats set dev dummy1 ${type}_stats off 395 396 nsim_hwstats_disable 3 dummy1 l3 397 nsim_hwstats_disable 2 dummy1 l3 398 nsim_hwstats_disable 1 dummy1 l3 399 400 log_test "Failure in $type stats enablement rolled back" 401} 402 403l3_rollback_test() 404{ 405 rollback_test l3 406} 407 408l3_monitor_test() 409{ 410 hw_stats_monitor_test dummy1 l3 \ 411 "nsim_hwstats_enable 1 dummy1 l3" \ 412 "nsim_hwstats_disable 1 dummy1 l3" \ 413 "$IP" 414} 415 416trap cleanup EXIT 417 418setup_prepare 419tests_run 420 421exit $EXIT_STATUS 422