selftests: forwarding: bridge_mdb: Fix failing test with old libnet
[platform/kernel/linux-starfive.git] / tools / testing / selftests / net / forwarding / bridge_mdb.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 # +-----------------------+                          +------------------------+
5 # | H1 (vrf)              |                          | H2 (vrf)               |
6 # | + $h1.10              |                          | + $h2.10               |
7 # | | 192.0.2.1/28        |                          | | 192.0.2.2/28         |
8 # | | 2001:db8:1::1/64    |                          | | 2001:db8:1::2/64     |
9 # | |                     |                          | |                      |
10 # | |  + $h1.20           |                          | |  + $h2.20            |
11 # | \  | 198.51.100.1/24  |                          | \  | 198.51.100.2/24   |
12 # |  \ | 2001:db8:2::1/64 |                          |  \ | 2001:db8:2::2/64  |
13 # |   \|                  |                          |   \|                   |
14 # |    + $h1              |                          |    + $h2               |
15 # +----|------------------+                          +----|-------------------+
16 #      |                                                  |
17 # +----|--------------------------------------------------|-------------------+
18 # | SW |                                                  |                   |
19 # | +--|--------------------------------------------------|-----------------+ |
20 # | |  + $swp1                   BR0 (802.1q)             + $swp2           | |
21 # | |     vid 10                                             vid 10         | |
22 # | |     vid 20                                             vid 20         | |
23 # | |                                                                       | |
24 # | +-----------------------------------------------------------------------+ |
25 # +---------------------------------------------------------------------------+
26
27 ALL_TESTS="
28         cfg_test
29         fwd_test
30         ctrl_test
31 "
32
33 NUM_NETIFS=4
34 source lib.sh
35 source tc_common.sh
36
37 h1_create()
38 {
39         simple_if_init $h1
40         vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64
41         vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64
42 }
43
44 h1_destroy()
45 {
46         vlan_destroy $h1 20
47         vlan_destroy $h1 10
48         simple_if_fini $h1
49 }
50
51 h2_create()
52 {
53         simple_if_init $h2
54         vlan_create $h2 10 v$h2 192.0.2.2/28
55         vlan_create $h2 20 v$h2 198.51.100.2/24
56 }
57
58 h2_destroy()
59 {
60         vlan_destroy $h2 20
61         vlan_destroy $h2 10
62         simple_if_fini $h2
63 }
64
65 switch_create()
66 {
67         ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0 \
68                 mcast_snooping 1 mcast_igmp_version 3 mcast_mld_version 2
69         bridge vlan add vid 10 dev br0 self
70         bridge vlan add vid 20 dev br0 self
71         ip link set dev br0 up
72
73         ip link set dev $swp1 master br0
74         ip link set dev $swp1 up
75         bridge vlan add vid 10 dev $swp1
76         bridge vlan add vid 20 dev $swp1
77
78         ip link set dev $swp2 master br0
79         ip link set dev $swp2 up
80         bridge vlan add vid 10 dev $swp2
81         bridge vlan add vid 20 dev $swp2
82
83         tc qdisc add dev br0 clsact
84         tc qdisc add dev $h2 clsact
85 }
86
87 switch_destroy()
88 {
89         tc qdisc del dev $h2 clsact
90         tc qdisc del dev br0 clsact
91
92         bridge vlan del vid 20 dev $swp2
93         bridge vlan del vid 10 dev $swp2
94         ip link set dev $swp2 down
95         ip link set dev $swp2 nomaster
96
97         bridge vlan del vid 20 dev $swp1
98         bridge vlan del vid 10 dev $swp1
99         ip link set dev $swp1 down
100         ip link set dev $swp1 nomaster
101
102         ip link set dev br0 down
103         bridge vlan del vid 20 dev br0 self
104         bridge vlan del vid 10 dev br0 self
105         ip link del dev br0
106 }
107
108 setup_prepare()
109 {
110         h1=${NETIFS[p1]}
111         swp1=${NETIFS[p2]}
112
113         swp2=${NETIFS[p3]}
114         h2=${NETIFS[p4]}
115
116         vrf_prepare
117         forwarding_enable
118
119         h1_create
120         h2_create
121         switch_create
122 }
123
124 cleanup()
125 {
126         pre_cleanup
127
128         switch_destroy
129         h2_destroy
130         h1_destroy
131
132         forwarding_restore
133         vrf_cleanup
134 }
135
136 cfg_test_host_common()
137 {
138         local name=$1; shift
139         local grp=$1; shift
140         local src=$1; shift
141         local state=$1; shift
142         local invalid_state=$1; shift
143
144         RET=0
145
146         # Check basic add, replace and delete behavior.
147         bridge mdb add dev br0 port br0 grp $grp $state vid 10
148         bridge mdb show dev br0 vid 10 | grep -q "$grp"
149         check_err $? "Failed to add $name host entry"
150
151         bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null
152         check_fail $? "Managed to replace $name host entry"
153
154         bridge mdb del dev br0 port br0 grp $grp $state vid 10
155         bridge mdb show dev br0 vid 10 | grep -q "$grp"
156         check_fail $? "Failed to delete $name host entry"
157
158         # Check error cases.
159         bridge mdb add dev br0 port br0 grp $grp $invalid_state vid 10 \
160                 &> /dev/null
161         check_fail $? "Managed to add $name host entry with a $invalid_state state"
162
163         bridge mdb add dev br0 port br0 grp $grp src $src $state vid 10 \
164                 &> /dev/null
165         check_fail $? "Managed to add $name host entry with a source"
166
167         bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
168                 filter_mode exclude &> /dev/null
169         check_fail $? "Managed to add $name host entry with a filter mode"
170
171         bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
172                 source_list $src &> /dev/null
173         check_fail $? "Managed to add $name host entry with a source list"
174
175         bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
176                 proto 123 &> /dev/null
177         check_fail $? "Managed to add $name host entry with a protocol"
178
179         log_test "Common host entries configuration tests ($name)"
180 }
181
182 # Check configuration of host entries from all types.
183 cfg_test_host()
184 {
185         echo
186         log_info "# Host entries configuration tests"
187
188         cfg_test_host_common "IPv4" "239.1.1.1" "192.0.2.1" "temp" "permanent"
189         cfg_test_host_common "IPv6" "ff0e::1" "2001:db8:1::1" "temp" "permanent"
190         cfg_test_host_common "L2" "01:02:03:04:05:06" "00:00:00:00:00:01" \
191                 "permanent" "temp"
192 }
193
194 cfg_test_port_common()
195 {
196         local name=$1;shift
197         local grp_key=$1; shift
198
199         RET=0
200
201         # Check basic add, replace and delete behavior.
202         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
203         bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
204         check_err $? "Failed to add $name entry"
205
206         bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
207                 &> /dev/null
208         check_err $? "Failed to replace $name entry"
209
210         bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
211         bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
212         check_fail $? "Failed to delete $name entry"
213
214         # Check default protocol and replacement.
215         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
216         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "static"
217         check_err $? "$name entry not added with default \"static\" protocol"
218
219         bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
220                 proto 123
221         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "123"
222         check_err $? "Failed to replace protocol of $name entry"
223         bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
224
225         # Check behavior when VLAN is not specified.
226         bridge mdb add dev br0 port $swp1 $grp_key permanent
227         bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
228         check_err $? "$name entry with VLAN 10 not added when VLAN was not specified"
229         bridge mdb show dev br0 vid 20 | grep -q "$grp_key"
230         check_err $? "$name entry with VLAN 20 not added when VLAN was not specified"
231
232         bridge mdb del dev br0 port $swp1 $grp_key permanent
233         bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
234         check_fail $? "$name entry with VLAN 10 not deleted when VLAN was not specified"
235         bridge mdb show dev br0 vid 20 | grep -q "$grp_key"
236         check_fail $? "$name entry with VLAN 20 not deleted when VLAN was not specified"
237
238         # Check behavior when bridge port is down.
239         ip link set dev $swp1 down
240
241         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
242         check_err $? "Failed to add $name permanent entry when bridge port is down"
243
244         bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
245
246         bridge mdb add dev br0 port $swp1 $grp_key temp vid 10 &> /dev/null
247         check_fail $? "Managed to add $name temporary entry when bridge port is down"
248
249         ip link set dev $swp1 up
250         setup_wait_dev $swp1
251
252         # Check error cases.
253         ip link set dev br0 down
254         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 \
255                 &> /dev/null
256         check_fail $? "Managed to add $name entry when bridge is down"
257         ip link set dev br0 up
258
259         ip link set dev br0 type bridge mcast_snooping 0
260         bridge mdb add dev br0 port $swp1 $grp_key permanent vid \
261                 10 &> /dev/null
262         check_fail $? "Managed to add $name entry when multicast snooping is disabled"
263         ip link set dev br0 type bridge mcast_snooping 1
264
265         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 5000 \
266                 &> /dev/null
267         check_fail $? "Managed to add $name entry with an invalid VLAN"
268
269         log_test "Common port group entries configuration tests ($name)"
270 }
271
272 src_list_create()
273 {
274         local src_prefix=$1; shift
275         local num_srcs=$1; shift
276         local src_list
277         local i
278
279         for i in $(seq 1 $num_srcs); do
280                 src_list=${src_list},${src_prefix}${i}
281         done
282
283         echo $src_list | cut -c 2-
284 }
285
286 __cfg_test_port_ip_star_g()
287 {
288         local name=$1; shift
289         local grp=$1; shift
290         local invalid_grp=$1; shift
291         local src_prefix=$1; shift
292         local src1=${src_prefix}1
293         local src2=${src_prefix}2
294         local src3=${src_prefix}3
295         local max_srcs=31
296         local num_srcs
297
298         RET=0
299
300         bridge mdb add dev br0 port $swp1 grp $grp vid 10
301         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "exclude"
302         check_err $? "Default filter mode is not \"exclude\""
303         bridge mdb del dev br0 port $swp1 grp $grp vid 10
304
305         # Check basic add and delete behavior.
306         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
307                 source_list $src1
308         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q -v "src"
309         check_err $? "(*, G) entry not created"
310         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
311         check_err $? "(S, G) entry not created"
312         bridge mdb del dev br0 port $swp1 grp $grp vid 10
313         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q -v "src"
314         check_fail $? "(*, G) entry not deleted"
315         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
316         check_fail $? "(S, G) entry not deleted"
317
318         ## State (permanent / temp) tests.
319
320         # Check that group and source timer are not set for permanent entries.
321         bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
322                 filter_mode exclude source_list $src1
323
324         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
325                 grep -q "permanent"
326         check_err $? "(*, G) entry not added as \"permanent\" when should"
327         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
328                 grep -q "permanent"
329         check_err $? "(S, G) entry not added as \"permanent\" when should"
330
331         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
332                 grep -q " 0.00"
333         check_err $? "(*, G) \"permanent\" entry has a pending group timer"
334         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
335                 grep -q "\/0.00"
336         check_err $? "\"permanent\" source entry has a pending source timer"
337
338         bridge mdb del dev br0 port $swp1 grp $grp vid 10
339
340         # Check that group timer is set for temporary (*, G) EXCLUDE, but not
341         # the source timer.
342         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
343                 filter_mode exclude source_list $src1
344
345         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
346                 grep -q "temp"
347         check_err $? "(*, G) EXCLUDE entry not added as \"temp\" when should"
348         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
349                 grep -q "temp"
350         check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should"
351
352         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
353                 grep -q " 0.00"
354         check_fail $? "(*, G) EXCLUDE entry does not have a pending group timer"
355         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
356                 grep -q "\/0.00"
357         check_err $? "\"blocked\" source entry has a pending source timer"
358
359         bridge mdb del dev br0 port $swp1 grp $grp vid 10
360
361         # Check that group timer is not set for temporary (*, G) INCLUDE, but
362         # that the source timer is set.
363         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
364                 filter_mode include source_list $src1
365
366         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
367                 grep -q "temp"
368         check_err $? "(*, G) INCLUDE entry not added as \"temp\" when should"
369         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
370                 grep -q "temp"
371         check_err $? "(S, G) entry not added as \"temp\" when should"
372
373         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
374                 grep -q " 0.00"
375         check_err $? "(*, G) INCLUDE entry has a pending group timer"
376         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
377                 grep -q "\/0.00"
378         check_fail $? "Source entry does not have a pending source timer"
379
380         bridge mdb del dev br0 port $swp1 grp $grp vid 10
381
382         # Check that group timer is never set for (S, G) entries.
383         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
384                 filter_mode include source_list $src1
385
386         bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
387                 grep -q " 0.00"
388         check_err $? "(S, G) entry has a pending group timer"
389
390         bridge mdb del dev br0 port $swp1 grp $grp vid 10
391
392         ## Filter mode (include / exclude) tests.
393
394         # Check that (*, G) INCLUDE entries are added with correct filter mode
395         # and that (S, G) entries are not marked as "blocked".
396         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
397                 filter_mode include source_list $src1
398
399         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
400                 grep -q "include"
401         check_err $? "(*, G) INCLUDE not added with \"include\" filter mode"
402         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
403                 grep -q "blocked"
404         check_fail $? "(S, G) entry marked as \"blocked\" when should not"
405
406         bridge mdb del dev br0 port $swp1 grp $grp vid 10
407
408         # Check that (*, G) EXCLUDE entries are added with correct filter mode
409         # and that (S, G) entries are marked as "blocked".
410         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
411                 filter_mode exclude source_list $src1
412
413         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
414                 grep -q "exclude"
415         check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode"
416         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
417                 grep -q "blocked"
418         check_err $? "(S, G) entry not marked as \"blocked\" when should"
419
420         bridge mdb del dev br0 port $swp1 grp $grp vid 10
421
422         ## Protocol tests.
423
424         # Check that (*, G) and (S, G) entries are added with the specified
425         # protocol.
426         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
427                 filter_mode exclude source_list $src1 proto zebra
428
429         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
430                 grep -q "zebra"
431         check_err $? "(*, G) entry not added with \"zebra\" protocol"
432         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
433                 grep -q "zebra"
434         check_err $? "(S, G) entry not marked added with \"zebra\" protocol"
435
436         bridge mdb del dev br0 port $swp1 grp $grp vid 10
437
438         ## Replace tests.
439
440         # Check that state can be modified.
441         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
442                 filter_mode exclude source_list $src1
443
444         bridge mdb replace dev br0 port $swp1 grp $grp permanent vid 10 \
445                 filter_mode exclude source_list $src1
446         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
447                 grep -q "permanent"
448         check_err $? "(*, G) entry not marked as \"permanent\" after replace"
449         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
450                 grep -q "permanent"
451         check_err $? "(S, G) entry not marked as \"permanent\" after replace"
452
453         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
454                 filter_mode exclude source_list $src1
455         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
456                 grep -q "temp"
457         check_err $? "(*, G) entry not marked as \"temp\" after replace"
458         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
459                 grep -q "temp"
460         check_err $? "(S, G) entry not marked as \"temp\" after replace"
461
462         bridge mdb del dev br0 port $swp1 grp $grp vid 10
463
464         # Check that filter mode can be modified.
465         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
466                 filter_mode exclude source_list $src1
467
468         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
469                 filter_mode include source_list $src1
470         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
471                 grep -q "include"
472         check_err $? "(*, G) not marked with \"include\" filter mode after replace"
473         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
474                 grep -q "blocked"
475         check_fail $? "(S, G) marked as \"blocked\" after replace"
476
477         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
478                 filter_mode exclude source_list $src1
479         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
480                 grep -q "exclude"
481         check_err $? "(*, G) not marked with \"exclude\" filter mode after replace"
482         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
483                 grep -q "blocked"
484         check_err $? "(S, G) not marked as \"blocked\" after replace"
485
486         bridge mdb del dev br0 port $swp1 grp $grp vid 10
487
488         # Check that sources can be added to and removed from the source list.
489         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
490                 filter_mode exclude source_list $src1
491
492         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
493                 filter_mode exclude source_list $src1,$src2,$src3
494         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
495         check_err $? "(S, G) entry for source $src1 not created after replace"
496         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src2"
497         check_err $? "(S, G) entry for source $src2 not created after replace"
498         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src3"
499         check_err $? "(S, G) entry for source $src3 not created after replace"
500
501         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
502                 filter_mode exclude source_list $src1,$src3
503         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
504         check_err $? "(S, G) entry for source $src1 not created after second replace"
505         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src2"
506         check_fail $? "(S, G) entry for source $src2 created after second replace"
507         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src3"
508         check_err $? "(S, G) entry for source $src3 not created after second replace"
509
510         bridge mdb del dev br0 port $swp1 grp $grp vid 10
511
512         # Check that protocol can be modified.
513         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
514                 filter_mode exclude source_list $src1 proto zebra
515
516         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
517                 filter_mode exclude source_list $src1 proto bgp
518         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
519                 grep -q "bgp"
520         check_err $? "(*, G) protocol not changed to \"bgp\" after replace"
521         bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
522                 grep -q "bgp"
523         check_err $? "(S, G) protocol not changed to \"bgp\" after replace"
524
525         bridge mdb del dev br0 port $swp1 grp $grp vid 10
526
527         ## Star exclude tests.
528
529         # Check star exclude functionality. When adding a new EXCLUDE (*, G),
530         # it needs to be also added to all (S, G) entries for proper
531         # replication.
532         bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
533                 filter_mode include source_list $src1
534         bridge mdb add dev br0 port $swp1 grp $grp vid 10
535         bridge -d mdb show dev br0 vid 10 | grep "$swp1" | grep "$grp" | \
536                 grep "$src1" | grep -q "added_by_star_ex"
537         check_err $? "\"added_by_star_ex\" entry not created after adding (*, G) entry"
538         bridge mdb del dev br0 port $swp1 grp $grp vid 10
539         bridge mdb del dev br0 port $swp2 grp $grp src $src1 vid 10
540
541         ## Error cases tests.
542
543         bridge mdb add dev br0 port $swp1 grp $invalid_grp vid 10 &> /dev/null
544         check_fail $? "Managed to add an entry with an invalid group"
545
546         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
547                 &> /dev/null
548         check_fail $? "Managed to add an INCLUDE entry with an empty source list"
549
550         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
551                 source_list $grp &> /dev/null
552         check_fail $? "Managed to add an entry with an invalid source in source list"
553
554         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
555                 source_list $src &> /dev/null
556         check_fail $? "Managed to add an entry with a source list and no filter mode"
557
558         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
559                 source_list $src1
560         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
561                 source_list $src1 &> /dev/null
562         check_fail $? "Managed to replace an entry without using replace"
563         bridge mdb del dev br0 port $swp1 grp $grp vid 10
564
565         bridge mdb add dev br0 port $swp1 grp $grp src $src2 vid 10
566         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
567                 source_list $src1,$src2,$src3 &> /dev/null
568         check_fail $? "Managed to add a source that already has a forwarding entry"
569         bridge mdb del dev br0 port $swp1 grp $grp src $src2 vid 10
570
571         # Check maximum number of sources.
572         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
573                 source_list $(src_list_create $src_prefix $max_srcs)
574         num_srcs=$(bridge -d mdb show dev br0 vid 10 | grep "$grp" | \
575                 grep "src" | wc -l)
576         [[ $num_srcs -eq $max_srcs ]]
577         check_err $? "Failed to configure maximum number of sources ($max_srcs)"
578         bridge mdb del dev br0 port $swp1 grp $grp vid 10
579
580         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
581                 source_list $(src_list_create $src_prefix $((max_srcs + 1))) \
582                 &> /dev/null
583         check_fail $? "Managed to exceed maximum number of sources ($max_srcs)"
584
585         log_test "$name (*, G) port group entries configuration tests"
586 }
587
588 cfg_test_port_ip_star_g()
589 {
590         echo
591         log_info "# Port group entries configuration tests - (*, G)"
592
593         cfg_test_port_common "IPv4 (*, G)" "grp 239.1.1.1"
594         cfg_test_port_common "IPv6 (*, G)" "grp ff0e::1"
595         __cfg_test_port_ip_star_g "IPv4" "239.1.1.1" "224.0.0.1" "192.0.2."
596         __cfg_test_port_ip_star_g "IPv6" "ff0e::1" "ff02::1" "2001:db8:1::"
597 }
598
599 __cfg_test_port_ip_sg()
600 {
601         local name=$1; shift
602         local grp=$1; shift
603         local src=$1; shift
604         local grp_key="grp $grp src $src"
605
606         RET=0
607
608         bridge mdb add dev br0 port $swp1 $grp_key vid 10
609         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "include"
610         check_err $? "Default filter mode is not \"include\""
611         bridge mdb del dev br0 port $swp1 $grp_key vid 10
612
613         # Check that entries can be added as both permanent and temp and that
614         # group timer is set correctly.
615         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
616         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
617                 grep -q "permanent"
618         check_err $? "Entry not added as \"permanent\" when should"
619         bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
620                 grep -q "0.00"
621         check_err $? "\"permanent\" entry has a pending group timer"
622         bridge mdb del dev br0 port $swp1 $grp_key vid 10
623
624         bridge mdb add dev br0 port $swp1 $grp_key temp vid 10
625         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
626                 grep -q "temp"
627         check_err $? "Entry not added as \"temp\" when should"
628         bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
629                 grep -q "0.00"
630         check_fail $? "\"temp\" entry has an unpending group timer"
631         bridge mdb del dev br0 port $swp1 $grp_key vid 10
632
633         # Check error cases.
634         bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
635                 filter_mode include &> /dev/null
636         check_fail $? "Managed to add an entry with a filter mode"
637
638         bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
639                 filter_mode include source_list $src &> /dev/null
640         check_fail $? "Managed to add an entry with a source list"
641
642         bridge mdb add dev br0 port $swp1 grp $grp src $grp vid 10 &> /dev/null
643         check_fail $? "Managed to add an entry with an invalid source"
644
645         bridge mdb add dev br0 port $swp1 $grp_key vid 10 temp
646         bridge mdb add dev br0 port $swp1 $grp_key vid 10 permanent &> /dev/null
647         check_fail $? "Managed to replace an entry without using replace"
648         bridge mdb del dev br0 port $swp1 $grp_key vid 10
649
650         # Check that we can replace available attributes.
651         bridge mdb add dev br0 port $swp1 $grp_key vid 10 proto 123
652         bridge mdb replace dev br0 port $swp1 $grp_key vid 10 proto 111
653         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
654                 grep -q "111"
655         check_err $? "Failed to replace protocol"
656
657         bridge mdb replace dev br0 port $swp1 $grp_key vid 10 permanent
658         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
659                 grep -q "permanent"
660         check_err $? "Entry not marked as \"permanent\" after replace"
661         bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
662                 grep -q "0.00"
663         check_err $? "Entry has a pending group timer after replace"
664
665         bridge mdb replace dev br0 port $swp1 $grp_key vid 10 temp
666         bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
667                 grep -q "temp"
668         check_err $? "Entry not marked as \"temp\" after replace"
669         bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
670                 grep -q "0.00"
671         check_fail $? "Entry has an unpending group timer after replace"
672         bridge mdb del dev br0 port $swp1 $grp_key vid 10
673
674         # Check star exclude functionality. When adding a (S, G), all matching
675         # (*, G) ports need to be added to it.
676         bridge mdb add dev br0 port $swp2 grp $grp vid 10
677         bridge mdb add dev br0 port $swp1 $grp_key vid 10
678         bridge mdb show dev br0 vid 10 | grep "$grp_key" | grep $swp2 | \
679                 grep -q "added_by_star_ex"
680         check_err $? "\"added_by_star_ex\" entry not created after adding (S, G) entry"
681         bridge mdb del dev br0 port $swp1 $grp_key vid 10
682         bridge mdb del dev br0 port $swp2 grp $grp vid 10
683
684         log_test "$name (S, G) port group entries configuration tests"
685 }
686
687 cfg_test_port_ip_sg()
688 {
689         echo
690         log_info "# Port group entries configuration tests - (S, G)"
691
692         cfg_test_port_common "IPv4 (S, G)" "grp 239.1.1.1 src 192.0.2.1"
693         cfg_test_port_common "IPv6 (S, G)" "grp ff0e::1 src 2001:db8:1::1"
694         __cfg_test_port_ip_sg "IPv4" "239.1.1.1" "192.0.2.1"
695         __cfg_test_port_ip_sg "IPv6" "ff0e::1" "2001:db8:1::1"
696 }
697
698 cfg_test_port_ip()
699 {
700         cfg_test_port_ip_star_g
701         cfg_test_port_ip_sg
702 }
703
704 __cfg_test_port_l2()
705 {
706         local grp="01:02:03:04:05:06"
707
708         RET=0
709
710         bridge meb add dev br0 port $swp grp 00:01:02:03:04:05 \
711                 permanent vid 10 &> /dev/null
712         check_fail $? "Managed to add an entry with unicast MAC"
713
714         bridge mdb add dev br0 port $swp grp $grp src 00:01:02:03:04:05 \
715                 permanent vid 10 &> /dev/null
716         check_fail $? "Managed to add an entry with a source"
717
718         bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
719                 filter_mode include &> /dev/null
720         check_fail $? "Managed to add an entry with a filter mode"
721
722         bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
723                 source_list 00:01:02:03:04:05 &> /dev/null
724         check_fail $? "Managed to add an entry with a source list"
725
726         log_test "L2 (*, G) port group entries configuration tests"
727 }
728
729 cfg_test_port_l2()
730 {
731         echo
732         log_info "# Port group entries configuration tests - L2"
733
734         cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06"
735         __cfg_test_port_l2
736 }
737
738 # Check configuration of regular (port) entries of all types.
739 cfg_test_port()
740 {
741         cfg_test_port_ip
742         cfg_test_port_l2
743 }
744
745 ipv4_grps_get()
746 {
747         local max_grps=$1; shift
748         local i
749
750         for i in $(seq 0 $((max_grps - 1))); do
751                 echo "239.1.1.$i"
752         done
753 }
754
755 ipv6_grps_get()
756 {
757         local max_grps=$1; shift
758         local i
759
760         for i in $(seq 0 $((max_grps - 1))); do
761                 echo "ff0e::$(printf %x $i)"
762         done
763 }
764
765 l2_grps_get()
766 {
767         local max_grps=$1; shift
768         local i
769
770         for i in $(seq 0 $((max_grps - 1))); do
771                 echo "01:00:00:00:00:$(printf %02x $i)"
772         done
773 }
774
775 cfg_test_dump_common()
776 {
777         local name=$1; shift
778         local fn=$1; shift
779         local max_bridges=2
780         local max_grps=256
781         local max_ports=32
782         local num_entries
783         local batch_file
784         local grp
785         local i j
786
787         RET=0
788
789         # Create net devices.
790         for i in $(seq 1 $max_bridges); do
791                 ip link add name br-test${i} up type bridge vlan_filtering 1 \
792                         mcast_snooping 1
793                 for j in $(seq 1 $max_ports); do
794                         ip link add name br-test${i}-du${j} up \
795                                 master br-test${i} type dummy
796                 done
797         done
798
799         # Create batch file with MDB entries.
800         batch_file=$(mktemp)
801         for i in $(seq 1 $max_bridges); do
802                 for j in $(seq 1 $max_ports); do
803                         for grp in $($fn $max_grps); do
804                                 echo "mdb add dev br-test${i} \
805                                         port br-test${i}-du${j} grp $grp \
806                                         permanent vid 1" >> $batch_file
807                         done
808                 done
809         done
810
811         # Program the batch file and check for expected number of entries.
812         bridge -b $batch_file
813         for i in $(seq 1 $max_bridges); do
814                 num_entries=$(bridge mdb show dev br-test${i} | \
815                         grep "permanent" | wc -l)
816                 [[ $num_entries -eq $((max_grps * max_ports)) ]]
817                 check_err $? "Wrong number of entries in br-test${i}"
818         done
819
820         # Cleanup.
821         rm $batch_file
822         for i in $(seq 1 $max_bridges); do
823                 ip link del dev br-test${i}
824                 for j in $(seq $max_ports); do
825                         ip link del dev br-test${i}-du${j}
826                 done
827         done
828
829         log_test "$name large scale dump tests"
830 }
831
832 # Check large scale dump.
833 cfg_test_dump()
834 {
835         echo
836         log_info "# Large scale dump tests"
837
838         cfg_test_dump_common "IPv4" ipv4_grps_get
839         cfg_test_dump_common "IPv6" ipv6_grps_get
840         cfg_test_dump_common "L2" l2_grps_get
841 }
842
843 cfg_test()
844 {
845         cfg_test_host
846         cfg_test_port
847         cfg_test_dump
848 }
849
850 __fwd_test_host_ip()
851 {
852         local grp=$1; shift
853         local dmac=$1; shift
854         local src=$1; shift
855         local mode=$1; shift
856         local name
857         local eth_type
858
859         RET=0
860
861         if [[ $mode == "-4" ]]; then
862                 name="IPv4"
863                 eth_type="ipv4"
864         else
865                 name="IPv6"
866                 eth_type="ipv6"
867         fi
868
869         tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \
870                 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \
871                 action drop
872
873         # Packet should only be flooded to multicast router ports when there is
874         # no matching MDB entry. The bridge is not configured as a multicast
875         # router port.
876         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
877         tc_check_packets "dev br0 ingress" 1 0
878         check_err $? "Packet locally received after flood"
879
880         # Install a regular port group entry and expect the packet to not be
881         # locally received.
882         bridge mdb add dev br0 port $swp2 grp $grp temp vid 10
883         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
884         tc_check_packets "dev br0 ingress" 1 0
885         check_err $? "Packet locally received after installing a regular entry"
886
887         # Add a host entry and expect the packet to be locally received.
888         bridge mdb add dev br0 port br0 grp $grp temp vid 10
889         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
890         tc_check_packets "dev br0 ingress" 1 1
891         check_err $? "Packet not locally received after adding a host entry"
892
893         # Remove the host entry and expect the packet to not be locally
894         # received.
895         bridge mdb del dev br0 port br0 grp $grp vid 10
896         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
897         tc_check_packets "dev br0 ingress" 1 1
898         check_err $? "Packet locally received after removing a host entry"
899
900         bridge mdb del dev br0 port $swp2 grp $grp vid 10
901
902         tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower
903
904         log_test "$name host entries forwarding tests"
905 }
906
907 fwd_test_host_ip()
908 {
909         __fwd_test_host_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "-4"
910         __fwd_test_host_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "-6"
911 }
912
913 fwd_test_host_l2()
914 {
915         local dmac=01:02:03:04:05:06
916
917         RET=0
918
919         tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \
920                 dst_mac $dmac action drop
921
922         # Packet should be flooded and locally received when there is no
923         # matching MDB entry.
924         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
925         tc_check_packets "dev br0 ingress" 1 1
926         check_err $? "Packet not locally received after flood"
927
928         # Install a regular port group entry and expect the packet to not be
929         # locally received.
930         bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
931         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
932         tc_check_packets "dev br0 ingress" 1 1
933         check_err $? "Packet locally received after installing a regular entry"
934
935         # Add a host entry and expect the packet to be locally received.
936         bridge mdb add dev br0 port br0 grp $dmac permanent vid 10
937         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
938         tc_check_packets "dev br0 ingress" 1 2
939         check_err $? "Packet not locally received after adding a host entry"
940
941         # Remove the host entry and expect the packet to not be locally
942         # received.
943         bridge mdb del dev br0 port br0 grp $dmac permanent vid 10
944         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
945         tc_check_packets "dev br0 ingress" 1 2
946         check_err $? "Packet locally received after removing a host entry"
947
948         bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
949
950         tc filter del dev br0 ingress protocol all pref 1 handle 1 flower
951
952         log_test "L2 host entries forwarding tests"
953 }
954
955 fwd_test_host()
956 {
957         # Disable multicast router on the bridge to ensure that packets are
958         # only locally received when a matching host entry is present.
959         ip link set dev br0 type bridge mcast_router 0
960
961         fwd_test_host_ip
962         fwd_test_host_l2
963
964         ip link set dev br0 type bridge mcast_router 1
965 }
966
967 __fwd_test_port_ip()
968 {
969         local grp=$1; shift
970         local dmac=$1; shift
971         local valid_src=$1; shift
972         local invalid_src=$1; shift
973         local mode=$1; shift
974         local filter_mode=$1; shift
975         local name
976         local eth_type
977         local src_list
978
979         RET=0
980
981         if [[ $mode == "-4" ]]; then
982                 name="IPv4"
983                 eth_type="ipv4"
984         else
985                 name="IPv6"
986                 eth_type="ipv6"
987         fi
988
989         # The valid source is the one we expect to get packets from after
990         # adding the entry.
991         if [[ $filter_mode == "include" ]]; then
992                 src_list=$valid_src
993         else
994                 src_list=$invalid_src
995         fi
996
997         tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \
998                 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
999                 src_ip $valid_src action drop
1000         tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \
1001                 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
1002                 src_ip $invalid_src action drop
1003
1004         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1005         tc_check_packets "dev $h2 ingress" 1 0
1006         check_err $? "Packet from valid source received on H2 before adding entry"
1007
1008         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1009         tc_check_packets "dev $h2 ingress" 2 0
1010         check_err $? "Packet from invalid source received on H2 before adding entry"
1011
1012         bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
1013                 filter_mode $filter_mode source_list $src_list
1014
1015         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1016         tc_check_packets "dev $h2 ingress" 1 1
1017         check_err $? "Packet from valid source not received on H2 after adding entry"
1018
1019         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1020         tc_check_packets "dev $h2 ingress" 2 0
1021         check_err $? "Packet from invalid source received on H2 after adding entry"
1022
1023         bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \
1024                 filter_mode exclude
1025
1026         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1027         tc_check_packets "dev $h2 ingress" 1 2
1028         check_err $? "Packet from valid source not received on H2 after allowing all sources"
1029
1030         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1031         tc_check_packets "dev $h2 ingress" 2 1
1032         check_err $? "Packet from invalid source not received on H2 after allowing all sources"
1033
1034         bridge mdb del dev br0 port $swp2 grp $grp vid 10
1035
1036         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1037         tc_check_packets "dev $h2 ingress" 1 2
1038         check_err $? "Packet from valid source received on H2 after deleting entry"
1039
1040         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1041         tc_check_packets "dev $h2 ingress" 2 1
1042         check_err $? "Packet from invalid source received on H2 after deleting entry"
1043
1044         tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower
1045         tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower
1046
1047         log_test "$name port group \"$filter_mode\" entries forwarding tests"
1048 }
1049
1050 fwd_test_port_ip()
1051 {
1052         __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "exclude"
1053         __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
1054                 "exclude"
1055         __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "include"
1056         __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
1057                 "include"
1058 }
1059
1060 fwd_test_port_l2()
1061 {
1062         local dmac=01:02:03:04:05:06
1063
1064         RET=0
1065
1066         tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \
1067                 dst_mac $dmac action drop
1068
1069         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1070         tc_check_packets "dev $h2 ingress" 1 0
1071         check_err $? "Packet received on H2 before adding entry"
1072
1073         bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
1074         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1075         tc_check_packets "dev $h2 ingress" 1 1
1076         check_err $? "Packet not received on H2 after adding entry"
1077
1078         bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
1079         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1080         tc_check_packets "dev $h2 ingress" 1 1
1081         check_err $? "Packet received on H2 after deleting entry"
1082
1083         tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower
1084
1085         log_test "L2 port entries forwarding tests"
1086 }
1087
1088 fwd_test_port()
1089 {
1090         # Disable multicast flooding to ensure that packets are only forwarded
1091         # out of a port when a matching port group entry is present.
1092         bridge link set dev $swp2 mcast_flood off
1093
1094         fwd_test_port_ip
1095         fwd_test_port_l2
1096
1097         bridge link set dev $swp2 mcast_flood on
1098 }
1099
1100 fwd_test()
1101 {
1102         echo
1103         log_info "# Forwarding tests"
1104
1105         # Forwarding according to MDB entries only takes place when the bridge
1106         # detects that there is a valid querier in the network. Set the bridge
1107         # as the querier and assign it a valid IPv6 link-local address to be
1108         # used as the source address for MLD queries.
1109         ip -6 address add fe80::1/64 nodad dev br0
1110         ip link set dev br0 type bridge mcast_querier 1
1111         # Wait the default Query Response Interval (10 seconds) for the bridge
1112         # to determine that there are no other queriers in the network.
1113         sleep 10
1114
1115         fwd_test_host
1116         fwd_test_port
1117
1118         ip link set dev br0 type bridge mcast_querier 0
1119         ip -6 address del fe80::1/64 dev br0
1120 }
1121
1122 ctrl_igmpv3_is_in_test()
1123 {
1124         RET=0
1125
1126         # Add a permanent entry and check that it is not affected by the
1127         # received IGMP packet.
1128         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \
1129                 filter_mode include source_list 192.0.2.1
1130
1131         # IS_IN ( 192.0.2.2 )
1132         $MZ $h1.10 -c 1 -a own -b 01:00:5e:01:01:01 -A 192.0.2.1 -B 239.1.1.1 \
1133                 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
1134
1135         bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -q 192.0.2.2
1136         check_fail $? "Permanent entry affected by IGMP packet"
1137
1138         # Replace the permanent entry with a temporary one and check that after
1139         # processing the IGMP packet, a new source is added to the list along
1140         # with a new forwarding entry.
1141         bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \
1142                 filter_mode include source_list 192.0.2.1
1143
1144         # IS_IN ( 192.0.2.2 )
1145         $MZ $h1.10 -a own -b 01:00:5e:01:01:01 -c 1 -A 192.0.2.1 -B 239.1.1.1 \
1146                 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
1147
1148         bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -v "src" | \
1149                 grep -q 192.0.2.2
1150         check_err $? "Source not add to source list"
1151
1152         bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | \
1153                 grep -q "src 192.0.2.2"
1154         check_err $? "(S, G) entry not created for new source"
1155
1156         bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10
1157
1158         log_test "IGMPv3 MODE_IS_INCLUDE tests"
1159 }
1160
1161 ctrl_mldv2_is_in_test()
1162 {
1163         RET=0
1164
1165         # Add a permanent entry and check that it is not affected by the
1166         # received MLD packet.
1167         bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \
1168                 filter_mode include source_list 2001:db8:1::1
1169
1170         # IS_IN ( 2001:db8:1::2 )
1171         local p=$(mldv2_is_in_get fe80::1 ff0e::1 2001:db8:1::2)
1172         $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
1173                 -t ip hop=1,next=0,p="$p" -q
1174
1175         bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \
1176                 grep -q 2001:db8:1::2
1177         check_fail $? "Permanent entry affected by MLD packet"
1178
1179         # Replace the permanent entry with a temporary one and check that after
1180         # processing the MLD packet, a new source is added to the list along
1181         # with a new forwarding entry.
1182         bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \
1183                 filter_mode include source_list 2001:db8:1::1
1184
1185         # IS_IN ( 2001:db8:1::2 )
1186         $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
1187                 -t ip hop=1,next=0,p="$p" -q
1188
1189         bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | grep -v "src" | \
1190                 grep -q 2001:db8:1::2
1191         check_err $? "Source not add to source list"
1192
1193         bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \
1194                 grep -q "src 2001:db8:1::2"
1195         check_err $? "(S, G) entry not created for new source"
1196
1197         bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10
1198
1199         log_test "MLDv2 MODE_IS_INCLUDE tests"
1200 }
1201
1202 ctrl_test()
1203 {
1204         echo
1205         log_info "# Control packets tests"
1206
1207         ctrl_igmpv3_is_in_test
1208         ctrl_mldv2_is_in_test
1209 }
1210
1211 if ! bridge mdb help 2>&1 | grep -q "replace"; then
1212         echo "SKIP: iproute2 too old, missing bridge mdb replace support"
1213         exit $ksft_skip
1214 fi
1215
1216 trap cleanup EXIT
1217
1218 setup_prepare
1219 setup_wait
1220 tests_run
1221
1222 exit $EXIT_STATUS