# This test sends one stream of traffic from H1 through a TBF shaper, to a RED # within TBF shaper on $swp3. The two shapers have the same configuration, and # thus the resulting stream should fill all available bandwidth on the latter # shaper. A second stream is sent from H2 also via $swp3, and used to inject # additional traffic. Since all available bandwidth is taken, this traffic has # to go to backlog. # # +--------------------------+ +--------------------------+ # | H1 | | H2 | # | + $h1 | | + $h2 | # | | 192.0.2.1/28 | | | 192.0.2.2/28 | # | | TBF 10Mbps | | | | # +-----|--------------------+ +-----|--------------------+ # | | # +-----|------------------------------------------------|--------------------+ # | SW | | | # | +--|------------------------------------------------|----------------+ | # | | + $swp1 + $swp2 | | # | | BR | | # | | | | # | | + $swp3 | | # | | | TBF 10Mbps / RED | | # | +--------------------------------|-----------------------------------+ | # | | | # +-----------------------------------|---------------------------------------+ # | # +-----|--------------------+ # | H3 | | # | + $h1 | # | 192.0.2.3/28 | # | | # +--------------------------+
send_packets()
{
local proto=$1; shift
local pkts=$1; shift
$MZ $h2 -p $PKTSZ -a own -b $h3_mac -A 192.0.2.2 -B 192.0.2.3 -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 size=$1; shift
local proto=$1; shift
local i=0
while :; do
local cur=$(get_qdisc_backlog)
local diff=$((size - cur))
local pkts=$(((diff + PKTSZ - 1) / PKTSZ))
if ((cur >= size)); then echo $cur
return 0 elif ((i++ > 10)); then echo $cur
return 1 fi
send_packets $proto $pkts "$@"
sleep 1 done
}
check_marking()
{
local cond=$1; shift
local npackets_0=$(get_qdisc_npackets)
local nmarked_0=$(get_nmarked)
sleep 5
local npackets_1=$(get_qdisc_npackets)
local nmarked_1=$(get_nmarked)
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))
}
check_mirroring()
{
local cond=$1; shift
local npackets_0=$(get_qdisc_npackets)
local nmirrored_0=$(get_nmirrored)
sleep 5
local npackets_1=$(get_qdisc_npackets)
local nmirrored_1=$(get_nmirrored)
local nmirrored_d=$((nmirrored_1 - nmirrored_0))
local npackets_d=$((npackets_1 - npackets_0))
local pct=$((100 * nmirrored_d / npackets_d))
echo $pct
((pct $cond))
}
ecn_test_common()
{
local name=$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 $((2 * limit / 3)) udp)
check_err $? "Could not build the requested backlog"
pct=$(check_marking "== 0")
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
log_test "$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 $((3 * limit / 2)) tcp tos=0x01)
check_err $? "Could not build the requested backlog"
pct=$(check_marking ">= 95")
check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95."
log_test "$name backlog > limit"
}
do_ecn_test()
{
local limit=$1; shift
local name=ECN
$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
-a own -b $h3_mac -t tcp -q tos=0x01 &
defer stop_traffic $!
sleep 1
ecn_test_common "$name" $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 $((2 * limit)) udp >/dev/null
check_fail $? "UDP traffic went into backlog instead of being early-dropped"
log_test "$name backlog > limit: UDP early-dropped"
}
do_ecn_nodrop_test()
{
local limit=$1; shift
local name="ECN nodrop"
$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
-a own -b $h3_mac -t tcp -q tos=0x01 &
defer stop_traffic $!
sleep 1
ecn_test_common "$name" $limit
# 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 $((2 * limit)) udp >/dev/null
check_err $? "UDP traffic was early-dropped instead of getting into backlog"
log_test "$name backlog > limit: UDP not dropped"
}
do_red_test()
{
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.
$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
-a own -b $h3_mac -t tcp -q tos=0x01 &
defer stop_traffic $!
# Push to the queue until it's at the limit. The configured limit is # rounded by the qdisc, so this is the best we can do to get to the real # limit.
build_backlog $((3 * limit / 2)) udp >/dev/null
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.