| #!/bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| |
| # +--------------------+ +----------------------+ |
| # | H1 | | H2 | |
| # | | | | |
| # | $h1.200 + | | + $h2.200 | |
| # | 192.0.2.1/28 | | | | 192.0.2.18/28 | |
| # | 2001:db8:1::1/64 | | | | 2001:db8:2::1/64 | |
| # | | | | | | |
| # | $h1 + | | + $h2 | |
| # | | | | | | |
| # +------------------|-+ +-|--------------------+ |
| # | | |
| # +------------------|-------------------------|--------------------+ |
| # | SW | | | |
| # | | | | |
| # | $rp1 + + $rp2 | |
| # | | | | |
| # | $rp1.200 + + $rp2.200 | |
| # | 192.0.2.2/28 192.0.2.17/28 | |
| # | 2001:db8:1::2/64 2001:db8:2::2/64 | |
| # | | |
| # +-----------------------------------------------------------------+ |
| |
| ALL_TESTS=" |
| ping_ipv4 |
| ping_ipv6 |
| test_stats_rx_ipv4 |
| test_stats_tx_ipv4 |
| test_stats_rx_ipv6 |
| test_stats_tx_ipv6 |
| respin_enablement |
| test_stats_rx_ipv4 |
| test_stats_tx_ipv4 |
| test_stats_rx_ipv6 |
| test_stats_tx_ipv6 |
| reapply_config |
| ping_ipv4 |
| ping_ipv6 |
| test_stats_rx_ipv4 |
| test_stats_tx_ipv4 |
| test_stats_rx_ipv6 |
| test_stats_tx_ipv6 |
| test_stats_report_rx |
| test_stats_report_tx |
| test_destroy_enabled |
| test_double_enable |
| " |
| NUM_NETIFS=4 |
| lib_dir=$(dirname "$0") |
| source "$lib_dir"/../../../net/forwarding/lib.sh |
| source "$lib_dir"/../../../net/forwarding/tc_common.sh |
| |
| h1_create() |
| { |
| simple_if_init $h1 |
| vlan_create $h1 200 v$h1 192.0.2.1/28 2001:db8:1::1/64 |
| ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 |
| ip -6 route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2 |
| } |
| |
| h1_destroy() |
| { |
| ip -6 route del 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2 |
| ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 |
| vlan_destroy $h1 200 |
| simple_if_fini $h1 |
| } |
| |
| h2_create() |
| { |
| simple_if_init $h2 |
| vlan_create $h2 200 v$h2 192.0.2.18/28 2001:db8:2::1/64 |
| ip route add 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.17 |
| ip -6 route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::2 |
| } |
| |
| h2_destroy() |
| { |
| ip -6 route del 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::2 |
| ip route del 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.17 |
| vlan_destroy $h2 200 |
| simple_if_fini $h2 |
| } |
| |
| router_rp1_200_create() |
| { |
| ip link add name $rp1.200 link $rp1 type vlan id 200 |
| ip link set dev $rp1.200 addrgenmode eui64 |
| ip link set dev $rp1.200 up |
| ip address add dev $rp1.200 192.0.2.2/28 |
| ip address add dev $rp1.200 2001:db8:1::2/64 |
| ip stats set dev $rp1.200 l3_stats on |
| } |
| |
| router_rp1_200_destroy() |
| { |
| ip stats set dev $rp1.200 l3_stats off |
| ip address del dev $rp1.200 2001:db8:1::2/64 |
| ip address del dev $rp1.200 192.0.2.2/28 |
| ip link del dev $rp1.200 |
| } |
| |
| router_create() |
| { |
| ip link set dev $rp1 up |
| router_rp1_200_create |
| |
| ip link set dev $rp2 up |
| vlan_create $rp2 200 "" 192.0.2.17/28 2001:db8:2::2/64 |
| } |
| |
| router_destroy() |
| { |
| vlan_destroy $rp2 200 |
| ip link set dev $rp2 down |
| |
| router_rp1_200_destroy |
| ip link set dev $rp1 down |
| } |
| |
| setup_prepare() |
| { |
| h1=${NETIFS[p1]} |
| rp1=${NETIFS[p2]} |
| |
| rp2=${NETIFS[p3]} |
| h2=${NETIFS[p4]} |
| |
| rp1mac=$(mac_get $rp1) |
| rp2mac=$(mac_get $rp2) |
| |
| vrf_prepare |
| |
| h1_create |
| h2_create |
| |
| router_create |
| |
| forwarding_enable |
| } |
| |
| cleanup() |
| { |
| pre_cleanup |
| |
| forwarding_restore |
| |
| router_destroy |
| |
| h2_destroy |
| h1_destroy |
| |
| vrf_cleanup |
| } |
| |
| ping_ipv4() |
| { |
| ping_test $h1.200 192.0.2.18 " IPv4" |
| } |
| |
| ping_ipv6() |
| { |
| ping_test $h1.200 2001:db8:2::1 " IPv6" |
| } |
| |
| send_packets_rx_ipv4() |
| { |
| # Send 21 packets instead of 20, because the first one might trap and go |
| # through the SW datapath, which might not bump the HW counter. |
| $MZ $h1.200 -c 21 -d 20msec -p 100 \ |
| -a own -b $rp1mac -A 192.0.2.1 -B 192.0.2.18 \ |
| -q -t udp sp=54321,dp=12345 |
| } |
| |
| send_packets_rx_ipv6() |
| { |
| $MZ $h1.200 -6 -c 21 -d 20msec -p 100 \ |
| -a own -b $rp1mac -A 2001:db8:1::1 -B 2001:db8:2::1 \ |
| -q -t udp sp=54321,dp=12345 |
| } |
| |
| send_packets_tx_ipv4() |
| { |
| $MZ $h2.200 -c 21 -d 20msec -p 100 \ |
| -a own -b $rp2mac -A 192.0.2.18 -B 192.0.2.1 \ |
| -q -t udp sp=54321,dp=12345 |
| } |
| |
| send_packets_tx_ipv6() |
| { |
| $MZ $h2.200 -6 -c 21 -d 20msec -p 100 \ |
| -a own -b $rp2mac -A 2001:db8:2::1 -B 2001:db8:1::1 \ |
| -q -t udp sp=54321,dp=12345 |
| } |
| |
| ___test_stats() |
| { |
| local dir=$1; shift |
| local prot=$1; shift |
| |
| local a |
| local b |
| |
| a=$(hw_stats_get l3_stats $rp1.200 ${dir} packets) |
| send_packets_${dir}_${prot} |
| "$@" |
| b=$(busywait "$TC_HIT_TIMEOUT" until_counter_is ">= $a + 20" \ |
| hw_stats_get l3_stats $rp1.200 ${dir} packets) |
| check_err $? "Traffic not reflected in the counter: $a -> $b" |
| } |
| |
| __test_stats() |
| { |
| local dir=$1; shift |
| local prot=$1; shift |
| |
| RET=0 |
| ___test_stats "$dir" "$prot" |
| log_test "Test $dir packets: $prot" |
| } |
| |
| test_stats_rx_ipv4() |
| { |
| __test_stats rx ipv4 |
| } |
| |
| test_stats_tx_ipv4() |
| { |
| __test_stats tx ipv4 |
| } |
| |
| test_stats_rx_ipv6() |
| { |
| __test_stats rx ipv6 |
| } |
| |
| test_stats_tx_ipv6() |
| { |
| __test_stats tx ipv6 |
| } |
| |
| # Make sure everything works well even after stats have been disabled and |
| # reenabled on the same device without touching the L3 configuration. |
| respin_enablement() |
| { |
| log_info "Turning stats off and on again" |
| ip stats set dev $rp1.200 l3_stats off |
| ip stats set dev $rp1.200 l3_stats on |
| } |
| |
| # For the initial run, l3_stats is enabled on a completely set up netdevice. Now |
| # do it the other way around: enabling the L3 stats on an L2 netdevice, and only |
| # then apply the L3 configuration. |
| reapply_config() |
| { |
| log_info "Reapplying configuration" |
| |
| router_rp1_200_destroy |
| |
| ip link add name $rp1.200 link $rp1 type vlan id 200 |
| ip link set dev $rp1.200 addrgenmode none |
| ip stats set dev $rp1.200 l3_stats on |
| ip link set dev $rp1.200 addrgenmode eui64 |
| ip link set dev $rp1.200 up |
| ip address add dev $rp1.200 192.0.2.2/28 |
| ip address add dev $rp1.200 2001:db8:1::2/64 |
| } |
| |
| __test_stats_report() |
| { |
| local dir=$1; shift |
| local prot=$1; shift |
| |
| local a |
| local b |
| |
| RET=0 |
| |
| a=$(hw_stats_get l3_stats $rp1.200 ${dir} packets) |
| send_packets_${dir}_${prot} |
| ip address flush dev $rp1.200 |
| b=$(busywait "$TC_HIT_TIMEOUT" until_counter_is ">= $a + 20" \ |
| hw_stats_get l3_stats $rp1.200 ${dir} packets) |
| check_err $? "Traffic not reflected in the counter: $a -> $b" |
| log_test "Test ${dir} packets: stats pushed on loss of L3" |
| |
| ip stats set dev $rp1.200 l3_stats off |
| ip link del dev $rp1.200 |
| router_rp1_200_create |
| } |
| |
| test_stats_report_rx() |
| { |
| __test_stats_report rx ipv4 |
| } |
| |
| test_stats_report_tx() |
| { |
| __test_stats_report tx ipv4 |
| } |
| |
| test_destroy_enabled() |
| { |
| RET=0 |
| |
| ip link del dev $rp1.200 |
| router_rp1_200_create |
| |
| log_test "Destroy l3_stats-enabled netdev" |
| } |
| |
| test_double_enable() |
| { |
| RET=0 |
| ___test_stats rx ipv4 \ |
| ip stats set dev $rp1.200 l3_stats on |
| log_test "Test stat retention across a spurious enablement" |
| } |
| |
| trap cleanup EXIT |
| |
| setup_prepare |
| setup_wait |
| |
| used=$(ip -j stats show dev $rp1.200 group offload subgroup hw_stats_info | |
| jq '.[].info.l3_stats.used') |
| [[ $used = true ]] |
| check_err $? "hw_stats_info.used=$used" |
| log_test "l3_stats offloaded" |
| tests_run |
| |
| exit $EXIT_STATUS |