1216 lines
39 KiB
Bash
1216 lines
39 KiB
Bash
|
#!/bin/bash
|
||
|
# SPDX-License-Identifier: GPL-2.0
|
||
|
|
||
|
# +-----------------------+ +------------------------+
|
||
|
# | H1 (vrf) | | H2 (vrf) |
|
||
|
# | + $h1.10 | | + $h2.10 |
|
||
|
# | | 192.0.2.1/28 | | | 192.0.2.2/28 |
|
||
|
# | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 |
|
||
|
# | | | | | |
|
||
|
# | | + $h1.20 | | | + $h2.20 |
|
||
|
# | \ | 198.51.100.1/24 | | \ | 198.51.100.2/24 |
|
||
|
# | \ | 2001:db8:2::1/64 | | \ | 2001:db8:2::2/64 |
|
||
|
# | \| | | \| |
|
||
|
# | + $h1 | | + $h2 |
|
||
|
# +----|------------------+ +----|-------------------+
|
||
|
# | |
|
||
|
# +----|--------------------------------------------------|-------------------+
|
||
|
# | SW | | |
|
||
|
# | +--|--------------------------------------------------|-----------------+ |
|
||
|
# | | + $swp1 BR0 (802.1q) + $swp2 | |
|
||
|
# | | vid 10 vid 10 | |
|
||
|
# | | vid 20 vid 20 | |
|
||
|
# | | | |
|
||
|
# | +-----------------------------------------------------------------------+ |
|
||
|
# +---------------------------------------------------------------------------+
|
||
|
|
||
|
ALL_TESTS="
|
||
|
cfg_test
|
||
|
fwd_test
|
||
|
ctrl_test
|
||
|
"
|
||
|
|
||
|
NUM_NETIFS=4
|
||
|
source lib.sh
|
||
|
source tc_common.sh
|
||
|
|
||
|
h1_create()
|
||
|
{
|
||
|
simple_if_init $h1
|
||
|
vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64
|
||
|
vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64
|
||
|
}
|
||
|
|
||
|
h1_destroy()
|
||
|
{
|
||
|
vlan_destroy $h1 20
|
||
|
vlan_destroy $h1 10
|
||
|
simple_if_fini $h1
|
||
|
}
|
||
|
|
||
|
h2_create()
|
||
|
{
|
||
|
simple_if_init $h2
|
||
|
vlan_create $h2 10 v$h2 192.0.2.2/28
|
||
|
vlan_create $h2 20 v$h2 198.51.100.2/24
|
||
|
}
|
||
|
|
||
|
h2_destroy()
|
||
|
{
|
||
|
vlan_destroy $h2 20
|
||
|
vlan_destroy $h2 10
|
||
|
simple_if_fini $h2
|
||
|
}
|
||
|
|
||
|
switch_create()
|
||
|
{
|
||
|
ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0 \
|
||
|
mcast_snooping 1 mcast_igmp_version 3 mcast_mld_version 2
|
||
|
bridge vlan add vid 10 dev br0 self
|
||
|
bridge vlan add vid 20 dev br0 self
|
||
|
ip link set dev br0 up
|
||
|
|
||
|
ip link set dev $swp1 master br0
|
||
|
ip link set dev $swp1 up
|
||
|
bridge vlan add vid 10 dev $swp1
|
||
|
bridge vlan add vid 20 dev $swp1
|
||
|
|
||
|
ip link set dev $swp2 master br0
|
||
|
ip link set dev $swp2 up
|
||
|
bridge vlan add vid 10 dev $swp2
|
||
|
bridge vlan add vid 20 dev $swp2
|
||
|
|
||
|
tc qdisc add dev br0 clsact
|
||
|
tc qdisc add dev $h2 clsact
|
||
|
}
|
||
|
|
||
|
switch_destroy()
|
||
|
{
|
||
|
tc qdisc del dev $h2 clsact
|
||
|
tc qdisc del dev br0 clsact
|
||
|
|
||
|
bridge vlan del vid 20 dev $swp2
|
||
|
bridge vlan del vid 10 dev $swp2
|
||
|
ip link set dev $swp2 down
|
||
|
ip link set dev $swp2 nomaster
|
||
|
|
||
|
bridge vlan del vid 20 dev $swp1
|
||
|
bridge vlan del vid 10 dev $swp1
|
||
|
ip link set dev $swp1 down
|
||
|
ip link set dev $swp1 nomaster
|
||
|
|
||
|
ip link set dev br0 down
|
||
|
bridge vlan del vid 20 dev br0 self
|
||
|
bridge vlan del vid 10 dev br0 self
|
||
|
ip link del dev br0
|
||
|
}
|
||
|
|
||
|
setup_prepare()
|
||
|
{
|
||
|
h1=${NETIFS[p1]}
|
||
|
swp1=${NETIFS[p2]}
|
||
|
|
||
|
swp2=${NETIFS[p3]}
|
||
|
h2=${NETIFS[p4]}
|
||
|
|
||
|
vrf_prepare
|
||
|
forwarding_enable
|
||
|
|
||
|
h1_create
|
||
|
h2_create
|
||
|
switch_create
|
||
|
}
|
||
|
|
||
|
cleanup()
|
||
|
{
|
||
|
pre_cleanup
|
||
|
|
||
|
switch_destroy
|
||
|
h2_destroy
|
||
|
h1_destroy
|
||
|
|
||
|
forwarding_restore
|
||
|
vrf_cleanup
|
||
|
}
|
||
|
|
||
|
cfg_test_host_common()
|
||
|
{
|
||
|
local name=$1; shift
|
||
|
local grp=$1; shift
|
||
|
local src=$1; shift
|
||
|
local state=$1; shift
|
||
|
local invalid_state=$1; shift
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
# Check basic add, replace and delete behavior.
|
||
|
bridge mdb add dev br0 port br0 grp $grp $state vid 10
|
||
|
bridge mdb show dev br0 vid 10 | grep -q "$grp"
|
||
|
check_err $? "Failed to add $name host entry"
|
||
|
|
||
|
bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null
|
||
|
check_fail $? "Managed to replace $name host entry"
|
||
|
|
||
|
bridge mdb del dev br0 port br0 grp $grp $state vid 10
|
||
|
bridge mdb show dev br0 vid 10 | grep -q "$grp"
|
||
|
check_fail $? "Failed to delete $name host entry"
|
||
|
|
||
|
# Check error cases.
|
||
|
bridge mdb add dev br0 port br0 grp $grp $invalid_state vid 10 \
|
||
|
&> /dev/null
|
||
|
check_fail $? "Managed to add $name host entry with a $invalid_state state"
|
||
|
|
||
|
bridge mdb add dev br0 port br0 grp $grp src $src $state vid 10 \
|
||
|
&> /dev/null
|
||
|
check_fail $? "Managed to add $name host entry with a source"
|
||
|
|
||
|
bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
|
||
|
filter_mode exclude &> /dev/null
|
||
|
check_fail $? "Managed to add $name host entry with a filter mode"
|
||
|
|
||
|
bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
|
||
|
source_list $src &> /dev/null
|
||
|
check_fail $? "Managed to add $name host entry with a source list"
|
||
|
|
||
|
bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
|
||
|
proto 123 &> /dev/null
|
||
|
check_fail $? "Managed to add $name host entry with a protocol"
|
||
|
|
||
|
log_test "Common host entries configuration tests ($name)"
|
||
|
}
|
||
|
|
||
|
# Check configuration of host entries from all types.
|
||
|
cfg_test_host()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Host entries configuration tests"
|
||
|
|
||
|
cfg_test_host_common "IPv4" "239.1.1.1" "192.0.2.1" "temp" "permanent"
|
||
|
cfg_test_host_common "IPv6" "ff0e::1" "2001:db8:1::1" "temp" "permanent"
|
||
|
cfg_test_host_common "L2" "01:02:03:04:05:06" "00:00:00:00:00:01" \
|
||
|
"permanent" "temp"
|
||
|
}
|
||
|
|
||
|
cfg_test_port_common()
|
||
|
{
|
||
|
local name=$1;shift
|
||
|
local grp_key=$1; shift
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
# Check basic add, replace and delete behavior.
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
|
||
|
check_err $? "Failed to add $name entry"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
|
||
|
&> /dev/null
|
||
|
check_err $? "Failed to replace $name entry"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
|
||
|
check_fail $? "Failed to delete $name entry"
|
||
|
|
||
|
# Check default protocol and replacement.
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "static"
|
||
|
check_err $? "$name entry not added with default \"static\" protocol"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
|
||
|
proto 123
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "123"
|
||
|
check_err $? "Failed to replace protocol of $name entry"
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
|
||
|
# Check behavior when VLAN is not specified.
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent
|
||
|
bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
|
||
|
check_err $? "$name entry with VLAN 10 not added when VLAN was not specified"
|
||
|
bridge mdb show dev br0 vid 20 | grep -q "$grp_key"
|
||
|
check_err $? "$name entry with VLAN 20 not added when VLAN was not specified"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key permanent
|
||
|
bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
|
||
|
check_fail $? "$name entry with VLAN 10 not deleted when VLAN was not specified"
|
||
|
bridge mdb show dev br0 vid 20 | grep -q "$grp_key"
|
||
|
check_fail $? "$name entry with VLAN 20 not deleted when VLAN was not specified"
|
||
|
|
||
|
# Check behavior when bridge port is down.
|
||
|
ip link set dev $swp1 down
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
check_err $? "Failed to add $name permanent entry when bridge port is down"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key temp vid 10 &> /dev/null
|
||
|
check_fail $? "Managed to add $name temporary entry when bridge port is down"
|
||
|
|
||
|
ip link set dev $swp1 up
|
||
|
setup_wait_dev $swp1
|
||
|
|
||
|
# Check error cases.
|
||
|
ip link set dev br0 down
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 \
|
||
|
&> /dev/null
|
||
|
check_fail $? "Managed to add $name entry when bridge is down"
|
||
|
ip link set dev br0 up
|
||
|
|
||
|
ip link set dev br0 type bridge mcast_snooping 0
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid \
|
||
|
10 &> /dev/null
|
||
|
check_fail $? "Managed to add $name entry when multicast snooping is disabled"
|
||
|
ip link set dev br0 type bridge mcast_snooping 1
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid 5000 \
|
||
|
&> /dev/null
|
||
|
check_fail $? "Managed to add $name entry with an invalid VLAN"
|
||
|
|
||
|
log_test "Common port group entries configuration tests ($name)"
|
||
|
}
|
||
|
|
||
|
src_list_create()
|
||
|
{
|
||
|
local src_prefix=$1; shift
|
||
|
local num_srcs=$1; shift
|
||
|
local src_list
|
||
|
local i
|
||
|
|
||
|
for i in $(seq 1 $num_srcs); do
|
||
|
src_list=${src_list},${src_prefix}${i}
|
||
|
done
|
||
|
|
||
|
echo $src_list | cut -c 2-
|
||
|
}
|
||
|
|
||
|
__cfg_test_port_ip_star_g()
|
||
|
{
|
||
|
local name=$1; shift
|
||
|
local grp=$1; shift
|
||
|
local invalid_grp=$1; shift
|
||
|
local src_prefix=$1; shift
|
||
|
local src1=${src_prefix}1
|
||
|
local src2=${src_prefix}2
|
||
|
local src3=${src_prefix}3
|
||
|
local max_srcs=31
|
||
|
local num_srcs
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "exclude"
|
||
|
check_err $? "Default filter mode is not \"exclude\""
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check basic add and delete behavior.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
|
||
|
source_list $src1
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q -v "src"
|
||
|
check_err $? "(*, G) entry not created"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
|
||
|
check_err $? "(S, G) entry not created"
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q -v "src"
|
||
|
check_fail $? "(*, G) entry not deleted"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
|
||
|
check_fail $? "(S, G) entry not deleted"
|
||
|
|
||
|
## State (permanent / temp) tests.
|
||
|
|
||
|
# Check that group and source timer are not set for permanent entries.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "permanent"
|
||
|
check_err $? "(*, G) entry not added as \"permanent\" when should"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "permanent"
|
||
|
check_err $? "(S, G) entry not added as \"permanent\" when should"
|
||
|
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q " 0.00"
|
||
|
check_err $? "(*, G) \"permanent\" entry has a pending group timer"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "\/0.00"
|
||
|
check_err $? "\"permanent\" source entry has a pending source timer"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that group timer is set for temporary (*, G) EXCLUDE, but not
|
||
|
# the source timer.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "(*, G) EXCLUDE entry not added as \"temp\" when should"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should"
|
||
|
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q " 0.00"
|
||
|
check_fail $? "(*, G) EXCLUDE entry does not have a pending group timer"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "\/0.00"
|
||
|
check_err $? "\"blocked\" source entry has a pending source timer"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that group timer is not set for temporary (*, G) INCLUDE, but
|
||
|
# that the source timer is set.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode include source_list $src1
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "(*, G) INCLUDE entry not added as \"temp\" when should"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "(S, G) entry not added as \"temp\" when should"
|
||
|
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q " 0.00"
|
||
|
check_err $? "(*, G) INCLUDE entry has a pending group timer"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "\/0.00"
|
||
|
check_fail $? "Source entry does not have a pending source timer"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that group timer is never set for (S, G) entries.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode include source_list $src1
|
||
|
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q " 0.00"
|
||
|
check_err $? "(S, G) entry has a pending group timer"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
## Filter mode (include / exclude) tests.
|
||
|
|
||
|
# Check that (*, G) INCLUDE entries are added with correct filter mode
|
||
|
# and that (S, G) entries are not marked as "blocked".
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
|
||
|
filter_mode include source_list $src1
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "include"
|
||
|
check_err $? "(*, G) INCLUDE not added with \"include\" filter mode"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "blocked"
|
||
|
check_fail $? "(S, G) entry marked as \"blocked\" when should not"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that (*, G) EXCLUDE entries are added with correct filter mode
|
||
|
# and that (S, G) entries are marked as "blocked".
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "exclude"
|
||
|
check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "blocked"
|
||
|
check_err $? "(S, G) entry not marked as \"blocked\" when should"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
## Protocol tests.
|
||
|
|
||
|
# Check that (*, G) and (S, G) entries are added with the specified
|
||
|
# protocol.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
|
||
|
filter_mode exclude source_list $src1 proto zebra
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "zebra"
|
||
|
check_err $? "(*, G) entry not added with \"zebra\" protocol"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "zebra"
|
||
|
check_err $? "(S, G) entry not marked added with \"zebra\" protocol"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
## Replace tests.
|
||
|
|
||
|
# Check that state can be modified.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp permanent vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "permanent"
|
||
|
check_err $? "(*, G) entry not marked as \"permanent\" after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "permanent"
|
||
|
check_err $? "(S, G) entry not marked as \"permanent\" after replace"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "(*, G) entry not marked as \"temp\" after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "(S, G) entry not marked as \"temp\" after replace"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that filter mode can be modified.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode include source_list $src1
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "include"
|
||
|
check_err $? "(*, G) not marked with \"include\" filter mode after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "blocked"
|
||
|
check_fail $? "(S, G) marked as \"blocked\" after replace"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "exclude"
|
||
|
check_err $? "(*, G) not marked with \"exclude\" filter mode after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "blocked"
|
||
|
check_err $? "(S, G) not marked as \"blocked\" after replace"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that sources can be added to and removed from the source list.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1,$src2,$src3
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
|
||
|
check_err $? "(S, G) entry for source $src1 not created after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src2"
|
||
|
check_err $? "(S, G) entry for source $src2 not created after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src3"
|
||
|
check_err $? "(S, G) entry for source $src3 not created after replace"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1,$src3
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
|
||
|
check_err $? "(S, G) entry for source $src1 not created after second replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src2"
|
||
|
check_fail $? "(S, G) entry for source $src2 created after second replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src3"
|
||
|
check_err $? "(S, G) entry for source $src3 not created after second replace"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
# Check that protocol can be modified.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1 proto zebra
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
|
||
|
filter_mode exclude source_list $src1 proto bgp
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
|
||
|
grep -q "bgp"
|
||
|
check_err $? "(*, G) protocol not changed to \"bgp\" after replace"
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
|
||
|
grep -q "bgp"
|
||
|
check_err $? "(S, G) protocol not changed to \"bgp\" after replace"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
## Star exclude tests.
|
||
|
|
||
|
# Check star exclude functionality. When adding a new EXCLUDE (*, G),
|
||
|
# it needs to be also added to all (S, G) entries for proper
|
||
|
# replication.
|
||
|
bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
|
||
|
filter_mode include source_list $src1
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$swp1" | grep "$grp" | \
|
||
|
grep "$src1" | grep -q "added_by_star_ex"
|
||
|
check_err $? "\"added_by_star_ex\" entry not created after adding (*, G) entry"
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
bridge mdb del dev br0 port $swp2 grp $grp src $src1 vid 10
|
||
|
|
||
|
## Error cases tests.
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $invalid_grp vid 10 &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with an invalid group"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
|
||
|
&> /dev/null
|
||
|
check_fail $? "Managed to add an INCLUDE entry with an empty source list"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
|
||
|
source_list $grp &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with an invalid source in source list"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
|
||
|
source_list $src &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with a source list and no filter mode"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
|
||
|
source_list $src1
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
|
||
|
source_list $src1 &> /dev/null
|
||
|
check_fail $? "Managed to replace an entry without using replace"
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp src $src2 vid 10
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
|
||
|
source_list $src1,$src2,$src3 &> /dev/null
|
||
|
check_fail $? "Managed to add a source that already has a forwarding entry"
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp src $src2 vid 10
|
||
|
|
||
|
# Check maximum number of sources.
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
|
||
|
source_list $(src_list_create $src_prefix $max_srcs)
|
||
|
num_srcs=$(bridge -d mdb show dev br0 vid 10 | grep "$grp" | \
|
||
|
grep "src" | wc -l)
|
||
|
[[ $num_srcs -eq $max_srcs ]]
|
||
|
check_err $? "Failed to configure maximum number of sources ($max_srcs)"
|
||
|
bridge mdb del dev br0 port $swp1 grp $grp vid 10
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
|
||
|
source_list $(src_list_create $src_prefix $((max_srcs + 1))) \
|
||
|
&> /dev/null
|
||
|
check_fail $? "Managed to exceed maximum number of sources ($max_srcs)"
|
||
|
|
||
|
log_test "$name (*, G) port group entries configuration tests"
|
||
|
}
|
||
|
|
||
|
cfg_test_port_ip_star_g()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Port group entries configuration tests - (*, G)"
|
||
|
|
||
|
cfg_test_port_common "IPv4 (*, G)" "grp 239.1.1.1"
|
||
|
cfg_test_port_common "IPv6 (*, G)" "grp ff0e::1"
|
||
|
__cfg_test_port_ip_star_g "IPv4" "239.1.1.1" "224.0.0.1" "192.0.2."
|
||
|
__cfg_test_port_ip_star_g "IPv6" "ff0e::1" "ff02::1" "2001:db8:1::"
|
||
|
}
|
||
|
|
||
|
__cfg_test_port_ip_sg()
|
||
|
{
|
||
|
local name=$1; shift
|
||
|
local grp=$1; shift
|
||
|
local src=$1; shift
|
||
|
local grp_key="grp $grp src $src"
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "include"
|
||
|
check_err $? "Default filter mode is not \"include\""
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key vid 10
|
||
|
|
||
|
# Check that entries can be added as both permanent and temp and that
|
||
|
# group timer is set correctly.
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "permanent"
|
||
|
check_err $? "Entry not added as \"permanent\" when should"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "0.00"
|
||
|
check_err $? "\"permanent\" entry has a pending group timer"
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key vid 10
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key temp vid 10
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "Entry not added as \"temp\" when should"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "0.00"
|
||
|
check_fail $? "\"temp\" entry has an unpending group timer"
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key vid 10
|
||
|
|
||
|
# Check error cases.
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
|
||
|
filter_mode include &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with a filter mode"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
|
||
|
filter_mode include source_list $src &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with a source list"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp src $grp vid 10 &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with an invalid source"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10 temp
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10 permanent &> /dev/null
|
||
|
check_fail $? "Managed to replace an entry without using replace"
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key vid 10
|
||
|
|
||
|
# Check that we can replace available attributes.
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10 proto 123
|
||
|
bridge mdb replace dev br0 port $swp1 $grp_key vid 10 proto 111
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "111"
|
||
|
check_err $? "Failed to replace protocol"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 $grp_key vid 10 permanent
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "permanent"
|
||
|
check_err $? "Entry not marked as \"permanent\" after replace"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "0.00"
|
||
|
check_err $? "Entry has a pending group timer after replace"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp1 $grp_key vid 10 temp
|
||
|
bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "temp"
|
||
|
check_err $? "Entry not marked as \"temp\" after replace"
|
||
|
bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
|
||
|
grep -q "0.00"
|
||
|
check_fail $? "Entry has an unpending group timer after replace"
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key vid 10
|
||
|
|
||
|
# Check star exclude functionality. When adding a (S, G), all matching
|
||
|
# (*, G) ports need to be added to it.
|
||
|
bridge mdb add dev br0 port $swp2 grp $grp vid 10
|
||
|
bridge mdb add dev br0 port $swp1 $grp_key vid 10
|
||
|
bridge mdb show dev br0 vid 10 | grep "$grp_key" | grep $swp2 | \
|
||
|
grep -q "added_by_star_ex"
|
||
|
check_err $? "\"added_by_star_ex\" entry not created after adding (S, G) entry"
|
||
|
bridge mdb del dev br0 port $swp1 $grp_key vid 10
|
||
|
bridge mdb del dev br0 port $swp2 grp $grp vid 10
|
||
|
|
||
|
log_test "$name (S, G) port group entries configuration tests"
|
||
|
}
|
||
|
|
||
|
cfg_test_port_ip_sg()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Port group entries configuration tests - (S, G)"
|
||
|
|
||
|
cfg_test_port_common "IPv4 (S, G)" "grp 239.1.1.1 src 192.0.2.1"
|
||
|
cfg_test_port_common "IPv6 (S, G)" "grp ff0e::1 src 2001:db8:1::1"
|
||
|
__cfg_test_port_ip_sg "IPv4" "239.1.1.1" "192.0.2.1"
|
||
|
__cfg_test_port_ip_sg "IPv6" "ff0e::1" "2001:db8:1::1"
|
||
|
}
|
||
|
|
||
|
cfg_test_port_ip()
|
||
|
{
|
||
|
cfg_test_port_ip_star_g
|
||
|
cfg_test_port_ip_sg
|
||
|
}
|
||
|
|
||
|
__cfg_test_port_l2()
|
||
|
{
|
||
|
local grp="01:02:03:04:05:06"
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
bridge meb add dev br0 port $swp grp 00:01:02:03:04:05 \
|
||
|
permanent vid 10 &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with unicast MAC"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp grp $grp src 00:01:02:03:04:05 \
|
||
|
permanent vid 10 &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with a source"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
|
||
|
filter_mode include &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with a filter mode"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
|
||
|
source_list 00:01:02:03:04:05 &> /dev/null
|
||
|
check_fail $? "Managed to add an entry with a source list"
|
||
|
|
||
|
log_test "L2 (*, G) port group entries configuration tests"
|
||
|
}
|
||
|
|
||
|
cfg_test_port_l2()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Port group entries configuration tests - L2"
|
||
|
|
||
|
cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06"
|
||
|
__cfg_test_port_l2
|
||
|
}
|
||
|
|
||
|
# Check configuration of regular (port) entries of all types.
|
||
|
cfg_test_port()
|
||
|
{
|
||
|
cfg_test_port_ip
|
||
|
cfg_test_port_l2
|
||
|
}
|
||
|
|
||
|
ipv4_grps_get()
|
||
|
{
|
||
|
local max_grps=$1; shift
|
||
|
local i
|
||
|
|
||
|
for i in $(seq 0 $((max_grps - 1))); do
|
||
|
echo "239.1.1.$i"
|
||
|
done
|
||
|
}
|
||
|
|
||
|
ipv6_grps_get()
|
||
|
{
|
||
|
local max_grps=$1; shift
|
||
|
local i
|
||
|
|
||
|
for i in $(seq 0 $((max_grps - 1))); do
|
||
|
echo "ff0e::$(printf %x $i)"
|
||
|
done
|
||
|
}
|
||
|
|
||
|
l2_grps_get()
|
||
|
{
|
||
|
local max_grps=$1; shift
|
||
|
local i
|
||
|
|
||
|
for i in $(seq 0 $((max_grps - 1))); do
|
||
|
echo "01:00:00:00:00:$(printf %02x $i)"
|
||
|
done
|
||
|
}
|
||
|
|
||
|
cfg_test_dump_common()
|
||
|
{
|
||
|
local name=$1; shift
|
||
|
local fn=$1; shift
|
||
|
local max_bridges=2
|
||
|
local max_grps=256
|
||
|
local max_ports=32
|
||
|
local num_entries
|
||
|
local batch_file
|
||
|
local grp
|
||
|
local i j
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
# Create net devices.
|
||
|
for i in $(seq 1 $max_bridges); do
|
||
|
ip link add name br-test${i} up type bridge vlan_filtering 1 \
|
||
|
mcast_snooping 1
|
||
|
for j in $(seq 1 $max_ports); do
|
||
|
ip link add name br-test${i}-du${j} up \
|
||
|
master br-test${i} type dummy
|
||
|
done
|
||
|
done
|
||
|
|
||
|
# Create batch file with MDB entries.
|
||
|
batch_file=$(mktemp)
|
||
|
for i in $(seq 1 $max_bridges); do
|
||
|
for j in $(seq 1 $max_ports); do
|
||
|
for grp in $($fn $max_grps); do
|
||
|
echo "mdb add dev br-test${i} \
|
||
|
port br-test${i}-du${j} grp $grp \
|
||
|
permanent vid 1" >> $batch_file
|
||
|
done
|
||
|
done
|
||
|
done
|
||
|
|
||
|
# Program the batch file and check for expected number of entries.
|
||
|
bridge -b $batch_file
|
||
|
for i in $(seq 1 $max_bridges); do
|
||
|
num_entries=$(bridge mdb show dev br-test${i} | \
|
||
|
grep "permanent" | wc -l)
|
||
|
[[ $num_entries -eq $((max_grps * max_ports)) ]]
|
||
|
check_err $? "Wrong number of entries in br-test${i}"
|
||
|
done
|
||
|
|
||
|
# Cleanup.
|
||
|
rm $batch_file
|
||
|
for i in $(seq 1 $max_bridges); do
|
||
|
ip link del dev br-test${i}
|
||
|
for j in $(seq $max_ports); do
|
||
|
ip link del dev br-test${i}-du${j}
|
||
|
done
|
||
|
done
|
||
|
|
||
|
log_test "$name large scale dump tests"
|
||
|
}
|
||
|
|
||
|
# Check large scale dump.
|
||
|
cfg_test_dump()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Large scale dump tests"
|
||
|
|
||
|
cfg_test_dump_common "IPv4" ipv4_grps_get
|
||
|
cfg_test_dump_common "IPv6" ipv6_grps_get
|
||
|
cfg_test_dump_common "L2" l2_grps_get
|
||
|
}
|
||
|
|
||
|
cfg_test()
|
||
|
{
|
||
|
cfg_test_host
|
||
|
cfg_test_port
|
||
|
cfg_test_dump
|
||
|
}
|
||
|
|
||
|
__fwd_test_host_ip()
|
||
|
{
|
||
|
local grp=$1; shift
|
||
|
local src=$1; shift
|
||
|
local mode=$1; shift
|
||
|
local name
|
||
|
local eth_type
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
if [[ $mode == "-4" ]]; then
|
||
|
name="IPv4"
|
||
|
eth_type="ipv4"
|
||
|
else
|
||
|
name="IPv6"
|
||
|
eth_type="ipv6"
|
||
|
fi
|
||
|
|
||
|
tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \
|
||
|
vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \
|
||
|
action drop
|
||
|
|
||
|
# Packet should only be flooded to multicast router ports when there is
|
||
|
# no matching MDB entry. The bridge is not configured as a multicast
|
||
|
# router port.
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q
|
||
|
tc_check_packets "dev br0 ingress" 1 0
|
||
|
check_err $? "Packet locally received after flood"
|
||
|
|
||
|
# Install a regular port group entry and expect the packet to not be
|
||
|
# locally received.
|
||
|
bridge mdb add dev br0 port $swp2 grp $grp temp vid 10
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q
|
||
|
tc_check_packets "dev br0 ingress" 1 0
|
||
|
check_err $? "Packet locally received after installing a regular entry"
|
||
|
|
||
|
# Add a host entry and expect the packet to be locally received.
|
||
|
bridge mdb add dev br0 port br0 grp $grp temp vid 10
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q
|
||
|
tc_check_packets "dev br0 ingress" 1 1
|
||
|
check_err $? "Packet not locally received after adding a host entry"
|
||
|
|
||
|
# Remove the host entry and expect the packet to not be locally
|
||
|
# received.
|
||
|
bridge mdb del dev br0 port br0 grp $grp vid 10
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q
|
||
|
tc_check_packets "dev br0 ingress" 1 1
|
||
|
check_err $? "Packet locally received after removing a host entry"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp2 grp $grp vid 10
|
||
|
|
||
|
tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower
|
||
|
|
||
|
log_test "$name host entries forwarding tests"
|
||
|
}
|
||
|
|
||
|
fwd_test_host_ip()
|
||
|
{
|
||
|
__fwd_test_host_ip "239.1.1.1" "192.0.2.1" "-4"
|
||
|
__fwd_test_host_ip "ff0e::1" "2001:db8:1::1" "-6"
|
||
|
}
|
||
|
|
||
|
fwd_test_host_l2()
|
||
|
{
|
||
|
local dmac=01:02:03:04:05:06
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \
|
||
|
dst_mac $dmac action drop
|
||
|
|
||
|
# Packet should be flooded and locally received when there is no
|
||
|
# matching MDB entry.
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev br0 ingress" 1 1
|
||
|
check_err $? "Packet not locally received after flood"
|
||
|
|
||
|
# Install a regular port group entry and expect the packet to not be
|
||
|
# locally received.
|
||
|
bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev br0 ingress" 1 1
|
||
|
check_err $? "Packet locally received after installing a regular entry"
|
||
|
|
||
|
# Add a host entry and expect the packet to be locally received.
|
||
|
bridge mdb add dev br0 port br0 grp $dmac permanent vid 10
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev br0 ingress" 1 2
|
||
|
check_err $? "Packet not locally received after adding a host entry"
|
||
|
|
||
|
# Remove the host entry and expect the packet to not be locally
|
||
|
# received.
|
||
|
bridge mdb del dev br0 port br0 grp $dmac permanent vid 10
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev br0 ingress" 1 2
|
||
|
check_err $? "Packet locally received after removing a host entry"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
|
||
|
|
||
|
tc filter del dev br0 ingress protocol all pref 1 handle 1 flower
|
||
|
|
||
|
log_test "L2 host entries forwarding tests"
|
||
|
}
|
||
|
|
||
|
fwd_test_host()
|
||
|
{
|
||
|
# Disable multicast router on the bridge to ensure that packets are
|
||
|
# only locally received when a matching host entry is present.
|
||
|
ip link set dev br0 type bridge mcast_router 0
|
||
|
|
||
|
fwd_test_host_ip
|
||
|
fwd_test_host_l2
|
||
|
|
||
|
ip link set dev br0 type bridge mcast_router 1
|
||
|
}
|
||
|
|
||
|
__fwd_test_port_ip()
|
||
|
{
|
||
|
local grp=$1; shift
|
||
|
local valid_src=$1; shift
|
||
|
local invalid_src=$1; shift
|
||
|
local mode=$1; shift
|
||
|
local filter_mode=$1; shift
|
||
|
local name
|
||
|
local eth_type
|
||
|
local src_list
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
if [[ $mode == "-4" ]]; then
|
||
|
name="IPv4"
|
||
|
eth_type="ipv4"
|
||
|
else
|
||
|
name="IPv6"
|
||
|
eth_type="ipv6"
|
||
|
fi
|
||
|
|
||
|
# The valid source is the one we expect to get packets from after
|
||
|
# adding the entry.
|
||
|
if [[ $filter_mode == "include" ]]; then
|
||
|
src_list=$valid_src
|
||
|
else
|
||
|
src_list=$invalid_src
|
||
|
fi
|
||
|
|
||
|
tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \
|
||
|
vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
|
||
|
src_ip $valid_src action drop
|
||
|
tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \
|
||
|
vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
|
||
|
src_ip $invalid_src action drop
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 0
|
||
|
check_err $? "Packet from valid source received on H2 before adding entry"
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 2 0
|
||
|
check_err $? "Packet from invalid source received on H2 before adding entry"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
|
||
|
filter_mode $filter_mode source_list $src_list
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 1
|
||
|
check_err $? "Packet from valid source not received on H2 after adding entry"
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 2 0
|
||
|
check_err $? "Packet from invalid source received on H2 after adding entry"
|
||
|
|
||
|
bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \
|
||
|
filter_mode exclude
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 2
|
||
|
check_err $? "Packet from valid source not received on H2 after allowing all sources"
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 2 1
|
||
|
check_err $? "Packet from invalid source not received on H2 after allowing all sources"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp2 grp $grp vid 10
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 2
|
||
|
check_err $? "Packet from valid source received on H2 after deleting entry"
|
||
|
|
||
|
$MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
|
||
|
tc_check_packets "dev $h2 ingress" 2 1
|
||
|
check_err $? "Packet from invalid source received on H2 after deleting entry"
|
||
|
|
||
|
tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower
|
||
|
tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower
|
||
|
|
||
|
log_test "$name port group \"$filter_mode\" entries forwarding tests"
|
||
|
}
|
||
|
|
||
|
fwd_test_port_ip()
|
||
|
{
|
||
|
__fwd_test_port_ip "239.1.1.1" "192.0.2.1" "192.0.2.2" "-4" "exclude"
|
||
|
__fwd_test_port_ip "ff0e::1" "2001:db8:1::1" "2001:db8:1::2" "-6" \
|
||
|
"exclude"
|
||
|
__fwd_test_port_ip "239.1.1.1" "192.0.2.1" "192.0.2.2" "-4" "include"
|
||
|
__fwd_test_port_ip "ff0e::1" "2001:db8:1::1" "2001:db8:1::2" "-6" \
|
||
|
"include"
|
||
|
}
|
||
|
|
||
|
fwd_test_port_l2()
|
||
|
{
|
||
|
local dmac=01:02:03:04:05:06
|
||
|
|
||
|
RET=0
|
||
|
|
||
|
tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \
|
||
|
dst_mac $dmac action drop
|
||
|
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 0
|
||
|
check_err $? "Packet received on H2 before adding entry"
|
||
|
|
||
|
bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 1
|
||
|
check_err $? "Packet not received on H2 after adding entry"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
|
||
|
$MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
|
||
|
tc_check_packets "dev $h2 ingress" 1 1
|
||
|
check_err $? "Packet received on H2 after deleting entry"
|
||
|
|
||
|
tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower
|
||
|
|
||
|
log_test "L2 port entries forwarding tests"
|
||
|
}
|
||
|
|
||
|
fwd_test_port()
|
||
|
{
|
||
|
# Disable multicast flooding to ensure that packets are only forwarded
|
||
|
# out of a port when a matching port group entry is present.
|
||
|
bridge link set dev $swp2 mcast_flood off
|
||
|
|
||
|
fwd_test_port_ip
|
||
|
fwd_test_port_l2
|
||
|
|
||
|
bridge link set dev $swp2 mcast_flood on
|
||
|
}
|
||
|
|
||
|
fwd_test()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Forwarding tests"
|
||
|
|
||
|
# Forwarding according to MDB entries only takes place when the bridge
|
||
|
# detects that there is a valid querier in the network. Set the bridge
|
||
|
# as the querier and assign it a valid IPv6 link-local address to be
|
||
|
# used as the source address for MLD queries.
|
||
|
ip -6 address add fe80::1/64 nodad dev br0
|
||
|
ip link set dev br0 type bridge mcast_querier 1
|
||
|
# Wait the default Query Response Interval (10 seconds) for the bridge
|
||
|
# to determine that there are no other queriers in the network.
|
||
|
sleep 10
|
||
|
|
||
|
fwd_test_host
|
||
|
fwd_test_port
|
||
|
|
||
|
ip link set dev br0 type bridge mcast_querier 0
|
||
|
ip -6 address del fe80::1/64 dev br0
|
||
|
}
|
||
|
|
||
|
ctrl_igmpv3_is_in_test()
|
||
|
{
|
||
|
RET=0
|
||
|
|
||
|
# Add a permanent entry and check that it is not affected by the
|
||
|
# received IGMP packet.
|
||
|
bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \
|
||
|
filter_mode include source_list 192.0.2.1
|
||
|
|
||
|
# IS_IN ( 192.0.2.2 )
|
||
|
$MZ $h1.10 -c 1 -A 192.0.2.1 -B 239.1.1.1 \
|
||
|
-t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -q 192.0.2.2
|
||
|
check_fail $? "Permanent entry affected by IGMP packet"
|
||
|
|
||
|
# Replace the permanent entry with a temporary one and check that after
|
||
|
# processing the IGMP packet, a new source is added to the list along
|
||
|
# with a new forwarding entry.
|
||
|
bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \
|
||
|
filter_mode include source_list 192.0.2.1
|
||
|
|
||
|
# IS_IN ( 192.0.2.2 )
|
||
|
$MZ $h1.10 -c 1 -A 192.0.2.1 -B 239.1.1.1 \
|
||
|
-t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -v "src" | \
|
||
|
grep -q 192.0.2.2
|
||
|
check_err $? "Source not add to source list"
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | \
|
||
|
grep -q "src 192.0.2.2"
|
||
|
check_err $? "(S, G) entry not created for new source"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10
|
||
|
|
||
|
log_test "IGMPv3 MODE_IS_INCLUDE tests"
|
||
|
}
|
||
|
|
||
|
ctrl_mldv2_is_in_test()
|
||
|
{
|
||
|
RET=0
|
||
|
|
||
|
# Add a permanent entry and check that it is not affected by the
|
||
|
# received MLD packet.
|
||
|
bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \
|
||
|
filter_mode include source_list 2001:db8:1::1
|
||
|
|
||
|
# IS_IN ( 2001:db8:1::2 )
|
||
|
local p=$(mldv2_is_in_get fe80::1 ff0e::1 2001:db8:1::2)
|
||
|
$MZ -6 $h1.10 -c 1 -A fe80::1 -B ff0e::1 \
|
||
|
-t ip hop=1,next=0,p="$p" -q
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \
|
||
|
grep -q 2001:db8:1::2
|
||
|
check_fail $? "Permanent entry affected by MLD packet"
|
||
|
|
||
|
# Replace the permanent entry with a temporary one and check that after
|
||
|
# processing the MLD packet, a new source is added to the list along
|
||
|
# with a new forwarding entry.
|
||
|
bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \
|
||
|
filter_mode include source_list 2001:db8:1::1
|
||
|
|
||
|
# IS_IN ( 2001:db8:1::2 )
|
||
|
$MZ -6 $h1.10 -c 1 -A fe80::1 -B ff0e::1 \
|
||
|
-t ip hop=1,next=0,p="$p" -q
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | grep -v "src" | \
|
||
|
grep -q 2001:db8:1::2
|
||
|
check_err $? "Source not add to source list"
|
||
|
|
||
|
bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \
|
||
|
grep -q "src 2001:db8:1::2"
|
||
|
check_err $? "(S, G) entry not created for new source"
|
||
|
|
||
|
bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10
|
||
|
|
||
|
log_test "MLDv2 MODE_IS_INCLUDE tests"
|
||
|
}
|
||
|
|
||
|
ctrl_test()
|
||
|
{
|
||
|
echo
|
||
|
log_info "# Control packets tests"
|
||
|
|
||
|
ctrl_igmpv3_is_in_test
|
||
|
ctrl_mldv2_is_in_test
|
||
|
}
|
||
|
|
||
|
trap cleanup EXIT
|
||
|
|
||
|
setup_prepare
|
||
|
setup_wait
|
||
|
tests_run
|
||
|
|
||
|
exit $EXIT_STATUS
|