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