hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/tools/testing/selftests/net/forwarding/lib.sh
....@@ -15,6 +15,11 @@
1515 PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no}
1616 NETIF_TYPE=${NETIF_TYPE:=veth}
1717 NETIF_CREATE=${NETIF_CREATE:=yes}
18
+MCD=${MCD:=smcrouted}
19
+MC_CLI=${MC_CLI:=smcroutectl}
20
+PING_TIMEOUT=${PING_TIMEOUT:=5}
21
+WAIT_TIMEOUT=${WAIT_TIMEOUT:=20}
22
+INTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600}
1823
1924 relative_path="${BASH_SOURCE%/*}"
2025 if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then
....@@ -51,6 +56,15 @@
5156 tc help 2>&1|grep chain &> /dev/null
5257 if [[ $? -ne 0 ]]; then
5358 echo "SKIP: iproute2 too old; tc is missing chain support"
59
+ exit 1
60
+ fi
61
+}
62
+
63
+check_tc_action_hw_stats_support()
64
+{
65
+ tc actions help 2>&1 | grep -q hw_stats
66
+ if [[ $? -ne 0 ]]; then
67
+ echo "SKIP: iproute2 too old; tc is missing action hw_stats support"
5468 exit 1
5569 fi
5670 }
....@@ -104,7 +118,7 @@
104118 {
105119 local i
106120
107
- for i in $(eval echo {1..$NUM_NETIFS}); do
121
+ for ((i = 1; i <= NUM_NETIFS; ++i)); do
108122 local j=$((i+1))
109123
110124 ip link show dev ${NETIFS[p$i]} &> /dev/null
....@@ -135,7 +149,7 @@
135149 create_netif
136150 fi
137151
138
-for i in $(eval echo {1..$NUM_NETIFS}); do
152
+for ((i = 1; i <= NUM_NETIFS; ++i)); do
139153 ip link show dev ${NETIFS[p$i]} &> /dev/null
140154 if [[ $? -ne 0 ]]; then
141155 echo "SKIP: could not find all required interfaces"
....@@ -209,7 +223,7 @@
209223 return 1
210224 fi
211225
212
- printf "TEST: %-60s [PASS]\n" "$test_name $opt_str"
226
+ printf "TEST: %-60s [ OK ]\n" "$test_name $opt_str"
213227 return 0
214228 }
215229
....@@ -220,31 +234,144 @@
220234 echo "INFO: $msg"
221235 }
222236
237
+busywait()
238
+{
239
+ local timeout=$1; shift
240
+
241
+ local start_time="$(date -u +%s%3N)"
242
+ while true
243
+ do
244
+ local out
245
+ out=$("$@")
246
+ local ret=$?
247
+ if ((!ret)); then
248
+ echo -n "$out"
249
+ return 0
250
+ fi
251
+
252
+ local current_time="$(date -u +%s%3N)"
253
+ if ((current_time - start_time > timeout)); then
254
+ echo -n "$out"
255
+ return 1
256
+ fi
257
+ done
258
+}
259
+
260
+not()
261
+{
262
+ "$@"
263
+ [[ $? != 0 ]]
264
+}
265
+
266
+grep_bridge_fdb()
267
+{
268
+ local addr=$1; shift
269
+ local word
270
+ local flag
271
+
272
+ if [ "$1" == "self" ] || [ "$1" == "master" ]; then
273
+ word=$1; shift
274
+ if [ "$1" == "-v" ]; then
275
+ flag=$1; shift
276
+ fi
277
+ fi
278
+
279
+ $@ | grep $addr | grep $flag "$word"
280
+}
281
+
282
+wait_for_offload()
283
+{
284
+ "$@" | grep -q offload
285
+}
286
+
287
+until_counter_is()
288
+{
289
+ local expr=$1; shift
290
+ local current=$("$@")
291
+
292
+ echo $((current))
293
+ ((current $expr))
294
+}
295
+
296
+busywait_for_counter()
297
+{
298
+ local timeout=$1; shift
299
+ local delta=$1; shift
300
+
301
+ local base=$("$@")
302
+ busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"
303
+}
304
+
223305 setup_wait_dev()
224306 {
225307 local dev=$1; shift
308
+ local wait_time=${1:-$WAIT_TIME}; shift
226309
227
- while true; do
310
+ setup_wait_dev_with_timeout "$dev" $INTERFACE_TIMEOUT $wait_time
311
+
312
+ if (($?)); then
313
+ check_err 1
314
+ log_test setup_wait_dev ": Interface $dev does not come up."
315
+ exit 1
316
+ fi
317
+}
318
+
319
+setup_wait_dev_with_timeout()
320
+{
321
+ local dev=$1; shift
322
+ local max_iterations=${1:-$WAIT_TIMEOUT}; shift
323
+ local wait_time=${1:-$WAIT_TIME}; shift
324
+ local i
325
+
326
+ for ((i = 1; i <= $max_iterations; ++i)); do
228327 ip link show dev $dev up \
229328 | grep 'state UP' &> /dev/null
230329 if [[ $? -ne 0 ]]; then
231330 sleep 1
232331 else
233
- break
332
+ sleep $wait_time
333
+ return 0
234334 fi
235335 done
336
+
337
+ return 1
236338 }
237339
238340 setup_wait()
239341 {
240342 local num_netifs=${1:-$NUM_NETIFS}
343
+ local i
241344
242345 for ((i = 1; i <= num_netifs; ++i)); do
243
- setup_wait_dev ${NETIFS[p$i]}
346
+ setup_wait_dev ${NETIFS[p$i]} 0
244347 done
245348
246349 # Make sure links are ready.
247350 sleep $WAIT_TIME
351
+}
352
+
353
+cmd_jq()
354
+{
355
+ local cmd=$1
356
+ local jq_exp=$2
357
+ local jq_opts=$3
358
+ local ret
359
+ local output
360
+
361
+ output="$($cmd)"
362
+ # it the command fails, return error right away
363
+ ret=$?
364
+ if [[ $ret -ne 0 ]]; then
365
+ return $ret
366
+ fi
367
+ output=$(echo $output | jq -r $jq_opts "$jq_exp")
368
+ ret=$?
369
+ if [[ $ret -ne 0 ]]; then
370
+ return $ret
371
+ fi
372
+ echo $output
373
+ # return success only in case of non-empty output
374
+ [ ! -z "$output" ]
248375 }
249376
250377 lldpad_app_wait_set()
....@@ -477,11 +604,24 @@
477604 ip -j link show dev $if_name | jq -r '.[]["master"]'
478605 }
479606
607
+link_stats_get()
608
+{
609
+ local if_name=$1; shift
610
+ local dir=$1; shift
611
+ local stat=$1; shift
612
+
613
+ ip -j -s link show dev $if_name \
614
+ | jq '.[]["stats64"]["'$dir'"]["'$stat'"]'
615
+}
616
+
480617 link_stats_tx_packets_get()
481618 {
482
- local if_name=$1
619
+ link_stats_get $1 tx packets
620
+}
483621
484
- ip -j -s link show dev $if_name | jq '.[]["stats64"]["tx"]["packets"]'
622
+link_stats_rx_errors_get()
623
+{
624
+ link_stats_get $1 rx errors
485625 }
486626
487627 tc_rule_stats_get()
....@@ -489,9 +629,81 @@
489629 local dev=$1; shift
490630 local pref=$1; shift
491631 local dir=$1; shift
632
+ local selector=${1:-.packets}; shift
492633
493634 tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \
494
- | jq '.[1].options.actions[].stats.packets'
635
+ | jq ".[1].options.actions[].stats$selector"
636
+}
637
+
638
+tc_rule_handle_stats_get()
639
+{
640
+ local id=$1; shift
641
+ local handle=$1; shift
642
+ local selector=${1:-.packets}; shift
643
+
644
+ tc -j -s filter show $id \
645
+ | jq ".[] | select(.options.handle == $handle) | \
646
+ .options.actions[0].stats$selector"
647
+}
648
+
649
+ethtool_stats_get()
650
+{
651
+ local dev=$1; shift
652
+ local stat=$1; shift
653
+
654
+ ethtool -S $dev | grep "^ *$stat:" | head -n 1 | cut -d: -f2
655
+}
656
+
657
+qdisc_stats_get()
658
+{
659
+ local dev=$1; shift
660
+ local handle=$1; shift
661
+ local selector=$1; shift
662
+
663
+ tc -j -s qdisc show dev "$dev" \
664
+ | jq '.[] | select(.handle == "'"$handle"'") | '"$selector"
665
+}
666
+
667
+qdisc_parent_stats_get()
668
+{
669
+ local dev=$1; shift
670
+ local parent=$1; shift
671
+ local selector=$1; shift
672
+
673
+ tc -j -s qdisc show dev "$dev" invisible \
674
+ | jq '.[] | select(.parent == "'"$parent"'") | '"$selector"
675
+}
676
+
677
+ipv6_stats_get()
678
+{
679
+ local dev=$1; shift
680
+ local stat=$1; shift
681
+
682
+ cat /proc/net/dev_snmp6/$dev | grep "^$stat" | cut -f2
683
+}
684
+
685
+humanize()
686
+{
687
+ local speed=$1; shift
688
+
689
+ for unit in bps Kbps Mbps Gbps; do
690
+ if (($(echo "$speed < 1024" | bc))); then
691
+ break
692
+ fi
693
+
694
+ speed=$(echo "scale=1; $speed / 1024" | bc)
695
+ done
696
+
697
+ echo "$speed${unit}"
698
+}
699
+
700
+rate()
701
+{
702
+ local t0=$1; shift
703
+ local t1=$1; shift
704
+ local interval=$1; shift
705
+
706
+ echo $((8 * (t1 - t0) / interval))
495707 }
496708
497709 mac_get()
....@@ -539,6 +751,23 @@
539751 {
540752 sysctl_restore net.ipv6.conf.all.forwarding
541753 sysctl_restore net.ipv4.conf.all.forwarding
754
+}
755
+
756
+declare -A MTU_ORIG
757
+mtu_set()
758
+{
759
+ local dev=$1; shift
760
+ local mtu=$1; shift
761
+
762
+ MTU_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].mtu')
763
+ ip link set dev $dev mtu $mtu
764
+}
765
+
766
+mtu_restore()
767
+{
768
+ local dev=$1; shift
769
+
770
+ ip link set dev $dev mtu ${MTU_ORIG["$dev"]}
542771 }
543772
544773 tc_offload_check()
....@@ -758,6 +987,17 @@
758987 log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio"
759988 }
760989
990
+in_ns()
991
+{
992
+ local name=$1; shift
993
+
994
+ ip netns exec $name bash <<-EOF
995
+ NUM_NETIFS=0
996
+ source lib.sh
997
+ $(for a in "$@"; do printf "%q${IFS:0:1}" "$a"; done)
998
+ EOF
999
+}
1000
+
7611001 ##############################################################################
7621002 # Tests
7631003
....@@ -765,10 +1005,12 @@
7651005 {
7661006 local if_name=$1
7671007 local dip=$2
1008
+ local args=$3
7681009 local vrf_name
7691010
7701011 vrf_name=$(master_name_get $if_name)
771
- ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null
1012
+ ip vrf exec $vrf_name \
1013
+ $PING $args $dip -c 10 -i 0.1 -w $PING_TIMEOUT &> /dev/null
7721014 }
7731015
7741016 ping_test()
....@@ -777,17 +1019,19 @@
7771019
7781020 ping_do $1 $2
7791021 check_err $?
780
- log_test "ping"
1022
+ log_test "ping$3"
7811023 }
7821024
7831025 ping6_do()
7841026 {
7851027 local if_name=$1
7861028 local dip=$2
1029
+ local args=$3
7871030 local vrf_name
7881031
7891032 vrf_name=$(master_name_get $if_name)
790
- ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null
1033
+ ip vrf exec $vrf_name \
1034
+ $PING6 $args $dip -c 10 -i 0.1 -w $PING_TIMEOUT &> /dev/null
7911035 }
7921036
7931037 ping6_test()
....@@ -796,7 +1040,7 @@
7961040
7971041 ping6_do $1 $2
7981042 check_err $?
799
- log_test "ping6"
1043
+ log_test "ping6$3"
8001044 }
8011045
8021046 learning_test()
....@@ -819,6 +1063,7 @@
8191063 # FDB entry was installed.
8201064 bridge link set dev $br_port1 flood off
8211065
1066
+ ip link set $host1_if promisc on
8221067 tc qdisc add dev $host1_if ingress
8231068 tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \
8241069 flower dst_mac $mac action drop
....@@ -829,7 +1074,7 @@
8291074 tc -j -s filter show dev $host1_if ingress \
8301075 | jq -e ".[] | select(.options.handle == 101) \
8311076 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
832
- check_fail $? "Packet reached second host when should not"
1077
+ check_fail $? "Packet reached first host when should not"
8331078
8341079 $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
8351080 sleep 1
....@@ -868,6 +1113,7 @@
8681113
8691114 tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower
8701115 tc qdisc del dev $host1_if ingress
1116
+ ip link set $host1_if promisc off
8711117
8721118 bridge link set dev $br_port1 flood on
8731119
....@@ -885,6 +1131,7 @@
8851131
8861132 # Add an ACL on `host2_if` which will tell us whether the packet
8871133 # was flooded to it or not.
1134
+ ip link set $host2_if promisc on
8881135 tc qdisc add dev $host2_if ingress
8891136 tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \
8901137 flower dst_mac $mac action drop
....@@ -902,6 +1149,7 @@
9021149
9031150 tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower
9041151 tc qdisc del dev $host2_if ingress
1152
+ ip link set $host2_if promisc off
9051153
9061154 return $err
9071155 }
....@@ -962,3 +1210,75 @@
9621210 flood_unicast_test $br_port $host1_if $host2_if
9631211 flood_multicast_test $br_port $host1_if $host2_if
9641212 }
1213
+
1214
+__start_traffic()
1215
+{
1216
+ local proto=$1; shift
1217
+ local h_in=$1; shift # Where the traffic egresses the host
1218
+ local sip=$1; shift
1219
+ local dip=$1; shift
1220
+ local dmac=$1; shift
1221
+
1222
+ $MZ $h_in -p 8000 -A $sip -B $dip -c 0 \
1223
+ -a own -b $dmac -t "$proto" -q "$@" &
1224
+ sleep 1
1225
+}
1226
+
1227
+start_traffic()
1228
+{
1229
+ __start_traffic udp "$@"
1230
+}
1231
+
1232
+start_tcp_traffic()
1233
+{
1234
+ __start_traffic tcp "$@"
1235
+}
1236
+
1237
+stop_traffic()
1238
+{
1239
+ # Suppress noise from killing mausezahn.
1240
+ { kill %% && wait %%; } 2>/dev/null
1241
+}
1242
+
1243
+tcpdump_start()
1244
+{
1245
+ local if_name=$1; shift
1246
+ local ns=$1; shift
1247
+
1248
+ capfile=$(mktemp)
1249
+ capout=$(mktemp)
1250
+
1251
+ if [ -z $ns ]; then
1252
+ ns_cmd=""
1253
+ else
1254
+ ns_cmd="ip netns exec ${ns}"
1255
+ fi
1256
+
1257
+ if [ -z $SUDO_USER ] ; then
1258
+ capuser=""
1259
+ else
1260
+ capuser="-Z $SUDO_USER"
1261
+ fi
1262
+
1263
+ $ns_cmd tcpdump -e -n -Q in -i $if_name \
1264
+ -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
1265
+ cappid=$!
1266
+
1267
+ sleep 1
1268
+}
1269
+
1270
+tcpdump_stop()
1271
+{
1272
+ $ns_cmd kill $cappid
1273
+ sleep 1
1274
+}
1275
+
1276
+tcpdump_cleanup()
1277
+{
1278
+ rm $capfile $capout
1279
+}
1280
+
1281
+tcpdump_show()
1282
+{
1283
+ tcpdump -e -n -r $capfile 2>&1
1284
+}