0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 ALL_TESTS="
0038 ping_ipv4
0039 ecn_test
0040 ecn_nodrop_test
0041 red_test
0042 red_qevent_test
0043 ecn_qevent_test
0044 "
0045
0046 NUM_NETIFS=6
0047 CHECK_TC="yes"
0048 source lib.sh
0049
0050 BACKLOG=30000
0051 PKTSZ=1400
0052
0053 h1_create()
0054 {
0055 simple_if_init $h1 192.0.2.1/28
0056 mtu_set $h1 10000
0057 tc qdisc replace dev $h1 root handle 1: tbf \
0058 rate 10Mbit burst 10K limit 1M
0059 }
0060
0061 h1_destroy()
0062 {
0063 tc qdisc del dev $h1 root
0064 mtu_restore $h1
0065 simple_if_fini $h1 192.0.2.1/28
0066 }
0067
0068 h2_create()
0069 {
0070 simple_if_init $h2 192.0.2.2/28
0071 mtu_set $h2 10000
0072 }
0073
0074 h2_destroy()
0075 {
0076 mtu_restore $h2
0077 simple_if_fini $h2 192.0.2.2/28
0078 }
0079
0080 h3_create()
0081 {
0082 simple_if_init $h3 192.0.2.3/28
0083 mtu_set $h3 10000
0084 }
0085
0086 h3_destroy()
0087 {
0088 mtu_restore $h3
0089 simple_if_fini $h3 192.0.2.3/28
0090 }
0091
0092 switch_create()
0093 {
0094 ip link add dev br up type bridge
0095 ip link set dev $swp1 up master br
0096 ip link set dev $swp2 up master br
0097 ip link set dev $swp3 up master br
0098
0099 mtu_set $swp1 10000
0100 mtu_set $swp2 10000
0101 mtu_set $swp3 10000
0102
0103 tc qdisc replace dev $swp3 root handle 1: tbf \
0104 rate 10Mbit burst 10K limit 1M
0105 ip link add name _drop_test up type dummy
0106 }
0107
0108 switch_destroy()
0109 {
0110 ip link del dev _drop_test
0111 tc qdisc del dev $swp3 root
0112
0113 mtu_restore $h3
0114 mtu_restore $h2
0115 mtu_restore $h1
0116
0117 ip link set dev $swp3 down nomaster
0118 ip link set dev $swp2 down nomaster
0119 ip link set dev $swp1 down nomaster
0120 ip link del dev br
0121 }
0122
0123 setup_prepare()
0124 {
0125 h1=${NETIFS[p1]}
0126 swp1=${NETIFS[p2]}
0127
0128 h2=${NETIFS[p3]}
0129 swp2=${NETIFS[p4]}
0130
0131 swp3=${NETIFS[p5]}
0132 h3=${NETIFS[p6]}
0133
0134 h3_mac=$(mac_get $h3)
0135
0136 vrf_prepare
0137
0138 h1_create
0139 h2_create
0140 h3_create
0141 switch_create
0142 }
0143
0144 cleanup()
0145 {
0146 pre_cleanup
0147
0148 switch_destroy
0149 h3_destroy
0150 h2_destroy
0151 h1_destroy
0152
0153 vrf_cleanup
0154 }
0155
0156 ping_ipv4()
0157 {
0158 ping_test $h1 192.0.2.3 " from host 1"
0159 ping_test $h2 192.0.2.3 " from host 2"
0160 }
0161
0162 get_qdisc_backlog()
0163 {
0164 qdisc_stats_get $swp3 11: .backlog
0165 }
0166
0167 get_nmarked()
0168 {
0169 qdisc_stats_get $swp3 11: .marked
0170 }
0171
0172 get_qdisc_npackets()
0173 {
0174 qdisc_stats_get $swp3 11: .packets
0175 }
0176
0177 get_nmirrored()
0178 {
0179 link_stats_get _drop_test tx packets
0180 }
0181
0182 send_packets()
0183 {
0184 local proto=$1; shift
0185 local pkts=$1; shift
0186
0187 $MZ $h2 -p $PKTSZ -a own -b $h3_mac -A 192.0.2.2 -B 192.0.2.3 -t $proto -q -c $pkts "$@"
0188 }
0189
0190
0191
0192
0193 build_backlog()
0194 {
0195 local size=$1; shift
0196 local proto=$1; shift
0197
0198 local i=0
0199
0200 while :; do
0201 local cur=$(get_qdisc_backlog)
0202 local diff=$((size - cur))
0203 local pkts=$(((diff + PKTSZ - 1) / PKTSZ))
0204
0205 if ((cur >= size)); then
0206 echo $cur
0207 return 0
0208 elif ((i++ > 10)); then
0209 echo $cur
0210 return 1
0211 fi
0212
0213 send_packets $proto $pkts "$@"
0214 sleep 1
0215 done
0216 }
0217
0218 check_marking()
0219 {
0220 local cond=$1; shift
0221
0222 local npackets_0=$(get_qdisc_npackets)
0223 local nmarked_0=$(get_nmarked)
0224 sleep 5
0225 local npackets_1=$(get_qdisc_npackets)
0226 local nmarked_1=$(get_nmarked)
0227
0228 local nmarked_d=$((nmarked_1 - nmarked_0))
0229 local npackets_d=$((npackets_1 - npackets_0))
0230 local pct=$((100 * nmarked_d / npackets_d))
0231
0232 echo $pct
0233 ((pct $cond))
0234 }
0235
0236 check_mirroring()
0237 {
0238 local cond=$1; shift
0239
0240 local npackets_0=$(get_qdisc_npackets)
0241 local nmirrored_0=$(get_nmirrored)
0242 sleep 5
0243 local npackets_1=$(get_qdisc_npackets)
0244 local nmirrored_1=$(get_nmirrored)
0245
0246 local nmirrored_d=$((nmirrored_1 - nmirrored_0))
0247 local npackets_d=$((npackets_1 - npackets_0))
0248 local pct=$((100 * nmirrored_d / npackets_d))
0249
0250 echo $pct
0251 ((pct $cond))
0252 }
0253
0254 ecn_test_common()
0255 {
0256 local name=$1; shift
0257 local limit=$1; shift
0258 local backlog
0259 local pct
0260
0261
0262
0263
0264
0265 RET=0
0266 backlog=$(build_backlog $((2 * limit / 3)) udp)
0267 check_err $? "Could not build the requested backlog"
0268 pct=$(check_marking "== 0")
0269 check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
0270 log_test "$name backlog < limit"
0271
0272
0273
0274
0275 RET=0
0276 backlog=$(build_backlog $((3 * limit / 2)) tcp tos=0x01)
0277 check_err $? "Could not build the requested backlog"
0278 pct=$(check_marking ">= 95")
0279 check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95."
0280 log_test "$name backlog > limit"
0281 }
0282
0283 do_ecn_test()
0284 {
0285 local limit=$1; shift
0286 local name=ECN
0287
0288 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
0289 -a own -b $h3_mac -t tcp -q tos=0x01 &
0290 sleep 1
0291
0292 ecn_test_common "$name" $limit
0293
0294
0295
0296
0297 RET=0
0298 build_backlog $((2 * limit)) udp >/dev/null
0299 check_fail $? "UDP traffic went into backlog instead of being early-dropped"
0300 log_test "$name backlog > limit: UDP early-dropped"
0301
0302 stop_traffic
0303 sleep 1
0304 }
0305
0306 do_ecn_nodrop_test()
0307 {
0308 local limit=$1; shift
0309 local name="ECN nodrop"
0310
0311 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
0312 -a own -b $h3_mac -t tcp -q tos=0x01 &
0313 sleep 1
0314
0315 ecn_test_common "$name" $limit
0316
0317
0318
0319
0320 RET=0
0321 build_backlog $((2 * limit)) udp >/dev/null
0322 check_err $? "UDP traffic was early-dropped instead of getting into backlog"
0323 log_test "$name backlog > limit: UDP not dropped"
0324
0325 stop_traffic
0326 sleep 1
0327 }
0328
0329 do_red_test()
0330 {
0331 local limit=$1; shift
0332 local backlog
0333 local pct
0334
0335
0336
0337 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
0338 -a own -b $h3_mac -t tcp -q tos=0x01 &
0339
0340
0341 RET=0
0342 backlog=$(build_backlog $((2 * limit / 3)) tcp tos=0x01)
0343 check_err $? "Could not build the requested backlog"
0344 pct=$(check_marking "== 0")
0345 check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
0346 log_test "RED backlog < limit"
0347
0348
0349 RET=0
0350 backlog=$(build_backlog $((3 * limit / 2)) tcp tos=0x01)
0351 check_fail $? "Traffic went into backlog instead of being early-dropped"
0352 pct=$(check_marking "== 0")
0353 check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
0354 log_test "RED backlog > limit"
0355
0356 stop_traffic
0357 sleep 1
0358 }
0359
0360 do_red_qevent_test()
0361 {
0362 local limit=$1; shift
0363 local backlog
0364 local base
0365 local now
0366 local pct
0367
0368 RET=0
0369
0370 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
0371 -a own -b $h3_mac -t udp -q &
0372 sleep 1
0373
0374 tc filter add block 10 pref 1234 handle 102 matchall skip_hw \
0375 action mirred egress mirror dev _drop_test
0376
0377
0378
0379
0380 build_backlog $((3 * limit / 2)) udp >/dev/null
0381
0382 base=$(get_nmirrored)
0383 send_packets udp 100
0384 sleep 1
0385 now=$(get_nmirrored)
0386 ((now >= base + 100))
0387 check_err $? "Dropped packets not observed: 100 expected, $((now - base)) seen"
0388
0389 tc filter del block 10 pref 1234 handle 102 matchall
0390
0391 base=$(get_nmirrored)
0392 send_packets udp 100
0393 sleep 1
0394 now=$(get_nmirrored)
0395 ((now == base))
0396 check_err $? "Dropped packets still observed: 0 expected, $((now - base)) seen"
0397
0398 log_test "RED early_dropped packets mirrored"
0399
0400 stop_traffic
0401 sleep 1
0402 }
0403
0404 do_ecn_qevent_test()
0405 {
0406 local limit=$1; shift
0407 local name=ECN
0408
0409 RET=0
0410
0411 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
0412 -a own -b $h3_mac -t tcp -q tos=0x01 &
0413 sleep 1
0414
0415 tc filter add block 10 pref 1234 handle 102 matchall skip_hw \
0416 action mirred egress mirror dev _drop_test
0417
0418 backlog=$(build_backlog $((2 * limit / 3)) tcp tos=0x01)
0419 check_err $? "Could not build the requested backlog"
0420 pct=$(check_mirroring "== 0")
0421 check_err $? "backlog $backlog / $limit Got $pct% mirrored packets, expected == 0."
0422
0423 backlog=$(build_backlog $((3 * limit / 2)) tcp tos=0x01)
0424 check_err $? "Could not build the requested backlog"
0425 pct=$(check_mirroring ">= 95")
0426 check_err $? "backlog $backlog / $limit Got $pct% mirrored packets, expected >= 95."
0427
0428 tc filter del block 10 pref 1234 handle 102 matchall
0429
0430 log_test "ECN marked packets mirrored"
0431
0432 stop_traffic
0433 sleep 1
0434 }
0435
0436 install_qdisc()
0437 {
0438 local -a args=("$@")
0439
0440 tc qdisc replace dev $swp3 parent 1:1 handle 11: red \
0441 limit 1M avpkt $PKTSZ probability 1 \
0442 min $BACKLOG max $((BACKLOG + 1)) burst 38 "${args[@]}"
0443 sleep 1
0444 }
0445
0446 uninstall_qdisc()
0447 {
0448 tc qdisc del dev $swp3 parent 1:1
0449 }
0450
0451 ecn_test()
0452 {
0453 install_qdisc ecn
0454 do_ecn_test $BACKLOG
0455 uninstall_qdisc
0456 }
0457
0458 ecn_nodrop_test()
0459 {
0460 install_qdisc ecn nodrop
0461 do_ecn_nodrop_test $BACKLOG
0462 uninstall_qdisc
0463 }
0464
0465 red_test()
0466 {
0467 install_qdisc
0468 do_red_test $BACKLOG
0469 uninstall_qdisc
0470 }
0471
0472 red_qevent_test()
0473 {
0474 install_qdisc qevent early_drop block 10
0475 do_red_qevent_test $BACKLOG
0476 uninstall_qdisc
0477 }
0478
0479 ecn_qevent_test()
0480 {
0481 install_qdisc ecn qevent mark block 10
0482 do_ecn_qevent_test $BACKLOG
0483 uninstall_qdisc
0484 }
0485
0486 trap cleanup EXIT
0487
0488 setup_prepare
0489 setup_wait
0490
0491 tests_run
0492
0493 exit $EXIT_STATUS