net: bridge: mcast: factor out common allow/block EHT handling

We hande EHT state change for ALLOW messages in INCLUDE mode and for
BLOCK messages in EXCLUDE mode similarly - create the new set entries
with the proper filter mode. We also handle EHT state change for ALLOW
messages in EXCLUDE mode and for BLOCK messages in INCLUDE mode in a
similar way - delete the common entries (current set and new set).
Factor out all the common code as follows:
 - ALLOW/INCLUDE, BLOCK/EXCLUDE: call __eht_create_set_entries()
 - ALLOW/EXCLUDE, BLOCK/INCLUDE: call __eht_del_common_set_entries()

The set entries creation can be reused in __eht_inc_exc() as well.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Nikolay Aleksandrov 2021-03-15 19:13:42 +02:00 committed by David S. Miller
parent 6aa2c371c7
commit e09cf58205
1 changed files with 37 additions and 81 deletions

View File

@ -498,11 +498,13 @@ static void br_multicast_del_eht_host(struct net_bridge_port_group *pg,
&set_h->h_addr);
}
static void __eht_allow_incl(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
/* create new set entries from reports */
static void __eht_create_set_entries(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size,
int filter_mode)
{
union net_bridge_eht_addr eht_src_addr;
u32 src_idx;
@ -511,65 +513,17 @@ static void __eht_allow_incl(struct net_bridge_port_group *pg,
for (src_idx = 0; src_idx < nsrcs; src_idx++) {
memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
br_multicast_create_eht_set_entry(pg, &eht_src_addr, h_addr,
MCAST_INCLUDE,
filter_mode,
false);
}
}
static bool __eht_allow_excl(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
{
union net_bridge_eht_addr eht_src_addr;
struct net_bridge_group_src *src_ent;
bool changed = false;
struct br_ip src_ip;
u32 src_idx;
memset(&eht_src_addr, 0, sizeof(eht_src_addr));
for (src_idx = 0; src_idx < nsrcs; src_idx++) {
memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
if (!br_multicast_del_eht_set_entry(pg, &eht_src_addr,
h_addr))
continue;
memcpy(&src_ip, srcs + (src_idx * addr_size), addr_size);
src_ent = br_multicast_find_group_src(pg, &src_ip);
if (!src_ent)
continue;
br_multicast_del_group_src(src_ent, true);
changed = true;
}
return changed;
}
static bool br_multicast_eht_allow(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
{
bool changed = false;
switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
case MCAST_INCLUDE:
__eht_allow_incl(pg, h_addr, srcs, nsrcs, addr_size);
break;
case MCAST_EXCLUDE:
changed = __eht_allow_excl(pg, h_addr, srcs, nsrcs, addr_size);
break;
}
return changed;
}
static bool __eht_block_incl(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
/* delete existing set entries and their (S,G) entries if they were the last */
static bool __eht_del_set_entries(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
{
union net_bridge_eht_addr eht_src_addr;
struct net_bridge_group_src *src_ent;
@ -595,22 +549,26 @@ static bool __eht_block_incl(struct net_bridge_port_group *pg,
return changed;
}
static void __eht_block_excl(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
static bool br_multicast_eht_allow(struct net_bridge_port_group *pg,
union net_bridge_eht_addr *h_addr,
void *srcs,
u32 nsrcs,
size_t addr_size)
{
union net_bridge_eht_addr eht_src_addr;
u32 src_idx;
bool changed = false;
memset(&eht_src_addr, 0, sizeof(eht_src_addr));
for (src_idx = 0; src_idx < nsrcs; src_idx++) {
memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
br_multicast_create_eht_set_entry(pg, &eht_src_addr, h_addr,
MCAST_EXCLUDE,
false);
switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
case MCAST_INCLUDE:
__eht_create_set_entries(pg, h_addr, srcs, nsrcs, addr_size,
MCAST_INCLUDE);
break;
case MCAST_EXCLUDE:
changed = __eht_del_set_entries(pg, h_addr, srcs, nsrcs,
addr_size);
break;
}
return changed;
}
static bool br_multicast_eht_block(struct net_bridge_port_group *pg,
@ -623,10 +581,12 @@ static bool br_multicast_eht_block(struct net_bridge_port_group *pg,
switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
case MCAST_INCLUDE:
changed = __eht_block_incl(pg, h_addr, srcs, nsrcs, addr_size);
changed = __eht_del_set_entries(pg, h_addr, srcs, nsrcs,
addr_size);
break;
case MCAST_EXCLUDE:
__eht_block_excl(pg, h_addr, srcs, nsrcs, addr_size);
__eht_create_set_entries(pg, h_addr, srcs, nsrcs, addr_size,
MCAST_EXCLUDE);
break;
}
@ -644,7 +604,6 @@ static bool __eht_inc_exc(struct net_bridge_port_group *pg,
{
bool changed = false, flush_entries = to_report;
union net_bridge_eht_addr eht_src_addr;
u32 src_idx;
if (br_multicast_eht_host_filter_mode(pg, h_addr) != filter_mode)
flush_entries = true;
@ -653,11 +612,8 @@ static bool __eht_inc_exc(struct net_bridge_port_group *pg,
/* if we're changing mode del host and its entries */
if (flush_entries)
br_multicast_del_eht_host(pg, h_addr);
for (src_idx = 0; src_idx < nsrcs; src_idx++) {
memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
br_multicast_create_eht_set_entry(pg, &eht_src_addr, h_addr,
filter_mode, false);
}
__eht_create_set_entries(pg, h_addr, srcs, nsrcs, addr_size,
filter_mode);
/* we can be missing sets only if we've deleted some entries */
if (flush_entries) {
struct net_bridge *br = pg->key.port->br;