File Index
Files and directories
Sign in
FILE

bridge_fdb_local_vlan_0.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/forwarding/bridge_fdb_local_vlan_0.sh BASH
  1#!/bin/bash
  2# SPDX-License-Identifier: GPL-2.0
  3
  4# +-----------------------+ +-----------------------+ +-----------------------+
  5# | H1 (vrf)              | | H2 (vrf)              | | H3 (vrf)              |
  6# |    + $h1              | |    + $h2              | |    + $h3              |
  7# |    | 192.0.2.1/28     | |    | 192.0.2.2/28     | |    | 192.0.2.18/28    |
  8# |    | 2001:db8:1::1/64 | |    | 2001:db8:1::2/64 | |    | 2001:db8:2::2/64 |
  9# |    |                  | |    |                  | |    |                  |
 10# +----|------------------+ +----|------------------+ +----|------------------+
 11#      |                         |                         |
 12# +----|-------------------------|-------------------------|------------------+
 13# | +--|-------------------------|------------------+      |                  |
 14# | |  + $swp1                   + $swp2            |      + $swp3            |
 15# | |                                               |        192.0.2.17/28    |
 16# | |  BR1 (802.1q)                                 |        2001:db8:2::1/64 |
 17# | |  192.0.2.3/28                                 |                         |
 18# | |  2001:db8:1::3/64                             |                         |
 19# | +-----------------------------------------------+                      SW |
 20# +---------------------------------------------------------------------------+
 21#
 22#shellcheck disable=SC2317 # SC doesn't see our uses of functions.
 23#shellcheck disable=SC2034 # ... and global variables
 24
 25ALL_TESTS="
 26	test_d_no_sharing
 27	test_d_sharing
 28	test_q_no_sharing
 29	test_q_sharing
 30	test_addr_set
 31"
 32
 33NUM_NETIFS=6
 34source lib.sh
 35
 36pMAC=00:11:22:33:44:55
 37bMAC=00:11:22:33:44:66
 38mMAC=00:11:22:33:44:77
 39xMAC=00:11:22:33:44:88
 40
 41host_create()
 42{
 43	local h=$1; shift
 44	local ipv4=$1; shift
 45	local ipv6=$1; shift
 46
 47	adf_simple_if_init "$h" "$ipv4" "$ipv6"
 48	adf_ip_route_add vrf "v$h" 192.0.2.16/28 nexthop via 192.0.2.3
 49	adf_ip_route_add vrf "v$h" 2001:db8:2::/64 nexthop via 2001:db8:1::3
 50}
 51
 52h3_create()
 53{
 54	adf_simple_if_init "$h3" 192.0.2.18/28 2001:db8:2::2/64
 55	adf_ip_route_add vrf "v$h3" 192.0.2.0/28 nexthop via 192.0.2.17
 56	adf_ip_route_add vrf "v$h3" 2001:db8:1::/64 nexthop via 2001:db8:2::1
 57
 58	tc qdisc add dev "$h3" clsact
 59	defer tc qdisc del dev "$h3" clsact
 60
 61	tc filter add dev "$h3" ingress proto ip pref 104 \
 62	   flower skip_hw ip_proto udp dst_port 4096 \
 63	   action pass
 64	defer tc filter del dev "$h3" ingress proto ip pref 104
 65
 66	tc qdisc add dev "$h2" clsact
 67	defer tc qdisc del dev "$h2" clsact
 68
 69	tc filter add dev "$h2" ingress proto ip pref 104 \
 70	   flower skip_hw ip_proto udp dst_port 4096 \
 71	   action pass
 72	defer tc filter del dev "$h2" ingress proto ip pref 104
 73}
 74
 75switch_create()
 76{
 77	adf_ip_link_set_up "$swp1"
 78
 79	adf_ip_link_set_up "$swp2"
 80
 81	adf_ip_addr_add "$swp3" 192.0.2.17/28
 82	adf_ip_addr_add "$swp3" 2001:db8:2::1/64
 83	adf_ip_link_set_up "$swp3"
 84}
 85
 86setup_prepare()
 87{
 88	h1=${NETIFS[p1]}
 89	swp1=${NETIFS[p2]}
 90
 91	swp2=${NETIFS[p3]}
 92	h2=${NETIFS[p4]}
 93
 94	swp3=${NETIFS[p5]}
 95	h3=${NETIFS[p6]}
 96
 97	adf_vrf_prepare
 98	adf_forwarding_enable
 99
100	host_create "$h1" 192.0.2.1/28 2001:db8:1::1/64
101	host_create "$h2" 192.0.2.2/28 2001:db8:1::2/64
102	h3_create
103
104	switch_create
105}
106
107adf_bridge_configure()
108{
109	local dev
110
111	adf_ip_addr_add br 192.0.2.3/28
112	adf_ip_addr_add br 2001:db8:1::3/64
113
114	adf_bridge_vlan_add dev br vid 1 pvid untagged self
115	adf_bridge_vlan_add dev br vid 2 self
116	adf_bridge_vlan_add dev br vid 3 self
117
118	for dev in "$swp1" "$swp2"; do
119		adf_ip_link_set_master "$dev" br
120		adf_bridge_vlan_add dev "$dev" vid 1 pvid untagged
121		adf_bridge_vlan_add dev "$dev" vid 2
122		adf_bridge_vlan_add dev "$dev" vid 3
123	done
124}
125
126adf_bridge_create()
127{
128	local mac
129
130	adf_ip_link_add br up type bridge vlan_default_pvid 0 "$@"
131	mac=$(mac_get br)
132	adf_bridge_configure
133	adf_ip_link_set_addr br "$mac"
134}
135
136check_fdb_local_vlan_0_support()
137{
138	if adf_ip_link_add XXbr up type bridge vlan_filtering 1 \
139			fdb_local_vlan_0 1 &>/dev/null; then
140		return 0
141	fi
142
143	log_test_skip "FDB sharing" \
144		      "iproute 2 or the kernel do not support fdb_local_vlan_0"
145}
146
147check_mac_presence()
148{
149	local should_fail=$1; shift
150	local dev=$1; shift
151	local vlan=$1; shift
152	local mac
153
154	mac=$(mac_get "$dev")
155
156	if ((vlan == 0)); then
157		vlan=null
158	fi
159
160	bridge -j fdb show dev "$dev" |
161	    jq -e --arg mac "$mac" --argjson vlan "$vlan" \
162	       '.[] | select(.mac == $mac) | select(.vlan == $vlan)' > /dev/null
163	check_err_fail "$should_fail" $? "FDB dev $dev vid $vlan addr $mac exists"
164}
165
166do_sharing_test()
167{
168	local should_fail=$1; shift
169	local what=$1; shift
170	local dev
171
172	RET=0
173
174	for dev in "$swp1" "$swp2" br; do
175		check_mac_presence 0 "$dev" 0
176		check_mac_presence "$should_fail" "$dev" 1
177		check_mac_presence "$should_fail" "$dev" 2
178		check_mac_presence "$should_fail" "$dev" 3
179	done
180
181	log_test "$what"
182}
183
184do_end_to_end_test()
185{
186	local mac=$1; shift
187	local what=$1; shift
188	local probe_dev=${1-$h3}; shift
189	local expect=${1-10}; shift
190
191	local t0
192	local t1
193	local dd
194
195	RET=0
196
197	# In mausezahn, use $dev MAC as the destination MAC. In the MAC sharing
198	# context, that will cause an FDB miss on VLAN 1 and prompt a second
199	# lookup in VLAN 0.
200
201	t0=$(tc_rule_stats_get "$probe_dev" 104 ingress)
202
203	$MZ "$h1" -c 10 -p 64 -a own -b "$mac" \
204		  -A 192.0.2.1 -B 192.0.2.18 -t udp "dp=4096,sp=2048" -q
205	sleep 1
206
207	t1=$(tc_rule_stats_get "$probe_dev" 104 ingress)
208	dd=$((t1 - t0))
209
210	((dd == expect))
211	check_err $? "Expected $expect packets on $probe_dev got $dd"
212
213	log_test "$what"
214}
215
216do_tests()
217{
218	local should_fail=$1; shift
219	local what=$1; shift
220	local swp1_mac
221	local br_mac
222
223	swp1_mac=$(mac_get "$swp1")
224	br_mac=$(mac_get br)
225
226	do_sharing_test "$should_fail" "$what"
227	do_end_to_end_test "$swp1_mac" "$what: end to end, $swp1 MAC"
228	do_end_to_end_test "$br_mac" "$what: end to end, br MAC"
229}
230
231bridge_standard()
232{
233	local vlan_filtering=$1; shift
234
235	if ((vlan_filtering)); then
236		echo 802.1q
237	else
238		echo 802.1d
239	fi
240}
241
242nonexistent_fdb_test()
243{
244	local vlan_filtering=$1; shift
245	local standard
246
247	standard=$(bridge_standard "$vlan_filtering")
248
249	# We expect flooding, so $h2 should get the traffic.
250	do_end_to_end_test "$xMAC" "$standard: Nonexistent FDB" "$h2"
251}
252
253misleading_fdb_test()
254{
255	local vlan_filtering=$1; shift
256	local standard
257
258	standard=$(bridge_standard "$vlan_filtering")
259
260	defer_scope_push
261		# Add an FDB entry on VLAN 0. The lookup on VLAN-aware bridge
262		# shouldn't pick this up even with fdb_local_vlan_0 enabled, so
263		# the traffic should be flooded. This all holds on
264		# vlan_filtering bridge, on non-vlan_filtering one the FDB entry
265		# is expected to be found as usual, no flooding takes place.
266		#
267		# Adding only on VLAN 0 is a bit tricky, because bridge is
268		# trying to be nice and interprets the request as if the FDB
269		# should be added on each VLAN.
270
271		bridge fdb add "$mMAC" dev "$swp1" master
272		bridge fdb del "$mMAC" dev "$swp1" vlan 1 master
273		bridge fdb del "$mMAC" dev "$swp1" vlan 2 master
274		bridge fdb del "$mMAC" dev "$swp1" vlan 3 master
275
276		local expect=$((vlan_filtering ? 10 : 0))
277		do_end_to_end_test "$mMAC" \
278				   "$standard: Lookup of non-local MAC on VLAN 0" \
279				   "$h2" "$expect"
280	defer_scope_pop
281}
282
283change_mac()
284{
285	local dev=$1; shift
286	local mac=$1; shift
287	local cur_mac
288
289	cur_mac=$(mac_get "$dev")
290
291	log_info "Change $dev MAC $cur_mac -> $mac"
292	adf_ip_link_set_addr "$dev" "$mac"
293	defer log_info "Change $dev MAC back"
294}
295
296do_test_no_sharing()
297{
298	local vlan_filtering=$1; shift
299	local standard
300
301	standard=$(bridge_standard "$vlan_filtering")
302
303	adf_bridge_create vlan_filtering "$vlan_filtering"
304	setup_wait
305
306	do_tests 0 "$standard, no FDB sharing"
307
308	change_mac "$swp1" "$pMAC"
309	change_mac br "$bMAC"
310
311	do_tests 0 "$standard, no FDB sharing after MAC change"
312
313	in_defer_scope check_fdb_local_vlan_0_support || return
314
315	log_info "Set fdb_local_vlan_0=1"
316	ip link set dev br type bridge fdb_local_vlan_0 1
317
318	do_tests 1 "$standard, fdb sharing after toggle"
319}
320
321do_test_sharing()
322{
323	local vlan_filtering=$1; shift
324	local standard
325
326	standard=$(bridge_standard "$vlan_filtering")
327
328	in_defer_scope check_fdb_local_vlan_0_support || return
329
330	adf_bridge_create vlan_filtering "$vlan_filtering" fdb_local_vlan_0 1
331	setup_wait
332
333	do_tests 1 "$standard, FDB sharing"
334
335	nonexistent_fdb_test "$vlan_filtering"
336	misleading_fdb_test "$vlan_filtering"
337
338	change_mac "$swp1" "$pMAC"
339	change_mac br "$bMAC"
340
341	do_tests 1 "$standard, FDB sharing after MAC change"
342
343	log_info "Set fdb_local_vlan_0=0"
344	ip link set dev br type bridge fdb_local_vlan_0 0
345
346	do_tests 0 "$standard, No FDB sharing after toggle"
347}
348
349test_d_no_sharing()
350{
351	do_test_no_sharing 0
352}
353
354test_d_sharing()
355{
356	do_test_sharing 0
357}
358
359test_q_no_sharing()
360{
361	do_test_no_sharing 1
362}
363
364test_q_sharing()
365{
366	do_test_sharing 1
367}
368
369adf_addr_set_bridge_create()
370{
371	adf_ip_link_add br up type bridge vlan_filtering 0
372	adf_ip_link_set_addr br "$(mac_get br)"
373	adf_bridge_configure
374}
375
376test_addr_set()
377{
378	adf_addr_set_bridge_create
379	setup_wait
380
381	do_end_to_end_test "$(mac_get br)" "NET_ADDR_SET: end to end, br MAC"
382}
383
384trap cleanup EXIT
385
386setup_prepare
387tests_run
~/ Read-only file preview.