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>
This commit is contained in:
+28
-21
@@ -259,7 +259,7 @@ static int __mdb_fill_info(struct sk_buff *skb,
|
||||
#endif
|
||||
} else {
|
||||
ether_addr_copy(e.addr.u.mac_addr, mp->addr.dst.mac_addr);
|
||||
e.state = MDB_PG_FLAGS_PERMANENT;
|
||||
e.state = MDB_PERMANENT;
|
||||
}
|
||||
e.addr.proto = mp->addr.proto;
|
||||
nest_ent = nla_nest_start_noflag(skb,
|
||||
@@ -421,8 +421,6 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
cb->seq = net->dev_base_seq;
|
||||
|
||||
for_each_netdev_rcu(net, dev) {
|
||||
if (netif_is_bridge_master(dev)) {
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
@@ -685,51 +683,58 @@ static const struct nla_policy br_mdbe_attrs_pol[MDBE_ATTR_MAX + 1] = {
|
||||
[MDBE_ATTR_RTPROT] = NLA_POLICY_MIN(NLA_U8, RTPROT_STATIC),
|
||||
};
|
||||
|
||||
static bool is_valid_mdb_entry(struct br_mdb_entry *entry,
|
||||
struct netlink_ext_ack *extack)
|
||||
static int validate_mdb_entry(const struct nlattr *attr,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct br_mdb_entry *entry = nla_data(attr);
|
||||
|
||||
if (nla_len(attr) != sizeof(struct br_mdb_entry)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->ifindex == 0) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Zero entry ifindex is not allowed");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->addr.proto == htons(ETH_P_IP)) {
|
||||
if (!ipv4_is_multicast(entry->addr.u.ip4)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is not multicast");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ipv4_is_local_multicast(entry->addr.u.ip4)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is local multicast");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
} else if (entry->addr.proto == htons(ETH_P_IPV6)) {
|
||||
if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "IPv6 entry group address is link-local all nodes");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
} else if (entry->addr.proto == 0) {
|
||||
/* L2 mdb */
|
||||
if (!is_multicast_ether_addr(entry->addr.u.mac_addr)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "L2 entry group is not multicast");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unknown entry protocol");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unknown entry state");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (entry->vid >= VLAN_VID_MASK) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Invalid entry VLAN id");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nla_policy mdba_policy[MDBA_SET_ENTRY_MAX + 1] = {
|
||||
[MDBA_SET_ENTRY_UNSPEC] = { .strict_start_type = MDBA_SET_ENTRY_ATTRS + 1 },
|
||||
[MDBA_SET_ENTRY] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
|
||||
validate_mdb_entry,
|
||||
sizeof(struct br_mdb_entry)),
|
||||
[MDBA_SET_ENTRY_ATTRS] = { .type = NLA_NESTED },
|
||||
};
|
||||
|
||||
static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
|
||||
struct br_mdb_config *cfg,
|
||||
struct netlink_ext_ack *extack)
|
||||
@@ -1304,7 +1317,7 @@ static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse_deprecated(nlh, sizeof(*bpm), tb,
|
||||
MDBA_SET_ENTRY_MAX, NULL, extack);
|
||||
MDBA_SET_ENTRY_MAX, mdba_policy, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1346,14 +1359,8 @@ static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
|
||||
NL_SET_ERR_MSG_MOD(extack, "Missing MDBA_SET_ENTRY attribute");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cfg->entry = nla_data(tb[MDBA_SET_ENTRY]);
|
||||
if (!is_valid_mdb_entry(cfg->entry, extack))
|
||||
return -EINVAL;
|
||||
|
||||
if (cfg->entry->ifindex != cfg->br->dev->ifindex) {
|
||||
struct net_device *pdev;
|
||||
|
||||
@@ -742,10 +742,109 @@ cfg_test_port()
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user