# Issuing a kill still leaves a bunch of packets lingering in the # buffers. This traffic then arrives at the point where a follow-up test # is already running, and can confuse the test. Therefore sleep after # stopping traffic to flush any leftover packets.
stop_traffic "$pid"
sleep 1
}
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
defer simple_if_fini $dev
mtu_set $dev 10000
defer mtu_restore $dev
vlan_create $dev 10 v$dev $(ipaddr $host 10)/28
defer vlan_destroy $dev 10
ip link set dev $dev.10 type vlan egress 0:0
vlan_create $dev 11 v$dev $(ipaddr $host 11)/28
defer vlan_destroy $dev 11
ip link set dev $dev.11 type vlan egress 0:1
}
h1_create()
{
host_create $h1 1
}
h2_create()
{
host_create $h2 2
tc qdisc add dev $h2 clsact
defer tc qdisc del dev $h2 clsact
# 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 adding a shaper which limits the traffic in $h2 to # 1Gbps.
tc qdisc replace dev $h2 root handle 10: tbf rate 200mbit \
burst 128K limit 1G
defer tc qdisc del dev $h2 root handle 10:
}
h3_create()
{
host_create $h3 3
}
switch_create()
{
local intf
local vlan
ip link add dev br1_10 type bridge
defer ip link del dev br1_10
ip link add dev br1_11 type bridge
defer ip link del dev br1_11
ip link add dev br2_10 type bridge
defer ip link del dev br2_10
ip link add dev br2_11 type bridge
defer ip link del dev br2_11
for intf in $swp1 $swp2 $swp3 $swp4 $swp5; do
ip link set dev $intf up
defer ip link set dev $intf down
mtu_set $intf 10000
defer mtu_restore $intf done
for intf in $swp1 $swp4; do for vlan in 10 11; do
vlan_create $intf $vlan
defer vlan_destroy $intf $vlan
ip link set dev $intf.$vlan master br1_$vlan
defer ip link set dev $intf.$vlan nomaster
ip link set dev $intf.$vlan up
defer 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
defer vlan_destroy $intf $vlan
ip link set dev $intf.$vlan master br2_$vlan
defer ip link set dev $intf.$vlan nomaster
ip link set dev $intf.$vlan up
defer 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 $swp3 $swp4; do
tc qdisc replace dev $intf root handle 1: tbf rate 200mbit \
burst 128K limit 1G
defer tc qdisc del dev $intf root handle 1: done
ip link set dev br1_10 up
defer ip link set dev br1_10 down
ip link set dev br1_11 up
defer ip link set dev br1_11 down
ip link set dev br2_10 up
defer ip link set dev br2_10 down
ip link set dev br2_11 up
defer ip link set dev br2_11 down
send_packets()
{
local vlan=$1; shift
local proto=$1; shift
local pkts=$1; shift
$MZ $h2.$vlan -p 8000 -a own -b $h3_mac \
-A $(ipaddr 2 $vlan) -B $(ipaddr 3 $vlan) \
-t $proto -q -c $pkts "$@"
}
# 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
sleep 1
local cur=$(busywait 1100 until_counter_is "> $cur" \
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
send_packets $vlan $proto $pkts "$@" done
}
check_marking()
{
local get_nmarked=$1; shift
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))
}
ecn_test_common()
{
local name=$1; shift
local get_nmarked=$1; shift
local vlan=$1; shift
local limit=$1; shift
local backlog
local pct
# 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 "$get_nmarked" $vlan "== 0")
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
log_test "TC $((vlan - 10)): $name 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 "$get_nmarked" $vlan ">= 95")
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95."
log_test "TC $((vlan - 10)): $name backlog > limit"
}
__do_ecn_test()
{
local get_nmarked=$1; shift
local vlan=$1; shift
local limit=$1; shift
local name=${1-ECN}; shift
# 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)): $name backlog > limit: UDP early-dropped"
}
do_ecn_test()
{
local vlan=$1; shift
local limit=$1; shift
# Up there we saw that UDP gets accepted when backlog is below the # limit. Now that it is above, in nodrop mode, make sure it goes to # backlog as well.
RET=0
build_backlog $vlan $((2 * limit)) udp >/dev/null
check_err $? "UDP traffic was early-dropped instead of getting into backlog"
log_test "TC $((vlan - 10)): $name backlog > limit: UDP not dropped"
}
__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
defer stop_traffic_sleep $!
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"
log_test "TC $((vlan - 10)): Qdisc reports MC backlog"
}
__do_mark_test()
{
local vlan=$1; shift
local limit=$1; shift
local subtest=$1; shift
local fetch_counter=$1; shift
local should_fail=$1; shift
local base
# Above limit, everything should be mirrored, we should see lots of # packets.
build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01 >/dev/null
busywait_for_counter 1100 +2500 \
$fetch_counter > /dev/null
check_err_fail "$should_fail" $? "ECN-marked packets $subtest'd"
# When the rule is uninstalled, there should be no mirroring.
qevent_rule_uninstall_$subtest
busywait_for_counter 1100 +10 \
$fetch_counter > /dev/null
check_fail $? "Spurious packets observed after uninstall"
if ((should_fail)); then
log_test "TC $((vlan - 10)): marked packets not $subtest'd" else
log_test "TC $((vlan - 10)): marked packets $subtest'd" fi
}
__do_drop_test()
{
local vlan=$1; shift
local limit=$1; shift
local trigger=$1; shift
local subtest=$1; shift
local fetch_counter=$1; shift
local base
local now
# Push to the queue until it's at the limit. The configured limit is # rounded by the qdisc and then by the driver, so this is the best we # can do to get to the real limit of the system.
build_backlog $vlan $((3 * limit / 2)) udp >/dev/null
# When no extra traffic is injected, there should be no mirroring.
busywait 1100 until_counter_is ">= $((base + 110))" \
$fetch_counter >/dev/null
check_fail $? "Spurious packets observed"
# When the rule is uninstalled, there should be no mirroring.
qevent_rule_uninstall_$subtest
send_packets $vlan udp 100
now=$(busywait 1100 until_counter_is ">= $((base + 110))" \
$fetch_counter)
check_fail $? "$((now - base)) spurious packets observed after uninstall"
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.