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