summaryrefslogtreecommitdiff
path: root/net/bridge/br_multicast_eht.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_multicast_eht.c')
-rw-r--r--net/bridge/br_multicast_eht.c141
1 files changed, 35 insertions, 106 deletions
diff --git a/net/bridge/br_multicast_eht.c b/net/bridge/br_multicast_eht.c
index fea38b9a7268..13290a749d09 100644
--- a/net/bridge/br_multicast_eht.c
+++ b/net/bridge/br_multicast_eht.c
@@ -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,72 +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)
-{
- bool changed = false, host_excl = false;
- union net_bridge_eht_addr eht_src_addr;
- struct net_bridge_group_src *src_ent;
- struct br_ip src_ip;
- u32 src_idx;
-
- host_excl = !!(br_multicast_eht_host_filter_mode(pg, h_addr) == MCAST_EXCLUDE);
- 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 (!host_excl) {
- br_multicast_create_eht_set_entry(pg, &eht_src_addr, h_addr,
- MCAST_INCLUDE,
- false);
- } else {
- 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;
@@ -602,39 +549,23 @@ static bool __eht_block_incl(struct net_bridge_port_group *pg,
return changed;
}
-static bool __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)
{
- bool changed = false, host_excl = false;
- union net_bridge_eht_addr eht_src_addr;
- struct net_bridge_group_src *src_ent;
- struct br_ip src_ip;
- u32 src_idx;
+ bool changed = false;
- host_excl = !!(br_multicast_eht_host_filter_mode(pg, h_addr) == MCAST_EXCLUDE);
- memset(&eht_src_addr, 0, sizeof(eht_src_addr));
- memset(&src_ip, 0, sizeof(src_ip));
- src_ip.proto = pg->key.addr.proto;
- for (src_idx = 0; src_idx < nsrcs; src_idx++) {
- memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
- if (host_excl) {
- br_multicast_create_eht_set_entry(pg, &eht_src_addr, h_addr,
- MCAST_EXCLUDE,
- false);
- } else {
- 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;
- }
+ 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;
@@ -650,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:
- changed = __eht_block_excl(pg, h_addr, srcs, nsrcs, addr_size);
+ __eht_create_set_entries(pg, h_addr, srcs, nsrcs, addr_size,
+ MCAST_EXCLUDE);
break;
}
@@ -671,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;
@@ -680,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;