0001
0002
0003 #include <linux/err.h>
0004 #include <linux/export.h>
0005 #include <linux/if_ether.h>
0006 #include <linux/igmp.h>
0007 #include <linux/in.h>
0008 #include <linux/jhash.h>
0009 #include <linux/kernel.h>
0010 #include <linux/log2.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/netfilter_bridge.h>
0013 #include <linux/random.h>
0014 #include <linux/rculist.h>
0015 #include <linux/skbuff.h>
0016 #include <linux/slab.h>
0017 #include <linux/timer.h>
0018 #include <linux/inetdevice.h>
0019 #include <linux/mroute.h>
0020 #include <net/ip.h>
0021 #include <net/switchdev.h>
0022 #if IS_ENABLED(CONFIG_IPV6)
0023 #include <linux/icmpv6.h>
0024 #include <net/ipv6.h>
0025 #include <net/mld.h>
0026 #include <net/ip6_checksum.h>
0027 #include <net/addrconf.h>
0028 #endif
0029
0030 #include "br_private.h"
0031 #include "br_private_mcast_eht.h"
0032
0033 static bool br_multicast_del_eht_set_entry(struct net_bridge_port_group *pg,
0034 union net_bridge_eht_addr *src_addr,
0035 union net_bridge_eht_addr *h_addr);
0036 static void br_multicast_create_eht_set_entry(const struct net_bridge_mcast *brmctx,
0037 struct net_bridge_port_group *pg,
0038 union net_bridge_eht_addr *src_addr,
0039 union net_bridge_eht_addr *h_addr,
0040 int filter_mode,
0041 bool allow_zero_src);
0042
0043 static struct net_bridge_group_eht_host *
0044 br_multicast_eht_host_lookup(struct net_bridge_port_group *pg,
0045 union net_bridge_eht_addr *h_addr)
0046 {
0047 struct rb_node *node = pg->eht_host_tree.rb_node;
0048
0049 while (node) {
0050 struct net_bridge_group_eht_host *this;
0051 int result;
0052
0053 this = rb_entry(node, struct net_bridge_group_eht_host,
0054 rb_node);
0055 result = memcmp(h_addr, &this->h_addr, sizeof(*h_addr));
0056 if (result < 0)
0057 node = node->rb_left;
0058 else if (result > 0)
0059 node = node->rb_right;
0060 else
0061 return this;
0062 }
0063
0064 return NULL;
0065 }
0066
0067 static int br_multicast_eht_host_filter_mode(struct net_bridge_port_group *pg,
0068 union net_bridge_eht_addr *h_addr)
0069 {
0070 struct net_bridge_group_eht_host *eht_host;
0071
0072 eht_host = br_multicast_eht_host_lookup(pg, h_addr);
0073 if (!eht_host)
0074 return MCAST_INCLUDE;
0075
0076 return eht_host->filter_mode;
0077 }
0078
0079 static struct net_bridge_group_eht_set_entry *
0080 br_multicast_eht_set_entry_lookup(struct net_bridge_group_eht_set *eht_set,
0081 union net_bridge_eht_addr *h_addr)
0082 {
0083 struct rb_node *node = eht_set->entry_tree.rb_node;
0084
0085 while (node) {
0086 struct net_bridge_group_eht_set_entry *this;
0087 int result;
0088
0089 this = rb_entry(node, struct net_bridge_group_eht_set_entry,
0090 rb_node);
0091 result = memcmp(h_addr, &this->h_addr, sizeof(*h_addr));
0092 if (result < 0)
0093 node = node->rb_left;
0094 else if (result > 0)
0095 node = node->rb_right;
0096 else
0097 return this;
0098 }
0099
0100 return NULL;
0101 }
0102
0103 static struct net_bridge_group_eht_set *
0104 br_multicast_eht_set_lookup(struct net_bridge_port_group *pg,
0105 union net_bridge_eht_addr *src_addr)
0106 {
0107 struct rb_node *node = pg->eht_set_tree.rb_node;
0108
0109 while (node) {
0110 struct net_bridge_group_eht_set *this;
0111 int result;
0112
0113 this = rb_entry(node, struct net_bridge_group_eht_set,
0114 rb_node);
0115 result = memcmp(src_addr, &this->src_addr, sizeof(*src_addr));
0116 if (result < 0)
0117 node = node->rb_left;
0118 else if (result > 0)
0119 node = node->rb_right;
0120 else
0121 return this;
0122 }
0123
0124 return NULL;
0125 }
0126
0127 static void __eht_destroy_host(struct net_bridge_group_eht_host *eht_host)
0128 {
0129 WARN_ON(!hlist_empty(&eht_host->set_entries));
0130
0131 br_multicast_eht_hosts_dec(eht_host->pg);
0132
0133 rb_erase(&eht_host->rb_node, &eht_host->pg->eht_host_tree);
0134 RB_CLEAR_NODE(&eht_host->rb_node);
0135 kfree(eht_host);
0136 }
0137
0138 static void br_multicast_destroy_eht_set_entry(struct net_bridge_mcast_gc *gc)
0139 {
0140 struct net_bridge_group_eht_set_entry *set_h;
0141
0142 set_h = container_of(gc, struct net_bridge_group_eht_set_entry, mcast_gc);
0143 WARN_ON(!RB_EMPTY_NODE(&set_h->rb_node));
0144
0145 del_timer_sync(&set_h->timer);
0146 kfree(set_h);
0147 }
0148
0149 static void br_multicast_destroy_eht_set(struct net_bridge_mcast_gc *gc)
0150 {
0151 struct net_bridge_group_eht_set *eht_set;
0152
0153 eht_set = container_of(gc, struct net_bridge_group_eht_set, mcast_gc);
0154 WARN_ON(!RB_EMPTY_NODE(&eht_set->rb_node));
0155 WARN_ON(!RB_EMPTY_ROOT(&eht_set->entry_tree));
0156
0157 del_timer_sync(&eht_set->timer);
0158 kfree(eht_set);
0159 }
0160
0161 static void __eht_del_set_entry(struct net_bridge_group_eht_set_entry *set_h)
0162 {
0163 struct net_bridge_group_eht_host *eht_host = set_h->h_parent;
0164 union net_bridge_eht_addr zero_addr;
0165
0166 rb_erase(&set_h->rb_node, &set_h->eht_set->entry_tree);
0167 RB_CLEAR_NODE(&set_h->rb_node);
0168 hlist_del_init(&set_h->host_list);
0169 memset(&zero_addr, 0, sizeof(zero_addr));
0170 if (memcmp(&set_h->h_addr, &zero_addr, sizeof(zero_addr)))
0171 eht_host->num_entries--;
0172 hlist_add_head(&set_h->mcast_gc.gc_node, &set_h->br->mcast_gc_list);
0173 queue_work(system_long_wq, &set_h->br->mcast_gc_work);
0174
0175 if (hlist_empty(&eht_host->set_entries))
0176 __eht_destroy_host(eht_host);
0177 }
0178
0179 static void br_multicast_del_eht_set(struct net_bridge_group_eht_set *eht_set)
0180 {
0181 struct net_bridge_group_eht_set_entry *set_h;
0182 struct rb_node *node;
0183
0184 while ((node = rb_first(&eht_set->entry_tree))) {
0185 set_h = rb_entry(node, struct net_bridge_group_eht_set_entry,
0186 rb_node);
0187 __eht_del_set_entry(set_h);
0188 }
0189
0190 rb_erase(&eht_set->rb_node, &eht_set->pg->eht_set_tree);
0191 RB_CLEAR_NODE(&eht_set->rb_node);
0192 hlist_add_head(&eht_set->mcast_gc.gc_node, &eht_set->br->mcast_gc_list);
0193 queue_work(system_long_wq, &eht_set->br->mcast_gc_work);
0194 }
0195
0196 void br_multicast_eht_clean_sets(struct net_bridge_port_group *pg)
0197 {
0198 struct net_bridge_group_eht_set *eht_set;
0199 struct rb_node *node;
0200
0201 while ((node = rb_first(&pg->eht_set_tree))) {
0202 eht_set = rb_entry(node, struct net_bridge_group_eht_set,
0203 rb_node);
0204 br_multicast_del_eht_set(eht_set);
0205 }
0206 }
0207
0208 static void br_multicast_eht_set_entry_expired(struct timer_list *t)
0209 {
0210 struct net_bridge_group_eht_set_entry *set_h = from_timer(set_h, t, timer);
0211 struct net_bridge *br = set_h->br;
0212
0213 spin_lock(&br->multicast_lock);
0214 if (RB_EMPTY_NODE(&set_h->rb_node) || timer_pending(&set_h->timer))
0215 goto out;
0216
0217 br_multicast_del_eht_set_entry(set_h->eht_set->pg,
0218 &set_h->eht_set->src_addr,
0219 &set_h->h_addr);
0220 out:
0221 spin_unlock(&br->multicast_lock);
0222 }
0223
0224 static void br_multicast_eht_set_expired(struct timer_list *t)
0225 {
0226 struct net_bridge_group_eht_set *eht_set = from_timer(eht_set, t,
0227 timer);
0228 struct net_bridge *br = eht_set->br;
0229
0230 spin_lock(&br->multicast_lock);
0231 if (RB_EMPTY_NODE(&eht_set->rb_node) || timer_pending(&eht_set->timer))
0232 goto out;
0233
0234 br_multicast_del_eht_set(eht_set);
0235 out:
0236 spin_unlock(&br->multicast_lock);
0237 }
0238
0239 static struct net_bridge_group_eht_host *
0240 __eht_lookup_create_host(struct net_bridge_port_group *pg,
0241 union net_bridge_eht_addr *h_addr,
0242 unsigned char filter_mode)
0243 {
0244 struct rb_node **link = &pg->eht_host_tree.rb_node, *parent = NULL;
0245 struct net_bridge_group_eht_host *eht_host;
0246
0247 while (*link) {
0248 struct net_bridge_group_eht_host *this;
0249 int result;
0250
0251 this = rb_entry(*link, struct net_bridge_group_eht_host,
0252 rb_node);
0253 result = memcmp(h_addr, &this->h_addr, sizeof(*h_addr));
0254 parent = *link;
0255 if (result < 0)
0256 link = &((*link)->rb_left);
0257 else if (result > 0)
0258 link = &((*link)->rb_right);
0259 else
0260 return this;
0261 }
0262
0263 if (br_multicast_eht_hosts_over_limit(pg))
0264 return NULL;
0265
0266 eht_host = kzalloc(sizeof(*eht_host), GFP_ATOMIC);
0267 if (!eht_host)
0268 return NULL;
0269
0270 memcpy(&eht_host->h_addr, h_addr, sizeof(*h_addr));
0271 INIT_HLIST_HEAD(&eht_host->set_entries);
0272 eht_host->pg = pg;
0273 eht_host->filter_mode = filter_mode;
0274
0275 rb_link_node(&eht_host->rb_node, parent, link);
0276 rb_insert_color(&eht_host->rb_node, &pg->eht_host_tree);
0277
0278 br_multicast_eht_hosts_inc(pg);
0279
0280 return eht_host;
0281 }
0282
0283 static struct net_bridge_group_eht_set_entry *
0284 __eht_lookup_create_set_entry(struct net_bridge *br,
0285 struct net_bridge_group_eht_set *eht_set,
0286 struct net_bridge_group_eht_host *eht_host,
0287 bool allow_zero_src)
0288 {
0289 struct rb_node **link = &eht_set->entry_tree.rb_node, *parent = NULL;
0290 struct net_bridge_group_eht_set_entry *set_h;
0291
0292 while (*link) {
0293 struct net_bridge_group_eht_set_entry *this;
0294 int result;
0295
0296 this = rb_entry(*link, struct net_bridge_group_eht_set_entry,
0297 rb_node);
0298 result = memcmp(&eht_host->h_addr, &this->h_addr,
0299 sizeof(union net_bridge_eht_addr));
0300 parent = *link;
0301 if (result < 0)
0302 link = &((*link)->rb_left);
0303 else if (result > 0)
0304 link = &((*link)->rb_right);
0305 else
0306 return this;
0307 }
0308
0309
0310 if (!allow_zero_src && eht_host->num_entries >= PG_SRC_ENT_LIMIT)
0311 return NULL;
0312
0313 set_h = kzalloc(sizeof(*set_h), GFP_ATOMIC);
0314 if (!set_h)
0315 return NULL;
0316
0317 memcpy(&set_h->h_addr, &eht_host->h_addr,
0318 sizeof(union net_bridge_eht_addr));
0319 set_h->mcast_gc.destroy = br_multicast_destroy_eht_set_entry;
0320 set_h->eht_set = eht_set;
0321 set_h->h_parent = eht_host;
0322 set_h->br = br;
0323 timer_setup(&set_h->timer, br_multicast_eht_set_entry_expired, 0);
0324
0325 hlist_add_head(&set_h->host_list, &eht_host->set_entries);
0326 rb_link_node(&set_h->rb_node, parent, link);
0327 rb_insert_color(&set_h->rb_node, &eht_set->entry_tree);
0328
0329
0330
0331 if (!allow_zero_src)
0332 eht_host->num_entries++;
0333
0334 return set_h;
0335 }
0336
0337 static struct net_bridge_group_eht_set *
0338 __eht_lookup_create_set(struct net_bridge_port_group *pg,
0339 union net_bridge_eht_addr *src_addr)
0340 {
0341 struct rb_node **link = &pg->eht_set_tree.rb_node, *parent = NULL;
0342 struct net_bridge_group_eht_set *eht_set;
0343
0344 while (*link) {
0345 struct net_bridge_group_eht_set *this;
0346 int result;
0347
0348 this = rb_entry(*link, struct net_bridge_group_eht_set,
0349 rb_node);
0350 result = memcmp(src_addr, &this->src_addr, sizeof(*src_addr));
0351 parent = *link;
0352 if (result < 0)
0353 link = &((*link)->rb_left);
0354 else if (result > 0)
0355 link = &((*link)->rb_right);
0356 else
0357 return this;
0358 }
0359
0360 eht_set = kzalloc(sizeof(*eht_set), GFP_ATOMIC);
0361 if (!eht_set)
0362 return NULL;
0363
0364 memcpy(&eht_set->src_addr, src_addr, sizeof(*src_addr));
0365 eht_set->mcast_gc.destroy = br_multicast_destroy_eht_set;
0366 eht_set->pg = pg;
0367 eht_set->br = pg->key.port->br;
0368 eht_set->entry_tree = RB_ROOT;
0369 timer_setup(&eht_set->timer, br_multicast_eht_set_expired, 0);
0370
0371 rb_link_node(&eht_set->rb_node, parent, link);
0372 rb_insert_color(&eht_set->rb_node, &pg->eht_set_tree);
0373
0374 return eht_set;
0375 }
0376
0377 static void br_multicast_ip_src_to_eht_addr(const struct br_ip *src,
0378 union net_bridge_eht_addr *dest)
0379 {
0380 switch (src->proto) {
0381 case htons(ETH_P_IP):
0382 dest->ip4 = src->src.ip4;
0383 break;
0384 #if IS_ENABLED(CONFIG_IPV6)
0385 case htons(ETH_P_IPV6):
0386 memcpy(&dest->ip6, &src->src.ip6, sizeof(struct in6_addr));
0387 break;
0388 #endif
0389 }
0390 }
0391
0392 static void br_eht_convert_host_filter_mode(const struct net_bridge_mcast *brmctx,
0393 struct net_bridge_port_group *pg,
0394 union net_bridge_eht_addr *h_addr,
0395 int filter_mode)
0396 {
0397 struct net_bridge_group_eht_host *eht_host;
0398 union net_bridge_eht_addr zero_addr;
0399
0400 eht_host = br_multicast_eht_host_lookup(pg, h_addr);
0401 if (eht_host)
0402 eht_host->filter_mode = filter_mode;
0403
0404 memset(&zero_addr, 0, sizeof(zero_addr));
0405 switch (filter_mode) {
0406 case MCAST_INCLUDE:
0407 br_multicast_del_eht_set_entry(pg, &zero_addr, h_addr);
0408 break;
0409 case MCAST_EXCLUDE:
0410 br_multicast_create_eht_set_entry(brmctx, pg, &zero_addr,
0411 h_addr, MCAST_EXCLUDE,
0412 true);
0413 break;
0414 }
0415 }
0416
0417 static void br_multicast_create_eht_set_entry(const struct net_bridge_mcast *brmctx,
0418 struct net_bridge_port_group *pg,
0419 union net_bridge_eht_addr *src_addr,
0420 union net_bridge_eht_addr *h_addr,
0421 int filter_mode,
0422 bool allow_zero_src)
0423 {
0424 struct net_bridge_group_eht_set_entry *set_h;
0425 struct net_bridge_group_eht_host *eht_host;
0426 struct net_bridge *br = pg->key.port->br;
0427 struct net_bridge_group_eht_set *eht_set;
0428 union net_bridge_eht_addr zero_addr;
0429
0430 memset(&zero_addr, 0, sizeof(zero_addr));
0431 if (!allow_zero_src && !memcmp(src_addr, &zero_addr, sizeof(zero_addr)))
0432 return;
0433
0434 eht_set = __eht_lookup_create_set(pg, src_addr);
0435 if (!eht_set)
0436 return;
0437
0438 eht_host = __eht_lookup_create_host(pg, h_addr, filter_mode);
0439 if (!eht_host)
0440 goto fail_host;
0441
0442 set_h = __eht_lookup_create_set_entry(br, eht_set, eht_host,
0443 allow_zero_src);
0444 if (!set_h)
0445 goto fail_set_entry;
0446
0447 mod_timer(&set_h->timer, jiffies + br_multicast_gmi(brmctx));
0448 mod_timer(&eht_set->timer, jiffies + br_multicast_gmi(brmctx));
0449
0450 return;
0451
0452 fail_set_entry:
0453 if (hlist_empty(&eht_host->set_entries))
0454 __eht_destroy_host(eht_host);
0455 fail_host:
0456 if (RB_EMPTY_ROOT(&eht_set->entry_tree))
0457 br_multicast_del_eht_set(eht_set);
0458 }
0459
0460 static bool br_multicast_del_eht_set_entry(struct net_bridge_port_group *pg,
0461 union net_bridge_eht_addr *src_addr,
0462 union net_bridge_eht_addr *h_addr)
0463 {
0464 struct net_bridge_group_eht_set_entry *set_h;
0465 struct net_bridge_group_eht_set *eht_set;
0466 bool set_deleted = false;
0467
0468 eht_set = br_multicast_eht_set_lookup(pg, src_addr);
0469 if (!eht_set)
0470 goto out;
0471
0472 set_h = br_multicast_eht_set_entry_lookup(eht_set, h_addr);
0473 if (!set_h)
0474 goto out;
0475
0476 __eht_del_set_entry(set_h);
0477
0478 if (RB_EMPTY_ROOT(&eht_set->entry_tree)) {
0479 br_multicast_del_eht_set(eht_set);
0480 set_deleted = true;
0481 }
0482
0483 out:
0484 return set_deleted;
0485 }
0486
0487 static void br_multicast_del_eht_host(struct net_bridge_port_group *pg,
0488 union net_bridge_eht_addr *h_addr)
0489 {
0490 struct net_bridge_group_eht_set_entry *set_h;
0491 struct net_bridge_group_eht_host *eht_host;
0492 struct hlist_node *tmp;
0493
0494 eht_host = br_multicast_eht_host_lookup(pg, h_addr);
0495 if (!eht_host)
0496 return;
0497
0498 hlist_for_each_entry_safe(set_h, tmp, &eht_host->set_entries, host_list)
0499 br_multicast_del_eht_set_entry(set_h->eht_set->pg,
0500 &set_h->eht_set->src_addr,
0501 &set_h->h_addr);
0502 }
0503
0504
0505 static void __eht_create_set_entries(const struct net_bridge_mcast *brmctx,
0506 struct net_bridge_port_group *pg,
0507 union net_bridge_eht_addr *h_addr,
0508 void *srcs,
0509 u32 nsrcs,
0510 size_t addr_size,
0511 int filter_mode)
0512 {
0513 union net_bridge_eht_addr eht_src_addr;
0514 u32 src_idx;
0515
0516 memset(&eht_src_addr, 0, sizeof(eht_src_addr));
0517 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
0518 memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
0519 br_multicast_create_eht_set_entry(brmctx, pg, &eht_src_addr,
0520 h_addr, filter_mode,
0521 false);
0522 }
0523 }
0524
0525
0526 static bool __eht_del_set_entries(struct net_bridge_port_group *pg,
0527 union net_bridge_eht_addr *h_addr,
0528 void *srcs,
0529 u32 nsrcs,
0530 size_t addr_size)
0531 {
0532 union net_bridge_eht_addr eht_src_addr;
0533 struct net_bridge_group_src *src_ent;
0534 bool changed = false;
0535 struct br_ip src_ip;
0536 u32 src_idx;
0537
0538 memset(&eht_src_addr, 0, sizeof(eht_src_addr));
0539 memset(&src_ip, 0, sizeof(src_ip));
0540 src_ip.proto = pg->key.addr.proto;
0541 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
0542 memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
0543 if (!br_multicast_del_eht_set_entry(pg, &eht_src_addr, h_addr))
0544 continue;
0545 memcpy(&src_ip, srcs + (src_idx * addr_size), addr_size);
0546 src_ent = br_multicast_find_group_src(pg, &src_ip);
0547 if (!src_ent)
0548 continue;
0549 br_multicast_del_group_src(src_ent, true);
0550 changed = true;
0551 }
0552
0553 return changed;
0554 }
0555
0556 static bool br_multicast_eht_allow(const struct net_bridge_mcast *brmctx,
0557 struct net_bridge_port_group *pg,
0558 union net_bridge_eht_addr *h_addr,
0559 void *srcs,
0560 u32 nsrcs,
0561 size_t addr_size)
0562 {
0563 bool changed = false;
0564
0565 switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
0566 case MCAST_INCLUDE:
0567 __eht_create_set_entries(brmctx, pg, h_addr, srcs, nsrcs,
0568 addr_size, MCAST_INCLUDE);
0569 break;
0570 case MCAST_EXCLUDE:
0571 changed = __eht_del_set_entries(pg, h_addr, srcs, nsrcs,
0572 addr_size);
0573 break;
0574 }
0575
0576 return changed;
0577 }
0578
0579 static bool br_multicast_eht_block(const struct net_bridge_mcast *brmctx,
0580 struct net_bridge_port_group *pg,
0581 union net_bridge_eht_addr *h_addr,
0582 void *srcs,
0583 u32 nsrcs,
0584 size_t addr_size)
0585 {
0586 bool changed = false;
0587
0588 switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
0589 case MCAST_INCLUDE:
0590 changed = __eht_del_set_entries(pg, h_addr, srcs, nsrcs,
0591 addr_size);
0592 break;
0593 case MCAST_EXCLUDE:
0594 __eht_create_set_entries(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
0595 MCAST_EXCLUDE);
0596 break;
0597 }
0598
0599 return changed;
0600 }
0601
0602
0603 static bool __eht_inc_exc(const struct net_bridge_mcast *brmctx,
0604 struct net_bridge_port_group *pg,
0605 union net_bridge_eht_addr *h_addr,
0606 void *srcs,
0607 u32 nsrcs,
0608 size_t addr_size,
0609 unsigned char filter_mode,
0610 bool to_report)
0611 {
0612 bool changed = false, flush_entries = to_report;
0613 union net_bridge_eht_addr eht_src_addr;
0614
0615 if (br_multicast_eht_host_filter_mode(pg, h_addr) != filter_mode)
0616 flush_entries = true;
0617
0618 memset(&eht_src_addr, 0, sizeof(eht_src_addr));
0619
0620 if (flush_entries)
0621 br_multicast_del_eht_host(pg, h_addr);
0622 __eht_create_set_entries(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
0623 filter_mode);
0624
0625 if (flush_entries) {
0626 struct net_bridge_group_eht_set *eht_set;
0627 struct net_bridge_group_src *src_ent;
0628 struct hlist_node *tmp;
0629
0630 hlist_for_each_entry_safe(src_ent, tmp, &pg->src_list, node) {
0631 br_multicast_ip_src_to_eht_addr(&src_ent->addr,
0632 &eht_src_addr);
0633 if (!br_multicast_eht_set_lookup(pg, &eht_src_addr)) {
0634 br_multicast_del_group_src(src_ent, true);
0635 changed = true;
0636 continue;
0637 }
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648 if (!(src_ent->flags & BR_SGRP_F_SEND) ||
0649 filter_mode != MCAST_INCLUDE ||
0650 !to_report)
0651 continue;
0652 eht_set = br_multicast_eht_set_lookup(pg,
0653 &eht_src_addr);
0654 if (!eht_set)
0655 continue;
0656 mod_timer(&eht_set->timer, jiffies + br_multicast_lmqt(brmctx));
0657 }
0658 }
0659
0660 return changed;
0661 }
0662
0663 static bool br_multicast_eht_inc(const struct net_bridge_mcast *brmctx,
0664 struct net_bridge_port_group *pg,
0665 union net_bridge_eht_addr *h_addr,
0666 void *srcs,
0667 u32 nsrcs,
0668 size_t addr_size,
0669 bool to_report)
0670 {
0671 bool changed;
0672
0673 changed = __eht_inc_exc(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
0674 MCAST_INCLUDE, to_report);
0675 br_eht_convert_host_filter_mode(brmctx, pg, h_addr, MCAST_INCLUDE);
0676
0677 return changed;
0678 }
0679
0680 static bool br_multicast_eht_exc(const struct net_bridge_mcast *brmctx,
0681 struct net_bridge_port_group *pg,
0682 union net_bridge_eht_addr *h_addr,
0683 void *srcs,
0684 u32 nsrcs,
0685 size_t addr_size,
0686 bool to_report)
0687 {
0688 bool changed;
0689
0690 changed = __eht_inc_exc(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
0691 MCAST_EXCLUDE, to_report);
0692 br_eht_convert_host_filter_mode(brmctx, pg, h_addr, MCAST_EXCLUDE);
0693
0694 return changed;
0695 }
0696
0697 static bool __eht_ip4_handle(const struct net_bridge_mcast *brmctx,
0698 struct net_bridge_port_group *pg,
0699 union net_bridge_eht_addr *h_addr,
0700 void *srcs,
0701 u32 nsrcs,
0702 int grec_type)
0703 {
0704 bool changed = false, to_report = false;
0705
0706 switch (grec_type) {
0707 case IGMPV3_ALLOW_NEW_SOURCES:
0708 br_multicast_eht_allow(brmctx, pg, h_addr, srcs, nsrcs,
0709 sizeof(__be32));
0710 break;
0711 case IGMPV3_BLOCK_OLD_SOURCES:
0712 changed = br_multicast_eht_block(brmctx, pg, h_addr, srcs, nsrcs,
0713 sizeof(__be32));
0714 break;
0715 case IGMPV3_CHANGE_TO_INCLUDE:
0716 to_report = true;
0717 fallthrough;
0718 case IGMPV3_MODE_IS_INCLUDE:
0719 changed = br_multicast_eht_inc(brmctx, pg, h_addr, srcs, nsrcs,
0720 sizeof(__be32), to_report);
0721 break;
0722 case IGMPV3_CHANGE_TO_EXCLUDE:
0723 to_report = true;
0724 fallthrough;
0725 case IGMPV3_MODE_IS_EXCLUDE:
0726 changed = br_multicast_eht_exc(brmctx, pg, h_addr, srcs, nsrcs,
0727 sizeof(__be32), to_report);
0728 break;
0729 }
0730
0731 return changed;
0732 }
0733
0734 #if IS_ENABLED(CONFIG_IPV6)
0735 static bool __eht_ip6_handle(const struct net_bridge_mcast *brmctx,
0736 struct net_bridge_port_group *pg,
0737 union net_bridge_eht_addr *h_addr,
0738 void *srcs,
0739 u32 nsrcs,
0740 int grec_type)
0741 {
0742 bool changed = false, to_report = false;
0743
0744 switch (grec_type) {
0745 case MLD2_ALLOW_NEW_SOURCES:
0746 br_multicast_eht_allow(brmctx, pg, h_addr, srcs, nsrcs,
0747 sizeof(struct in6_addr));
0748 break;
0749 case MLD2_BLOCK_OLD_SOURCES:
0750 changed = br_multicast_eht_block(brmctx, pg, h_addr, srcs, nsrcs,
0751 sizeof(struct in6_addr));
0752 break;
0753 case MLD2_CHANGE_TO_INCLUDE:
0754 to_report = true;
0755 fallthrough;
0756 case MLD2_MODE_IS_INCLUDE:
0757 changed = br_multicast_eht_inc(brmctx, pg, h_addr, srcs, nsrcs,
0758 sizeof(struct in6_addr),
0759 to_report);
0760 break;
0761 case MLD2_CHANGE_TO_EXCLUDE:
0762 to_report = true;
0763 fallthrough;
0764 case MLD2_MODE_IS_EXCLUDE:
0765 changed = br_multicast_eht_exc(brmctx, pg, h_addr, srcs, nsrcs,
0766 sizeof(struct in6_addr),
0767 to_report);
0768 break;
0769 }
0770
0771 return changed;
0772 }
0773 #endif
0774
0775
0776 bool br_multicast_eht_handle(const struct net_bridge_mcast *brmctx,
0777 struct net_bridge_port_group *pg,
0778 void *h_addr,
0779 void *srcs,
0780 u32 nsrcs,
0781 size_t addr_size,
0782 int grec_type)
0783 {
0784 bool eht_enabled = !!(pg->key.port->flags & BR_MULTICAST_FAST_LEAVE);
0785 union net_bridge_eht_addr eht_host_addr;
0786 bool changed = false;
0787
0788 if (!eht_enabled)
0789 goto out;
0790
0791 memset(&eht_host_addr, 0, sizeof(eht_host_addr));
0792 memcpy(&eht_host_addr, h_addr, addr_size);
0793 if (addr_size == sizeof(__be32))
0794 changed = __eht_ip4_handle(brmctx, pg, &eht_host_addr, srcs,
0795 nsrcs, grec_type);
0796 #if IS_ENABLED(CONFIG_IPV6)
0797 else
0798 changed = __eht_ip6_handle(brmctx, pg, &eht_host_addr, srcs,
0799 nsrcs, grec_type);
0800 #endif
0801
0802 out:
0803 return changed;
0804 }
0805
0806 int br_multicast_eht_set_hosts_limit(struct net_bridge_port *p,
0807 u32 eht_hosts_limit)
0808 {
0809 struct net_bridge *br = p->br;
0810
0811 if (!eht_hosts_limit)
0812 return -EINVAL;
0813
0814 spin_lock_bh(&br->multicast_lock);
0815 p->multicast_eht_hosts_limit = eht_hosts_limit;
0816 spin_unlock_bh(&br->multicast_lock);
0817
0818 return 0;
0819 }