Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / net / forwarding / bridge_fdb_learning_limit.sh
bloba21b7085da2e99d51a9871e0d77b540b1171d33e
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
4 # ShellCheck incorrectly believes that most of the code here is unreachable
5 # because it's invoked by variable name following ALL_TESTS.
7 # shellcheck disable=SC2317
9 ALL_TESTS="check_accounting check_limit"
10 NUM_NETIFS=6
11 source lib.sh
13 TEST_MAC_BASE=de:ad:be:ef:42:
15 NUM_PKTS=16
16 FDB_LIMIT=8
18 FDB_TYPES=(
19 # name is counted? overrides learned?
20 'learned 1 0'
21 'static 0 1'
22 'user 0 1'
23 'extern_learn 0 1'
24 'local 0 1'
27 mac()
29 printf "${TEST_MAC_BASE}%02x" "$1"
32 H1_DEFAULT_MAC=$(mac 42)
34 switch_create()
36 ip link add dev br0 type bridge
38 ip link set dev "$swp1" master br0
39 ip link set dev "$swp2" master br0
40 # swp3 is used to add local MACs, so do not add it to the bridge yet.
42 # swp2 is only used for replying when learning on swp1, its MAC should not be learned.
43 ip link set dev "$swp2" type bridge_slave learning off
45 ip link set dev br0 up
47 ip link set dev "$swp1" up
48 ip link set dev "$swp2" up
49 ip link set dev "$swp3" up
52 switch_destroy()
54 ip link set dev "$swp3" down
55 ip link set dev "$swp2" down
56 ip link set dev "$swp1" down
58 ip link del dev br0
61 h_create()
63 ip link set "$h1" addr "$H1_DEFAULT_MAC"
65 simple_if_init "$h1" 192.0.2.1/24
66 simple_if_init "$h2" 192.0.2.2/24
69 h_destroy()
71 simple_if_fini "$h1" 192.0.2.1/24
72 simple_if_fini "$h2" 192.0.2.2/24
75 setup_prepare()
77 h1=${NETIFS[p1]}
78 swp1=${NETIFS[p2]}
80 h2=${NETIFS[p3]}
81 swp2=${NETIFS[p4]}
83 swp3=${NETIFS[p6]}
85 vrf_prepare
87 h_create
89 switch_create
92 cleanup()
94 pre_cleanup
96 switch_destroy
98 h_destroy
100 vrf_cleanup
103 fdb_get_n_learned()
105 ip -d -j link show dev br0 type bridge | \
106 jq '.[]["linkinfo"]["info_data"]["fdb_n_learned"]'
109 fdb_get_n_mac()
111 local mac=${1}
113 bridge -j fdb show br br0 | \
114 jq "map(select(.mac == \"${mac}\" and (has(\"vlan\") | not))) | length"
117 fdb_fill_learned()
119 local i
121 for i in $(seq 1 "$NUM_PKTS"); do
122 fdb_add learned "$(mac "$i")"
123 done
126 fdb_reset()
128 bridge fdb flush dev br0
130 # Keep the default MAC address of h1 in the table. We set it to a different one when
131 # testing dynamic learning.
132 bridge fdb add "$H1_DEFAULT_MAC" dev "$swp1" master static use
135 fdb_add()
137 local type=$1 mac=$2
139 case "$type" in
140 learned)
141 ip link set "$h1" addr "$mac"
142 # Wait for a reply so we implicitly wait until after the forwarding
143 # code finished and the FDB entry was created.
144 PING_COUNT=1 ping_do "$h1" 192.0.2.2
145 check_err $? "Failed to ping another bridge port"
146 ip link set "$h1" addr "$H1_DEFAULT_MAC"
148 local)
149 ip link set dev "$swp3" addr "$mac" && ip link set "$swp3" master br0
151 static)
152 bridge fdb replace "$mac" dev "$swp1" master static
154 user)
155 bridge fdb replace "$mac" dev "$swp1" master static use
157 extern_learn)
158 bridge fdb replace "$mac" dev "$swp1" master extern_learn
160 esac
162 check_err $? "Failed to add a FDB entry of type ${type}"
165 fdb_del()
167 local type=$1 mac=$2
169 case "$type" in
170 local)
171 ip link set "$swp3" nomaster
174 bridge fdb del "$mac" dev "$swp1" master
176 esac
178 check_err $? "Failed to remove a FDB entry of type ${type}"
181 check_fdb_n_learned_support()
183 if ! ip link help bridge 2>&1 | grep -q "fdb_max_learned"; then
184 echo "SKIP: iproute2 too old, missing bridge max learned support"
185 exit $ksft_skip
188 ip link add dev br0 type bridge
189 local learned=$(fdb_get_n_learned)
190 ip link del dev br0
191 if [ "$learned" == "null" ]; then
192 echo "SKIP: kernel too old; bridge fdb_n_learned feature not supported."
193 exit $ksft_skip
197 check_accounting_one_type()
199 local type=$1 is_counted=$2 overrides_learned=$3
200 shift 3
201 RET=0
203 fdb_reset
204 fdb_add "$type" "$(mac 0)"
205 learned=$(fdb_get_n_learned)
206 [ "$learned" -ne "$is_counted" ]
207 check_fail $? "Inserted FDB type ${type}: Expected the count ${is_counted}, but got ${learned}"
209 fdb_del "$type" "$(mac 0)"
210 learned=$(fdb_get_n_learned)
211 [ "$learned" -ne 0 ]
212 check_fail $? "Removed FDB type ${type}: Expected the count 0, but got ${learned}"
214 if [ "$overrides_learned" -eq 1 ]; then
215 fdb_reset
216 fdb_add learned "$(mac 0)"
217 fdb_add "$type" "$(mac 0)"
218 learned=$(fdb_get_n_learned)
219 [ "$learned" -ne "$is_counted" ]
220 check_fail $? "Set a learned entry to FDB type ${type}: Expected the count ${is_counted}, but got ${learned}"
221 fdb_del "$type" "$(mac 0)"
224 log_test "FDB accounting interacting with FDB type ${type}"
227 check_accounting()
229 local type_args learned
230 RET=0
232 fdb_reset
233 learned=$(fdb_get_n_learned)
234 [ "$learned" -ne 0 ]
235 check_fail $? "Flushed the FDB table: Expected the count 0, but got ${learned}"
237 fdb_fill_learned
238 sleep 1
240 learned=$(fdb_get_n_learned)
241 [ "$learned" -ne "$NUM_PKTS" ]
242 check_fail $? "Filled the FDB table: Expected the count ${NUM_PKTS}, but got ${learned}"
244 log_test "FDB accounting"
246 for type_args in "${FDB_TYPES[@]}"; do
247 # This is intentional use of word splitting.
248 # shellcheck disable=SC2086
249 check_accounting_one_type $type_args
250 done
253 check_limit_one_type()
255 local type=$1 is_counted=$2
256 local n_mac expected=$((1 - is_counted))
257 RET=0
259 fdb_reset
260 fdb_fill_learned
262 fdb_add "$type" "$(mac 0)"
263 n_mac=$(fdb_get_n_mac "$(mac 0)")
264 [ "$n_mac" -ne "$expected" ]
265 check_fail $? "Inserted FDB type ${type} at limit: Expected the count ${expected}, but got ${n_mac}"
267 log_test "FDB limits interacting with FDB type ${type}"
270 check_limit()
272 local learned
273 RET=0
275 ip link set br0 type bridge fdb_max_learned "$FDB_LIMIT"
277 fdb_reset
278 fdb_fill_learned
280 learned=$(fdb_get_n_learned)
281 [ "$learned" -ne "$FDB_LIMIT" ]
282 check_fail $? "Filled the limited FDB table: Expected the count ${FDB_LIMIT}, but got ${learned}"
284 log_test "FDB limits"
286 for type_args in "${FDB_TYPES[@]}"; do
287 # This is intentional use of word splitting.
288 # shellcheck disable=SC2086
289 check_limit_one_type $type_args
290 done
293 check_fdb_n_learned_support
295 trap cleanup EXIT
297 setup_prepare
299 tests_run
301 exit $EXIT_STATUS