Skip to content

Commit 1bc6cc4

Browse files
committed
Merge branch 'bridge-mcast-preparations-for-vxlan-mdb'
Ido Schimmel says: ==================== bridge: mcast: Preparations for VXLAN MDB This patchset contains small preparations for VXLAN MDB that were split from this RFC [1]. Tested using existing bridge MDB forwarding selftests. [1] https://lore.kernel.org/netdev/20230204170801.3897900-1-idosch@nvidia.com/ ==================== Link: https://lore.kernel.org/r/20230209071852.613102-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents ee7e178 + 0491391 commit 1bc6cc4

File tree

2 files changed

+127
-21
lines changed

2 files changed

+127
-21
lines changed

net/bridge/br_mdb.c

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static int __mdb_fill_info(struct sk_buff *skb,
259259
#endif
260260
} else {
261261
ether_addr_copy(e.addr.u.mac_addr, mp->addr.dst.mac_addr);
262-
e.state = MDB_PG_FLAGS_PERMANENT;
262+
e.state = MDB_PERMANENT;
263263
}
264264
e.addr.proto = mp->addr.proto;
265265
nest_ent = nla_nest_start_noflag(skb,
@@ -421,8 +421,6 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
421421

422422
rcu_read_lock();
423423

424-
cb->seq = net->dev_base_seq;
425-
426424
for_each_netdev_rcu(net, dev) {
427425
if (netif_is_bridge_master(dev)) {
428426
struct net_bridge *br = netdev_priv(dev);
@@ -685,51 +683,58 @@ static const struct nla_policy br_mdbe_attrs_pol[MDBE_ATTR_MAX + 1] = {
685683
[MDBE_ATTR_RTPROT] = NLA_POLICY_MIN(NLA_U8, RTPROT_STATIC),
686684
};
687685

688-
static bool is_valid_mdb_entry(struct br_mdb_entry *entry,
689-
struct netlink_ext_ack *extack)
686+
static int validate_mdb_entry(const struct nlattr *attr,
687+
struct netlink_ext_ack *extack)
690688
{
689+
struct br_mdb_entry *entry = nla_data(attr);
690+
691+
if (nla_len(attr) != sizeof(struct br_mdb_entry)) {
692+
NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
693+
return -EINVAL;
694+
}
695+
691696
if (entry->ifindex == 0) {
692697
NL_SET_ERR_MSG_MOD(extack, "Zero entry ifindex is not allowed");
693-
return false;
698+
return -EINVAL;
694699
}
695700

696701
if (entry->addr.proto == htons(ETH_P_IP)) {
697702
if (!ipv4_is_multicast(entry->addr.u.ip4)) {
698703
NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is not multicast");
699-
return false;
704+
return -EINVAL;
700705
}
701706
if (ipv4_is_local_multicast(entry->addr.u.ip4)) {
702707
NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is local multicast");
703-
return false;
708+
return -EINVAL;
704709
}
705710
#if IS_ENABLED(CONFIG_IPV6)
706711
} else if (entry->addr.proto == htons(ETH_P_IPV6)) {
707712
if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) {
708713
NL_SET_ERR_MSG_MOD(extack, "IPv6 entry group address is link-local all nodes");
709-
return false;
714+
return -EINVAL;
710715
}
711716
#endif
712717
} else if (entry->addr.proto == 0) {
713718
/* L2 mdb */
714719
if (!is_multicast_ether_addr(entry->addr.u.mac_addr)) {
715720
NL_SET_ERR_MSG_MOD(extack, "L2 entry group is not multicast");
716-
return false;
721+
return -EINVAL;
717722
}
718723
} else {
719724
NL_SET_ERR_MSG_MOD(extack, "Unknown entry protocol");
720-
return false;
725+
return -EINVAL;
721726
}
722727

723728
if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) {
724729
NL_SET_ERR_MSG_MOD(extack, "Unknown entry state");
725-
return false;
730+
return -EINVAL;
726731
}
727732
if (entry->vid >= VLAN_VID_MASK) {
728733
NL_SET_ERR_MSG_MOD(extack, "Invalid entry VLAN id");
729-
return false;
734+
return -EINVAL;
730735
}
731736

732-
return true;
737+
return 0;
733738
}
734739

735740
static bool is_valid_mdb_source(struct nlattr *attr, __be16 proto,
@@ -1294,6 +1299,14 @@ static int br_mdb_config_attrs_init(struct nlattr *set_attrs,
12941299
return 0;
12951300
}
12961301

1302+
static const struct nla_policy mdba_policy[MDBA_SET_ENTRY_MAX + 1] = {
1303+
[MDBA_SET_ENTRY_UNSPEC] = { .strict_start_type = MDBA_SET_ENTRY_ATTRS + 1 },
1304+
[MDBA_SET_ENTRY] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
1305+
validate_mdb_entry,
1306+
sizeof(struct br_mdb_entry)),
1307+
[MDBA_SET_ENTRY_ATTRS] = { .type = NLA_NESTED },
1308+
};
1309+
12971310
static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
12981311
struct br_mdb_config *cfg,
12991312
struct netlink_ext_ack *extack)
@@ -1304,7 +1317,7 @@ static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
13041317
int err;
13051318

13061319
err = nlmsg_parse_deprecated(nlh, sizeof(*bpm), tb,
1307-
MDBA_SET_ENTRY_MAX, NULL, extack);
1320+
MDBA_SET_ENTRY_MAX, mdba_policy, extack);
13081321
if (err)
13091322
return err;
13101323

@@ -1346,14 +1359,8 @@ static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
13461359
NL_SET_ERR_MSG_MOD(extack, "Missing MDBA_SET_ENTRY attribute");
13471360
return -EINVAL;
13481361
}
1349-
if (nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
1350-
NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
1351-
return -EINVAL;
1352-
}
13531362

13541363
cfg->entry = nla_data(tb[MDBA_SET_ENTRY]);
1355-
if (!is_valid_mdb_entry(cfg->entry, extack))
1356-
return -EINVAL;
13571364

13581365
if (cfg->entry->ifindex != cfg->br->dev->ifindex) {
13591366
struct net_device *pdev;

tools/testing/selftests/net/forwarding/bridge_mdb.sh

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,10 +742,109 @@ cfg_test_port()
742742
cfg_test_port_l2
743743
}
744744

745+
ipv4_grps_get()
746+
{
747+
local max_grps=$1; shift
748+
local i
749+
750+
for i in $(seq 0 $((max_grps - 1))); do
751+
echo "239.1.1.$i"
752+
done
753+
}
754+
755+
ipv6_grps_get()
756+
{
757+
local max_grps=$1; shift
758+
local i
759+
760+
for i in $(seq 0 $((max_grps - 1))); do
761+
echo "ff0e::$(printf %x $i)"
762+
done
763+
}
764+
765+
l2_grps_get()
766+
{
767+
local max_grps=$1; shift
768+
local i
769+
770+
for i in $(seq 0 $((max_grps - 1))); do
771+
echo "01:00:00:00:00:$(printf %02x $i)"
772+
done
773+
}
774+
775+
cfg_test_dump_common()
776+
{
777+
local name=$1; shift
778+
local fn=$1; shift
779+
local max_bridges=2
780+
local max_grps=256
781+
local max_ports=32
782+
local num_entries
783+
local batch_file
784+
local grp
785+
local i j
786+
787+
RET=0
788+
789+
# Create net devices.
790+
for i in $(seq 1 $max_bridges); do
791+
ip link add name br-test${i} up type bridge vlan_filtering 1 \
792+
mcast_snooping 1
793+
for j in $(seq 1 $max_ports); do
794+
ip link add name br-test${i}-du${j} up \
795+
master br-test${i} type dummy
796+
done
797+
done
798+
799+
# Create batch file with MDB entries.
800+
batch_file=$(mktemp)
801+
for i in $(seq 1 $max_bridges); do
802+
for j in $(seq 1 $max_ports); do
803+
for grp in $($fn $max_grps); do
804+
echo "mdb add dev br-test${i} \
805+
port br-test${i}-du${j} grp $grp \
806+
permanent vid 1" >> $batch_file
807+
done
808+
done
809+
done
810+
811+
# Program the batch file and check for expected number of entries.
812+
bridge -b $batch_file
813+
for i in $(seq 1 $max_bridges); do
814+
num_entries=$(bridge mdb show dev br-test${i} | \
815+
grep "permanent" | wc -l)
816+
[[ $num_entries -eq $((max_grps * max_ports)) ]]
817+
check_err $? "Wrong number of entries in br-test${i}"
818+
done
819+
820+
# Cleanup.
821+
rm $batch_file
822+
for i in $(seq 1 $max_bridges); do
823+
ip link del dev br-test${i}
824+
for j in $(seq $max_ports); do
825+
ip link del dev br-test${i}-du${j}
826+
done
827+
done
828+
829+
log_test "$name large scale dump tests"
830+
}
831+
832+
# Check large scale dump.
833+
cfg_test_dump()
834+
{
835+
echo
836+
log_info "# Large scale dump tests"
837+
838+
cfg_test_dump_common "IPv4" ipv4_grps_get
839+
cfg_test_dump_common "IPv6" ipv6_grps_get
840+
cfg_test_dump_common "L2" l2_grps_get
841+
}
842+
745843
cfg_test()
746844
{
747845
cfg_test_host
748846
cfg_test_port
847+
cfg_test_dump
749848
}
750849

751850
__fwd_test_host_ip()

0 commit comments

Comments
 (0)