GNU Linux-libre 4.19.286-gnu1
[releases.git] / tools / testing / selftests / drivers / net / mlxsw / tc_flower_scale.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 # Test for resource limit of offloaded flower rules. The test adds a given
5 # number of flower matches for different IPv6 addresses, then generates traffic,
6 # and ensures each was hit exactly once. This file contains functions to set up
7 # a testing topology and run the test, and is meant to be sourced from a test
8 # script that calls the testing routine with a given number of rules.
9
10 TC_FLOWER_NUM_NETIFS=2
11
12 tc_flower_h1_create()
13 {
14         simple_if_init $h1
15         tc qdisc add dev $h1 clsact
16 }
17
18 tc_flower_h1_destroy()
19 {
20         tc qdisc del dev $h1 clsact
21         simple_if_fini $h1
22 }
23
24 tc_flower_h2_create()
25 {
26         simple_if_init $h2
27         tc qdisc add dev $h2 clsact
28 }
29
30 tc_flower_h2_destroy()
31 {
32         tc qdisc del dev $h2 clsact
33         simple_if_fini $h2
34 }
35
36 tc_flower_setup_prepare()
37 {
38         h1=${NETIFS[p1]}
39         h2=${NETIFS[p2]}
40
41         vrf_prepare
42
43         tc_flower_h1_create
44         tc_flower_h2_create
45 }
46
47 tc_flower_cleanup()
48 {
49         pre_cleanup
50
51         tc_flower_h2_destroy
52         tc_flower_h1_destroy
53
54         vrf_cleanup
55
56         if [[ -v TC_FLOWER_BATCH_FILE ]]; then
57                 rm -f $TC_FLOWER_BATCH_FILE
58         fi
59 }
60
61 tc_flower_addr()
62 {
63         local num=$1; shift
64
65         printf "2001:db8:1::%x" $num
66 }
67
68 tc_flower_rules_create()
69 {
70         local count=$1; shift
71         local should_fail=$1; shift
72
73         TC_FLOWER_BATCH_FILE="$(mktemp)"
74
75         for ((i = 0; i < count; ++i)); do
76                 cat >> $TC_FLOWER_BATCH_FILE <<-EOF
77                         filter add dev $h2 ingress \
78                                 prot ipv6 \
79                                 pref 1000 \
80                                 flower $tcflags dst_ip $(tc_flower_addr $i) \
81                                 action drop
82                 EOF
83         done
84
85         tc -b $TC_FLOWER_BATCH_FILE
86         check_err_fail $should_fail $? "Rule insertion"
87 }
88
89 __tc_flower_test()
90 {
91         local count=$1; shift
92         local should_fail=$1; shift
93         local last=$((count - 1))
94
95         tc_flower_rules_create $count $should_fail
96
97         for ((i = 0; i < count; ++i)); do
98                 $MZ $h1 -q -c 1 -t ip -p 20 -b bc -6 \
99                         -A 2001:db8:2::1 \
100                         -B $(tc_flower_addr $i)
101         done
102
103         MISMATCHES=$(
104                 tc -j -s filter show dev $h2 ingress |
105                 jq -r '[ .[] | select(.kind == "flower") | .options |
106                          values as $rule | .actions[].stats.packets |
107                          select(. != 1) | "\(.) on \($rule.keys.dst_ip)" ] |
108                        join(", ")'
109         )
110
111         test -z "$MISMATCHES"
112         check_err $? "Expected to capture 1 packet for each IP, but got $MISMATCHES"
113 }
114
115 tc_flower_test()
116 {
117         local count=$1; shift
118         local should_fail=$1; shift
119
120         # We use lower 16 bits of IPv6 address for match. Also there are only 16
121         # bits of rule priority space.
122         if ((count > 65536)); then
123                 check_err 1 "Invalid count of $count. At most 65536 rules supported"
124                 return
125         fi
126
127         if ! tc_offload_check $TC_FLOWER_NUM_NETIFS; then
128                 check_err 1 "Could not test offloaded functionality"
129                 return
130         fi
131
132         tcflags="skip_sw"
133         __tc_flower_test $count $should_fail
134 }