Merge branch 'selftests-updates-for-mlxsw-driver-test'
Jiri Pirko says: ==================== selftests: updates for mlxsw driver test This patchset contains tweaks to the existing tests and is also adding couple of new ones, namely tests for shared buffer and red offload. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
22339f2f30
|
@ -45,6 +45,7 @@ ALL_TESTS="
|
|||
blackhole_ipv6
|
||||
"
|
||||
NUM_NETIFS=4
|
||||
: ${TIMEOUT:=20000} # ms
|
||||
source $lib_dir/tc_common.sh
|
||||
source $lib_dir/lib.sh
|
||||
|
||||
|
@ -123,7 +124,7 @@ blackhole_ipv4()
|
|||
skip_hw dst_ip 198.51.100.1 src_ip 192.0.2.1 ip_proto icmp \
|
||||
action pass
|
||||
|
||||
ip -4 route show 198.51.100.0/30 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload ip -4 route show 198.51.100.0/30
|
||||
check_err $? "route not marked as offloaded when should"
|
||||
|
||||
ping_do $h1 198.51.100.1
|
||||
|
@ -147,7 +148,7 @@ blackhole_ipv6()
|
|||
skip_hw dst_ip 2001:db8:2::1 src_ip 2001:db8:1::1 \
|
||||
ip_proto icmpv6 action pass
|
||||
|
||||
ip -6 route show 2001:db8:2::/120 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload ip -6 route show 2001:db8:2::/120
|
||||
check_err $? "route not marked as offloaded when should"
|
||||
|
||||
ping6_do $h1 2001:db8:2::1
|
||||
|
|
|
@ -641,13 +641,9 @@ erif_disabled_test()
|
|||
mz_pid=$!
|
||||
|
||||
sleep 5
|
||||
# In order to see this trap we need a route that points to disabled RIF.
|
||||
# When ipv6 address is flushed, there is a delay and the routes are
|
||||
# deleted before the RIF and we cannot get state that we have route
|
||||
# to disabled RIF.
|
||||
# Delete IPv6 address first and then check this trap with flushing IPv4.
|
||||
ip -6 add flush dev br0
|
||||
ip -4 add flush dev br0
|
||||
# Unlinking the port from the bridge will disable the RIF associated
|
||||
# with br0 as it is no longer an upper of any mlxsw port.
|
||||
ip link set dev $rp1 nomaster
|
||||
|
||||
t1_packets=$(devlink_trap_rx_packets_get $trap_name)
|
||||
t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
|
||||
|
@ -659,7 +655,6 @@ erif_disabled_test()
|
|||
log_test "Egress RIF disabled"
|
||||
|
||||
kill $mz_pid && wait $mz_pid &> /dev/null
|
||||
ip link set dev $rp1 nomaster
|
||||
__addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
|
||||
ip link del dev br0 type bridge
|
||||
devlink_trap_action_set $trap_name "drop"
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
##############################################################################
|
||||
# Defines
|
||||
|
||||
if [[ ! -v MLXSW_CHIP ]]; then
|
||||
MLXSW_CHIP=$(devlink -j dev info $DEVLINK_DEV | jq -r '.[][]["driver"]')
|
||||
if [ -z "$MLXSW_CHIP" ]; then
|
||||
echo "SKIP: Device $DEVLINK_DEV doesn't support devlink info command"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
|
@ -2,16 +2,15 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ROUTER_NUM_NETIFS=4
|
||||
: ${TIMEOUT:=20000} # ms
|
||||
|
||||
router_h1_create()
|
||||
{
|
||||
simple_if_init $h1 192.0.1.1/24
|
||||
ip route add 193.0.0.0/8 via 192.0.1.2 dev $h1
|
||||
}
|
||||
|
||||
router_h1_destroy()
|
||||
{
|
||||
ip route del 193.0.0.0/8 via 192.0.1.2 dev $h1
|
||||
simple_if_fini $h1 192.0.1.1/24
|
||||
}
|
||||
|
||||
|
@ -64,13 +63,15 @@ router_setup_prepare()
|
|||
router_create
|
||||
}
|
||||
|
||||
router_offload_validate()
|
||||
wait_for_routes()
|
||||
{
|
||||
local route_count=$1
|
||||
local offloaded_count
|
||||
local t0=$1; shift
|
||||
local route_count=$1; shift
|
||||
|
||||
offloaded_count=$(ip route | grep -o 'offload' | wc -l)
|
||||
[[ $offloaded_count -ge $route_count ]]
|
||||
local t1=$(ip route | grep -o 'offload' | wc -l)
|
||||
local delta=$((t1 - t0))
|
||||
echo $delta
|
||||
[[ $delta -ge $route_count ]]
|
||||
}
|
||||
|
||||
router_routes_create()
|
||||
|
@ -90,8 +91,8 @@ router_routes_create()
|
|||
break 3
|
||||
fi
|
||||
|
||||
echo route add 193.${i}.${j}.${k}/32 via \
|
||||
192.0.2.1 dev $rp2 >> $ROUTE_FILE
|
||||
echo route add 193.${i}.${j}.${k}/32 dev $rp2 \
|
||||
>> $ROUTE_FILE
|
||||
((count++))
|
||||
done
|
||||
done
|
||||
|
@ -111,45 +112,19 @@ router_test()
|
|||
{
|
||||
local route_count=$1
|
||||
local should_fail=$2
|
||||
local count=0
|
||||
local delta
|
||||
|
||||
RET=0
|
||||
|
||||
local t0=$(ip route | grep -o 'offload' | wc -l)
|
||||
router_routes_create $route_count
|
||||
delta=$(busywait "$TIMEOUT" wait_for_routes $t0 $route_count)
|
||||
|
||||
router_offload_validate $route_count
|
||||
check_err_fail $should_fail $? "Offload of $route_count routes"
|
||||
check_err_fail $should_fail $? "Offload routes: Expected $route_count, got $delta."
|
||||
if [[ $RET -ne 0 ]] || [[ $should_fail -eq 1 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
tc filter add dev $h2 ingress protocol ip pref 1 flower \
|
||||
skip_sw dst_ip 193.0.0.0/8 action drop
|
||||
|
||||
for i in {0..255}
|
||||
do
|
||||
for j in {0..255}
|
||||
do
|
||||
for k in {0..255}
|
||||
do
|
||||
if [[ $count -eq $route_count ]]; then
|
||||
break 3
|
||||
fi
|
||||
|
||||
$MZ $h1 -c 1 -p 64 -a $h1mac -b $rp1mac \
|
||||
-A 192.0.1.1 -B 193.${i}.${j}.${k} \
|
||||
-t ip -q
|
||||
((count++))
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
tc_check_packets "dev $h2 ingress" 1 $route_count
|
||||
check_err $? "Offload mismatch"
|
||||
|
||||
tc filter del dev $h2 ingress protocol ip pref 1 flower \
|
||||
skip_sw dst_ip 193.0.0.0/8 action drop
|
||||
|
||||
router_routes_destroy
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ ALL_TESTS="
|
|||
devlink_reload_test
|
||||
"
|
||||
NUM_NETIFS=2
|
||||
: ${TIMEOUT:=20000} # ms
|
||||
source $lib_dir/lib.sh
|
||||
source $lib_dir/devlink_lib.sh
|
||||
|
||||
|
@ -360,20 +361,24 @@ vlan_rif_refcount_test()
|
|||
ip link add link br0 name br0.10 up type vlan id 10
|
||||
ip -6 address add 2001:db8:1::1/64 dev br0.10
|
||||
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10
|
||||
check_err $? "vlan rif was not created before adding port to vlan"
|
||||
|
||||
bridge vlan add vid 10 dev $swp1
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10
|
||||
check_err $? "vlan rif was destroyed after adding port to vlan"
|
||||
|
||||
bridge vlan del vid 10 dev $swp1
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10
|
||||
check_err $? "vlan rif was destroyed after removing port from vlan"
|
||||
|
||||
ip link set dev $swp1 nomaster
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
|
||||
check_fail $? "vlan rif was not destroyed after unlinking port from bridge"
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev br0.10
|
||||
check_err $? "vlan rif was not destroyed after unlinking port from bridge"
|
||||
|
||||
log_test "vlan rif refcount"
|
||||
|
||||
|
@ -401,22 +406,28 @@ subport_rif_refcount_test()
|
|||
ip -6 address add 2001:db8:1::1/64 dev bond1
|
||||
ip -6 address add 2001:db8:2::1/64 dev bond1.10
|
||||
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev bond1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev bond1
|
||||
check_err $? "subport rif was not created on lag device"
|
||||
ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10
|
||||
check_err $? "subport rif was not created on vlan device"
|
||||
|
||||
ip link set dev $swp1 nomaster
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev bond1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev bond1
|
||||
check_err $? "subport rif of lag device was destroyed when should not"
|
||||
ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10
|
||||
check_err $? "subport rif of vlan device was destroyed when should not"
|
||||
|
||||
ip link set dev $swp2 nomaster
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev bond1 | grep -q offload
|
||||
check_fail $? "subport rif of lag device was not destroyed when should"
|
||||
ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10 | grep -q offload
|
||||
check_fail $? "subport rif of vlan device was not destroyed when should"
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:1::2 dev bond1
|
||||
check_err $? "subport rif of lag device was not destroyed when should"
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10
|
||||
check_err $? "subport rif of vlan device was not destroyed when should"
|
||||
|
||||
log_test "subport rif refcount"
|
||||
|
||||
|
@ -575,7 +586,8 @@ bridge_extern_learn_test()
|
|||
|
||||
bridge fdb add de:ad:be:ef:13:37 dev $swp1 master extern_learn
|
||||
|
||||
bridge fdb show brport $swp1 | grep de:ad:be:ef:13:37 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
bridge fdb show brport $swp1 de:ad:be:ef:13:37
|
||||
check_err $? "fdb entry not marked as offloaded when should"
|
||||
|
||||
log_test "externally learned fdb entry"
|
||||
|
@ -595,9 +607,11 @@ neigh_offload_test()
|
|||
ip -6 neigh add 2001:db8:1::2 lladdr de:ad:be:ef:13:37 nud perm \
|
||||
dev $swp1
|
||||
|
||||
ip -4 neigh show dev $swp1 | grep 192.0.2.2 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -4 neigh show dev $swp1 192.0.2.2
|
||||
check_err $? "ipv4 neigh entry not marked as offloaded when should"
|
||||
ip -6 neigh show dev $swp1 | grep 2001:db8:1::2 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 neigh show dev $swp1 2001:db8:1::2
|
||||
check_err $? "ipv6 neigh entry not marked as offloaded when should"
|
||||
|
||||
log_test "neighbour offload indication"
|
||||
|
@ -623,25 +637,31 @@ nexthop_offload_test()
|
|||
ip -6 route add 2001:db8:2::/64 vrf v$swp1 \
|
||||
nexthop via 2001:db8:1::2 dev $swp1
|
||||
|
||||
ip -4 route show 198.51.100.0/24 vrf v$swp1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -4 route show 198.51.100.0/24 vrf v$swp1
|
||||
check_err $? "ipv4 nexthop not marked as offloaded when should"
|
||||
ip -6 route show 2001:db8:2::/64 vrf v$swp1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route show 2001:db8:2::/64 vrf v$swp1
|
||||
check_err $? "ipv6 nexthop not marked as offloaded when should"
|
||||
|
||||
ip link set dev $swp2 down
|
||||
sleep 1
|
||||
|
||||
ip -4 route show 198.51.100.0/24 vrf v$swp1 | grep -q offload
|
||||
check_fail $? "ipv4 nexthop marked as offloaded when should not"
|
||||
ip -6 route show 2001:db8:2::/64 vrf v$swp1 | grep -q offload
|
||||
check_fail $? "ipv6 nexthop marked as offloaded when should not"
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip -4 route show 198.51.100.0/24 vrf v$swp1
|
||||
check_err $? "ipv4 nexthop marked as offloaded when should not"
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip -6 route show 2001:db8:2::/64 vrf v$swp1
|
||||
check_err $? "ipv6 nexthop marked as offloaded when should not"
|
||||
|
||||
ip link set dev $swp2 up
|
||||
setup_wait
|
||||
|
||||
ip -4 route show 198.51.100.0/24 vrf v$swp1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -4 route show 198.51.100.0/24 vrf v$swp1
|
||||
check_err $? "ipv4 nexthop not marked as offloaded after neigh add"
|
||||
ip -6 route show 2001:db8:2::/64 vrf v$swp1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip -6 route show 2001:db8:2::/64 vrf v$swp1
|
||||
check_err $? "ipv6 nexthop not marked as offloaded after neigh add"
|
||||
|
||||
log_test "nexthop offload indication"
|
||||
|
|
|
@ -0,0 +1,499 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# This test sends a >1Gbps stream of traffic from H1, to the switch, which
|
||||
# forwards it to a 1Gbps port. This 1Gbps stream is then looped back to the
|
||||
# switch and forwarded to the port under test $swp3, which is also 1Gbps.
|
||||
#
|
||||
# This way, $swp3 should be 100% filled with traffic without any of it spilling
|
||||
# to the backlog. Any extra packets sent should almost 1:1 go to backlog. That
|
||||
# is what H2 is used for--it sends the extra traffic to create backlog.
|
||||
#
|
||||
# A RED Qdisc is installed on $swp3. The configuration is such that the minimum
|
||||
# and maximum size are 1 byte apart, so there is a very clear border under which
|
||||
# no marking or dropping takes place, and above which everything is marked or
|
||||
# dropped.
|
||||
#
|
||||
# The test uses the buffer build-up behavior to test the installed RED.
|
||||
#
|
||||
# In order to test WRED, $swp3 actually contains RED under PRIO, with two
|
||||
# different configurations. Traffic is prioritized using 802.1p and relies on
|
||||
# the implicit mlxsw configuration, where packet priority is taken 1:1 from the
|
||||
# 802.1p marking.
|
||||
#
|
||||
# +--------------------------+ +--------------------------+
|
||||
# | H1 | | H2 |
|
||||
# | + $h1.10 | | + $h2.10 |
|
||||
# | | 192.0.2.1/28 | | | 192.0.2.2/28 |
|
||||
# | | | | | |
|
||||
# | | $h1.11 + | | | $h2.11 + |
|
||||
# | | 192.0.2.17/28 | | | | 192.0.2.18/28 | |
|
||||
# | | | | | | | |
|
||||
# | \______ ______/ | | \______ ______/ |
|
||||
# | \ / | | \ / |
|
||||
# | + $h1 | | + $h2 |
|
||||
# +-------------|------------+ +-------------|------------+
|
||||
# | >1Gbps |
|
||||
# +-------------|------------------------------------------------|------------+
|
||||
# | SW + $swp1 + $swp2 |
|
||||
# | _______/ \___________ ___________/ \_______ |
|
||||
# | / \ / \ |
|
||||
# | +-|-----------------+ | +-|-----------------+ | |
|
||||
# | | + $swp1.10 | | | + $swp2.10 | | |
|
||||
# | | | | .-------------+ $swp5.10 | | |
|
||||
# | | BR1_10 | | | | | | |
|
||||
# | | | | | | BR2_10 | | |
|
||||
# | | + $swp2.10 | | | | | | |
|
||||
# | +-|-----------------+ | | | + $swp3.10 | | |
|
||||
# | | | | +-|-----------------+ | |
|
||||
# | | +-----------------|-+ | | +-----------------|-+ |
|
||||
# | | | $swp1.11 + | | | | $swp2.11 + | |
|
||||
# | | | | | .-----------------+ $swp5.11 | |
|
||||
# | | | BR1_11 | | | | | | |
|
||||
# | | | | | | | | BR2_11 | |
|
||||
# | | | $swp2.11 + | | | | | | |
|
||||
# | | +-----------------|-+ | | | | $swp3.11 + | |
|
||||
# | | | | | | +-----------------|-+ |
|
||||
# | \_______ ___________/ | | \___________ _______/ |
|
||||
# | \ / \ / \ / |
|
||||
# | + $swp4 + $swp5 + $swp3 |
|
||||
# +-------------|----------------------|-------------------------|------------+
|
||||
# | | | 1Gbps
|
||||
# \________1Gbps_________/ |
|
||||
# +----------------------------|------------+
|
||||
# | H3 + $h3 |
|
||||
# | _____________________/ \_______ |
|
||||
# | / \ |
|
||||
# | | | |
|
||||
# | + $h3.10 $h3.11 + |
|
||||
# | 192.0.2.3/28 192.0.2.19/28 |
|
||||
# +-----------------------------------------+
|
||||
|
||||
NUM_NETIFS=8
|
||||
CHECK_TC="yes"
|
||||
lib_dir=$(dirname $0)/../../../net/forwarding
|
||||
source $lib_dir/lib.sh
|
||||
source $lib_dir/devlink_lib.sh
|
||||
source qos_lib.sh
|
||||
|
||||
ipaddr()
|
||||
{
|
||||
local host=$1; shift
|
||||
local vlan=$1; shift
|
||||
|
||||
echo 192.0.2.$((16 * (vlan - 10) + host))
|
||||
}
|
||||
|
||||
host_create()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local host=$1; shift
|
||||
|
||||
simple_if_init $dev
|
||||
mtu_set $dev 10000
|
||||
|
||||
vlan_create $dev 10 v$dev $(ipaddr $host 10)/28
|
||||
ip link set dev $dev.10 type vlan egress 0:0
|
||||
|
||||
vlan_create $dev 11 v$dev $(ipaddr $host 11)/28
|
||||
ip link set dev $dev.11 type vlan egress 0:1
|
||||
}
|
||||
|
||||
host_destroy()
|
||||
{
|
||||
local dev=$1; shift
|
||||
|
||||
vlan_destroy $dev 11
|
||||
vlan_destroy $dev 10
|
||||
mtu_restore $dev
|
||||
simple_if_fini $dev
|
||||
}
|
||||
|
||||
h1_create()
|
||||
{
|
||||
host_create $h1 1
|
||||
}
|
||||
|
||||
h1_destroy()
|
||||
{
|
||||
host_destroy $h1
|
||||
}
|
||||
|
||||
h2_create()
|
||||
{
|
||||
host_create $h2 2
|
||||
|
||||
# Some of the tests in this suite use multicast traffic. As this traffic
|
||||
# enters BR2_10 resp. BR2_11, it is flooded to all other ports. Thus
|
||||
# e.g. traffic ingressing through $swp2 is flooded to $swp3 (the
|
||||
# intended destination) and $swp5 (which is intended as ingress for
|
||||
# another stream of traffic).
|
||||
#
|
||||
# This is generally not a problem, but if the $swp5 throughput is lower
|
||||
# than $swp2 throughput, there will be a build-up at $swp5. That may
|
||||
# cause packets to fail to queue up at $swp3 due to shared buffer
|
||||
# quotas, and the test to spuriously fail.
|
||||
#
|
||||
# Prevent this by setting the speed of $h2 to 1Gbps.
|
||||
|
||||
ethtool -s $h2 speed 1000 autoneg off
|
||||
}
|
||||
|
||||
h2_destroy()
|
||||
{
|
||||
ethtool -s $h2 autoneg on
|
||||
host_destroy $h2
|
||||
}
|
||||
|
||||
h3_create()
|
||||
{
|
||||
host_create $h3 3
|
||||
ethtool -s $h3 speed 1000 autoneg off
|
||||
}
|
||||
|
||||
h3_destroy()
|
||||
{
|
||||
ethtool -s $h3 autoneg on
|
||||
host_destroy $h3
|
||||
}
|
||||
|
||||
switch_create()
|
||||
{
|
||||
local intf
|
||||
local vlan
|
||||
|
||||
ip link add dev br1_10 type bridge
|
||||
ip link add dev br1_11 type bridge
|
||||
|
||||
ip link add dev br2_10 type bridge
|
||||
ip link add dev br2_11 type bridge
|
||||
|
||||
for intf in $swp1 $swp2 $swp3 $swp4 $swp5; do
|
||||
ip link set dev $intf up
|
||||
mtu_set $intf 10000
|
||||
done
|
||||
|
||||
for intf in $swp1 $swp4; do
|
||||
for vlan in 10 11; do
|
||||
vlan_create $intf $vlan
|
||||
ip link set dev $intf.$vlan master br1_$vlan
|
||||
ip link set dev $intf.$vlan up
|
||||
done
|
||||
done
|
||||
|
||||
for intf in $swp2 $swp3 $swp5; do
|
||||
for vlan in 10 11; do
|
||||
vlan_create $intf $vlan
|
||||
ip link set dev $intf.$vlan master br2_$vlan
|
||||
ip link set dev $intf.$vlan up
|
||||
done
|
||||
done
|
||||
|
||||
ip link set dev $swp4.10 type vlan egress 0:0
|
||||
ip link set dev $swp4.11 type vlan egress 0:1
|
||||
for intf in $swp1 $swp2 $swp5; do
|
||||
for vlan in 10 11; do
|
||||
ip link set dev $intf.$vlan type vlan ingress 0:0 1:1
|
||||
done
|
||||
done
|
||||
|
||||
for intf in $swp2 $swp3 $swp4 $swp5; do
|
||||
ethtool -s $intf speed 1000 autoneg off
|
||||
done
|
||||
|
||||
ip link set dev br1_10 up
|
||||
ip link set dev br1_11 up
|
||||
ip link set dev br2_10 up
|
||||
ip link set dev br2_11 up
|
||||
|
||||
local size=$(devlink_pool_size_thtype 0 | cut -d' ' -f 1)
|
||||
devlink_port_pool_th_set $swp3 8 $size
|
||||
}
|
||||
|
||||
switch_destroy()
|
||||
{
|
||||
local intf
|
||||
local vlan
|
||||
|
||||
devlink_port_pool_th_restore $swp3 8
|
||||
|
||||
tc qdisc del dev $swp3 root 2>/dev/null
|
||||
|
||||
ip link set dev br2_11 down
|
||||
ip link set dev br2_10 down
|
||||
ip link set dev br1_11 down
|
||||
ip link set dev br1_10 down
|
||||
|
||||
for intf in $swp5 $swp4 $swp3 $swp2; do
|
||||
ethtool -s $intf autoneg on
|
||||
done
|
||||
|
||||
for intf in $swp5 $swp3 $swp2 $swp4 $swp1; do
|
||||
for vlan in 11 10; do
|
||||
ip link set dev $intf.$vlan down
|
||||
ip link set dev $intf.$vlan nomaster
|
||||
vlan_destroy $intf $vlan
|
||||
done
|
||||
|
||||
mtu_restore $intf
|
||||
ip link set dev $intf down
|
||||
done
|
||||
|
||||
ip link del dev br2_11
|
||||
ip link del dev br2_10
|
||||
ip link del dev br1_11
|
||||
ip link del dev br1_10
|
||||
}
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
h1=${NETIFS[p1]}
|
||||
swp1=${NETIFS[p2]}
|
||||
|
||||
swp2=${NETIFS[p3]}
|
||||
h2=${NETIFS[p4]}
|
||||
|
||||
swp3=${NETIFS[p5]}
|
||||
h3=${NETIFS[p6]}
|
||||
|
||||
swp4=${NETIFS[p7]}
|
||||
swp5=${NETIFS[p8]}
|
||||
|
||||
h3_mac=$(mac_get $h3)
|
||||
|
||||
vrf_prepare
|
||||
|
||||
h1_create
|
||||
h2_create
|
||||
h3_create
|
||||
switch_create
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
||||
switch_destroy
|
||||
h3_destroy
|
||||
h2_destroy
|
||||
h1_destroy
|
||||
|
||||
vrf_cleanup
|
||||
}
|
||||
|
||||
ping_ipv4()
|
||||
{
|
||||
ping_test $h1.10 $(ipaddr 3 10) " from host 1, vlan 10"
|
||||
ping_test $h1.11 $(ipaddr 3 11) " from host 1, vlan 11"
|
||||
ping_test $h2.10 $(ipaddr 3 10) " from host 2, vlan 10"
|
||||
ping_test $h2.11 $(ipaddr 3 11) " from host 2, vlan 11"
|
||||
}
|
||||
|
||||
get_tc()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
|
||||
echo $((vlan - 10))
|
||||
}
|
||||
|
||||
get_qdisc_handle()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
|
||||
local tc=$(get_tc $vlan)
|
||||
local band=$((8 - tc))
|
||||
|
||||
# Handle is 107: for TC1, 108: for TC0.
|
||||
echo "10$band:"
|
||||
}
|
||||
|
||||
get_qdisc_backlog()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
|
||||
qdisc_stats_get $swp3 $(get_qdisc_handle $vlan) .backlog
|
||||
}
|
||||
|
||||
get_mc_transmit_queue()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
|
||||
local tc=$(($(get_tc $vlan) + 8))
|
||||
ethtool_stats_get $swp3 tc_transmit_queue_tc_$tc
|
||||
}
|
||||
|
||||
get_nmarked()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
|
||||
ethtool_stats_get $swp3 ecn_marked
|
||||
}
|
||||
|
||||
get_qdisc_npackets()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
|
||||
busywait_for_counter 1100 +1 \
|
||||
qdisc_stats_get $swp3 $(get_qdisc_handle $vlan) .packets
|
||||
}
|
||||
|
||||
# This sends traffic in an attempt to build a backlog of $size. Returns 0 on
|
||||
# success. After 10 failed attempts it bails out and returns 1. It dumps the
|
||||
# backlog size to stdout.
|
||||
build_backlog()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
local size=$1; shift
|
||||
local proto=$1; shift
|
||||
|
||||
local tc=$((vlan - 10))
|
||||
local band=$((8 - tc))
|
||||
local cur=-1
|
||||
local i=0
|
||||
|
||||
while :; do
|
||||
local cur=$(busywait 1100 until_counter_is $((cur + 1)) \
|
||||
get_qdisc_backlog $vlan)
|
||||
local diff=$((size - cur))
|
||||
local pkts=$(((diff + 7999) / 8000))
|
||||
|
||||
if ((cur >= size)); then
|
||||
echo $cur
|
||||
return 0
|
||||
elif ((i++ > 10)); then
|
||||
echo $cur
|
||||
return 1
|
||||
fi
|
||||
|
||||
$MZ $h2.$vlan -p 8000 -a own -b $h3_mac \
|
||||
-A $(ipaddr 2 $vlan) -B $(ipaddr 3 $vlan) \
|
||||
-t $proto -q -c $pkts "$@"
|
||||
done
|
||||
}
|
||||
|
||||
check_marking()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
local cond=$1; shift
|
||||
|
||||
local npackets_0=$(get_qdisc_npackets $vlan)
|
||||
local nmarked_0=$(get_nmarked $vlan)
|
||||
sleep 5
|
||||
local npackets_1=$(get_qdisc_npackets $vlan)
|
||||
local nmarked_1=$(get_nmarked $vlan)
|
||||
|
||||
local nmarked_d=$((nmarked_1 - nmarked_0))
|
||||
local npackets_d=$((npackets_1 - npackets_0))
|
||||
local pct=$((100 * nmarked_d / npackets_d))
|
||||
|
||||
echo $pct
|
||||
((pct $cond))
|
||||
}
|
||||
|
||||
do_ecn_test()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
local limit=$1; shift
|
||||
local backlog
|
||||
local pct
|
||||
|
||||
# Main stream.
|
||||
start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \
|
||||
$h3_mac tos=0x01
|
||||
|
||||
# Build the below-the-limit backlog using UDP. We could use TCP just
|
||||
# fine, but this way we get a proof that UDP is accepted when queue
|
||||
# length is below the limit. The main stream is using TCP, and if the
|
||||
# limit is misconfigured, we would see this traffic being ECN marked.
|
||||
RET=0
|
||||
backlog=$(build_backlog $vlan $((2 * limit / 3)) udp)
|
||||
check_err $? "Could not build the requested backlog"
|
||||
pct=$(check_marking $vlan "== 0")
|
||||
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
|
||||
log_test "TC $((vlan - 10)): ECN backlog < limit"
|
||||
|
||||
# Now push TCP, because non-TCP traffic would be early-dropped after the
|
||||
# backlog crosses the limit, and we want to make sure that the backlog
|
||||
# is above the limit.
|
||||
RET=0
|
||||
backlog=$(build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01)
|
||||
check_err $? "Could not build the requested backlog"
|
||||
pct=$(check_marking $vlan ">= 95")
|
||||
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95."
|
||||
log_test "TC $((vlan - 10)): ECN backlog > limit"
|
||||
|
||||
# Up there we saw that UDP gets accepted when backlog is below the
|
||||
# limit. Now that it is above, it should all get dropped, and backlog
|
||||
# building should fail.
|
||||
RET=0
|
||||
build_backlog $vlan $((2 * limit)) udp >/dev/null
|
||||
check_fail $? "UDP traffic went into backlog instead of being early-dropped"
|
||||
log_test "TC $((vlan - 10)): ECN backlog > limit: UDP early-dropped"
|
||||
|
||||
stop_traffic
|
||||
sleep 1
|
||||
}
|
||||
|
||||
do_red_test()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
local limit=$1; shift
|
||||
local backlog
|
||||
local pct
|
||||
|
||||
# Use ECN-capable TCP to verify there's no marking even though the queue
|
||||
# is above limit.
|
||||
start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \
|
||||
$h3_mac tos=0x01
|
||||
|
||||
# Pushing below the queue limit should work.
|
||||
RET=0
|
||||
backlog=$(build_backlog $vlan $((2 * limit / 3)) tcp tos=0x01)
|
||||
check_err $? "Could not build the requested backlog"
|
||||
pct=$(check_marking $vlan "== 0")
|
||||
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
|
||||
log_test "TC $((vlan - 10)): RED backlog < limit"
|
||||
|
||||
# Pushing above should not.
|
||||
RET=0
|
||||
backlog=$(build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01)
|
||||
check_fail $? "Traffic went into backlog instead of being early-dropped"
|
||||
pct=$(check_marking $vlan "== 0")
|
||||
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
|
||||
local diff=$((limit - backlog))
|
||||
pct=$((100 * diff / limit))
|
||||
((0 <= pct && pct <= 5))
|
||||
check_err $? "backlog $backlog / $limit expected <= 5% distance"
|
||||
log_test "TC $((vlan - 10)): RED backlog > limit"
|
||||
|
||||
stop_traffic
|
||||
sleep 1
|
||||
}
|
||||
|
||||
do_mc_backlog_test()
|
||||
{
|
||||
local vlan=$1; shift
|
||||
local limit=$1; shift
|
||||
local backlog
|
||||
local pct
|
||||
|
||||
RET=0
|
||||
|
||||
start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) bc
|
||||
start_tcp_traffic $h2.$vlan $(ipaddr 2 $vlan) $(ipaddr 3 $vlan) bc
|
||||
|
||||
qbl=$(busywait 5000 until_counter_is 500000 \
|
||||
get_qdisc_backlog $vlan)
|
||||
check_err $? "Could not build MC backlog"
|
||||
|
||||
# Verify that we actually see the backlog on BUM TC. Do a busywait as
|
||||
# well, performance blips might cause false fail.
|
||||
local ebl
|
||||
ebl=$(busywait 5000 until_counter_is 500000 \
|
||||
get_mc_transmit_queue $vlan)
|
||||
check_err $? "MC backlog reported by qdisc not visible in ethtool"
|
||||
|
||||
stop_traffic
|
||||
stop_traffic
|
||||
|
||||
log_test "TC $((vlan - 10)): Qdisc reports MC backlog"
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ALL_TESTS="
|
||||
ping_ipv4
|
||||
ecn_test
|
||||
red_test
|
||||
mc_backlog_test
|
||||
"
|
||||
: ${QDISC:=ets}
|
||||
source sch_red_core.sh
|
||||
|
||||
# do_ecn_test first build 2/3 of the requested backlog and expects no marking,
|
||||
# and then builds 3/2 of it and does expect marking. The values of $BACKLOG1 and
|
||||
# $BACKLOG2 are far enough not to overlap, so that we can assume that if we do
|
||||
# see (do not see) marking, it is actually due to the configuration of that one
|
||||
# TC, and not due to configuration of the other TC leaking over.
|
||||
BACKLOG1=200000
|
||||
BACKLOG2=500000
|
||||
|
||||
install_qdisc()
|
||||
{
|
||||
local -a args=("$@")
|
||||
|
||||
tc qdisc add dev $swp3 root handle 10: $QDISC \
|
||||
bands 8 priomap 7 6 5 4 3 2 1 0
|
||||
tc qdisc add dev $swp3 parent 10:8 handle 108: red \
|
||||
limit 1000000 min $BACKLOG1 max $((BACKLOG1 + 1)) \
|
||||
probability 1.0 avpkt 8000 burst 38 "${args[@]}"
|
||||
tc qdisc add dev $swp3 parent 10:7 handle 107: red \
|
||||
limit 1000000 min $BACKLOG2 max $((BACKLOG2 + 1)) \
|
||||
probability 1.0 avpkt 8000 burst 63 "${args[@]}"
|
||||
sleep 1
|
||||
}
|
||||
|
||||
uninstall_qdisc()
|
||||
{
|
||||
tc qdisc del dev $swp3 parent 10:7
|
||||
tc qdisc del dev $swp3 parent 10:8
|
||||
tc qdisc del dev $swp3 root
|
||||
}
|
||||
|
||||
ecn_test()
|
||||
{
|
||||
install_qdisc ecn
|
||||
|
||||
do_ecn_test 10 $BACKLOG1
|
||||
do_ecn_test 11 $BACKLOG2
|
||||
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
red_test()
|
||||
{
|
||||
install_qdisc
|
||||
|
||||
do_red_test 10 $BACKLOG1
|
||||
do_red_test 11 $BACKLOG2
|
||||
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
mc_backlog_test()
|
||||
{
|
||||
install_qdisc
|
||||
|
||||
# Note that the backlog numbers here do not correspond to RED
|
||||
# configuration, but are arbitrary.
|
||||
do_mc_backlog_test 10 $BACKLOG1
|
||||
do_mc_backlog_test 11 $BACKLOG2
|
||||
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
||||
setup_wait
|
||||
|
||||
bail_on_lldpad
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
QDISC=prio
|
||||
source sch_red_ets.sh
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ALL_TESTS="
|
||||
ping_ipv4
|
||||
ecn_test
|
||||
red_test
|
||||
mc_backlog_test
|
||||
"
|
||||
source sch_red_core.sh
|
||||
|
||||
BACKLOG=300000
|
||||
|
||||
install_qdisc()
|
||||
{
|
||||
local -a args=("$@")
|
||||
|
||||
tc qdisc add dev $swp3 root handle 108: red \
|
||||
limit 1000000 min $BACKLOG max $((BACKLOG + 1)) \
|
||||
probability 1.0 avpkt 8000 burst 38 "${args[@]}"
|
||||
sleep 1
|
||||
}
|
||||
|
||||
uninstall_qdisc()
|
||||
{
|
||||
tc qdisc del dev $swp3 root
|
||||
}
|
||||
|
||||
ecn_test()
|
||||
{
|
||||
install_qdisc ecn
|
||||
do_ecn_test 10 $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
red_test()
|
||||
{
|
||||
install_qdisc
|
||||
do_red_test 10 $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
mc_backlog_test()
|
||||
{
|
||||
install_qdisc
|
||||
# Note that the backlog value here does not correspond to RED
|
||||
# configuration, but is arbitrary.
|
||||
do_mc_backlog_test 10 $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
||||
setup_wait
|
||||
|
||||
bail_on_lldpad
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
|
@ -0,0 +1,222 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ALL_TESTS="
|
||||
port_pool_test
|
||||
port_tc_ip_test
|
||||
port_tc_arp_test
|
||||
"
|
||||
|
||||
NUM_NETIFS=2
|
||||
source ../../../net/forwarding/lib.sh
|
||||
source ../../../net/forwarding/devlink_lib.sh
|
||||
source mlxsw_lib.sh
|
||||
|
||||
SB_POOL_ING=0
|
||||
SB_POOL_EGR_CPU=10
|
||||
|
||||
SB_ITC_CPU_IP=3
|
||||
SB_ITC_CPU_ARP=2
|
||||
SB_ITC=0
|
||||
|
||||
h1_create()
|
||||
{
|
||||
simple_if_init $h1 192.0.1.1/24
|
||||
}
|
||||
|
||||
h1_destroy()
|
||||
{
|
||||
simple_if_fini $h1 192.0.1.1/24
|
||||
}
|
||||
|
||||
h2_create()
|
||||
{
|
||||
simple_if_init $h2 192.0.1.2/24
|
||||
}
|
||||
|
||||
h2_destroy()
|
||||
{
|
||||
simple_if_fini $h2 192.0.1.2/24
|
||||
}
|
||||
|
||||
sb_occ_pool_check()
|
||||
{
|
||||
local dl_port=$1; shift
|
||||
local pool=$1; shift
|
||||
local exp_max_occ=$1
|
||||
local max_occ
|
||||
local err=0
|
||||
|
||||
max_occ=$(devlink sb -j occupancy show $dl_port \
|
||||
| jq -e ".[][][\"pool\"][\"$pool\"][\"max\"]")
|
||||
|
||||
if [[ "$max_occ" -ne "$exp_max_occ" ]]; then
|
||||
err=1
|
||||
fi
|
||||
|
||||
echo $max_occ
|
||||
return $err
|
||||
}
|
||||
|
||||
sb_occ_itc_check()
|
||||
{
|
||||
local dl_port=$1; shift
|
||||
local itc=$1; shift
|
||||
local exp_max_occ=$1
|
||||
local max_occ
|
||||
local err=0
|
||||
|
||||
max_occ=$(devlink sb -j occupancy show $dl_port \
|
||||
| jq -e ".[][][\"itc\"][\"$itc\"][\"max\"]")
|
||||
|
||||
if [[ "$max_occ" -ne "$exp_max_occ" ]]; then
|
||||
err=1
|
||||
fi
|
||||
|
||||
echo $max_occ
|
||||
return $err
|
||||
}
|
||||
|
||||
sb_occ_etc_check()
|
||||
{
|
||||
local dl_port=$1; shift
|
||||
local etc=$1; shift
|
||||
local exp_max_occ=$1; shift
|
||||
local max_occ
|
||||
local err=0
|
||||
|
||||
max_occ=$(devlink sb -j occupancy show $dl_port \
|
||||
| jq -e ".[][][\"etc\"][\"$etc\"][\"max\"]")
|
||||
|
||||
if [[ "$max_occ" -ne "$exp_max_occ" ]]; then
|
||||
err=1
|
||||
fi
|
||||
|
||||
echo $max_occ
|
||||
return $err
|
||||
}
|
||||
|
||||
port_pool_test()
|
||||
{
|
||||
local exp_max_occ=288
|
||||
local max_occ
|
||||
|
||||
devlink sb occupancy clearmax $DEVLINK_DEV
|
||||
|
||||
$MZ $h1 -c 1 -p 160 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \
|
||||
-t ip -q
|
||||
|
||||
devlink sb occupancy snapshot $DEVLINK_DEV
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_pool_check $dl_port1 $SB_POOL_ING $exp_max_occ)
|
||||
check_err $? "Expected iPool($SB_POOL_ING) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "physical port's($h1) ingress pool"
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_pool_check $dl_port2 $SB_POOL_ING $exp_max_occ)
|
||||
check_err $? "Expected iPool($SB_POOL_ING) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "physical port's($h2) ingress pool"
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_pool_check $cpu_dl_port $SB_POOL_EGR_CPU $exp_max_occ)
|
||||
check_err $? "Expected ePool($SB_POOL_EGR_CPU) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "CPU port's egress pool"
|
||||
}
|
||||
|
||||
port_tc_ip_test()
|
||||
{
|
||||
local exp_max_occ=288
|
||||
local max_occ
|
||||
|
||||
devlink sb occupancy clearmax $DEVLINK_DEV
|
||||
|
||||
$MZ $h1 -c 1 -p 160 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \
|
||||
-t ip -q
|
||||
|
||||
devlink sb occupancy snapshot $DEVLINK_DEV
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ)
|
||||
check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "physical port's($h1) ingress TC - IP packet"
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ)
|
||||
check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "physical port's($h2) ingress TC - IP packet"
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_etc_check $cpu_dl_port $SB_ITC_CPU_IP $exp_max_occ)
|
||||
check_err $? "Expected egress TC($SB_ITC_CPU_IP) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "CPU port's egress TC - IP packet"
|
||||
}
|
||||
|
||||
port_tc_arp_test()
|
||||
{
|
||||
local exp_max_occ=96
|
||||
local max_occ
|
||||
|
||||
if [[ $MLXSW_CHIP != "mlxsw_spectrum" ]]; then
|
||||
exp_max_occ=144
|
||||
fi
|
||||
|
||||
devlink sb occupancy clearmax $DEVLINK_DEV
|
||||
|
||||
$MZ $h1 -c 1 -p 160 -a $h1mac -A 192.0.1.1 -t arp -q
|
||||
|
||||
devlink sb occupancy snapshot $DEVLINK_DEV
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ)
|
||||
check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "physical port's($h1) ingress TC - ARP packet"
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ)
|
||||
check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "physical port's($h2) ingress TC - ARP packet"
|
||||
|
||||
RET=0
|
||||
max_occ=$(sb_occ_etc_check $cpu_dl_port $SB_ITC_CPU_ARP $exp_max_occ)
|
||||
check_err $? "Expected egress TC($SB_ITC_IP2ME) max occupancy to be $exp_max_occ, but got $max_occ"
|
||||
log_test "CPU port's egress TC - ARP packet"
|
||||
}
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
h1=${NETIFS[p1]}
|
||||
h2=${NETIFS[p2]}
|
||||
|
||||
h1mac=$(mac_get $h1)
|
||||
h2mac=$(mac_get $h2)
|
||||
|
||||
dl_port1=$(devlink_port_by_netdev $h1)
|
||||
dl_port2=$(devlink_port_by_netdev $h2)
|
||||
|
||||
cpu_dl_port=$(devlink_cpu_port_get)
|
||||
|
||||
vrf_prepare
|
||||
|
||||
h1_create
|
||||
h2_create
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
||||
h2_destroy
|
||||
h1_destroy
|
||||
|
||||
vrf_cleanup
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
||||
setup_wait
|
||||
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
|
@ -0,0 +1,416 @@
|
|||
#!/usr/bin/python
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
import subprocess
|
||||
import json as j
|
||||
import random
|
||||
|
||||
|
||||
class SkipTest(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RandomValuePicker:
|
||||
"""
|
||||
Class for storing shared buffer configuration. Can handle 3 different
|
||||
objects, pool, tcbind and portpool. Provide an interface to get random
|
||||
values for a specific object type as the follow:
|
||||
1. Pool:
|
||||
- random size
|
||||
|
||||
2. TcBind:
|
||||
- random pool number
|
||||
- random threshold
|
||||
|
||||
3. PortPool:
|
||||
- random threshold
|
||||
"""
|
||||
def __init__(self, pools):
|
||||
self._pools = []
|
||||
for pool in pools:
|
||||
self._pools.append(pool)
|
||||
|
||||
def _cell_size(self):
|
||||
return self._pools[0]["cell_size"]
|
||||
|
||||
def _get_static_size(self, th):
|
||||
# For threshold of 16, this works out to be about 12MB on Spectrum-1,
|
||||
# and about 17MB on Spectrum-2.
|
||||
return th * 8000 * self._cell_size()
|
||||
|
||||
def _get_size(self):
|
||||
return self._get_static_size(16)
|
||||
|
||||
def _get_thtype(self):
|
||||
return "static"
|
||||
|
||||
def _get_th(self, pool):
|
||||
# Threshold value could be any integer between 3 to 16
|
||||
th = random.randint(3, 16)
|
||||
if pool["thtype"] == "dynamic":
|
||||
return th
|
||||
else:
|
||||
return self._get_static_size(th)
|
||||
|
||||
def _get_pool(self, direction):
|
||||
ing_pools = []
|
||||
egr_pools = []
|
||||
for pool in self._pools:
|
||||
if pool["type"] == "ingress":
|
||||
ing_pools.append(pool)
|
||||
else:
|
||||
egr_pools.append(pool)
|
||||
if direction == "ingress":
|
||||
arr = ing_pools
|
||||
else:
|
||||
arr = egr_pools
|
||||
return arr[random.randint(0, len(arr) - 1)]
|
||||
|
||||
def get_value(self, objid):
|
||||
if isinstance(objid, Pool):
|
||||
if objid["pool"] in [4, 8, 9, 10]:
|
||||
# The threshold type of pools 4, 8, 9 and 10 cannot be changed
|
||||
raise SkipTest()
|
||||
else:
|
||||
return (self._get_size(), self._get_thtype())
|
||||
if isinstance(objid, TcBind):
|
||||
if objid["tc"] >= 8:
|
||||
# Multicast TCs cannot be changed
|
||||
raise SkipTest()
|
||||
else:
|
||||
pool = self._get_pool(objid["type"])
|
||||
th = self._get_th(pool)
|
||||
pool_n = pool["pool"]
|
||||
return (pool_n, th)
|
||||
if isinstance(objid, PortPool):
|
||||
pool_n = objid["pool"]
|
||||
pool = self._pools[pool_n]
|
||||
assert pool["pool"] == pool_n
|
||||
th = self._get_th(pool)
|
||||
return (th,)
|
||||
|
||||
|
||||
class RecordValuePickerException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RecordValuePicker:
|
||||
"""
|
||||
Class for storing shared buffer configuration. Can handle 2 different
|
||||
objects, pool and tcbind. Provide an interface to get the stored values per
|
||||
object type.
|
||||
"""
|
||||
def __init__(self, objlist):
|
||||
self._recs = []
|
||||
for item in objlist:
|
||||
self._recs.append({"objid": item, "value": item.var_tuple()})
|
||||
|
||||
def get_value(self, objid):
|
||||
if isinstance(objid, Pool) and objid["pool"] in [4, 8, 9, 10]:
|
||||
# The threshold type of pools 4, 8, 9 and 10 cannot be changed
|
||||
raise SkipTest()
|
||||
if isinstance(objid, TcBind) and objid["tc"] >= 8:
|
||||
# Multicast TCs cannot be changed
|
||||
raise SkipTest()
|
||||
for rec in self._recs:
|
||||
if rec["objid"].weak_eq(objid):
|
||||
return rec["value"]
|
||||
raise RecordValuePickerException()
|
||||
|
||||
|
||||
def run_cmd(cmd, json=False):
|
||||
out = subprocess.check_output(cmd, shell=True)
|
||||
if json:
|
||||
return j.loads(out)
|
||||
return out
|
||||
|
||||
|
||||
def run_json_cmd(cmd):
|
||||
return run_cmd(cmd, json=True)
|
||||
|
||||
|
||||
def log_test(test_name, err_msg=None):
|
||||
if err_msg:
|
||||
print("\t%s" % err_msg)
|
||||
print("TEST: %-80s [FAIL]" % test_name)
|
||||
else:
|
||||
print("TEST: %-80s [ OK ]" % test_name)
|
||||
|
||||
|
||||
class CommonItem(dict):
|
||||
varitems = []
|
||||
|
||||
def var_tuple(self):
|
||||
ret = []
|
||||
self.varitems.sort()
|
||||
for key in self.varitems:
|
||||
ret.append(self[key])
|
||||
return tuple(ret)
|
||||
|
||||
def weak_eq(self, other):
|
||||
for key in self:
|
||||
if key in self.varitems:
|
||||
continue
|
||||
if self[key] != other[key]:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class CommonList(list):
|
||||
def get_by(self, by_obj):
|
||||
for item in self:
|
||||
if item.weak_eq(by_obj):
|
||||
return item
|
||||
return None
|
||||
|
||||
def del_by(self, by_obj):
|
||||
for item in self:
|
||||
if item.weak_eq(by_obj):
|
||||
self.remove(item)
|
||||
|
||||
|
||||
class Pool(CommonItem):
|
||||
varitems = ["size", "thtype"]
|
||||
|
||||
def dl_set(self, dlname, size, thtype):
|
||||
run_cmd("devlink sb pool set {} sb {} pool {} size {} thtype {}".format(dlname, self["sb"],
|
||||
self["pool"],
|
||||
size, thtype))
|
||||
|
||||
|
||||
class PoolList(CommonList):
|
||||
pass
|
||||
|
||||
|
||||
def get_pools(dlname, direction=None):
|
||||
d = run_json_cmd("devlink sb pool show -j")
|
||||
pools = PoolList()
|
||||
for pooldict in d["pool"][dlname]:
|
||||
if not direction or direction == pooldict["type"]:
|
||||
pools.append(Pool(pooldict))
|
||||
return pools
|
||||
|
||||
|
||||
def do_check_pools(dlname, pools, vp):
|
||||
for pool in pools:
|
||||
pre_pools = get_pools(dlname)
|
||||
try:
|
||||
(size, thtype) = vp.get_value(pool)
|
||||
except SkipTest:
|
||||
continue
|
||||
pool.dl_set(dlname, size, thtype)
|
||||
post_pools = get_pools(dlname)
|
||||
pool = post_pools.get_by(pool)
|
||||
|
||||
err_msg = None
|
||||
if pool["size"] != size:
|
||||
err_msg = "Incorrect pool size (got {}, expected {})".format(pool["size"], size)
|
||||
if pool["thtype"] != thtype:
|
||||
err_msg = "Incorrect pool threshold type (got {}, expected {})".format(pool["thtype"], thtype)
|
||||
|
||||
pre_pools.del_by(pool)
|
||||
post_pools.del_by(pool)
|
||||
if pre_pools != post_pools:
|
||||
err_msg = "Other pool setup changed as well"
|
||||
log_test("pool {} of sb {} set verification".format(pool["pool"],
|
||||
pool["sb"]), err_msg)
|
||||
|
||||
|
||||
def check_pools(dlname, pools):
|
||||
# Save defaults
|
||||
record_vp = RecordValuePicker(pools)
|
||||
|
||||
# For each pool, set random size and static threshold type
|
||||
do_check_pools(dlname, pools, RandomValuePicker(pools))
|
||||
|
||||
# Restore defaults
|
||||
do_check_pools(dlname, pools, record_vp)
|
||||
|
||||
|
||||
class TcBind(CommonItem):
|
||||
varitems = ["pool", "threshold"]
|
||||
|
||||
def __init__(self, port, d):
|
||||
super(TcBind, self).__init__(d)
|
||||
self["dlportname"] = port.name
|
||||
|
||||
def dl_set(self, pool, th):
|
||||
run_cmd("devlink sb tc bind set {} sb {} tc {} type {} pool {} th {}".format(self["dlportname"],
|
||||
self["sb"],
|
||||
self["tc"],
|
||||
self["type"],
|
||||
pool, th))
|
||||
|
||||
|
||||
class TcBindList(CommonList):
|
||||
pass
|
||||
|
||||
|
||||
def get_tcbinds(ports, verify_existence=False):
|
||||
d = run_json_cmd("devlink sb tc bind show -j -n")
|
||||
tcbinds = TcBindList()
|
||||
for port in ports:
|
||||
err_msg = None
|
||||
if port.name not in d["tc_bind"] or len(d["tc_bind"][port.name]) == 0:
|
||||
err_msg = "No tc bind for port"
|
||||
else:
|
||||
for tcbinddict in d["tc_bind"][port.name]:
|
||||
tcbinds.append(TcBind(port, tcbinddict))
|
||||
if verify_existence:
|
||||
log_test("tc bind existence for port {} verification".format(port.name), err_msg)
|
||||
return tcbinds
|
||||
|
||||
|
||||
def do_check_tcbind(ports, tcbinds, vp):
|
||||
for tcbind in tcbinds:
|
||||
pre_tcbinds = get_tcbinds(ports)
|
||||
try:
|
||||
(pool, th) = vp.get_value(tcbind)
|
||||
except SkipTest:
|
||||
continue
|
||||
tcbind.dl_set(pool, th)
|
||||
post_tcbinds = get_tcbinds(ports)
|
||||
tcbind = post_tcbinds.get_by(tcbind)
|
||||
|
||||
err_msg = None
|
||||
if tcbind["pool"] != pool:
|
||||
err_msg = "Incorrect pool (got {}, expected {})".format(tcbind["pool"], pool)
|
||||
if tcbind["threshold"] != th:
|
||||
err_msg = "Incorrect threshold (got {}, expected {})".format(tcbind["threshold"], th)
|
||||
|
||||
pre_tcbinds.del_by(tcbind)
|
||||
post_tcbinds.del_by(tcbind)
|
||||
if pre_tcbinds != post_tcbinds:
|
||||
err_msg = "Other tc bind setup changed as well"
|
||||
log_test("tc bind {}-{} of sb {} set verification".format(tcbind["dlportname"],
|
||||
tcbind["tc"],
|
||||
tcbind["sb"]), err_msg)
|
||||
|
||||
|
||||
def check_tcbind(dlname, ports, pools):
|
||||
tcbinds = get_tcbinds(ports, verify_existence=True)
|
||||
|
||||
# Save defaults
|
||||
record_vp = RecordValuePicker(tcbinds)
|
||||
|
||||
# Bind each port and unicast TC (TCs < 8) to a random pool and a random
|
||||
# threshold
|
||||
do_check_tcbind(ports, tcbinds, RandomValuePicker(pools))
|
||||
|
||||
# Restore defaults
|
||||
do_check_tcbind(ports, tcbinds, record_vp)
|
||||
|
||||
|
||||
class PortPool(CommonItem):
|
||||
varitems = ["threshold"]
|
||||
|
||||
def __init__(self, port, d):
|
||||
super(PortPool, self).__init__(d)
|
||||
self["dlportname"] = port.name
|
||||
|
||||
def dl_set(self, th):
|
||||
run_cmd("devlink sb port pool set {} sb {} pool {} th {}".format(self["dlportname"],
|
||||
self["sb"],
|
||||
self["pool"], th))
|
||||
|
||||
|
||||
class PortPoolList(CommonList):
|
||||
pass
|
||||
|
||||
|
||||
def get_portpools(ports, verify_existence=False):
|
||||
d = run_json_cmd("devlink sb port pool -j -n")
|
||||
portpools = PortPoolList()
|
||||
for port in ports:
|
||||
err_msg = None
|
||||
if port.name not in d["port_pool"] or len(d["port_pool"][port.name]) == 0:
|
||||
err_msg = "No port pool for port"
|
||||
else:
|
||||
for portpooldict in d["port_pool"][port.name]:
|
||||
portpools.append(PortPool(port, portpooldict))
|
||||
if verify_existence:
|
||||
log_test("port pool existence for port {} verification".format(port.name), err_msg)
|
||||
return portpools
|
||||
|
||||
|
||||
def do_check_portpool(ports, portpools, vp):
|
||||
for portpool in portpools:
|
||||
pre_portpools = get_portpools(ports)
|
||||
(th,) = vp.get_value(portpool)
|
||||
portpool.dl_set(th)
|
||||
post_portpools = get_portpools(ports)
|
||||
portpool = post_portpools.get_by(portpool)
|
||||
|
||||
err_msg = None
|
||||
if portpool["threshold"] != th:
|
||||
err_msg = "Incorrect threshold (got {}, expected {})".format(portpool["threshold"], th)
|
||||
|
||||
pre_portpools.del_by(portpool)
|
||||
post_portpools.del_by(portpool)
|
||||
if pre_portpools != post_portpools:
|
||||
err_msg = "Other port pool setup changed as well"
|
||||
log_test("port pool {}-{} of sb {} set verification".format(portpool["dlportname"],
|
||||
portpool["pool"],
|
||||
portpool["sb"]), err_msg)
|
||||
|
||||
|
||||
def check_portpool(dlname, ports, pools):
|
||||
portpools = get_portpools(ports, verify_existence=True)
|
||||
|
||||
# Save defaults
|
||||
record_vp = RecordValuePicker(portpools)
|
||||
|
||||
# For each port pool, set a random threshold
|
||||
do_check_portpool(ports, portpools, RandomValuePicker(pools))
|
||||
|
||||
# Restore defaults
|
||||
do_check_portpool(ports, portpools, record_vp)
|
||||
|
||||
|
||||
class Port:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
class PortList(list):
|
||||
pass
|
||||
|
||||
|
||||
def get_ports(dlname):
|
||||
d = run_json_cmd("devlink port show -j")
|
||||
ports = PortList()
|
||||
for name in d["port"]:
|
||||
if name.find(dlname) == 0 and d["port"][name]["flavour"] == "physical":
|
||||
ports.append(Port(name))
|
||||
return ports
|
||||
|
||||
|
||||
def get_device():
|
||||
devices_info = run_json_cmd("devlink -j dev info")["info"]
|
||||
for d in devices_info:
|
||||
if "mlxsw_spectrum" in devices_info[d]["driver"]:
|
||||
return d
|
||||
return None
|
||||
|
||||
|
||||
class UnavailableDevlinkNameException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def test_sb_configuration():
|
||||
# Use static seed
|
||||
random.seed(0)
|
||||
|
||||
dlname = get_device()
|
||||
if not dlname:
|
||||
raise UnavailableDevlinkNameException()
|
||||
|
||||
ports = get_ports(dlname)
|
||||
pools = get_pools(dlname)
|
||||
|
||||
check_pools(dlname, pools)
|
||||
check_tcbind(dlname, ports, pools)
|
||||
check_portpool(dlname, ports, pools)
|
||||
|
||||
|
||||
test_sb_configuration()
|
|
@ -8,8 +8,9 @@ source $lib_dir/lib.sh
|
|||
source $lib_dir/tc_common.sh
|
||||
source $lib_dir/devlink_lib.sh
|
||||
|
||||
if [ "$DEVLINK_VIDDID" != "15b3:cf6c" ]; then
|
||||
echo "SKIP: test is tailored for Mellanox Spectrum-2"
|
||||
if [[ "$DEVLINK_VIDDID" != "15b3:cf6c" && \
|
||||
"$DEVLINK_VIDDID" != "15b3:cf70" ]]; then
|
||||
echo "SKIP: test is tailored for Mellanox Spectrum-2 and Spectrum-3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
|
||||
lib_dir=$(dirname $0)/../../../net/forwarding
|
||||
|
||||
ALL_TESTS="shared_block_drop_test"
|
||||
ALL_TESTS="
|
||||
shared_block_drop_test
|
||||
egress_redirect_test
|
||||
multi_mirror_test
|
||||
"
|
||||
NUM_NETIFS=2
|
||||
|
||||
source $lib_dir/tc_common.sh
|
||||
|
@ -69,6 +73,88 @@ shared_block_drop_test()
|
|||
log_test "shared block drop"
|
||||
}
|
||||
|
||||
egress_redirect_test()
|
||||
{
|
||||
RET=0
|
||||
|
||||
# It is forbidden in mlxsw driver to have mirred redirect on
|
||||
# egress-bound block.
|
||||
|
||||
tc qdisc add dev $swp1 ingress_block 22 clsact
|
||||
check_err $? "Failed to create clsact with ingress block"
|
||||
|
||||
tc filter add block 22 protocol ip pref 1 handle 101 flower \
|
||||
skip_sw dst_ip 192.0.2.2 \
|
||||
action mirred egress redirect dev $swp2
|
||||
check_err $? "Failed to add redirect rule to ingress bound block"
|
||||
|
||||
tc qdisc add dev $swp2 ingress_block 22 clsact
|
||||
check_err $? "Failed to create another clsact with ingress shared block"
|
||||
|
||||
tc qdisc del dev $swp2 clsact
|
||||
|
||||
tc qdisc add dev $swp2 egress_block 22 clsact
|
||||
check_fail $? "Incorrect success to create another clsact with egress shared block"
|
||||
|
||||
tc filter del block 22 protocol ip pref 1 handle 101 flower
|
||||
|
||||
tc qdisc add dev $swp2 egress_block 22 clsact
|
||||
check_err $? "Failed to create another clsact with egress shared block after blocker redirect rule removed"
|
||||
|
||||
tc filter add block 22 protocol ip pref 1 handle 101 flower \
|
||||
skip_sw dst_ip 192.0.2.2 \
|
||||
action mirred egress redirect dev $swp2
|
||||
check_fail $? "Incorrect success to add redirect rule to mixed bound block"
|
||||
|
||||
tc qdisc del dev $swp1 clsact
|
||||
|
||||
tc qdisc add dev $swp1 egress_block 22 clsact
|
||||
check_err $? "Failed to create another clsact with egress shared block"
|
||||
|
||||
tc filter add block 22 protocol ip pref 1 handle 101 flower \
|
||||
skip_sw dst_ip 192.0.2.2 \
|
||||
action mirred egress redirect dev $swp2
|
||||
check_fail $? "Incorrect success to add redirect rule to egress bound shared block"
|
||||
|
||||
tc qdisc del dev $swp2 clsact
|
||||
|
||||
tc filter add block 22 protocol ip pref 1 handle 101 flower \
|
||||
skip_sw dst_ip 192.0.2.2 \
|
||||
action mirred egress redirect dev $swp2
|
||||
check_fail $? "Incorrect success to add redirect rule to egress bound block"
|
||||
|
||||
tc qdisc del dev $swp1 clsact
|
||||
|
||||
log_test "shared block drop"
|
||||
}
|
||||
|
||||
multi_mirror_test()
|
||||
{
|
||||
RET=0
|
||||
|
||||
# It is forbidden in mlxsw driver to have multiple mirror
|
||||
# actions in a single rule.
|
||||
|
||||
tc qdisc add dev $swp1 clsact
|
||||
|
||||
tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
|
||||
skip_sw dst_ip 192.0.2.2 \
|
||||
action mirred egress mirror dev $swp2
|
||||
check_err $? "Failed to add rule with single mirror action"
|
||||
|
||||
tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
|
||||
|
||||
tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
|
||||
skip_sw dst_ip 192.0.2.2 \
|
||||
action mirred egress mirror dev $swp2 \
|
||||
action mirred egress mirror dev $swp1
|
||||
check_fail $? "Incorrect success to add rule with two mirror actions"
|
||||
|
||||
tc qdisc del dev $swp1 clsact
|
||||
|
||||
log_test "multi mirror"
|
||||
}
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
swp1=${NETIFS[p1]}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# Test for resource limit of offloaded flower rules. The test adds a given
|
||||
# number of flower matches for different IPv6 addresses, then generates traffic,
|
||||
# and ensures each was hit exactly once. This file contains functions to set up
|
||||
# a testing topology and run the test, and is meant to be sourced from a test
|
||||
# number of flower matches for different IPv6 addresses, then check the offload
|
||||
# indication for all of the tc flower rules. This file contains functions to set
|
||||
# up a testing topology and run the test, and is meant to be sourced from a test
|
||||
# script that calls the testing routine with a given number of rules.
|
||||
|
||||
TC_FLOWER_NUM_NETIFS=2
|
||||
|
@ -94,22 +94,15 @@ __tc_flower_test()
|
|||
|
||||
tc_flower_rules_create $count $should_fail
|
||||
|
||||
for ((i = 0; i < count; ++i)); do
|
||||
$MZ $h1 -q -c 1 -t ip -p 20 -b bc -6 \
|
||||
-A 2001:db8:2::1 \
|
||||
-B $(tc_flower_addr $i)
|
||||
done
|
||||
|
||||
MISMATCHES=$(
|
||||
tc -j -s filter show dev $h2 ingress |
|
||||
jq -r '[ .[] | select(.kind == "flower") | .options |
|
||||
values as $rule | .actions[].stats.packets |
|
||||
select(. != 1) | "\(.) on \($rule.keys.dst_ip)" ] |
|
||||
join(", ")'
|
||||
)
|
||||
|
||||
test -z "$MISMATCHES"
|
||||
check_err $? "Expected to capture 1 packet for each IP, but got $MISMATCHES"
|
||||
offload_count=$(tc -j -s filter show dev $h2 ingress |
|
||||
jq -r '[ .[] | select(.kind == "flower") |
|
||||
.options | .in_hw ]' | jq .[] | wc -l)
|
||||
[[ $((offload_count - 1)) -eq $count ]]
|
||||
if [[ $should_fail -eq 0 ]]; then
|
||||
check_err $? "Offload mismatch"
|
||||
else
|
||||
check_err_fail $should_fail $? "Offload more than expacted"
|
||||
fi
|
||||
}
|
||||
|
||||
tc_flower_test()
|
||||
|
|
|
@ -9,6 +9,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding
|
|||
ALL_TESTS="sanitization_test offload_indication_test \
|
||||
sanitization_vlan_aware_test offload_indication_vlan_aware_test"
|
||||
NUM_NETIFS=2
|
||||
: ${TIMEOUT:=20000} # ms
|
||||
source $lib_dir/lib.sh
|
||||
|
||||
setup_prepare()
|
||||
|
@ -470,8 +471,8 @@ offload_indication_fdb_flood_test()
|
|||
|
||||
bridge fdb append 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.2
|
||||
|
||||
bridge fdb show brport vxlan0 | grep 00:00:00:00:00:00 \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb 00:00:00:00:00:00 \
|
||||
bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
|
||||
bridge fdb del 00:00:00:00:00:00 dev vxlan0 self
|
||||
|
@ -486,11 +487,11 @@ offload_indication_fdb_bridge_test()
|
|||
bridge fdb add de:ad:be:ef:13:37 dev vxlan0 self master static \
|
||||
dst 198.51.100.2
|
||||
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - initial state"
|
||||
|
@ -500,9 +501,9 @@ offload_indication_fdb_bridge_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb del de:ad:be:ef:13:37 dev vxlan0 master
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after removal from bridge"
|
||||
|
||||
|
@ -511,11 +512,11 @@ offload_indication_fdb_bridge_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb add de:ad:be:ef:13:37 dev vxlan0 master static
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after re-add to bridge"
|
||||
|
@ -525,9 +526,9 @@ offload_indication_fdb_bridge_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb del de:ad:be:ef:13:37 dev vxlan0 self
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after removal from vxlan"
|
||||
|
||||
|
@ -536,11 +537,11 @@ offload_indication_fdb_bridge_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb add de:ad:be:ef:13:37 dev vxlan0 self dst 198.51.100.2
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
bridge fdb show brport vxlan0 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan0
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after re-add to vxlan"
|
||||
|
@ -558,27 +559,32 @@ offload_indication_decap_route_test()
|
|||
{
|
||||
RET=0
|
||||
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link set dev vxlan0 down
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link set dev vxlan1 down
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - vxlan device down"
|
||||
|
||||
RET=0
|
||||
|
||||
ip link set dev vxlan1 up
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link set dev vxlan0 up
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - vxlan device up"
|
||||
|
@ -586,11 +592,13 @@ offload_indication_decap_route_test()
|
|||
RET=0
|
||||
|
||||
ip address delete 198.51.100.1/32 dev lo
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip address add 198.51.100.1/32 dev lo
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - add local route"
|
||||
|
@ -598,16 +606,19 @@ offload_indication_decap_route_test()
|
|||
RET=0
|
||||
|
||||
ip link set dev $swp1 nomaster
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link set dev $swp2 nomaster
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link set dev $swp1 master br0
|
||||
ip link set dev $swp2 master br1
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - local ports enslavement"
|
||||
|
@ -615,12 +626,14 @@ offload_indication_decap_route_test()
|
|||
RET=0
|
||||
|
||||
ip link del dev br0
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link del dev br1
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - bridge device deletion"
|
||||
|
||||
|
@ -632,16 +645,19 @@ offload_indication_decap_route_test()
|
|||
ip link set dev $swp2 master br1
|
||||
ip link set dev vxlan0 master br0
|
||||
ip link set dev vxlan1 master br1
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link del dev vxlan0
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
ip link del dev vxlan1
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - vxlan device deletion"
|
||||
|
||||
|
@ -656,12 +672,15 @@ check_fdb_offloaded()
|
|||
local mac=00:11:22:33:44:55
|
||||
local zmac=00:00:00:00:00:00
|
||||
|
||||
bridge fdb show dev vxlan0 | grep $mac | grep self | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $mac self \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
bridge fdb show dev vxlan0 | grep $mac | grep master | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $mac master \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
|
||||
bridge fdb show dev vxlan0 | grep $zmac | grep self | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
}
|
||||
|
||||
|
@ -672,13 +691,15 @@ check_vxlan_fdb_not_offloaded()
|
|||
|
||||
bridge fdb show dev vxlan0 | grep $mac | grep -q self
|
||||
check_err $?
|
||||
bridge fdb show dev vxlan0 | grep $mac | grep self | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb $mac self \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
|
||||
bridge fdb show dev vxlan0 | grep $zmac | grep -q self
|
||||
check_err $?
|
||||
bridge fdb show dev vxlan0 | grep $zmac | grep self | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
}
|
||||
|
||||
check_bridge_fdb_not_offloaded()
|
||||
|
@ -688,8 +709,9 @@ check_bridge_fdb_not_offloaded()
|
|||
|
||||
bridge fdb show dev vxlan0 | grep $mac | grep -q master
|
||||
check_err $?
|
||||
bridge fdb show dev vxlan0 | grep $mac | grep master | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb $mac master \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
}
|
||||
|
||||
__offload_indication_join_vxlan_first()
|
||||
|
@ -771,12 +793,14 @@ __offload_indication_join_vxlan_last()
|
|||
|
||||
ip link set dev $swp1 master br0
|
||||
|
||||
bridge fdb show dev vxlan0 | grep $zmac | grep self | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
|
||||
ip link set dev vxlan0 master br0
|
||||
|
||||
bridge fdb show dev vxlan0 | grep $zmac | grep self | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show dev vxlan0
|
||||
check_err $?
|
||||
|
||||
log_test "offload indication - attach vxlan last"
|
||||
|
@ -866,8 +890,9 @@ sanitization_vlan_aware_test()
|
|||
ip link set dev $swp1 master br0 &> /dev/null
|
||||
check_fail $?
|
||||
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vlan-aware - failed enslavement to bridge due to conflict"
|
||||
|
||||
|
@ -929,11 +954,11 @@ offload_indication_vlan_aware_fdb_test()
|
|||
bridge fdb add de:ad:be:ef:13:37 dev vxlan10 self master static \
|
||||
dst 198.51.100.2 vlan 10
|
||||
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - initial state"
|
||||
|
@ -943,9 +968,9 @@ offload_indication_vlan_aware_fdb_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb del de:ad:be:ef:13:37 dev vxlan10 master vlan 10
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after removal from bridge"
|
||||
|
||||
|
@ -954,11 +979,11 @@ offload_indication_vlan_aware_fdb_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb add de:ad:be:ef:13:37 dev vxlan10 master static vlan 10
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after re-add to bridge"
|
||||
|
@ -968,9 +993,9 @@ offload_indication_vlan_aware_fdb_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb del de:ad:be:ef:13:37 dev vxlan10 self
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after removal from vxlan"
|
||||
|
||||
|
@ -979,11 +1004,11 @@ offload_indication_vlan_aware_fdb_test()
|
|||
RET=0
|
||||
|
||||
bridge fdb add de:ad:be:ef:13:37 dev vxlan10 self dst 198.51.100.2
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
bridge fdb show brport vxlan10 | grep de:ad:be:ef:13:37 | grep -v self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \
|
||||
de:ad:be:ef:13:37 self -v bridge fdb show brport vxlan10
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan entry offload indication - after re-add to vxlan"
|
||||
|
@ -995,28 +1020,31 @@ offload_indication_vlan_aware_decap_route_test()
|
|||
{
|
||||
RET=0
|
||||
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
# Toggle PVID flag on one VxLAN device and make sure route is still
|
||||
# marked as offloaded
|
||||
bridge vlan add vid 10 dev vxlan10 untagged
|
||||
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
# Toggle PVID flag on second VxLAN device and make sure route is no
|
||||
# longer marked as offloaded
|
||||
bridge vlan add vid 20 dev vxlan20 untagged
|
||||
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
check_fail $?
|
||||
busywait "$TIMEOUT" not wait_for_offload \
|
||||
ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
# Toggle PVID flag back and make sure route is marked as offloaded
|
||||
bridge vlan add vid 10 dev vxlan10 pvid untagged
|
||||
bridge vlan add vid 20 dev vxlan20 pvid untagged
|
||||
|
||||
ip route show table local | grep 198.51.100.1 | grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload ip route show table local 198.51.100.1
|
||||
check_err $?
|
||||
|
||||
log_test "vxlan decap route - vni map/unmap"
|
||||
|
@ -1069,33 +1097,33 @@ offload_indication_vlan_aware_l3vni_test()
|
|||
ip link set dev vxlan0 master br0
|
||||
bridge vlan add dev vxlan0 vid 10 pvid untagged
|
||||
|
||||
bridge fdb show brport vxlan0 | grep $zmac | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show brport vxlan0
|
||||
check_err $? "vxlan tunnel not offloaded when should"
|
||||
|
||||
# Configure a VLAN interface and make sure tunnel is offloaded
|
||||
ip link add link br0 name br10 up type vlan id 10
|
||||
sysctl_set net.ipv6.conf.br10.disable_ipv6 0
|
||||
ip -6 address add 2001:db8:1::1/64 dev br10
|
||||
bridge fdb show brport vxlan0 | grep $zmac | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show brport vxlan0
|
||||
check_err $? "vxlan tunnel not offloaded when should"
|
||||
|
||||
# Unlink the VXLAN device, make sure tunnel is no longer offloaded,
|
||||
# then add it back to the bridge and make sure it is offloaded
|
||||
ip link set dev vxlan0 nomaster
|
||||
bridge fdb show brport vxlan0 | grep $zmac | grep self \
|
||||
| grep -q offload
|
||||
check_fail $? "vxlan tunnel offloaded after unlinked from bridge"
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show brport vxlan0
|
||||
check_err $? "vxlan tunnel offloaded after unlinked from bridge"
|
||||
|
||||
ip link set dev vxlan0 master br0
|
||||
bridge fdb show brport vxlan0 | grep $zmac | grep self \
|
||||
| grep -q offload
|
||||
check_fail $? "vxlan tunnel offloaded despite no matching vid"
|
||||
busywait "$TIMEOUT" not wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show brport vxlan0
|
||||
check_err $? "vxlan tunnel offloaded despite no matching vid"
|
||||
|
||||
bridge vlan add dev vxlan0 vid 10 pvid untagged
|
||||
bridge fdb show brport vxlan0 | grep $zmac | grep self \
|
||||
| grep -q offload
|
||||
busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb $zmac self \
|
||||
bridge fdb show brport vxlan0
|
||||
check_err $? "vxlan tunnel not offloaded after adding vid"
|
||||
|
||||
log_test "vxlan - l3 vni"
|
||||
|
|
|
@ -35,6 +35,12 @@ if [ $? -ne 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
devlink dev help 2>&1 | grep info &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: iproute2 too old, missing devlink dev info support"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##############################################################################
|
||||
# Devlink helpers
|
||||
|
||||
|
@ -413,3 +419,19 @@ devlink_trap_drop_cleanup()
|
|||
kill $mz_pid && wait $mz_pid &> /dev/null
|
||||
tc filter del dev $dev egress protocol $proto pref $pref handle $handle flower
|
||||
}
|
||||
|
||||
devlink_port_by_netdev()
|
||||
{
|
||||
local if_name=$1
|
||||
|
||||
devlink -j port show $if_name | jq -e '.[] | keys' | jq -r '.[]'
|
||||
}
|
||||
|
||||
devlink_cpu_port_get()
|
||||
{
|
||||
local cpu_dl_port_num=$(devlink port list | grep "$DEVLINK_DEV" |
|
||||
grep cpu | cut -d/ -f3 | cut -d: -f1 |
|
||||
sed -n '1p')
|
||||
|
||||
echo "$DEVLINK_DEV/$cpu_dl_port_num"
|
||||
}
|
||||
|
|
|
@ -248,6 +248,33 @@ busywait()
|
|||
done
|
||||
}
|
||||
|
||||
not()
|
||||
{
|
||||
"$@"
|
||||
[[ $? != 0 ]]
|
||||
}
|
||||
|
||||
grep_bridge_fdb()
|
||||
{
|
||||
local addr=$1; shift
|
||||
local word
|
||||
local flag
|
||||
|
||||
if [ "$1" == "self" ] || [ "$1" == "master" ]; then
|
||||
word=$1; shift
|
||||
if [ "$1" == "-v" ]; then
|
||||
flag=$1; shift
|
||||
fi
|
||||
fi
|
||||
|
||||
$@ | grep $addr | grep $flag "$word"
|
||||
}
|
||||
|
||||
wait_for_offload()
|
||||
{
|
||||
"$@" | grep -q offload
|
||||
}
|
||||
|
||||
until_counter_is()
|
||||
{
|
||||
local value=$1; shift
|
||||
|
@ -607,6 +634,16 @@ ethtool_stats_get()
|
|||
ethtool -S $dev | grep "^ *$stat:" | head -n 1 | cut -d: -f2
|
||||
}
|
||||
|
||||
qdisc_stats_get()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local handle=$1; shift
|
||||
local selector=$1; shift
|
||||
|
||||
tc -j -s qdisc show dev "$dev" \
|
||||
| jq '.[] | select(.handle == "'"$handle"'") | '"$selector"
|
||||
}
|
||||
|
||||
humanize()
|
||||
{
|
||||
local speed=$1; shift
|
||||
|
@ -1132,18 +1169,29 @@ flood_test()
|
|||
flood_multicast_test $br_port $host1_if $host2_if
|
||||
}
|
||||
|
||||
start_traffic()
|
||||
__start_traffic()
|
||||
{
|
||||
local proto=$1; shift
|
||||
local h_in=$1; shift # Where the traffic egresses the host
|
||||
local sip=$1; shift
|
||||
local dip=$1; shift
|
||||
local dmac=$1; shift
|
||||
|
||||
$MZ $h_in -p 8000 -A $sip -B $dip -c 0 \
|
||||
-a own -b $dmac -t udp -q &
|
||||
-a own -b $dmac -t "$proto" -q "$@" &
|
||||
sleep 1
|
||||
}
|
||||
|
||||
start_traffic()
|
||||
{
|
||||
__start_traffic udp "$@"
|
||||
}
|
||||
|
||||
start_tcp_traffic()
|
||||
{
|
||||
__start_traffic tcp "$@"
|
||||
}
|
||||
|
||||
stop_traffic()
|
||||
{
|
||||
# Suppress noise from killing mausezahn.
|
||||
|
|
Загрузка…
Ссылка в новой задаче