1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# +--------------------+ +----------------------+ 5# | H1 | | H2 | 6# | | | | 7# | $h1.200 + | | + $h2.200 | 8# | 192.0.2.1/28 | | | | 192.0.2.18/28 | 9# | 2001:db8:1::1/64 | | | | 2001:db8:2::1/64 | 10# | | | | | | 11# | $h1 + | | + $h2 | 12# | | | | | | 13# +------------------|-+ +-|--------------------+ 14# | | 15# +------------------|-------------------------|--------------------+ 16# | SW | | | 17# | | | | 18# | $rp1 + + $rp2 | 19# | | | | 20# | $rp1.200 + + $rp2.200 | 21# | 192.0.2.2/28 192.0.2.17/28 | 22# | 2001:db8:1::2/64 2001:db8:2::2/64 | 23# | | 24# +-----------------------------------------------------------------+ 25 26ALL_TESTS=" 27 ping_ipv4 28 ping_ipv6 29 test_stats_rx_ipv4 30 test_stats_tx_ipv4 31 test_stats_rx_ipv6 32 test_stats_tx_ipv6 33 respin_enablement 34 test_stats_rx_ipv4 35 test_stats_tx_ipv4 36 test_stats_rx_ipv6 37 test_stats_tx_ipv6 38 reapply_config 39 ping_ipv4 40 ping_ipv6 41 test_stats_rx_ipv4 42 test_stats_tx_ipv4 43 test_stats_rx_ipv6 44 test_stats_tx_ipv6 45 test_stats_report_rx 46 test_stats_report_tx 47 test_destroy_enabled 48 test_double_enable 49" 50NUM_NETIFS=4 51source lib.sh 52 53h1_create() 54{ 55 simple_if_init $h1 56 vlan_create $h1 200 v$h1 192.0.2.1/28 2001:db8:1::1/64 57 ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 58 ip -6 route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2 59} 60 61h1_destroy() 62{ 63 ip -6 route del 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2 64 ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 65 vlan_destroy $h1 200 66 simple_if_fini $h1 67} 68 69h2_create() 70{ 71 simple_if_init $h2 72 vlan_create $h2 200 v$h2 192.0.2.18/28 2001:db8:2::1/64 73 ip route add 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.17 74 ip -6 route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::2 75} 76 77h2_destroy() 78{ 79 ip -6 route del 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::2 80 ip route del 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.17 81 vlan_destroy $h2 200 82 simple_if_fini $h2 83} 84 85router_rp1_200_create() 86{ 87 ip link add name $rp1.200 link $rp1 type vlan id 200 88 ip link set dev $rp1.200 addrgenmode eui64 89 ip link set dev $rp1.200 up 90 ip address add dev $rp1.200 192.0.2.2/28 91 ip address add dev $rp1.200 2001:db8:1::2/64 92 ip stats set dev $rp1.200 l3_stats on 93} 94 95router_rp1_200_destroy() 96{ 97 ip stats set dev $rp1.200 l3_stats off 98 ip address del dev $rp1.200 2001:db8:1::2/64 99 ip address del dev $rp1.200 192.0.2.2/28 100 ip link del dev $rp1.200 101} 102 103router_create() 104{ 105 ip link set dev $rp1 up 106 router_rp1_200_create 107 108 ip link set dev $rp2 up 109 vlan_create $rp2 200 "" 192.0.2.17/28 2001:db8:2::2/64 110} 111 112router_destroy() 113{ 114 vlan_destroy $rp2 200 115 ip link set dev $rp2 down 116 117 router_rp1_200_destroy 118 ip link set dev $rp1 down 119} 120 121setup_prepare() 122{ 123 h1=${NETIFS[p1]} 124 rp1=${NETIFS[p2]} 125 126 rp2=${NETIFS[p3]} 127 h2=${NETIFS[p4]} 128 129 rp1mac=$(mac_get $rp1) 130 rp2mac=$(mac_get $rp2) 131 132 vrf_prepare 133 134 h1_create 135 h2_create 136 137 router_create 138 139 forwarding_enable 140} 141 142cleanup() 143{ 144 pre_cleanup 145 146 forwarding_restore 147 148 router_destroy 149 150 h2_destroy 151 h1_destroy 152 153 vrf_cleanup 154} 155 156ping_ipv4() 157{ 158 ping_test $h1.200 192.0.2.18 " IPv4" 159} 160 161ping_ipv6() 162{ 163 ping_test $h1.200 2001:db8:2::1 " IPv6" 164} 165 166send_packets_rx_ipv4() 167{ 168 # Send 21 packets instead of 20, because the first one might trap and go 169 # through the SW datapath, which might not bump the HW counter. 170 $MZ $h1.200 -c 21 -d 20msec -p 100 \ 171 -a own -b $rp1mac -A 192.0.2.1 -B 192.0.2.18 \ 172 -q -t udp sp=54321,dp=12345 173} 174 175send_packets_rx_ipv6() 176{ 177 $MZ $h1.200 -6 -c 21 -d 20msec -p 100 \ 178 -a own -b $rp1mac -A 2001:db8:1::1 -B 2001:db8:2::1 \ 179 -q -t udp sp=54321,dp=12345 180} 181 182send_packets_tx_ipv4() 183{ 184 $MZ $h2.200 -c 21 -d 20msec -p 100 \ 185 -a own -b $rp2mac -A 192.0.2.18 -B 192.0.2.1 \ 186 -q -t udp sp=54321,dp=12345 187} 188 189send_packets_tx_ipv6() 190{ 191 $MZ $h2.200 -6 -c 21 -d 20msec -p 100 \ 192 -a own -b $rp2mac -A 2001:db8:2::1 -B 2001:db8:1::1 \ 193 -q -t udp sp=54321,dp=12345 194} 195 196___test_stats() 197{ 198 local dir=$1; shift 199 local prot=$1; shift 200 201 local a 202 local b 203 204 a=$(hw_stats_get l3_stats $rp1.200 ${dir} packets) 205 send_packets_${dir}_${prot} 206 "$@" 207 b=$(busywait "$TC_HIT_TIMEOUT" until_counter_is ">= $a + 20" \ 208 hw_stats_get l3_stats $rp1.200 ${dir} packets) 209 check_err $? "Traffic not reflected in the counter: $a -> $b" 210} 211 212__test_stats() 213{ 214 local dir=$1; shift 215 local prot=$1; shift 216 217 RET=0 218 ___test_stats "$dir" "$prot" 219 log_test "Test $dir packets: $prot" 220} 221 222test_stats_rx_ipv4() 223{ 224 __test_stats rx ipv4 225} 226 227test_stats_tx_ipv4() 228{ 229 __test_stats tx ipv4 230} 231 232test_stats_rx_ipv6() 233{ 234 __test_stats rx ipv6 235} 236 237test_stats_tx_ipv6() 238{ 239 __test_stats tx ipv6 240} 241 242# Make sure everything works well even after stats have been disabled and 243# reenabled on the same device without touching the L3 configuration. 244respin_enablement() 245{ 246 log_info "Turning stats off and on again" 247 ip stats set dev $rp1.200 l3_stats off 248 ip stats set dev $rp1.200 l3_stats on 249} 250 251# For the initial run, l3_stats is enabled on a completely set up netdevice. Now 252# do it the other way around: enabling the L3 stats on an L2 netdevice, and only 253# then apply the L3 configuration. 254reapply_config() 255{ 256 log_info "Reapplying configuration" 257 258 router_rp1_200_destroy 259 260 ip link add name $rp1.200 link $rp1 type vlan id 200 261 ip link set dev $rp1.200 addrgenmode none 262 ip stats set dev $rp1.200 l3_stats on 263 ip link set dev $rp1.200 addrgenmode eui64 264 ip link set dev $rp1.200 up 265 ip address add dev $rp1.200 192.0.2.2/28 266 ip address add dev $rp1.200 2001:db8:1::2/64 267} 268 269__test_stats_report() 270{ 271 local dir=$1; shift 272 local prot=$1; shift 273 274 local a 275 local b 276 277 RET=0 278 279 a=$(hw_stats_get l3_stats $rp1.200 ${dir} packets) 280 send_packets_${dir}_${prot} 281 ip address flush dev $rp1.200 282 b=$(busywait "$TC_HIT_TIMEOUT" until_counter_is ">= $a + 20" \ 283 hw_stats_get l3_stats $rp1.200 ${dir} packets) 284 check_err $? "Traffic not reflected in the counter: $a -> $b" 285 log_test "Test ${dir} packets: stats pushed on loss of L3" 286 287 ip stats set dev $rp1.200 l3_stats off 288 ip link del dev $rp1.200 289 router_rp1_200_create 290} 291 292test_stats_report_rx() 293{ 294 __test_stats_report rx ipv4 295} 296 297test_stats_report_tx() 298{ 299 __test_stats_report tx ipv4 300} 301 302test_destroy_enabled() 303{ 304 RET=0 305 306 ip link del dev $rp1.200 307 router_rp1_200_create 308 309 log_test "Destroy l3_stats-enabled netdev" 310} 311 312test_double_enable() 313{ 314 RET=0 315 ___test_stats rx ipv4 \ 316 ip stats set dev $rp1.200 l3_stats on 317 log_test "Test stat retention across a spurious enablement" 318} 319 320trap cleanup EXIT 321 322setup_prepare 323setup_wait 324 325used=$(ip -j stats show dev $rp1.200 group offload subgroup hw_stats_info | 326 jq '.[].info.l3_stats.used') 327kind=$(ip -j -d link show dev $rp1 | 328 jq -r '.[].linkinfo.info_kind') 329if [[ $used != true ]]; then 330 if [[ $kind == veth ]]; then 331 log_test_skip "l3_stats not offloaded on veth interface" 332 EXIT_STATUS=$ksft_skip 333 else 334 RET=1 log_test "l3_stats not offloaded" 335 fi 336else 337 tests_run 338fi 339 340exit $EXIT_STATUS 341