~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/forwarding/bridge_mdb.sh

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 get dev br0 grp $grp vid 10 &> /dev/null
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 get dev br0 grp $grp vid 10 &> /dev/null
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 get dev br0 $grp_key vid 10 &> /dev/null
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 get dev br0 $grp_key vid 10 &> /dev/null
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 get dev br0 $grp_key vid 10 | 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 get dev br0 $grp_key vid 10 | 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 get dev br0 $grp_key vid 10 &> /dev/null
228         check_err $? "$name entry with VLAN 10 not added when VLAN was not specified"
229         bridge mdb get dev br0 $grp_key vid 20 &> /dev/null
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 get dev br0 $grp_key vid 10 &> /dev/null
234         check_fail $? "$name entry with VLAN 10 not deleted when VLAN was not specified"
235         bridge mdb get dev br0 $grp_key vid 20 &> /dev/null
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 get dev br0 grp $grp vid 10 | 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 get dev br0 grp $grp vid 10 &> /dev/null
309         check_err $? "(*, G) entry not created"
310         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
311         check_err $? "(S, G) entry not created"
312         bridge mdb del dev br0 port $swp1 grp $grp vid 10
313         bridge -d mdb get dev br0 grp $grp vid 10 &> /dev/null
314         check_fail $? "(*, G) entry not deleted"
315         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
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 get dev br0 grp $grp vid 10 | grep -q "permanent"
325         check_err $? "(*, G) entry not added as \"permanent\" when should"
326         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | \
327                 grep -q "permanent"
328         check_err $? "(S, G) entry not added as \"permanent\" when should"
329 
330         bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00"
331         check_err $? "(*, G) \"permanent\" entry has a pending group timer"
332         bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00"
333         check_err $? "\"permanent\" source entry has a pending source timer"
334 
335         bridge mdb del dev br0 port $swp1 grp $grp vid 10
336 
337         # Check that group timer is set for temporary (*, G) EXCLUDE, but not
338         # the source timer.
339         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
340                 filter_mode exclude source_list $src1
341 
342         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp"
343         check_err $? "(*, G) EXCLUDE entry not added as \"temp\" when should"
344         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp"
345         check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should"
346 
347         bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00"
348         check_fail $? "(*, G) EXCLUDE entry does not have a pending group timer"
349         bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00"
350         check_err $? "\"blocked\" source entry has a pending source timer"
351 
352         bridge mdb del dev br0 port $swp1 grp $grp vid 10
353 
354         # Check that group timer is not set for temporary (*, G) INCLUDE, but
355         # that the source timer is set.
356         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
357                 filter_mode include source_list $src1
358 
359         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp"
360         check_err $? "(*, G) INCLUDE entry not added as \"temp\" when should"
361         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp"
362         check_err $? "(S, G) entry not added as \"temp\" when should"
363 
364         bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00"
365         check_err $? "(*, G) INCLUDE entry has a pending group timer"
366         bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00"
367         check_fail $? "Source entry does not have a pending source timer"
368 
369         bridge mdb del dev br0 port $swp1 grp $grp vid 10
370 
371         # Check that group timer is never set for (S, G) entries.
372         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
373                 filter_mode include source_list $src1
374 
375         bridge -d -s mdb get dev br0 grp $grp src $src1 vid 10 | grep -q " 0.00"
376         check_err $? "(S, G) entry has a pending group timer"
377 
378         bridge mdb del dev br0 port $swp1 grp $grp vid 10
379 
380         ## Filter mode (include / exclude) tests.
381 
382         # Check that (*, G) INCLUDE entries are added with correct filter mode
383         # and that (S, G) entries are not marked as "blocked".
384         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
385                 filter_mode include source_list $src1
386 
387         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "include"
388         check_err $? "(*, G) INCLUDE not added with \"include\" filter mode"
389         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
390         check_fail $? "(S, G) entry marked as \"blocked\" when should not"
391 
392         bridge mdb del dev br0 port $swp1 grp $grp vid 10
393 
394         # Check that (*, G) EXCLUDE entries are added with correct filter mode
395         # and that (S, G) entries are marked as "blocked".
396         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
397                 filter_mode exclude source_list $src1
398 
399         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude"
400         check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode"
401         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
402         check_err $? "(S, G) entry not marked as \"blocked\" when should"
403 
404         bridge mdb del dev br0 port $swp1 grp $grp vid 10
405 
406         ## Protocol tests.
407 
408         # Check that (*, G) and (S, G) entries are added with the specified
409         # protocol.
410         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
411                 filter_mode exclude source_list $src1 proto zebra
412 
413         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "zebra"
414         check_err $? "(*, G) entry not added with \"zebra\" protocol"
415         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "zebra"
416         check_err $? "(S, G) entry not marked added with \"zebra\" protocol"
417 
418         bridge mdb del dev br0 port $swp1 grp $grp vid 10
419 
420         ## Replace tests.
421 
422         # Check that state can be modified.
423         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
424                 filter_mode exclude source_list $src1
425 
426         bridge mdb replace dev br0 port $swp1 grp $grp permanent vid 10 \
427                 filter_mode exclude source_list $src1
428         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "permanent"
429         check_err $? "(*, G) entry not marked as \"permanent\" after replace"
430         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "permanent"
431         check_err $? "(S, G) entry not marked as \"permanent\" after replace"
432 
433         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
434                 filter_mode exclude source_list $src1
435         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp"
436         check_err $? "(*, G) entry not marked as \"temp\" after replace"
437         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp"
438         check_err $? "(S, G) entry not marked as \"temp\" after replace"
439 
440         bridge mdb del dev br0 port $swp1 grp $grp vid 10
441 
442         # Check that filter mode can be modified.
443         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
444                 filter_mode exclude source_list $src1
445 
446         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
447                 filter_mode include source_list $src1
448         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "include"
449         check_err $? "(*, G) not marked with \"include\" filter mode after replace"
450         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
451         check_fail $? "(S, G) marked as \"blocked\" 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 get dev br0 grp $grp vid 10 | grep -q "exclude"
456         check_err $? "(*, G) not marked with \"exclude\" filter mode after replace"
457         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
458         check_err $? "(S, G) not marked as \"blocked\" after replace"
459 
460         bridge mdb del dev br0 port $swp1 grp $grp vid 10
461 
462         # Check that sources can be added to and removed from the source list.
463         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
464                 filter_mode exclude source_list $src1
465 
466         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
467                 filter_mode exclude source_list $src1,$src2,$src3
468         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
469         check_err $? "(S, G) entry for source $src1 not created after replace"
470         bridge -d mdb get dev br0 grp $grp src $src2 vid 10 &> /dev/null
471         check_err $? "(S, G) entry for source $src2 not created after replace"
472         bridge -d mdb get dev br0 grp $grp src $src3 vid 10 &> /dev/null
473         check_err $? "(S, G) entry for source $src3 not created after replace"
474 
475         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
476                 filter_mode exclude source_list $src1,$src3
477         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
478         check_err $? "(S, G) entry for source $src1 not created after second replace"
479         bridge -d mdb get dev br0 grp $grp src $src2 vid 10 &> /dev/null
480         check_fail $? "(S, G) entry for source $src2 created after second replace"
481         bridge -d mdb get dev br0 grp $grp src $src3 vid 10 &> /dev/null
482         check_err $? "(S, G) entry for source $src3 not created after second replace"
483 
484         bridge mdb del dev br0 port $swp1 grp $grp vid 10
485 
486         # Check that protocol can be modified.
487         bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
488                 filter_mode exclude source_list $src1 proto zebra
489 
490         bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
491                 filter_mode exclude source_list $src1 proto bgp
492         bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "bgp"
493         check_err $? "(*, G) protocol not changed to \"bgp\" after replace"
494         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "bgp"
495         check_err $? "(S, G) protocol not changed to \"bgp\" after replace"
496 
497         bridge mdb del dev br0 port $swp1 grp $grp vid 10
498 
499         ## Star exclude tests.
500 
501         # Check star exclude functionality. When adding a new EXCLUDE (*, G),
502         # it needs to be also added to all (S, G) entries for proper
503         # replication.
504         bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
505                 filter_mode include source_list $src1
506         bridge mdb add dev br0 port $swp1 grp $grp vid 10
507         bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep "$swp1" | \
508                 grep -q "added_by_star_ex"
509         check_err $? "\"added_by_star_ex\" entry not created after adding (*, G) entry"
510         bridge mdb del dev br0 port $swp1 grp $grp vid 10
511         bridge mdb del dev br0 port $swp2 grp $grp src $src1 vid 10
512 
513         ## Error cases tests.
514 
515         bridge mdb add dev br0 port $swp1 grp $invalid_grp vid 10 &> /dev/null
516         check_fail $? "Managed to add an entry with an invalid group"
517 
518         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
519                 &> /dev/null
520         check_fail $? "Managed to add an INCLUDE entry with an empty source list"
521 
522         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
523                 source_list $grp &> /dev/null
524         check_fail $? "Managed to add an entry with an invalid source in source list"
525 
526         bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
527                 source_list $src &> /dev/null
528         check_fail $? "Managed to add an entry with a source list and no filter mode"
529 
530         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
531                 source_list $src1
532         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
533                 source_list $src1 &> /dev/null
534         check_fail $? "Managed to replace an entry without using replace"
535         bridge mdb del dev br0 port $swp1 grp $grp vid 10
536 
537         bridge mdb add dev br0 port $swp1 grp $grp src $src2 vid 10
538         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
539                 source_list $src1,$src2,$src3 &> /dev/null
540         check_fail $? "Managed to add a source that already has a forwarding entry"
541         bridge mdb del dev br0 port $swp1 grp $grp src $src2 vid 10
542 
543         # Check maximum number of sources.
544         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
545                 source_list $(src_list_create $src_prefix $max_srcs)
546         num_srcs=$(bridge -d mdb show dev br0 vid 10 | grep "$grp" | \
547                 grep "src" | wc -l)
548         [[ $num_srcs -eq $max_srcs ]]
549         check_err $? "Failed to configure maximum number of sources ($max_srcs)"
550         bridge mdb del dev br0 port $swp1 grp $grp vid 10
551 
552         bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
553                 source_list $(src_list_create $src_prefix $((max_srcs + 1))) \
554                 &> /dev/null
555         check_fail $? "Managed to exceed maximum number of sources ($max_srcs)"
556 
557         log_test "$name (*, G) port group entries configuration tests"
558 }
559 
560 cfg_test_port_ip_star_g()
561 {
562         echo
563         log_info "# Port group entries configuration tests - (*, G)"
564 
565         cfg_test_port_common "IPv4 (*, G)" "grp 239.1.1.1"
566         cfg_test_port_common "IPv6 (*, G)" "grp ff0e::1"
567         __cfg_test_port_ip_star_g "IPv4" "239.1.1.1" "224.0.0.1" "192.0.2."
568         __cfg_test_port_ip_star_g "IPv6" "ff0e::1" "ff02::1" "2001:db8:1::"
569 }
570 
571 __cfg_test_port_ip_sg()
572 {
573         local name=$1; shift
574         local grp=$1; shift
575         local src=$1; shift
576         local grp_key="grp $grp src $src"
577 
578         RET=0
579 
580         bridge mdb add dev br0 port $swp1 $grp_key vid 10
581         bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "include"
582         check_err $? "Default filter mode is not \"include\""
583         bridge mdb del dev br0 port $swp1 $grp_key vid 10
584 
585         # Check that entries can be added as both permanent and temp and that
586         # group timer is set correctly.
587         bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
588         bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "permanent"
589         check_err $? "Entry not added as \"permanent\" when should"
590         bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
591         check_err $? "\"permanent\" entry has a pending group timer"
592         bridge mdb del dev br0 port $swp1 $grp_key vid 10
593 
594         bridge mdb add dev br0 port $swp1 $grp_key temp vid 10
595         bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "temp"
596         check_err $? "Entry not added as \"temp\" when should"
597         bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
598         check_fail $? "\"temp\" entry has an unpending group timer"
599         bridge mdb del dev br0 port $swp1 $grp_key vid 10
600 
601         # Check error cases.
602         bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
603                 filter_mode include &> /dev/null
604         check_fail $? "Managed to add an entry with a filter mode"
605 
606         bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
607                 filter_mode include source_list $src &> /dev/null
608         check_fail $? "Managed to add an entry with a source list"
609 
610         bridge mdb add dev br0 port $swp1 grp $grp src $grp vid 10 &> /dev/null
611         check_fail $? "Managed to add an entry with an invalid source"
612 
613         bridge mdb add dev br0 port $swp1 $grp_key vid 10 temp
614         bridge mdb add dev br0 port $swp1 $grp_key vid 10 permanent &> /dev/null
615         check_fail $? "Managed to replace an entry without using replace"
616         bridge mdb del dev br0 port $swp1 $grp_key vid 10
617 
618         # Check that we can replace available attributes.
619         bridge mdb add dev br0 port $swp1 $grp_key vid 10 proto 123
620         bridge mdb replace dev br0 port $swp1 $grp_key vid 10 proto 111
621         bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "111"
622         check_err $? "Failed to replace protocol"
623 
624         bridge mdb replace dev br0 port $swp1 $grp_key vid 10 permanent
625         bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "permanent"
626         check_err $? "Entry not marked as \"permanent\" after replace"
627         bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
628         check_err $? "Entry has a pending group timer after replace"
629 
630         bridge mdb replace dev br0 port $swp1 $grp_key vid 10 temp
631         bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "temp"
632         check_err $? "Entry not marked as \"temp\" after replace"
633         bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
634         check_fail $? "Entry has an unpending group timer after replace"
635         bridge mdb del dev br0 port $swp1 $grp_key vid 10
636 
637         # Check star exclude functionality. When adding a (S, G), all matching
638         # (*, G) ports need to be added to it.
639         bridge mdb add dev br0 port $swp2 grp $grp vid 10
640         bridge mdb add dev br0 port $swp1 $grp_key vid 10
641         bridge mdb get dev br0 $grp_key vid 10 | grep $swp2 | \
642                 grep -q "added_by_star_ex"
643         check_err $? "\"added_by_star_ex\" entry not created after adding (S, G) entry"
644         bridge mdb del dev br0 port $swp1 $grp_key vid 10
645         bridge mdb del dev br0 port $swp2 grp $grp vid 10
646 
647         log_test "$name (S, G) port group entries configuration tests"
648 }
649 
650 cfg_test_port_ip_sg()
651 {
652         echo
653         log_info "# Port group entries configuration tests - (S, G)"
654 
655         cfg_test_port_common "IPv4 (S, G)" "grp 239.1.1.1 src 192.0.2.1"
656         cfg_test_port_common "IPv6 (S, G)" "grp ff0e::1 src 2001:db8:1::1"
657         __cfg_test_port_ip_sg "IPv4" "239.1.1.1" "192.0.2.1"
658         __cfg_test_port_ip_sg "IPv6" "ff0e::1" "2001:db8:1::1"
659 }
660 
661 cfg_test_port_ip()
662 {
663         cfg_test_port_ip_star_g
664         cfg_test_port_ip_sg
665 }
666 
667 __cfg_test_port_l2()
668 {
669         local grp="01:02:03:04:05:06"
670 
671         RET=0
672 
673         bridge meb add dev br0 port $swp grp 00:01:02:03:04:05 \
674                 permanent vid 10 &> /dev/null
675         check_fail $? "Managed to add an entry with unicast MAC"
676 
677         bridge mdb add dev br0 port $swp grp $grp src 00:01:02:03:04:05 \
678                 permanent vid 10 &> /dev/null
679         check_fail $? "Managed to add an entry with a source"
680 
681         bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
682                 filter_mode include &> /dev/null
683         check_fail $? "Managed to add an entry with a filter mode"
684 
685         bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
686                 source_list 00:01:02:03:04:05 &> /dev/null
687         check_fail $? "Managed to add an entry with a source list"
688 
689         log_test "L2 (*, G) port group entries configuration tests"
690 }
691 
692 cfg_test_port_l2()
693 {
694         echo
695         log_info "# Port group entries configuration tests - L2"
696 
697         cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06"
698         __cfg_test_port_l2
699 }
700 
701 # Check configuration of regular (port) entries of all types.
702 cfg_test_port()
703 {
704         cfg_test_port_ip
705         cfg_test_port_l2
706 }
707 
708 ipv4_grps_get()
709 {
710         local max_grps=$1; shift
711         local i
712 
713         for i in $(seq 0 $((max_grps - 1))); do
714                 echo "239.1.1.$i"
715         done
716 }
717 
718 ipv6_grps_get()
719 {
720         local max_grps=$1; shift
721         local i
722 
723         for i in $(seq 0 $((max_grps - 1))); do
724                 echo "ff0e::$(printf %x $i)"
725         done
726 }
727 
728 l2_grps_get()
729 {
730         local max_grps=$1; shift
731         local i
732 
733         for i in $(seq 0 $((max_grps - 1))); do
734                 echo "01:00:00:00:00:$(printf %02x $i)"
735         done
736 }
737 
738 cfg_test_dump_common()
739 {
740         local name=$1; shift
741         local fn=$1; shift
742         local max_bridges=2
743         local max_grps=256
744         local max_ports=32
745         local num_entries
746         local batch_file
747         local grp
748         local i j
749 
750         RET=0
751 
752         # Create net devices.
753         for i in $(seq 1 $max_bridges); do
754                 ip link add name br-test${i} up type bridge vlan_filtering 1 \
755                         mcast_snooping 1
756                 for j in $(seq 1 $max_ports); do
757                         ip link add name br-test${i}-du${j} up \
758                                 master br-test${i} type dummy
759                 done
760         done
761 
762         # Create batch file with MDB entries.
763         batch_file=$(mktemp)
764         for i in $(seq 1 $max_bridges); do
765                 for j in $(seq 1 $max_ports); do
766                         for grp in $($fn $max_grps); do
767                                 echo "mdb add dev br-test${i} \
768                                         port br-test${i}-du${j} grp $grp \
769                                         permanent vid 1" >> $batch_file
770                         done
771                 done
772         done
773 
774         # Program the batch file and check for expected number of entries.
775         bridge -b $batch_file
776         for i in $(seq 1 $max_bridges); do
777                 num_entries=$(bridge mdb show dev br-test${i} | \
778                         grep "permanent" | wc -l)
779                 [[ $num_entries -eq $((max_grps * max_ports)) ]]
780                 check_err $? "Wrong number of entries in br-test${i}"
781         done
782 
783         # Cleanup.
784         rm $batch_file
785         for i in $(seq 1 $max_bridges); do
786                 ip link del dev br-test${i}
787                 for j in $(seq $max_ports); do
788                         ip link del dev br-test${i}-du${j}
789                 done
790         done
791 
792         log_test "$name large scale dump tests"
793 }
794 
795 # Check large scale dump.
796 cfg_test_dump()
797 {
798         echo
799         log_info "# Large scale dump tests"
800 
801         cfg_test_dump_common "IPv4" ipv4_grps_get
802         cfg_test_dump_common "IPv6" ipv6_grps_get
803         cfg_test_dump_common "L2" l2_grps_get
804 }
805 
806 # Check flush functionality with different parameters.
807 cfg_test_flush()
808 {
809         local num_entries
810 
811         # Add entries with different attributes and check that they are all
812         # flushed when the flush command is given with no parameters.
813 
814         # Different port.
815         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10
816         bridge mdb add dev br0 port $swp2 grp 239.1.1.2 vid 10
817 
818         # Different VLAN ID.
819         bridge mdb add dev br0 port $swp1 grp 239.1.1.3 vid 10
820         bridge mdb add dev br0 port $swp1 grp 239.1.1.4 vid 20
821 
822         # Different routing protocol.
823         bridge mdb add dev br0 port $swp1 grp 239.1.1.5 vid 10 proto bgp
824         bridge mdb add dev br0 port $swp1 grp 239.1.1.6 vid 10 proto zebra
825 
826         # Different state.
827         bridge mdb add dev br0 port $swp1 grp 239.1.1.7 vid 10 permanent
828         bridge mdb add dev br0 port $swp1 grp 239.1.1.8 vid 10 temp
829 
830         bridge mdb flush dev br0
831         num_entries=$(bridge mdb show dev br0 | wc -l)
832         [[ $num_entries -eq 0 ]]
833         check_err $? 0 "Not all entries flushed after flush all"
834 
835         # Check that when flushing by port only entries programmed with the
836         # specified port are flushed and the rest are not.
837 
838         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10
839         bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10
840         bridge mdb add dev br0 port br0 grp 239.1.1.1 vid 10
841 
842         bridge mdb flush dev br0 port $swp1
843 
844         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
845         check_fail $? "Entry not flushed by specified port"
846         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
847         check_err $? "Entry flushed by wrong port"
848         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0"
849         check_err $? "Host entry flushed by wrong port"
850 
851         bridge mdb flush dev br0 port br0
852 
853         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0"
854         check_fail $? "Host entry not flushed by specified port"
855 
856         bridge mdb flush dev br0
857 
858         # Check that when flushing by VLAN ID only entries programmed with the
859         # specified VLAN ID are flushed and the rest are not.
860 
861         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10
862         bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10
863         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 20
864         bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 20
865 
866         bridge mdb flush dev br0 vid 10
867 
868         bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null
869         check_fail $? "Entry not flushed by specified VLAN ID"
870         bridge mdb get dev br0 grp 239.1.1.1 vid 20 &> /dev/null
871         check_err $? "Entry flushed by wrong VLAN ID"
872 
873         bridge mdb flush dev br0
874 
875         # Check that all permanent entries are flushed when "permanent" is
876         # specified and that temporary entries are not.
877 
878         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10
879         bridge mdb add dev br0 port $swp2 grp 239.1.1.1 temp vid 10
880 
881         bridge mdb flush dev br0 permanent
882 
883         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
884         check_fail $? "Entry not flushed by \"permanent\" state"
885         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
886         check_err $? "Entry flushed by wrong state (\"permanent\")"
887 
888         bridge mdb flush dev br0
889 
890         # Check that all temporary entries are flushed when "nopermanent" is
891         # specified and that permanent entries are not.
892 
893         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10
894         bridge mdb add dev br0 port $swp2 grp 239.1.1.1 temp vid 10
895 
896         bridge mdb flush dev br0 nopermanent
897 
898         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
899         check_err $? "Entry flushed by wrong state (\"nopermanent\")"
900         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
901         check_fail $? "Entry not flushed by \"nopermanent\" state"
902 
903         bridge mdb flush dev br0
904 
905         # Check that L2 host entries are not flushed when "nopermanent" is
906         # specified, but flushed when "permanent" is specified.
907 
908         bridge mdb add dev br0 port br0 grp 01:02:03:04:05:06 permanent vid 10
909 
910         bridge mdb flush dev br0 nopermanent
911 
912         bridge mdb get dev br0 grp 01:02:03:04:05:06 vid 10 &> /dev/null
913         check_err $? "L2 host entry flushed by wrong state (\"nopermanent\")"
914 
915         bridge mdb flush dev br0 permanent
916 
917         bridge mdb get dev br0 grp 01:02:03:04:05:06 vid 10 &> /dev/null
918         check_fail $? "L2 host entry not flushed by \"permanent\" state"
919 
920         bridge mdb flush dev br0
921 
922         # Check that IPv4 host entries are not flushed when "permanent" is
923         # specified, but flushed when "nopermanent" is specified.
924 
925         bridge mdb add dev br0 port br0 grp 239.1.1.1 temp vid 10
926 
927         bridge mdb flush dev br0 permanent
928 
929         bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null
930         check_err $? "IPv4 host entry flushed by wrong state (\"permanent\")"
931 
932         bridge mdb flush dev br0 nopermanent
933 
934         bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null
935         check_fail $? "IPv4 host entry not flushed by \"nopermanent\" state"
936 
937         bridge mdb flush dev br0
938 
939         # Check that IPv6 host entries are not flushed when "permanent" is
940         # specified, but flushed when "nopermanent" is specified.
941 
942         bridge mdb add dev br0 port br0 grp ff0e::1 temp vid 10
943 
944         bridge mdb flush dev br0 permanent
945 
946         bridge mdb get dev br0 grp ff0e::1 vid 10 &> /dev/null
947         check_err $? "IPv6 host entry flushed by wrong state (\"permanent\")"
948 
949         bridge mdb flush dev br0 nopermanent
950 
951         bridge mdb get dev br0 grp ff0e::1 vid 10 &> /dev/null
952         check_fail $? "IPv6 host entry not flushed by \"nopermanent\" state"
953 
954         bridge mdb flush dev br0
955 
956         # Check that when flushing by routing protocol only entries programmed
957         # with the specified routing protocol are flushed and the rest are not.
958 
959         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10 proto bgp
960         bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10 proto zebra
961         bridge mdb add dev br0 port br0 grp 239.1.1.1 vid 10
962 
963         bridge mdb flush dev br0 proto bgp
964 
965         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
966         check_fail $? "Entry not flushed by specified routing protocol"
967         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
968         check_err $? "Entry flushed by wrong routing protocol"
969         bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0"
970         check_err $? "Host entry flushed by wrong routing protocol"
971 
972         bridge mdb flush dev br0
973 
974         # Test that an error is returned when trying to flush using unsupported
975         # parameters.
976 
977         bridge mdb flush dev br0 src_vni 10 &> /dev/null
978         check_fail $? "Managed to flush by source VNI"
979 
980         bridge mdb flush dev br0 dst 198.51.100.1 &> /dev/null
981         check_fail $? "Managed to flush by destination IP"
982 
983         bridge mdb flush dev br0 dst_port 4789 &> /dev/null
984         check_fail $? "Managed to flush by UDP destination port"
985 
986         bridge mdb flush dev br0 vni 10 &> /dev/null
987         check_fail $? "Managed to flush by destination VNI"
988 
989         log_test "Flush tests"
990 }
991 
992 cfg_test()
993 {
994         cfg_test_host
995         cfg_test_port
996         cfg_test_dump
997         cfg_test_flush
998 }
999 
1000 __fwd_test_host_ip()
1001 {
1002         local grp=$1; shift
1003         local dmac=$1; shift
1004         local src=$1; shift
1005         local mode=$1; shift
1006         local name
1007         local eth_type
1008 
1009         RET=0
1010 
1011         if [[ $mode == "-4" ]]; then
1012                 name="IPv4"
1013                 eth_type="ipv4"
1014         else
1015                 name="IPv6"
1016                 eth_type="ipv6"
1017         fi
1018 
1019         tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \
1020                 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \
1021                 action drop
1022 
1023         # Packet should only be flooded to multicast router ports when there is
1024         # no matching MDB entry. The bridge is not configured as a multicast
1025         # router port.
1026         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
1027         tc_check_packets "dev br0 ingress" 1 0
1028         check_err $? "Packet locally received after flood"
1029 
1030         # Install a regular port group entry and expect the packet to not be
1031         # locally received.
1032         bridge mdb add dev br0 port $swp2 grp $grp temp vid 10
1033         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
1034         tc_check_packets "dev br0 ingress" 1 0
1035         check_err $? "Packet locally received after installing a regular entry"
1036 
1037         # Add a host entry and expect the packet to be locally received.
1038         bridge mdb add dev br0 port br0 grp $grp temp vid 10
1039         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
1040         tc_check_packets "dev br0 ingress" 1 1
1041         check_err $? "Packet not locally received after adding a host entry"
1042 
1043         # Remove the host entry and expect the packet to not be locally
1044         # received.
1045         bridge mdb del dev br0 port br0 grp $grp vid 10
1046         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
1047         tc_check_packets "dev br0 ingress" 1 1
1048         check_err $? "Packet locally received after removing a host entry"
1049 
1050         bridge mdb del dev br0 port $swp2 grp $grp vid 10
1051 
1052         tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower
1053 
1054         log_test "$name host entries forwarding tests"
1055 }
1056 
1057 fwd_test_host_ip()
1058 {
1059         __fwd_test_host_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "-4"
1060         __fwd_test_host_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "-6"
1061 }
1062 
1063 fwd_test_host_l2()
1064 {
1065         local dmac=01:02:03:04:05:06
1066 
1067         RET=0
1068 
1069         tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \
1070                 dst_mac $dmac action drop
1071 
1072         # Packet should be flooded and locally received when there is no
1073         # matching MDB entry.
1074         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1075         tc_check_packets "dev br0 ingress" 1 1
1076         check_err $? "Packet not locally received after flood"
1077 
1078         # Install a regular port group entry and expect the packet to not be
1079         # locally received.
1080         bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
1081         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1082         tc_check_packets "dev br0 ingress" 1 1
1083         check_err $? "Packet locally received after installing a regular entry"
1084 
1085         # Add a host entry and expect the packet to be locally received.
1086         bridge mdb add dev br0 port br0 grp $dmac permanent vid 10
1087         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1088         tc_check_packets "dev br0 ingress" 1 2
1089         check_err $? "Packet not locally received after adding a host entry"
1090 
1091         # Remove the host entry and expect the packet to not be locally
1092         # received.
1093         bridge mdb del dev br0 port br0 grp $dmac permanent vid 10
1094         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1095         tc_check_packets "dev br0 ingress" 1 2
1096         check_err $? "Packet locally received after removing a host entry"
1097 
1098         bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
1099 
1100         tc filter del dev br0 ingress protocol all pref 1 handle 1 flower
1101 
1102         log_test "L2 host entries forwarding tests"
1103 }
1104 
1105 fwd_test_host()
1106 {
1107         # Disable multicast router on the bridge to ensure that packets are
1108         # only locally received when a matching host entry is present.
1109         ip link set dev br0 type bridge mcast_router 0
1110 
1111         fwd_test_host_ip
1112         fwd_test_host_l2
1113 
1114         ip link set dev br0 type bridge mcast_router 1
1115 }
1116 
1117 __fwd_test_port_ip()
1118 {
1119         local grp=$1; shift
1120         local dmac=$1; shift
1121         local valid_src=$1; shift
1122         local invalid_src=$1; shift
1123         local mode=$1; shift
1124         local filter_mode=$1; shift
1125         local name
1126         local eth_type
1127         local src_list
1128 
1129         RET=0
1130 
1131         if [[ $mode == "-4" ]]; then
1132                 name="IPv4"
1133                 eth_type="ipv4"
1134         else
1135                 name="IPv6"
1136                 eth_type="ipv6"
1137         fi
1138 
1139         # The valid source is the one we expect to get packets from after
1140         # adding the entry.
1141         if [[ $filter_mode == "include" ]]; then
1142                 src_list=$valid_src
1143         else
1144                 src_list=$invalid_src
1145         fi
1146 
1147         tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \
1148                 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
1149                 src_ip $valid_src action drop
1150         tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \
1151                 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
1152                 src_ip $invalid_src action drop
1153 
1154         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1155         tc_check_packets "dev $h2 ingress" 1 0
1156         check_err $? "Packet from valid source received on H2 before adding entry"
1157 
1158         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1159         tc_check_packets "dev $h2 ingress" 2 0
1160         check_err $? "Packet from invalid source received on H2 before adding entry"
1161 
1162         bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
1163                 filter_mode $filter_mode source_list $src_list
1164 
1165         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1166         tc_check_packets "dev $h2 ingress" 1 1
1167         check_err $? "Packet from valid source not received on H2 after adding entry"
1168 
1169         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1170         tc_check_packets "dev $h2 ingress" 2 0
1171         check_err $? "Packet from invalid source received on H2 after adding entry"
1172 
1173         bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \
1174                 filter_mode exclude
1175 
1176         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1177         tc_check_packets "dev $h2 ingress" 1 2
1178         check_err $? "Packet from valid source not received on H2 after allowing all sources"
1179 
1180         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1181         tc_check_packets "dev $h2 ingress" 2 1
1182         check_err $? "Packet from invalid source not received on H2 after allowing all sources"
1183 
1184         bridge mdb del dev br0 port $swp2 grp $grp vid 10
1185 
1186         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1187         tc_check_packets "dev $h2 ingress" 1 2
1188         check_err $? "Packet from valid source received on H2 after deleting entry"
1189 
1190         $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1191         tc_check_packets "dev $h2 ingress" 2 1
1192         check_err $? "Packet from invalid source received on H2 after deleting entry"
1193 
1194         tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower
1195         tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower
1196 
1197         log_test "$name port group \"$filter_mode\" entries forwarding tests"
1198 }
1199 
1200 fwd_test_port_ip()
1201 {
1202         __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "exclude"
1203         __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
1204                 "exclude"
1205         __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "include"
1206         __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
1207                 "include"
1208 }
1209 
1210 fwd_test_port_l2()
1211 {
1212         local dmac=01:02:03:04:05:06
1213 
1214         RET=0
1215 
1216         tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \
1217                 dst_mac $dmac action drop
1218 
1219         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1220         tc_check_packets "dev $h2 ingress" 1 0
1221         check_err $? "Packet received on H2 before adding entry"
1222 
1223         bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
1224         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1225         tc_check_packets "dev $h2 ingress" 1 1
1226         check_err $? "Packet not received on H2 after adding entry"
1227 
1228         bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
1229         $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1230         tc_check_packets "dev $h2 ingress" 1 1
1231         check_err $? "Packet received on H2 after deleting entry"
1232 
1233         tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower
1234 
1235         log_test "L2 port entries forwarding tests"
1236 }
1237 
1238 fwd_test_port()
1239 {
1240         # Disable multicast flooding to ensure that packets are only forwarded
1241         # out of a port when a matching port group entry is present.
1242         bridge link set dev $swp2 mcast_flood off
1243 
1244         fwd_test_port_ip
1245         fwd_test_port_l2
1246 
1247         bridge link set dev $swp2 mcast_flood on
1248 }
1249 
1250 fwd_test()
1251 {
1252         echo
1253         log_info "# Forwarding tests"
1254 
1255         # Set the Max Response Delay to 100 centiseconds (1 second) so that the
1256         # bridge will start forwarding according to its MDB soon after a
1257         # multicast querier is enabled.
1258         ip link set dev br0 type bridge mcast_query_response_interval 100
1259 
1260         # Forwarding according to MDB entries only takes place when the bridge
1261         # detects that there is a valid querier in the network. Set the bridge
1262         # as the querier and assign it a valid IPv6 link-local address to be
1263         # used as the source address for MLD queries.
1264         ip -6 address add fe80::1/64 nodad dev br0
1265         ip link set dev br0 type bridge mcast_querier 1
1266         sleep 10
1267 
1268         fwd_test_host
1269         fwd_test_port
1270 
1271         ip link set dev br0 type bridge mcast_querier 0
1272         ip -6 address del fe80::1/64 dev br0
1273         ip link set dev br0 type bridge mcast_query_response_interval 1000
1274 }
1275 
1276 ctrl_igmpv3_is_in_test()
1277 {
1278         RET=0
1279 
1280         # Add a permanent entry and check that it is not affected by the
1281         # received IGMP packet.
1282         bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \
1283                 filter_mode include source_list 192.0.2.1
1284 
1285         # IS_IN ( 192.0.2.2 )
1286         $MZ $h1.10 -c 1 -a own -b 01:00:5e:01:01:01 -A 192.0.2.1 -B 239.1.1.1 \
1287                 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
1288 
1289         bridge mdb get dev br0 grp 239.1.1.1 src 192.0.2.2 vid 10 &> /dev/null
1290         check_fail $? "Permanent entry affected by IGMP packet"
1291 
1292         # Replace the permanent entry with a temporary one and check that after
1293         # processing the IGMP packet, a new source is added to the list along
1294         # with a new forwarding entry.
1295         bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \
1296                 filter_mode include source_list 192.0.2.1
1297 
1298         # IS_IN ( 192.0.2.2 )
1299         $MZ $h1.10 -a own -b 01:00:5e:01:01:01 -c 1 -A 192.0.2.1 -B 239.1.1.1 \
1300                 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
1301 
1302         bridge -d mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q 192.0.2.2
1303         check_err $? "Source not add to source list"
1304 
1305         bridge mdb get dev br0 grp 239.1.1.1 src 192.0.2.2 vid 10 &> /dev/null
1306         check_err $? "(S, G) entry not created for new source"
1307 
1308         bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10
1309 
1310         log_test "IGMPv3 MODE_IS_INCLUDE tests"
1311 }
1312 
1313 ctrl_mldv2_is_in_test()
1314 {
1315         RET=0
1316 
1317         # Add a permanent entry and check that it is not affected by the
1318         # received MLD packet.
1319         bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \
1320                 filter_mode include source_list 2001:db8:1::1
1321 
1322         # IS_IN ( 2001:db8:1::2 )
1323         local p=$(mldv2_is_in_get fe80::1 ff0e::1 2001:db8:1::2)
1324         $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
1325                 -t ip hop=1,next=0,p="$p" -q
1326 
1327         bridge mdb get dev br0 grp ff0e::1 src 2001:db8:1::2 vid 10 &> /dev/null
1328         check_fail $? "Permanent entry affected by MLD packet"
1329 
1330         # Replace the permanent entry with a temporary one and check that after
1331         # processing the MLD packet, a new source is added to the list along
1332         # with a new forwarding entry.
1333         bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \
1334                 filter_mode include source_list 2001:db8:1::1
1335 
1336         # IS_IN ( 2001:db8:1::2 )
1337         $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
1338                 -t ip hop=1,next=0,p="$p" -q
1339 
1340         bridge -d mdb get dev br0 grp ff0e::1 vid 10 | grep -q 2001:db8:1::2
1341         check_err $? "Source not add to source list"
1342 
1343         bridge mdb get dev br0 grp ff0e::1 src 2001:db8:1::2 vid 10 &> /dev/null
1344         check_err $? "(S, G) entry not created for new source"
1345 
1346         bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10
1347 
1348         log_test "MLDv2 MODE_IS_INCLUDE tests"
1349 }
1350 
1351 ctrl_test()
1352 {
1353         echo
1354         log_info "# Control packets tests"
1355 
1356         ctrl_igmpv3_is_in_test
1357         ctrl_mldv2_is_in_test
1358 }
1359 
1360 if ! bridge mdb help 2>&1 | grep -q "flush"; then
1361         echo "SKIP: iproute2 too old, missing bridge mdb flush support"
1362         exit $ksft_skip
1363 fi
1364 
1365 trap cleanup EXIT
1366 
1367 setup_prepare
1368 setup_wait
1369 tests_run
1370 
1371 exit $EXIT_STATUS

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php