cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sch_red.sh (11346B)


      1# SPDX-License-Identifier: GPL-2.0
      2
      3# This test sends one stream of traffic from H1 through a TBF shaper, to a RED
      4# within TBF shaper on $swp3. The two shapers have the same configuration, and
      5# thus the resulting stream should fill all available bandwidth on the latter
      6# shaper. A second stream is sent from H2 also via $swp3, and used to inject
      7# additional traffic. Since all available bandwidth is taken, this traffic has
      8# to go to backlog.
      9#
     10# +--------------------------+                     +--------------------------+
     11# | H1                       |                     | H2                       |
     12# |     + $h1                |                     |     + $h2                |
     13# |     | 192.0.2.1/28       |                     |     | 192.0.2.2/28       |
     14# |     | TBF 10Mbps         |                     |     |                    |
     15# +-----|--------------------+                     +-----|--------------------+
     16#       |                                                |
     17# +-----|------------------------------------------------|--------------------+
     18# | SW  |                                                |                    |
     19# |  +--|------------------------------------------------|----------------+   |
     20# |  |  + $swp1                                          + $swp2          |   |
     21# |  |                               BR                                   |   |
     22# |  |                                                                    |   |
     23# |  |                                + $swp3                             |   |
     24# |  |                                | TBF 10Mbps / RED                  |   |
     25# |  +--------------------------------|-----------------------------------+   |
     26# |                                   |                                       |
     27# +-----------------------------------|---------------------------------------+
     28#                                     |
     29#                               +-----|--------------------+
     30#			        | H3  |                    |
     31#			        |     + $h1                |
     32#			        |       192.0.2.3/28       |
     33#			        |                          |
     34#			        +--------------------------+
     35
     36ALL_TESTS="
     37	ping_ipv4
     38	ecn_test
     39	ecn_nodrop_test
     40	red_test
     41	red_qevent_test
     42	ecn_qevent_test
     43"
     44
     45NUM_NETIFS=6
     46CHECK_TC="yes"
     47source lib.sh
     48
     49BACKLOG=30000
     50PKTSZ=1400
     51
     52h1_create()
     53{
     54	simple_if_init $h1 192.0.2.1/28
     55	mtu_set $h1 10000
     56	tc qdisc replace dev $h1 root handle 1: tbf \
     57	   rate 10Mbit burst 10K limit 1M
     58}
     59
     60h1_destroy()
     61{
     62	tc qdisc del dev $h1 root
     63	mtu_restore $h1
     64	simple_if_fini $h1 192.0.2.1/28
     65}
     66
     67h2_create()
     68{
     69	simple_if_init $h2 192.0.2.2/28
     70	mtu_set $h2 10000
     71}
     72
     73h2_destroy()
     74{
     75	mtu_restore $h2
     76	simple_if_fini $h2 192.0.2.2/28
     77}
     78
     79h3_create()
     80{
     81	simple_if_init $h3 192.0.2.3/28
     82	mtu_set $h3 10000
     83}
     84
     85h3_destroy()
     86{
     87	mtu_restore $h3
     88	simple_if_fini $h3 192.0.2.3/28
     89}
     90
     91switch_create()
     92{
     93	ip link add dev br up type bridge
     94	ip link set dev $swp1 up master br
     95	ip link set dev $swp2 up master br
     96	ip link set dev $swp3 up master br
     97
     98	mtu_set $swp1 10000
     99	mtu_set $swp2 10000
    100	mtu_set $swp3 10000
    101
    102	tc qdisc replace dev $swp3 root handle 1: tbf \
    103	   rate 10Mbit burst 10K limit 1M
    104	ip link add name _drop_test up type dummy
    105}
    106
    107switch_destroy()
    108{
    109	ip link del dev _drop_test
    110	tc qdisc del dev $swp3 root
    111
    112	mtu_restore $h3
    113	mtu_restore $h2
    114	mtu_restore $h1
    115
    116	ip link set dev $swp3 down nomaster
    117	ip link set dev $swp2 down nomaster
    118	ip link set dev $swp1 down nomaster
    119	ip link del dev br
    120}
    121
    122setup_prepare()
    123{
    124	h1=${NETIFS[p1]}
    125	swp1=${NETIFS[p2]}
    126
    127	h2=${NETIFS[p3]}
    128	swp2=${NETIFS[p4]}
    129
    130	swp3=${NETIFS[p5]}
    131	h3=${NETIFS[p6]}
    132
    133	h3_mac=$(mac_get $h3)
    134
    135	vrf_prepare
    136
    137	h1_create
    138	h2_create
    139	h3_create
    140	switch_create
    141}
    142
    143cleanup()
    144{
    145	pre_cleanup
    146
    147	switch_destroy
    148	h3_destroy
    149	h2_destroy
    150	h1_destroy
    151
    152	vrf_cleanup
    153}
    154
    155ping_ipv4()
    156{
    157	ping_test $h1 192.0.2.3 " from host 1"
    158	ping_test $h2 192.0.2.3 " from host 2"
    159}
    160
    161get_qdisc_backlog()
    162{
    163	qdisc_stats_get $swp3 11: .backlog
    164}
    165
    166get_nmarked()
    167{
    168	qdisc_stats_get $swp3 11: .marked
    169}
    170
    171get_qdisc_npackets()
    172{
    173	qdisc_stats_get $swp3 11: .packets
    174}
    175
    176get_nmirrored()
    177{
    178	link_stats_get _drop_test tx packets
    179}
    180
    181send_packets()
    182{
    183	local proto=$1; shift
    184	local pkts=$1; shift
    185
    186	$MZ $h2 -p $PKTSZ -a own -b $h3_mac -A 192.0.2.2 -B 192.0.2.3 -t $proto -q -c $pkts "$@"
    187}
    188
    189# This sends traffic in an attempt to build a backlog of $size. Returns 0 on
    190# success. After 10 failed attempts it bails out and returns 1. It dumps the
    191# backlog size to stdout.
    192build_backlog()
    193{
    194	local size=$1; shift
    195	local proto=$1; shift
    196
    197	local i=0
    198
    199	while :; do
    200		local cur=$(get_qdisc_backlog)
    201		local diff=$((size - cur))
    202		local pkts=$(((diff + PKTSZ - 1) / PKTSZ))
    203
    204		if ((cur >= size)); then
    205			echo $cur
    206			return 0
    207		elif ((i++ > 10)); then
    208			echo $cur
    209			return 1
    210		fi
    211
    212		send_packets $proto $pkts "$@"
    213		sleep 1
    214	done
    215}
    216
    217check_marking()
    218{
    219	local cond=$1; shift
    220
    221	local npackets_0=$(get_qdisc_npackets)
    222	local nmarked_0=$(get_nmarked)
    223	sleep 5
    224	local npackets_1=$(get_qdisc_npackets)
    225	local nmarked_1=$(get_nmarked)
    226
    227	local nmarked_d=$((nmarked_1 - nmarked_0))
    228	local npackets_d=$((npackets_1 - npackets_0))
    229	local pct=$((100 * nmarked_d / npackets_d))
    230
    231	echo $pct
    232	((pct $cond))
    233}
    234
    235check_mirroring()
    236{
    237	local cond=$1; shift
    238
    239	local npackets_0=$(get_qdisc_npackets)
    240	local nmirrored_0=$(get_nmirrored)
    241	sleep 5
    242	local npackets_1=$(get_qdisc_npackets)
    243	local nmirrored_1=$(get_nmirrored)
    244
    245	local nmirrored_d=$((nmirrored_1 - nmirrored_0))
    246	local npackets_d=$((npackets_1 - npackets_0))
    247	local pct=$((100 * nmirrored_d / npackets_d))
    248
    249	echo $pct
    250	((pct $cond))
    251}
    252
    253ecn_test_common()
    254{
    255	local name=$1; shift
    256	local limit=$1; shift
    257	local backlog
    258	local pct
    259
    260	# Build the below-the-limit backlog using UDP. We could use TCP just
    261	# fine, but this way we get a proof that UDP is accepted when queue
    262	# length is below the limit. The main stream is using TCP, and if the
    263	# limit is misconfigured, we would see this traffic being ECN marked.
    264	RET=0
    265	backlog=$(build_backlog $((2 * limit / 3)) udp)
    266	check_err $? "Could not build the requested backlog"
    267	pct=$(check_marking "== 0")
    268	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
    269	log_test "$name backlog < limit"
    270
    271	# Now push TCP, because non-TCP traffic would be early-dropped after the
    272	# backlog crosses the limit, and we want to make sure that the backlog
    273	# is above the limit.
    274	RET=0
    275	backlog=$(build_backlog $((3 * limit / 2)) tcp tos=0x01)
    276	check_err $? "Could not build the requested backlog"
    277	pct=$(check_marking ">= 95")
    278	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95."
    279	log_test "$name backlog > limit"
    280}
    281
    282do_ecn_test()
    283{
    284	local limit=$1; shift
    285	local name=ECN
    286
    287	$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
    288		-a own -b $h3_mac -t tcp -q tos=0x01 &
    289	sleep 1
    290
    291	ecn_test_common "$name" $limit
    292
    293	# Up there we saw that UDP gets accepted when backlog is below the
    294	# limit. Now that it is above, it should all get dropped, and backlog
    295	# building should fail.
    296	RET=0
    297	build_backlog $((2 * limit)) udp >/dev/null
    298	check_fail $? "UDP traffic went into backlog instead of being early-dropped"
    299	log_test "$name backlog > limit: UDP early-dropped"
    300
    301	stop_traffic
    302	sleep 1
    303}
    304
    305do_ecn_nodrop_test()
    306{
    307	local limit=$1; shift
    308	local name="ECN nodrop"
    309
    310	$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
    311		-a own -b $h3_mac -t tcp -q tos=0x01 &
    312	sleep 1
    313
    314	ecn_test_common "$name" $limit
    315
    316	# Up there we saw that UDP gets accepted when backlog is below the
    317	# limit. Now that it is above, in nodrop mode, make sure it goes to
    318	# backlog as well.
    319	RET=0
    320	build_backlog $((2 * limit)) udp >/dev/null
    321	check_err $? "UDP traffic was early-dropped instead of getting into backlog"
    322	log_test "$name backlog > limit: UDP not dropped"
    323
    324	stop_traffic
    325	sleep 1
    326}
    327
    328do_red_test()
    329{
    330	local limit=$1; shift
    331	local backlog
    332	local pct
    333
    334	# Use ECN-capable TCP to verify there's no marking even though the queue
    335	# is above limit.
    336	$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
    337		-a own -b $h3_mac -t tcp -q tos=0x01 &
    338
    339	# Pushing below the queue limit should work.
    340	RET=0
    341	backlog=$(build_backlog $((2 * limit / 3)) tcp tos=0x01)
    342	check_err $? "Could not build the requested backlog"
    343	pct=$(check_marking "== 0")
    344	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
    345	log_test "RED backlog < limit"
    346
    347	# Pushing above should not.
    348	RET=0
    349	backlog=$(build_backlog $((3 * limit / 2)) tcp tos=0x01)
    350	check_fail $? "Traffic went into backlog instead of being early-dropped"
    351	pct=$(check_marking "== 0")
    352	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
    353	log_test "RED backlog > limit"
    354
    355	stop_traffic
    356	sleep 1
    357}
    358
    359do_red_qevent_test()
    360{
    361	local limit=$1; shift
    362	local backlog
    363	local base
    364	local now
    365	local pct
    366
    367	RET=0
    368
    369	$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
    370		-a own -b $h3_mac -t udp -q &
    371	sleep 1
    372
    373	tc filter add block 10 pref 1234 handle 102 matchall skip_hw \
    374	   action mirred egress mirror dev _drop_test
    375
    376	# Push to the queue until it's at the limit. The configured limit is
    377	# rounded by the qdisc, so this is the best we can do to get to the real
    378	# limit.
    379	build_backlog $((3 * limit / 2)) udp >/dev/null
    380
    381	base=$(get_nmirrored)
    382	send_packets udp 100
    383	sleep 1
    384	now=$(get_nmirrored)
    385	((now >= base + 100))
    386	check_err $? "Dropped packets not observed: 100 expected, $((now - base)) seen"
    387
    388	tc filter del block 10 pref 1234 handle 102 matchall
    389
    390	base=$(get_nmirrored)
    391	send_packets udp 100
    392	sleep 1
    393	now=$(get_nmirrored)
    394	((now == base))
    395	check_err $? "Dropped packets still observed: 0 expected, $((now - base)) seen"
    396
    397	log_test "RED early_dropped packets mirrored"
    398
    399	stop_traffic
    400	sleep 1
    401}
    402
    403do_ecn_qevent_test()
    404{
    405	local limit=$1; shift
    406	local name=ECN
    407
    408	RET=0
    409
    410	$MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \
    411		-a own -b $h3_mac -t tcp -q tos=0x01 &
    412	sleep 1
    413
    414	tc filter add block 10 pref 1234 handle 102 matchall skip_hw \
    415	   action mirred egress mirror dev _drop_test
    416
    417	backlog=$(build_backlog $((2 * limit / 3)) tcp tos=0x01)
    418	check_err $? "Could not build the requested backlog"
    419	pct=$(check_mirroring "== 0")
    420	check_err $? "backlog $backlog / $limit Got $pct% mirrored packets, expected == 0."
    421
    422	backlog=$(build_backlog $((3 * limit / 2)) tcp tos=0x01)
    423	check_err $? "Could not build the requested backlog"
    424	pct=$(check_mirroring ">= 95")
    425	check_err $? "backlog $backlog / $limit Got $pct% mirrored packets, expected >= 95."
    426
    427	tc filter del block 10 pref 1234 handle 102 matchall
    428
    429	log_test "ECN marked packets mirrored"
    430
    431	stop_traffic
    432	sleep 1
    433}
    434
    435install_qdisc()
    436{
    437	local -a args=("$@")
    438
    439	tc qdisc replace dev $swp3 parent 1:1 handle 11: red \
    440	   limit 1M avpkt $PKTSZ probability 1 \
    441	   min $BACKLOG max $((BACKLOG + 1)) burst 38 "${args[@]}"
    442	sleep 1
    443}
    444
    445uninstall_qdisc()
    446{
    447	tc qdisc del dev $swp3 parent 1:1
    448}
    449
    450ecn_test()
    451{
    452	install_qdisc ecn
    453	do_ecn_test $BACKLOG
    454	uninstall_qdisc
    455}
    456
    457ecn_nodrop_test()
    458{
    459	install_qdisc ecn nodrop
    460	do_ecn_nodrop_test $BACKLOG
    461	uninstall_qdisc
    462}
    463
    464red_test()
    465{
    466	install_qdisc
    467	do_red_test $BACKLOG
    468	uninstall_qdisc
    469}
    470
    471red_qevent_test()
    472{
    473	install_qdisc qevent early_drop block 10
    474	do_red_qevent_test $BACKLOG
    475	uninstall_qdisc
    476}
    477
    478ecn_qevent_test()
    479{
    480	install_qdisc ecn qevent mark block 10
    481	do_ecn_qevent_test $BACKLOG
    482	uninstall_qdisc
    483}
    484
    485trap cleanup EXIT
    486
    487setup_prepare
    488setup_wait
    489
    490tests_run
    491
    492exit $EXIT_STATUS