Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: netdevsim: hw_stats_l3: Add a new test

Add a test that verifies basic UAPI contracts, netdevsim operation,
rollbacks after partial enablement in core, and UAPI notifications.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Petr Machata and committed by
Paolo Abeni
9b18942e 1a6d7ae7

+481
+421
tools/testing/selftests/drivers/net/netdevsim/hw_stats_l3.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + lib_dir=$(dirname $0)/../../../net/forwarding 5 + 6 + ALL_TESTS=" 7 + l3_reporting_test 8 + l3_fail_next_test 9 + l3_counter_test 10 + l3_rollback_test 11 + l3_monitor_test 12 + " 13 + 14 + NETDEVSIM_PATH=/sys/bus/netdevsim/ 15 + DEV_ADDR_1=1337 16 + DEV_ADDR_2=1057 17 + DEV_ADDR_3=5417 18 + NUM_NETIFS=0 19 + source $lib_dir/lib.sh 20 + 21 + DUMMY_IFINDEX= 22 + 23 + DEV_ADDR() 24 + { 25 + local n=$1; shift 26 + local var=DEV_ADDR_$n 27 + 28 + echo ${!var} 29 + } 30 + 31 + DEV() 32 + { 33 + echo netdevsim$(DEV_ADDR $1) 34 + } 35 + 36 + DEVLINK_DEV() 37 + { 38 + echo netdevsim/$(DEV $1) 39 + } 40 + 41 + SYSFS_NET_DIR() 42 + { 43 + echo /sys/bus/netdevsim/devices/$(DEV $1)/net/ 44 + } 45 + 46 + DEBUGFS_DIR() 47 + { 48 + echo /sys/kernel/debug/netdevsim/$(DEV $1)/ 49 + } 50 + 51 + nsim_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 + 59 + nsim_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 + 73 + nsim_del() 74 + { 75 + local n=$1; shift 76 + 77 + echo "$(DEV_ADDR $n)" > ${NETDEVSIM_PATH}/del_device 78 + } 79 + 80 + nsim_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 + 92 + nsim_hwstats_enable() 93 + { 94 + nsim_hwstats_toggle enable_ifindex "$@" 95 + } 96 + 97 + nsim_hwstats_disable() 98 + { 99 + nsim_hwstats_toggle disable_ifindex "$@" 100 + } 101 + 102 + nsim_hwstats_fail_next_enable() 103 + { 104 + nsim_hwstats_toggle fail_next_enable "$@" 105 + } 106 + 107 + setup_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 + 132 + cleanup() 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 + 144 + netdev_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 + 153 + netdev_check_used() 154 + { 155 + local netdev=$1; shift 156 + local type=$1; shift 157 + 158 + [[ $(netdev_hwstats_used $netdev $type) == "true" ]] 159 + } 160 + 161 + netdev_check_unused() 162 + { 163 + local netdev=$1; shift 164 + local type=$1; shift 165 + 166 + [[ $(netdev_hwstats_used $netdev $type) == "false" ]] 167 + } 168 + 169 + netdev_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 + 178 + netdev_check_requested() 179 + { 180 + local netdev=$1; shift 181 + local type=$1; shift 182 + 183 + [[ $(netdev_hwstats_request $netdev $type) == "true" ]] 184 + } 185 + 186 + netdev_check_unrequested() 187 + { 188 + local netdev=$1; shift 189 + local type=$1; shift 190 + 191 + [[ $(netdev_hwstats_request $netdev $type) == "false" ]] 192 + } 193 + 194 + reporting_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 + 240 + l3_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 + 282 + fail_next_test() 283 + { 284 + __fail_next_test 1 "$@" 285 + __fail_next_test 2 "$@" 286 + __fail_next_test 3 "$@" 287 + } 288 + 289 + l3_fail_next_test() 290 + { 291 + fail_next_test l3 292 + } 293 + 294 + get_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 + 304 + counter_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 + 354 + l3_counter_test() 355 + { 356 + counter_test l3 357 + } 358 + 359 + rollback_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 + 403 + l3_rollback_test() 404 + { 405 + rollback_test l3 406 + } 407 + 408 + l3_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 + 416 + trap cleanup EXIT 417 + 418 + setup_prepare 419 + tests_run 420 + 421 + exit $EXIT_STATUS
+60
tools/testing/selftests/net/forwarding/lib.sh
··· 1498 1498 check_err_fail $should_fail $? "Entry $src has blocked flag" 1499 1499 done 1500 1500 } 1501 + 1502 + start_ip_monitor() 1503 + { 1504 + local mtype=$1; shift 1505 + local ip=${1-ip}; shift 1506 + 1507 + # start the monitor in the background 1508 + tmpfile=`mktemp /var/run/nexthoptestXXX` 1509 + mpid=`($ip monitor $mtype > $tmpfile & echo $!) 2>/dev/null` 1510 + sleep 0.2 1511 + echo "$mpid $tmpfile" 1512 + } 1513 + 1514 + stop_ip_monitor() 1515 + { 1516 + local mpid=$1; shift 1517 + local tmpfile=$1; shift 1518 + local el=$1; shift 1519 + local what=$1; shift 1520 + 1521 + sleep 0.2 1522 + kill $mpid 1523 + local lines=`grep '^\w' $tmpfile | wc -l` 1524 + test $lines -eq $el 1525 + check_err $? "$what: $lines lines of events, expected $el" 1526 + rm -rf $tmpfile 1527 + } 1528 + 1529 + hw_stats_monitor_test() 1530 + { 1531 + local dev=$1; shift 1532 + local type=$1; shift 1533 + local make_suitable=$1; shift 1534 + local make_unsuitable=$1; shift 1535 + local ip=${1-ip}; shift 1536 + 1537 + RET=0 1538 + 1539 + # Expect a notification about enablement. 1540 + local ipmout=$(start_ip_monitor stats "$ip") 1541 + $ip stats set dev $dev ${type}_stats on 1542 + stop_ip_monitor $ipmout 1 "${type}_stats enablement" 1543 + 1544 + # Expect a notification about offload. 1545 + local ipmout=$(start_ip_monitor stats "$ip") 1546 + $make_suitable 1547 + stop_ip_monitor $ipmout 1 "${type}_stats installation" 1548 + 1549 + # Expect a notification about loss of offload. 1550 + local ipmout=$(start_ip_monitor stats "$ip") 1551 + $make_unsuitable 1552 + stop_ip_monitor $ipmout 1 "${type}_stats deinstallation" 1553 + 1554 + # Expect a notification about disablement 1555 + local ipmout=$(start_ip_monitor stats "$ip") 1556 + $ip stats set dev $dev ${type}_stats off 1557 + stop_ip_monitor $ipmout 1 "${type}_stats disablement" 1558 + 1559 + log_test "${type}_stats notifications" 1560 + }