xref: /linux/tools/testing/selftests/net/fdb_flush.sh (revision bb118e86dfcc096b8a3889c1a5c88f214e1f65fa)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# This test is for checking functionality of flushing FDB entries.
5# Check that flush works as expected with all the supported arguments and verify
6# some combinations of arguments.
7
8FLUSH_BY_STATE_TESTS="
9	vxlan_test_flush_by_permanent
10	vxlan_test_flush_by_nopermanent
11	vxlan_test_flush_by_static
12	vxlan_test_flush_by_nostatic
13	vxlan_test_flush_by_dynamic
14	vxlan_test_flush_by_nodynamic
15"
16
17FLUSH_BY_FLAG_TESTS="
18	vxlan_test_flush_by_extern_learn
19	vxlan_test_flush_by_noextern_learn
20	vxlan_test_flush_by_router
21	vxlan_test_flush_by_norouter
22"
23
24TESTS="
25	vxlan_test_flush_by_dev
26	vxlan_test_flush_by_vni
27	vxlan_test_flush_by_src_vni
28	vxlan_test_flush_by_port
29	vxlan_test_flush_by_dst_ip
30	vxlan_test_flush_by_nhid
31	$FLUSH_BY_STATE_TESTS
32	$FLUSH_BY_FLAG_TESTS
33	vxlan_test_flush_by_several_args
34	vxlan_test_flush_by_remote_attributes
35	bridge_test_flush_by_dev
36	bridge_test_flush_by_vlan
37	bridge_vxlan_test_flush
38"
39
40: ${VERBOSE:=0}
41: ${PAUSE_ON_FAIL:=no}
42: ${PAUSE:=no}
43: ${VXPORT:=4789}
44
45run_cmd()
46{
47	local cmd="$1"
48	local out
49	local rc
50	local stderr="2>/dev/null"
51
52	if [ "$VERBOSE" = "1" ]; then
53		printf "COMMAND: $cmd\n"
54		stderr=
55	fi
56
57	out=$(eval $cmd $stderr)
58	rc=$?
59	if [ "$VERBOSE" = "1" -a -n "$out" ]; then
60		echo "    $out"
61	fi
62
63	return $rc
64}
65
66log_test()
67{
68	local rc=$1
69	local expected=$2
70	local msg="$3"
71	local nsuccess
72	local nfail
73	local ret
74
75	if [ ${rc} -eq ${expected} ]; then
76		printf "TEST: %-60s  [ OK ]\n" "${msg}"
77		nsuccess=$((nsuccess+1))
78	else
79		ret=1
80		nfail=$((nfail+1))
81		printf "TEST: %-60s  [FAIL]\n" "${msg}"
82		if [ "$VERBOSE" = "1" ]; then
83			echo "    rc=$rc, expected $expected"
84		fi
85
86		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
87		echo
88			echo "hit enter to continue, 'q' to quit"
89			read a
90			[ "$a" = "q" ] && exit 1
91		fi
92	fi
93
94	if [ "${PAUSE}" = "yes" ]; then
95		echo
96		echo "hit enter to continue, 'q' to quit"
97		read a
98		[ "$a" = "q" ] && exit 1
99	fi
100
101	[ "$VERBOSE" = "1" ] && echo
102}
103
104MAC_POOL_1="
105	de:ad:be:ef:13:10
106	de:ad:be:ef:13:11
107	de:ad:be:ef:13:12
108	de:ad:be:ef:13:13
109	de:ad:be:ef:13:14
110"
111mac_pool_1_len=$(echo "$MAC_POOL_1" | grep -c .)
112
113MAC_POOL_2="
114	ca:fe:be:ef:13:10
115	ca:fe:be:ef:13:11
116	ca:fe:be:ef:13:12
117	ca:fe:be:ef:13:13
118	ca:fe:be:ef:13:14
119"
120mac_pool_2_len=$(echo "$MAC_POOL_2" | grep -c .)
121
122fdb_add_mac_pool_1()
123{
124	local dev=$1; shift
125	local args="$@"
126
127	for mac in $MAC_POOL_1
128	do
129		$BRIDGE fdb add $mac dev $dev $args
130	done
131}
132
133fdb_add_mac_pool_2()
134{
135	local dev=$1; shift
136	local args="$@"
137
138	for mac in $MAC_POOL_2
139	do
140		$BRIDGE fdb add $mac dev $dev $args
141	done
142}
143
144fdb_check_n_entries_by_dev_filter()
145{
146	local dev=$1; shift
147	local exp_entries=$1; shift
148	local filter="$@"
149
150	local entries=$($BRIDGE fdb show dev $dev | grep "$filter" | wc -l)
151
152	[[ $entries -eq $exp_entries ]]
153	rc=$?
154
155	log_test $rc 0 "$dev: Expected $exp_entries FDB entries, got $entries"
156	return $rc
157}
158
159vxlan_test_flush_by_dev()
160{
161	local vni=3000
162	local dst_ip=192.0.2.1
163
164	fdb_add_mac_pool_1 vx10 vni $vni dst $dst_ip
165	fdb_add_mac_pool_2 vx20 vni $vni dst $dst_ip
166
167	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len
168	fdb_check_n_entries_by_dev_filter vx20 $mac_pool_2_len
169
170	run_cmd "$BRIDGE fdb flush dev vx10"
171	log_test $? 0 "Flush FDB by dev vx10"
172
173	fdb_check_n_entries_by_dev_filter vx10 0
174	log_test $? 0 "Flush FDB by dev vx10 - test vx10 entries"
175
176	fdb_check_n_entries_by_dev_filter vx20 $mac_pool_2_len
177	log_test $? 0 "Flush FDB by dev vx10 - test vx20 entries"
178}
179
180vxlan_test_flush_by_vni()
181{
182	local vni_1=3000
183	local vni_2=4000
184	local dst_ip=192.0.2.1
185
186	fdb_add_mac_pool_1 vx10 vni $vni_1 dst $dst_ip
187	fdb_add_mac_pool_2 vx10 vni $vni_2 dst $dst_ip
188
189	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len vni $vni_1
190	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len vni $vni_2
191
192	run_cmd "$BRIDGE fdb flush dev vx10 vni $vni_2"
193	log_test $? 0 "Flush FDB by dev vx10 and vni $vni_2"
194
195	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len vni $vni_1
196	log_test $? 0 "Test entries with vni $vni_1"
197
198	fdb_check_n_entries_by_dev_filter vx10 0 vni $vni_2
199	log_test $? 0 "Test entries with vni $vni_2"
200}
201
202vxlan_test_flush_by_src_vni()
203{
204	# Set some entries with {vni=x,src_vni=y} and some with the opposite -
205	# {vni=y,src_vni=x}, to verify that when we flush by src_vni=x, entries
206	# with vni=x are not flused.
207	local vni_1=3000
208	local vni_2=4000
209	local src_vni_1=4000
210	local src_vni_2=3000
211	local dst_ip=192.0.2.1
212
213	# Reconfigure vx10 with 'external' to get 'src_vni' details in
214	# 'bridge fdb' output
215	$IP link del dev vx10
216	$IP link add name vx10 type vxlan dstport "$VXPORT" external
217
218	fdb_add_mac_pool_1 vx10 vni $vni_1 src_vni $src_vni_1 dst $dst_ip
219	fdb_add_mac_pool_2 vx10 vni $vni_2 src_vni $src_vni_2 dst $dst_ip
220
221	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len \
222		src_vni $src_vni_1
223	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len \
224		src_vni $src_vni_2
225
226	run_cmd "$BRIDGE fdb flush dev vx10 src_vni $src_vni_2"
227	log_test $? 0 "Flush FDB by dev vx10 and src_vni $src_vni_2"
228
229	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len \
230		src_vni $src_vni_1
231	log_test $? 0 "Test entries with src_vni $src_vni_1"
232
233	fdb_check_n_entries_by_dev_filter vx10 0 src_vni $src_vni_2
234	log_test $? 0 "Test entries with src_vni $src_vni_2"
235}
236
237vxlan_test_flush_by_port()
238{
239	local port_1=1234
240	local port_2=4321
241	local dst_ip=192.0.2.1
242
243	fdb_add_mac_pool_1 vx10 port $port_1 dst $dst_ip
244	fdb_add_mac_pool_2 vx10 port $port_2 dst $dst_ip
245
246	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len port $port_1
247	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len port $port_2
248
249	run_cmd "$BRIDGE fdb flush dev vx10 port $port_2"
250	log_test $? 0 "Flush FDB by dev vx10 and port $port_2"
251
252	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len port $port_1
253	log_test $? 0 "Test entries with port $port_1"
254
255	fdb_check_n_entries_by_dev_filter vx10 0 port $port_2
256	log_test $? 0 "Test entries with port $port_2"
257}
258
259vxlan_test_flush_by_dst_ip()
260{
261	local dst_ip_1=192.0.2.1
262	local dst_ip_2=192.0.2.2
263
264	fdb_add_mac_pool_1 vx10 dst $dst_ip_1
265	fdb_add_mac_pool_2 vx10 dst $dst_ip_2
266
267	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len dst $dst_ip_1
268	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len dst $dst_ip_2
269
270	run_cmd "$BRIDGE fdb flush dev vx10 dst $dst_ip_2"
271	log_test $? 0 "Flush FDB by dev vx10 and dst $dst_ip_2"
272
273	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len dst $dst_ip_1
274	log_test $? 0 "Test entries with dst $dst_ip_1"
275
276	fdb_check_n_entries_by_dev_filter vx10 0 dst $dst_ip_2
277	log_test $? 0 "Test entries with dst $dst_ip_2"
278}
279
280nexthops_add()
281{
282	local nhid_1=$1; shift
283	local nhid_2=$1; shift
284
285	$IP nexthop add id 10 via 192.0.2.1 fdb
286	$IP nexthop add id $nhid_1 group 10 fdb
287
288	$IP nexthop add id 20 via 192.0.2.2 fdb
289	$IP nexthop add id $nhid_2 group 20 fdb
290}
291
292vxlan_test_flush_by_nhid()
293{
294	local nhid_1=100
295	local nhid_2=200
296
297	nexthops_add $nhid_1 $nhid_2
298
299	fdb_add_mac_pool_1 vx10 nhid $nhid_1
300	fdb_add_mac_pool_2 vx10 nhid $nhid_2
301
302	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len nhid $nhid_1
303	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len nhid $nhid_2
304
305	run_cmd "$BRIDGE fdb flush dev vx10 nhid $nhid_2"
306	log_test $? 0 "Flush FDB by dev vx10 and nhid $nhid_2"
307
308	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len nhid $nhid_1
309	log_test $? 0 "Test entries with nhid $nhid_1"
310
311	fdb_check_n_entries_by_dev_filter vx10 0 nhid $nhid_2
312	log_test $? 0 "Test entries with nhid $nhid_2"
313
314	# Flush also entries with $nhid_1, and then verify that flushing by
315	# 'nhid' does not return an error when there are no entries with
316	# nexthops.
317	run_cmd "$BRIDGE fdb flush dev vx10 nhid $nhid_1"
318	log_test $? 0 "Flush FDB by dev vx10 and nhid $nhid_1"
319
320	fdb_check_n_entries_by_dev_filter vx10 0 nhid
321	log_test $? 0 "Test entries with 'nhid' keyword"
322
323	run_cmd "$BRIDGE fdb flush dev vx10 nhid $nhid_1"
324	log_test $? 0 "Flush FDB by nhid when there are no entries with nexthop"
325}
326
327vxlan_test_flush_by_state()
328{
329	local flush_by_state=$1; shift
330	local state_1=$1; shift
331	local exp_state_1=$1; shift
332	local state_2=$1; shift
333	local exp_state_2=$1; shift
334
335	local dst_ip_1=192.0.2.1
336	local dst_ip_2=192.0.2.2
337
338	fdb_add_mac_pool_1 vx10 dst $dst_ip_1 $state_1
339	fdb_add_mac_pool_2 vx10 dst $dst_ip_2 $state_2
340
341	# Check the entries by dst_ip as not all states appear in 'bridge fdb'
342	# output.
343	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len dst $dst_ip_1
344	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len dst $dst_ip_2
345
346	run_cmd "$BRIDGE fdb flush dev vx10 $flush_by_state"
347	log_test $? 0 "Flush FDB by dev vx10 and state $flush_by_state"
348
349	fdb_check_n_entries_by_dev_filter vx10 $exp_state_1 dst $dst_ip_1
350	log_test $? 0 "Test entries with state $state_1"
351
352	fdb_check_n_entries_by_dev_filter vx10 $exp_state_2 dst $dst_ip_2
353	log_test $? 0 "Test entries with state $state_2"
354}
355
356vxlan_test_flush_by_permanent()
357{
358	# Entries that are added without state get 'permanent' state by
359	# default, add some entries with flag 'extern_learn' instead of state,
360	# so they will be added with 'permanent' and should be flushed also.
361	local flush_by_state="permanent"
362	local state_1="permanent"
363	local exp_state_1=0
364	local state_2="extern_learn"
365	local exp_state_2=0
366
367	vxlan_test_flush_by_state $flush_by_state $state_1 $exp_state_1 \
368		$state_2 $exp_state_2
369}
370
371vxlan_test_flush_by_nopermanent()
372{
373	local flush_by_state="nopermanent"
374	local state_1="permanent"
375	local exp_state_1=$mac_pool_1_len
376	local state_2="static"
377	local exp_state_2=0
378
379	vxlan_test_flush_by_state $flush_by_state $state_1 $exp_state_1 \
380		$state_2 $exp_state_2
381}
382
383vxlan_test_flush_by_static()
384{
385	local flush_by_state="static"
386	local state_1="static"
387	local exp_state_1=0
388	local state_2="dynamic"
389	local exp_state_2=$mac_pool_2_len
390
391	vxlan_test_flush_by_state $flush_by_state $state_1 $exp_state_1 \
392		$state_2 $exp_state_2
393}
394
395vxlan_test_flush_by_nostatic()
396{
397	local flush_by_state="nostatic"
398	local state_1="permanent"
399	local exp_state_1=$mac_pool_1_len
400	local state_2="dynamic"
401	local exp_state_2=0
402
403	vxlan_test_flush_by_state $flush_by_state $state_1 $exp_state_1 \
404		$state_2 $exp_state_2
405}
406
407vxlan_test_flush_by_dynamic()
408{
409	local flush_by_state="dynamic"
410	local state_1="dynamic"
411	local exp_state_1=0
412	local state_2="static"
413	local exp_state_2=$mac_pool_2_len
414
415	vxlan_test_flush_by_state $flush_by_state $state_1 $exp_state_1 \
416		$state_2 $exp_state_2
417}
418
419vxlan_test_flush_by_nodynamic()
420{
421	local flush_by_state="nodynamic"
422	local state_1="permanent"
423	local exp_state_1=0
424	local state_2="dynamic"
425	local exp_state_2=$mac_pool_2_len
426
427	vxlan_test_flush_by_state $flush_by_state $state_1 $exp_state_1 \
428		$state_2 $exp_state_2
429}
430
431vxlan_test_flush_by_flag()
432{
433	local flush_by_flag=$1; shift
434	local flag_1=$1; shift
435	local exp_flag_1=$1; shift
436	local flag_2=$1; shift
437	local exp_flag_2=$1; shift
438
439	local dst_ip_1=192.0.2.1
440	local dst_ip_2=192.0.2.2
441
442	fdb_add_mac_pool_1 vx10 dst $dst_ip_1 $flag_1
443	fdb_add_mac_pool_2 vx10 dst $dst_ip_2 $flag_2
444
445	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len $flag_1
446	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len $flag_2
447
448	run_cmd "$BRIDGE fdb flush dev vx10 $flush_by_flag"
449	log_test $? 0 "Flush FDB by dev vx10 and flag $flush_by_flag"
450
451	fdb_check_n_entries_by_dev_filter vx10 $exp_flag_1 dst $dst_ip_1
452	log_test $? 0 "Test entries with flag $flag_1"
453
454	fdb_check_n_entries_by_dev_filter vx10 $exp_flag_2 dst $dst_ip_2
455	log_test $? 0 "Test entries with flag $flag_2"
456}
457
458vxlan_test_flush_by_extern_learn()
459{
460	local flush_by_flag="extern_learn"
461	local flag_1="extern_learn"
462	local exp_flag_1=0
463	local flag_2="router"
464	local exp_flag_2=$mac_pool_2_len
465
466	vxlan_test_flush_by_flag $flush_by_flag $flag_1 $exp_flag_1 \
467		$flag_2 $exp_flag_2
468}
469
470vxlan_test_flush_by_noextern_learn()
471{
472	local flush_by_flag="noextern_learn"
473	local flag_1="extern_learn"
474	local exp_flag_1=$mac_pool_1_len
475	local flag_2="router"
476	local exp_flag_2=0
477
478	vxlan_test_flush_by_flag $flush_by_flag $flag_1 $exp_flag_1 \
479		$flag_2 $exp_flag_2
480}
481
482vxlan_test_flush_by_router()
483{
484	local flush_by_flag="router"
485	local flag_1="router"
486	local exp_flag_1=0
487	local flag_2="extern_learn"
488	local exp_flag_2=$mac_pool_2_len
489
490	vxlan_test_flush_by_flag $flush_by_flag $flag_1 $exp_flag_1 \
491		$flag_2 $exp_flag_2
492}
493
494vxlan_test_flush_by_norouter()
495{
496
497	local flush_by_flag="norouter"
498	local flag_1="router"
499	local exp_flag_1=$mac_pool_1_len
500	local flag_2="extern_learn"
501	local exp_flag_2=0
502
503	vxlan_test_flush_by_flag $flush_by_flag $flag_1 $exp_flag_1 \
504		$flag_2 $exp_flag_2
505}
506
507vxlan_test_flush_by_several_args()
508{
509	local dst_ip_1=192.0.2.1
510	local dst_ip_2=192.0.2.2
511	local state_1=permanent
512	local state_2=static
513	local vni=3000
514	local port=1234
515	local nhid=100
516	local flag=router
517	local flush_args
518
519	################### Flush by 2 args - nhid and flag ####################
520	$IP nexthop add id 10 via 192.0.2.1 fdb
521	$IP nexthop add id $nhid group 10 fdb
522
523	fdb_add_mac_pool_1 vx10 nhid $nhid $flag $state_1
524	fdb_add_mac_pool_2 vx10 nhid $nhid $flag $state_2
525
526	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len $state_1
527	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len $state_2
528
529	run_cmd "$BRIDGE fdb flush dev vx10 nhid $nhid $flag"
530	log_test $? 0 "Flush FDB by dev vx10 nhid $nhid $flag"
531
532	# All entries should be flushed as 'state' is not an argument for flush
533	# filtering.
534	fdb_check_n_entries_by_dev_filter vx10 0 $state_1
535	log_test $? 0 "Test entries with state $state_1"
536
537	fdb_check_n_entries_by_dev_filter vx10 0 $state_2
538	log_test $? 0 "Test entries with state $state_2"
539
540	################ Flush by 3 args - VNI, port and dst_ip ################
541	fdb_add_mac_pool_1 vx10 vni $vni port $port dst $dst_ip_1
542	fdb_add_mac_pool_2 vx10 vni $vni port $port dst $dst_ip_2
543
544	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len dst $dst_ip_1
545	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_2_len dst $dst_ip_2
546
547	flush_args="vni $vni port $port dst $dst_ip_2"
548	run_cmd "$BRIDGE fdb flush dev vx10 $flush_args"
549	log_test $? 0 "Flush FDB by dev vx10 $flush_args"
550
551	# Only entries with $dst_ip_2 should be flushed, even the rest arguments
552	# match the filter, the flush should be AND of all the arguments.
553	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len dst $dst_ip_1
554	log_test $? 0 "Test entries with dst $dst_ip_1"
555
556	fdb_check_n_entries_by_dev_filter vx10 0 dst $dst_ip_2
557	log_test $? 0 "Test entries with dst $dst_ip_2"
558}
559
560multicast_fdb_entries_add()
561{
562	mac=00:00:00:00:00:00
563	vnis=(2000 3000)
564
565	for vni in "${vnis[@]}"; do
566		$BRIDGE fdb append $mac dev vx10 dst 192.0.2.1 vni $vni \
567			src_vni 5000
568		$BRIDGE fdb append $mac dev vx10 dst 192.0.2.1 vni $vni \
569			port 1111
570		$BRIDGE fdb append $mac dev vx10 dst 192.0.2.2 vni $vni \
571			port 2222
572	done
573}
574
575vxlan_test_flush_by_remote_attributes()
576{
577	local flush_args
578
579	# Reconfigure vx10 with 'external' to get 'src_vni' details in
580	# 'bridge fdb' output
581	$IP link del dev vx10
582	$IP link add name vx10 type vxlan dstport "$VXPORT" external
583
584	# For multicat FDB entries, the VXLAN driver stores a linked list of
585	# remotes for a given key. Verify that only the expected remotes are
586	# flushed.
587	multicast_fdb_entries_add
588
589	## Flush by 3 remote's attributes - destination IP, port and VNI ##
590	flush_args="dst 192.0.2.1 port 1111 vni 2000"
591	fdb_check_n_entries_by_dev_filter vx10 1 $flush_args
592
593	t0_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
594	run_cmd "$BRIDGE fdb flush dev vx10 $flush_args"
595	log_test $? 0 "Flush FDB by dev vx10 $flush_args"
596
597	fdb_check_n_entries_by_dev_filter vx10 0 $flush_args
598
599	exp_n_entries=$((t0_n_entries - 1))
600	t1_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
601	[[ $t1_n_entries -eq $exp_n_entries ]]
602	log_test $? 0 "Check how many entries were flushed"
603
604	## Flush by 2 remote's attributes - destination IP and port ##
605	flush_args="dst 192.0.2.2 port 2222"
606
607	fdb_check_n_entries_by_dev_filter vx10 2 $flush_args
608
609	t0_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
610	run_cmd "$BRIDGE fdb flush dev vx10 $flush_args"
611	log_test $? 0 "Flush FDB by dev vx10 $flush_args"
612
613	fdb_check_n_entries_by_dev_filter vx10 0 $flush_args
614
615	exp_n_entries=$((t0_n_entries - 2))
616	t1_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
617	[[ $t1_n_entries -eq $exp_n_entries ]]
618	log_test $? 0 "Check how many entries were flushed"
619
620	## Flush by source VNI, which is not remote's attribute and VNI ##
621	flush_args="vni 3000 src_vni 5000"
622
623	fdb_check_n_entries_by_dev_filter vx10 1 $flush_args
624
625	t0_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
626	run_cmd "$BRIDGE fdb flush dev vx10 $flush_args"
627	log_test $? 0 "Flush FDB by dev vx10 $flush_args"
628
629	fdb_check_n_entries_by_dev_filter vx10 0 $flush_args
630
631	exp_n_entries=$((t0_n_entries -1))
632	t1_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
633	[[ $t1_n_entries -eq $exp_n_entries ]]
634	log_test $? 0 "Check how many entries were flushed"
635
636	# Flush by 1 remote's attribute - destination IP ##
637	flush_args="dst 192.0.2.1"
638
639	fdb_check_n_entries_by_dev_filter vx10 2 $flush_args
640
641	t0_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
642	run_cmd "$BRIDGE fdb flush dev vx10 $flush_args"
643	log_test $? 0 "Flush FDB by dev vx10 $flush_args"
644
645	fdb_check_n_entries_by_dev_filter vx10 0 $flush_args
646
647	exp_n_entries=$((t0_n_entries -2))
648	t1_n_entries=$($BRIDGE fdb show dev vx10 | wc -l)
649	[[ $t1_n_entries -eq $exp_n_entries ]]
650	log_test $? 0 "Check how many entries were flushed"
651}
652
653bridge_test_flush_by_dev()
654{
655	local dst_ip=192.0.2.1
656	local br0_n_ent_t0=$($BRIDGE fdb show dev br0 | wc -l)
657	local br1_n_ent_t0=$($BRIDGE fdb show dev br1 | wc -l)
658
659	fdb_add_mac_pool_1 br0 dst $dst_ip
660	fdb_add_mac_pool_2 br1 dst $dst_ip
661
662	# Each 'fdb add' command adds one extra entry in the bridge with the
663	# default vlan.
664	local exp_br0_n_ent=$(($br0_n_ent_t0 + 2 * $mac_pool_1_len))
665	local exp_br1_n_ent=$(($br1_n_ent_t0 + 2 * $mac_pool_2_len))
666
667	fdb_check_n_entries_by_dev_filter br0 $exp_br0_n_ent
668	fdb_check_n_entries_by_dev_filter br1 $exp_br1_n_ent
669
670	run_cmd "$BRIDGE fdb flush dev br0"
671	log_test $? 0 "Flush FDB by dev br0"
672
673	# The default entry should not be flushed
674	fdb_check_n_entries_by_dev_filter br0 1
675	log_test $? 0 "Flush FDB by dev br0 - test br0 entries"
676
677	fdb_check_n_entries_by_dev_filter br1 $exp_br1_n_ent
678	log_test $? 0 "Flush FDB by dev br0 - test br1 entries"
679}
680
681bridge_test_flush_by_vlan()
682{
683	local vlan_1=10
684	local vlan_2=20
685	local vlan_1_ent_t0
686	local vlan_2_ent_t0
687
688	$BRIDGE vlan add vid $vlan_1 dev br0 self
689	$BRIDGE vlan add vid $vlan_2 dev br0 self
690
691	vlan_1_ent_t0=$($BRIDGE fdb show dev br0 | grep "vlan $vlan_1" | wc -l)
692	vlan_2_ent_t0=$($BRIDGE fdb show dev br0 | grep "vlan $vlan_2" | wc -l)
693
694	fdb_add_mac_pool_1 br0 vlan $vlan_1
695	fdb_add_mac_pool_2 br0 vlan $vlan_2
696
697	local exp_vlan_1_ent=$(($vlan_1_ent_t0 + $mac_pool_1_len))
698	local exp_vlan_2_ent=$(($vlan_2_ent_t0 + $mac_pool_2_len))
699
700	fdb_check_n_entries_by_dev_filter br0 $exp_vlan_1_ent vlan $vlan_1
701	fdb_check_n_entries_by_dev_filter br0 $exp_vlan_2_ent vlan $vlan_2
702
703	run_cmd "$BRIDGE fdb flush dev br0 vlan $vlan_1"
704	log_test $? 0 "Flush FDB by dev br0 and vlan $vlan_1"
705
706	fdb_check_n_entries_by_dev_filter br0 0 vlan $vlan_1
707	log_test $? 0 "Test entries with vlan $vlan_1"
708
709	fdb_check_n_entries_by_dev_filter br0 $exp_vlan_2_ent vlan $vlan_2
710	log_test $? 0 "Test entries with vlan $vlan_2"
711}
712
713bridge_vxlan_test_flush()
714{
715	local vlan_1=10
716	local dst_ip=192.0.2.1
717
718	$IP link set dev vx10 master br0
719	$BRIDGE vlan add vid $vlan_1 dev br0 self
720	$BRIDGE vlan add vid $vlan_1 dev vx10
721
722	fdb_add_mac_pool_1 vx10 vni 3000 dst $dst_ip self master
723
724	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len vlan $vlan_1
725	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len vni 3000
726
727	# Such command should fail in VXLAN driver as vlan is not supported,
728	# but the command should flush the entries in the bridge
729	run_cmd "$BRIDGE fdb flush dev vx10 vlan $vlan_1 master self"
730	log_test $? 255 \
731		"Flush FDB by dev vx10, vlan $vlan_1, master and self"
732
733	fdb_check_n_entries_by_dev_filter vx10 0 vlan $vlan_1
734	log_test $? 0 "Test entries with vlan $vlan_1"
735
736	fdb_check_n_entries_by_dev_filter vx10 $mac_pool_1_len dst $dst_ip
737	log_test $? 0 "Test entries with dst $dst_ip"
738}
739
740setup()
741{
742	IP="ip -netns ns1"
743	BRIDGE="bridge -netns ns1"
744
745	ip netns add ns1
746
747	$IP link add name vx10 type vxlan id 1000 dstport "$VXPORT"
748	$IP link add name vx20 type vxlan id 2000 dstport "$VXPORT"
749
750	$IP link add br0 type bridge vlan_filtering 1
751	$IP link add br1 type bridge vlan_filtering 1
752}
753
754cleanup()
755{
756	$IP link del dev br1
757	$IP link del dev br0
758
759	$IP link del dev vx20
760	$IP link del dev vx10
761
762	ip netns del ns1
763}
764
765################################################################################
766# main
767
768while getopts :t:pPhvw: o
769do
770	case $o in
771		t) TESTS=$OPTARG;;
772		p) PAUSE_ON_FAIL=yes;;
773		P) PAUSE=yes;;
774		v) VERBOSE=$(($VERBOSE + 1));;
775		w) PING_TIMEOUT=$OPTARG;;
776		h) usage; exit 0;;
777		*) usage; exit 1;;
778	esac
779done
780
781# make sure we don't pause twice
782[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
783
784if [ "$(id -u)" -ne 0 ];then
785	echo "SKIP: Need root privileges"
786	exit $ksft_skip;
787fi
788
789if [ ! -x "$(command -v ip)" ]; then
790	echo "SKIP: Could not run test without ip tool"
791	exit $ksft_skip
792fi
793
794# Check a flag that is added to flush command as part of VXLAN flush support
795bridge fdb help 2>&1 | grep -q "\[no\]router"
796if [ $? -ne 0 ]; then
797	echo "SKIP: iproute2 too old, missing flush command for VXLAN"
798	exit $ksft_skip
799fi
800
801ip link add dev vx10 type vxlan id 1000 2> /dev/null
802out=$(bridge fdb flush dev vx10 2>&1 | grep -q "Operation not supported")
803if [ $? -eq 0 ]; then
804	echo "SKIP: kernel lacks vxlan flush support"
805	exit $ksft_skip
806fi
807ip link del dev vx10
808
809for t in $TESTS
810do
811	setup; $t; cleanup;
812done
813