br_multicast_eht.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. // Copyright (c) 2020, Nikolay Aleksandrov <[email protected]>
  3. #include <linux/err.h>
  4. #include <linux/export.h>
  5. #include <linux/if_ether.h>
  6. #include <linux/igmp.h>
  7. #include <linux/in.h>
  8. #include <linux/jhash.h>
  9. #include <linux/kernel.h>
  10. #include <linux/log2.h>
  11. #include <linux/netdevice.h>
  12. #include <linux/netfilter_bridge.h>
  13. #include <linux/random.h>
  14. #include <linux/rculist.h>
  15. #include <linux/skbuff.h>
  16. #include <linux/slab.h>
  17. #include <linux/timer.h>
  18. #include <linux/inetdevice.h>
  19. #include <linux/mroute.h>
  20. #include <net/ip.h>
  21. #include <net/switchdev.h>
  22. #if IS_ENABLED(CONFIG_IPV6)
  23. #include <linux/icmpv6.h>
  24. #include <net/ipv6.h>
  25. #include <net/mld.h>
  26. #include <net/ip6_checksum.h>
  27. #include <net/addrconf.h>
  28. #endif
  29. #include "br_private.h"
  30. #include "br_private_mcast_eht.h"
  31. static bool br_multicast_del_eht_set_entry(struct net_bridge_port_group *pg,
  32. union net_bridge_eht_addr *src_addr,
  33. union net_bridge_eht_addr *h_addr);
  34. static void br_multicast_create_eht_set_entry(const struct net_bridge_mcast *brmctx,
  35. struct net_bridge_port_group *pg,
  36. union net_bridge_eht_addr *src_addr,
  37. union net_bridge_eht_addr *h_addr,
  38. int filter_mode,
  39. bool allow_zero_src);
  40. static struct net_bridge_group_eht_host *
  41. br_multicast_eht_host_lookup(struct net_bridge_port_group *pg,
  42. union net_bridge_eht_addr *h_addr)
  43. {
  44. struct rb_node *node = pg->eht_host_tree.rb_node;
  45. while (node) {
  46. struct net_bridge_group_eht_host *this;
  47. int result;
  48. this = rb_entry(node, struct net_bridge_group_eht_host,
  49. rb_node);
  50. result = memcmp(h_addr, &this->h_addr, sizeof(*h_addr));
  51. if (result < 0)
  52. node = node->rb_left;
  53. else if (result > 0)
  54. node = node->rb_right;
  55. else
  56. return this;
  57. }
  58. return NULL;
  59. }
  60. static int br_multicast_eht_host_filter_mode(struct net_bridge_port_group *pg,
  61. union net_bridge_eht_addr *h_addr)
  62. {
  63. struct net_bridge_group_eht_host *eht_host;
  64. eht_host = br_multicast_eht_host_lookup(pg, h_addr);
  65. if (!eht_host)
  66. return MCAST_INCLUDE;
  67. return eht_host->filter_mode;
  68. }
  69. static struct net_bridge_group_eht_set_entry *
  70. br_multicast_eht_set_entry_lookup(struct net_bridge_group_eht_set *eht_set,
  71. union net_bridge_eht_addr *h_addr)
  72. {
  73. struct rb_node *node = eht_set->entry_tree.rb_node;
  74. while (node) {
  75. struct net_bridge_group_eht_set_entry *this;
  76. int result;
  77. this = rb_entry(node, struct net_bridge_group_eht_set_entry,
  78. rb_node);
  79. result = memcmp(h_addr, &this->h_addr, sizeof(*h_addr));
  80. if (result < 0)
  81. node = node->rb_left;
  82. else if (result > 0)
  83. node = node->rb_right;
  84. else
  85. return this;
  86. }
  87. return NULL;
  88. }
  89. static struct net_bridge_group_eht_set *
  90. br_multicast_eht_set_lookup(struct net_bridge_port_group *pg,
  91. union net_bridge_eht_addr *src_addr)
  92. {
  93. struct rb_node *node = pg->eht_set_tree.rb_node;
  94. while (node) {
  95. struct net_bridge_group_eht_set *this;
  96. int result;
  97. this = rb_entry(node, struct net_bridge_group_eht_set,
  98. rb_node);
  99. result = memcmp(src_addr, &this->src_addr, sizeof(*src_addr));
  100. if (result < 0)
  101. node = node->rb_left;
  102. else if (result > 0)
  103. node = node->rb_right;
  104. else
  105. return this;
  106. }
  107. return NULL;
  108. }
  109. static void __eht_destroy_host(struct net_bridge_group_eht_host *eht_host)
  110. {
  111. WARN_ON(!hlist_empty(&eht_host->set_entries));
  112. br_multicast_eht_hosts_dec(eht_host->pg);
  113. rb_erase(&eht_host->rb_node, &eht_host->pg->eht_host_tree);
  114. RB_CLEAR_NODE(&eht_host->rb_node);
  115. kfree(eht_host);
  116. }
  117. static void br_multicast_destroy_eht_set_entry(struct net_bridge_mcast_gc *gc)
  118. {
  119. struct net_bridge_group_eht_set_entry *set_h;
  120. set_h = container_of(gc, struct net_bridge_group_eht_set_entry, mcast_gc);
  121. WARN_ON(!RB_EMPTY_NODE(&set_h->rb_node));
  122. del_timer_sync(&set_h->timer);
  123. kfree(set_h);
  124. }
  125. static void br_multicast_destroy_eht_set(struct net_bridge_mcast_gc *gc)
  126. {
  127. struct net_bridge_group_eht_set *eht_set;
  128. eht_set = container_of(gc, struct net_bridge_group_eht_set, mcast_gc);
  129. WARN_ON(!RB_EMPTY_NODE(&eht_set->rb_node));
  130. WARN_ON(!RB_EMPTY_ROOT(&eht_set->entry_tree));
  131. del_timer_sync(&eht_set->timer);
  132. kfree(eht_set);
  133. }
  134. static void __eht_del_set_entry(struct net_bridge_group_eht_set_entry *set_h)
  135. {
  136. struct net_bridge_group_eht_host *eht_host = set_h->h_parent;
  137. union net_bridge_eht_addr zero_addr;
  138. rb_erase(&set_h->rb_node, &set_h->eht_set->entry_tree);
  139. RB_CLEAR_NODE(&set_h->rb_node);
  140. hlist_del_init(&set_h->host_list);
  141. memset(&zero_addr, 0, sizeof(zero_addr));
  142. if (memcmp(&set_h->h_addr, &zero_addr, sizeof(zero_addr)))
  143. eht_host->num_entries--;
  144. hlist_add_head(&set_h->mcast_gc.gc_node, &set_h->br->mcast_gc_list);
  145. queue_work(system_long_wq, &set_h->br->mcast_gc_work);
  146. if (hlist_empty(&eht_host->set_entries))
  147. __eht_destroy_host(eht_host);
  148. }
  149. static void br_multicast_del_eht_set(struct net_bridge_group_eht_set *eht_set)
  150. {
  151. struct net_bridge_group_eht_set_entry *set_h;
  152. struct rb_node *node;
  153. while ((node = rb_first(&eht_set->entry_tree))) {
  154. set_h = rb_entry(node, struct net_bridge_group_eht_set_entry,
  155. rb_node);
  156. __eht_del_set_entry(set_h);
  157. }
  158. rb_erase(&eht_set->rb_node, &eht_set->pg->eht_set_tree);
  159. RB_CLEAR_NODE(&eht_set->rb_node);
  160. hlist_add_head(&eht_set->mcast_gc.gc_node, &eht_set->br->mcast_gc_list);
  161. queue_work(system_long_wq, &eht_set->br->mcast_gc_work);
  162. }
  163. void br_multicast_eht_clean_sets(struct net_bridge_port_group *pg)
  164. {
  165. struct net_bridge_group_eht_set *eht_set;
  166. struct rb_node *node;
  167. while ((node = rb_first(&pg->eht_set_tree))) {
  168. eht_set = rb_entry(node, struct net_bridge_group_eht_set,
  169. rb_node);
  170. br_multicast_del_eht_set(eht_set);
  171. }
  172. }
  173. static void br_multicast_eht_set_entry_expired(struct timer_list *t)
  174. {
  175. struct net_bridge_group_eht_set_entry *set_h = from_timer(set_h, t, timer);
  176. struct net_bridge *br = set_h->br;
  177. spin_lock(&br->multicast_lock);
  178. if (RB_EMPTY_NODE(&set_h->rb_node) || timer_pending(&set_h->timer))
  179. goto out;
  180. br_multicast_del_eht_set_entry(set_h->eht_set->pg,
  181. &set_h->eht_set->src_addr,
  182. &set_h->h_addr);
  183. out:
  184. spin_unlock(&br->multicast_lock);
  185. }
  186. static void br_multicast_eht_set_expired(struct timer_list *t)
  187. {
  188. struct net_bridge_group_eht_set *eht_set = from_timer(eht_set, t,
  189. timer);
  190. struct net_bridge *br = eht_set->br;
  191. spin_lock(&br->multicast_lock);
  192. if (RB_EMPTY_NODE(&eht_set->rb_node) || timer_pending(&eht_set->timer))
  193. goto out;
  194. br_multicast_del_eht_set(eht_set);
  195. out:
  196. spin_unlock(&br->multicast_lock);
  197. }
  198. static struct net_bridge_group_eht_host *
  199. __eht_lookup_create_host(struct net_bridge_port_group *pg,
  200. union net_bridge_eht_addr *h_addr,
  201. unsigned char filter_mode)
  202. {
  203. struct rb_node **link = &pg->eht_host_tree.rb_node, *parent = NULL;
  204. struct net_bridge_group_eht_host *eht_host;
  205. while (*link) {
  206. struct net_bridge_group_eht_host *this;
  207. int result;
  208. this = rb_entry(*link, struct net_bridge_group_eht_host,
  209. rb_node);
  210. result = memcmp(h_addr, &this->h_addr, sizeof(*h_addr));
  211. parent = *link;
  212. if (result < 0)
  213. link = &((*link)->rb_left);
  214. else if (result > 0)
  215. link = &((*link)->rb_right);
  216. else
  217. return this;
  218. }
  219. if (br_multicast_eht_hosts_over_limit(pg))
  220. return NULL;
  221. eht_host = kzalloc(sizeof(*eht_host), GFP_ATOMIC);
  222. if (!eht_host)
  223. return NULL;
  224. memcpy(&eht_host->h_addr, h_addr, sizeof(*h_addr));
  225. INIT_HLIST_HEAD(&eht_host->set_entries);
  226. eht_host->pg = pg;
  227. eht_host->filter_mode = filter_mode;
  228. rb_link_node(&eht_host->rb_node, parent, link);
  229. rb_insert_color(&eht_host->rb_node, &pg->eht_host_tree);
  230. br_multicast_eht_hosts_inc(pg);
  231. return eht_host;
  232. }
  233. static struct net_bridge_group_eht_set_entry *
  234. __eht_lookup_create_set_entry(struct net_bridge *br,
  235. struct net_bridge_group_eht_set *eht_set,
  236. struct net_bridge_group_eht_host *eht_host,
  237. bool allow_zero_src)
  238. {
  239. struct rb_node **link = &eht_set->entry_tree.rb_node, *parent = NULL;
  240. struct net_bridge_group_eht_set_entry *set_h;
  241. while (*link) {
  242. struct net_bridge_group_eht_set_entry *this;
  243. int result;
  244. this = rb_entry(*link, struct net_bridge_group_eht_set_entry,
  245. rb_node);
  246. result = memcmp(&eht_host->h_addr, &this->h_addr,
  247. sizeof(union net_bridge_eht_addr));
  248. parent = *link;
  249. if (result < 0)
  250. link = &((*link)->rb_left);
  251. else if (result > 0)
  252. link = &((*link)->rb_right);
  253. else
  254. return this;
  255. }
  256. /* always allow auto-created zero entry */
  257. if (!allow_zero_src && eht_host->num_entries >= PG_SRC_ENT_LIMIT)
  258. return NULL;
  259. set_h = kzalloc(sizeof(*set_h), GFP_ATOMIC);
  260. if (!set_h)
  261. return NULL;
  262. memcpy(&set_h->h_addr, &eht_host->h_addr,
  263. sizeof(union net_bridge_eht_addr));
  264. set_h->mcast_gc.destroy = br_multicast_destroy_eht_set_entry;
  265. set_h->eht_set = eht_set;
  266. set_h->h_parent = eht_host;
  267. set_h->br = br;
  268. timer_setup(&set_h->timer, br_multicast_eht_set_entry_expired, 0);
  269. hlist_add_head(&set_h->host_list, &eht_host->set_entries);
  270. rb_link_node(&set_h->rb_node, parent, link);
  271. rb_insert_color(&set_h->rb_node, &eht_set->entry_tree);
  272. /* we must not count the auto-created zero entry otherwise we won't be
  273. * able to track the full list of PG_SRC_ENT_LIMIT entries
  274. */
  275. if (!allow_zero_src)
  276. eht_host->num_entries++;
  277. return set_h;
  278. }
  279. static struct net_bridge_group_eht_set *
  280. __eht_lookup_create_set(struct net_bridge_port_group *pg,
  281. union net_bridge_eht_addr *src_addr)
  282. {
  283. struct rb_node **link = &pg->eht_set_tree.rb_node, *parent = NULL;
  284. struct net_bridge_group_eht_set *eht_set;
  285. while (*link) {
  286. struct net_bridge_group_eht_set *this;
  287. int result;
  288. this = rb_entry(*link, struct net_bridge_group_eht_set,
  289. rb_node);
  290. result = memcmp(src_addr, &this->src_addr, sizeof(*src_addr));
  291. parent = *link;
  292. if (result < 0)
  293. link = &((*link)->rb_left);
  294. else if (result > 0)
  295. link = &((*link)->rb_right);
  296. else
  297. return this;
  298. }
  299. eht_set = kzalloc(sizeof(*eht_set), GFP_ATOMIC);
  300. if (!eht_set)
  301. return NULL;
  302. memcpy(&eht_set->src_addr, src_addr, sizeof(*src_addr));
  303. eht_set->mcast_gc.destroy = br_multicast_destroy_eht_set;
  304. eht_set->pg = pg;
  305. eht_set->br = pg->key.port->br;
  306. eht_set->entry_tree = RB_ROOT;
  307. timer_setup(&eht_set->timer, br_multicast_eht_set_expired, 0);
  308. rb_link_node(&eht_set->rb_node, parent, link);
  309. rb_insert_color(&eht_set->rb_node, &pg->eht_set_tree);
  310. return eht_set;
  311. }
  312. static void br_multicast_ip_src_to_eht_addr(const struct br_ip *src,
  313. union net_bridge_eht_addr *dest)
  314. {
  315. switch (src->proto) {
  316. case htons(ETH_P_IP):
  317. dest->ip4 = src->src.ip4;
  318. break;
  319. #if IS_ENABLED(CONFIG_IPV6)
  320. case htons(ETH_P_IPV6):
  321. memcpy(&dest->ip6, &src->src.ip6, sizeof(struct in6_addr));
  322. break;
  323. #endif
  324. }
  325. }
  326. static void br_eht_convert_host_filter_mode(const struct net_bridge_mcast *brmctx,
  327. struct net_bridge_port_group *pg,
  328. union net_bridge_eht_addr *h_addr,
  329. int filter_mode)
  330. {
  331. struct net_bridge_group_eht_host *eht_host;
  332. union net_bridge_eht_addr zero_addr;
  333. eht_host = br_multicast_eht_host_lookup(pg, h_addr);
  334. if (eht_host)
  335. eht_host->filter_mode = filter_mode;
  336. memset(&zero_addr, 0, sizeof(zero_addr));
  337. switch (filter_mode) {
  338. case MCAST_INCLUDE:
  339. br_multicast_del_eht_set_entry(pg, &zero_addr, h_addr);
  340. break;
  341. case MCAST_EXCLUDE:
  342. br_multicast_create_eht_set_entry(brmctx, pg, &zero_addr,
  343. h_addr, MCAST_EXCLUDE,
  344. true);
  345. break;
  346. }
  347. }
  348. static void br_multicast_create_eht_set_entry(const struct net_bridge_mcast *brmctx,
  349. struct net_bridge_port_group *pg,
  350. union net_bridge_eht_addr *src_addr,
  351. union net_bridge_eht_addr *h_addr,
  352. int filter_mode,
  353. bool allow_zero_src)
  354. {
  355. struct net_bridge_group_eht_set_entry *set_h;
  356. struct net_bridge_group_eht_host *eht_host;
  357. struct net_bridge *br = pg->key.port->br;
  358. struct net_bridge_group_eht_set *eht_set;
  359. union net_bridge_eht_addr zero_addr;
  360. memset(&zero_addr, 0, sizeof(zero_addr));
  361. if (!allow_zero_src && !memcmp(src_addr, &zero_addr, sizeof(zero_addr)))
  362. return;
  363. eht_set = __eht_lookup_create_set(pg, src_addr);
  364. if (!eht_set)
  365. return;
  366. eht_host = __eht_lookup_create_host(pg, h_addr, filter_mode);
  367. if (!eht_host)
  368. goto fail_host;
  369. set_h = __eht_lookup_create_set_entry(br, eht_set, eht_host,
  370. allow_zero_src);
  371. if (!set_h)
  372. goto fail_set_entry;
  373. mod_timer(&set_h->timer, jiffies + br_multicast_gmi(brmctx));
  374. mod_timer(&eht_set->timer, jiffies + br_multicast_gmi(brmctx));
  375. return;
  376. fail_set_entry:
  377. if (hlist_empty(&eht_host->set_entries))
  378. __eht_destroy_host(eht_host);
  379. fail_host:
  380. if (RB_EMPTY_ROOT(&eht_set->entry_tree))
  381. br_multicast_del_eht_set(eht_set);
  382. }
  383. static bool br_multicast_del_eht_set_entry(struct net_bridge_port_group *pg,
  384. union net_bridge_eht_addr *src_addr,
  385. union net_bridge_eht_addr *h_addr)
  386. {
  387. struct net_bridge_group_eht_set_entry *set_h;
  388. struct net_bridge_group_eht_set *eht_set;
  389. bool set_deleted = false;
  390. eht_set = br_multicast_eht_set_lookup(pg, src_addr);
  391. if (!eht_set)
  392. goto out;
  393. set_h = br_multicast_eht_set_entry_lookup(eht_set, h_addr);
  394. if (!set_h)
  395. goto out;
  396. __eht_del_set_entry(set_h);
  397. if (RB_EMPTY_ROOT(&eht_set->entry_tree)) {
  398. br_multicast_del_eht_set(eht_set);
  399. set_deleted = true;
  400. }
  401. out:
  402. return set_deleted;
  403. }
  404. static void br_multicast_del_eht_host(struct net_bridge_port_group *pg,
  405. union net_bridge_eht_addr *h_addr)
  406. {
  407. struct net_bridge_group_eht_set_entry *set_h;
  408. struct net_bridge_group_eht_host *eht_host;
  409. struct hlist_node *tmp;
  410. eht_host = br_multicast_eht_host_lookup(pg, h_addr);
  411. if (!eht_host)
  412. return;
  413. hlist_for_each_entry_safe(set_h, tmp, &eht_host->set_entries, host_list)
  414. br_multicast_del_eht_set_entry(set_h->eht_set->pg,
  415. &set_h->eht_set->src_addr,
  416. &set_h->h_addr);
  417. }
  418. /* create new set entries from reports */
  419. static void __eht_create_set_entries(const struct net_bridge_mcast *brmctx,
  420. struct net_bridge_port_group *pg,
  421. union net_bridge_eht_addr *h_addr,
  422. void *srcs,
  423. u32 nsrcs,
  424. size_t addr_size,
  425. int filter_mode)
  426. {
  427. union net_bridge_eht_addr eht_src_addr;
  428. u32 src_idx;
  429. memset(&eht_src_addr, 0, sizeof(eht_src_addr));
  430. for (src_idx = 0; src_idx < nsrcs; src_idx++) {
  431. memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
  432. br_multicast_create_eht_set_entry(brmctx, pg, &eht_src_addr,
  433. h_addr, filter_mode,
  434. false);
  435. }
  436. }
  437. /* delete existing set entries and their (S,G) entries if they were the last */
  438. static bool __eht_del_set_entries(struct net_bridge_port_group *pg,
  439. union net_bridge_eht_addr *h_addr,
  440. void *srcs,
  441. u32 nsrcs,
  442. size_t addr_size)
  443. {
  444. union net_bridge_eht_addr eht_src_addr;
  445. struct net_bridge_group_src *src_ent;
  446. bool changed = false;
  447. struct br_ip src_ip;
  448. u32 src_idx;
  449. memset(&eht_src_addr, 0, sizeof(eht_src_addr));
  450. memset(&src_ip, 0, sizeof(src_ip));
  451. src_ip.proto = pg->key.addr.proto;
  452. for (src_idx = 0; src_idx < nsrcs; src_idx++) {
  453. memcpy(&eht_src_addr, srcs + (src_idx * addr_size), addr_size);
  454. if (!br_multicast_del_eht_set_entry(pg, &eht_src_addr, h_addr))
  455. continue;
  456. memcpy(&src_ip, srcs + (src_idx * addr_size), addr_size);
  457. src_ent = br_multicast_find_group_src(pg, &src_ip);
  458. if (!src_ent)
  459. continue;
  460. br_multicast_del_group_src(src_ent, true);
  461. changed = true;
  462. }
  463. return changed;
  464. }
  465. static bool br_multicast_eht_allow(const struct net_bridge_mcast *brmctx,
  466. struct net_bridge_port_group *pg,
  467. union net_bridge_eht_addr *h_addr,
  468. void *srcs,
  469. u32 nsrcs,
  470. size_t addr_size)
  471. {
  472. bool changed = false;
  473. switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
  474. case MCAST_INCLUDE:
  475. __eht_create_set_entries(brmctx, pg, h_addr, srcs, nsrcs,
  476. addr_size, MCAST_INCLUDE);
  477. break;
  478. case MCAST_EXCLUDE:
  479. changed = __eht_del_set_entries(pg, h_addr, srcs, nsrcs,
  480. addr_size);
  481. break;
  482. }
  483. return changed;
  484. }
  485. static bool br_multicast_eht_block(const struct net_bridge_mcast *brmctx,
  486. struct net_bridge_port_group *pg,
  487. union net_bridge_eht_addr *h_addr,
  488. void *srcs,
  489. u32 nsrcs,
  490. size_t addr_size)
  491. {
  492. bool changed = false;
  493. switch (br_multicast_eht_host_filter_mode(pg, h_addr)) {
  494. case MCAST_INCLUDE:
  495. changed = __eht_del_set_entries(pg, h_addr, srcs, nsrcs,
  496. addr_size);
  497. break;
  498. case MCAST_EXCLUDE:
  499. __eht_create_set_entries(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
  500. MCAST_EXCLUDE);
  501. break;
  502. }
  503. return changed;
  504. }
  505. /* flush_entries is true when changing mode */
  506. static bool __eht_inc_exc(const struct net_bridge_mcast *brmctx,
  507. struct net_bridge_port_group *pg,
  508. union net_bridge_eht_addr *h_addr,
  509. void *srcs,
  510. u32 nsrcs,
  511. size_t addr_size,
  512. unsigned char filter_mode,
  513. bool to_report)
  514. {
  515. bool changed = false, flush_entries = to_report;
  516. union net_bridge_eht_addr eht_src_addr;
  517. if (br_multicast_eht_host_filter_mode(pg, h_addr) != filter_mode)
  518. flush_entries = true;
  519. memset(&eht_src_addr, 0, sizeof(eht_src_addr));
  520. /* if we're changing mode del host and its entries */
  521. if (flush_entries)
  522. br_multicast_del_eht_host(pg, h_addr);
  523. __eht_create_set_entries(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
  524. filter_mode);
  525. /* we can be missing sets only if we've deleted some entries */
  526. if (flush_entries) {
  527. struct net_bridge_group_eht_set *eht_set;
  528. struct net_bridge_group_src *src_ent;
  529. struct hlist_node *tmp;
  530. hlist_for_each_entry_safe(src_ent, tmp, &pg->src_list, node) {
  531. br_multicast_ip_src_to_eht_addr(&src_ent->addr,
  532. &eht_src_addr);
  533. if (!br_multicast_eht_set_lookup(pg, &eht_src_addr)) {
  534. br_multicast_del_group_src(src_ent, true);
  535. changed = true;
  536. continue;
  537. }
  538. /* this is an optimization for TO_INCLUDE where we lower
  539. * the set's timeout to LMQT to catch timeout hosts:
  540. * - host A (timing out): set entries X, Y
  541. * - host B: set entry Z (new from current TO_INCLUDE)
  542. * sends BLOCK Z after LMQT but host A's EHT
  543. * entries still exist (unless lowered to LMQT
  544. * so they can timeout with the S,Gs)
  545. * => we wait another LMQT, when we can just delete the
  546. * group immediately
  547. */
  548. if (!(src_ent->flags & BR_SGRP_F_SEND) ||
  549. filter_mode != MCAST_INCLUDE ||
  550. !to_report)
  551. continue;
  552. eht_set = br_multicast_eht_set_lookup(pg,
  553. &eht_src_addr);
  554. if (!eht_set)
  555. continue;
  556. mod_timer(&eht_set->timer, jiffies + br_multicast_lmqt(brmctx));
  557. }
  558. }
  559. return changed;
  560. }
  561. static bool br_multicast_eht_inc(const struct net_bridge_mcast *brmctx,
  562. struct net_bridge_port_group *pg,
  563. union net_bridge_eht_addr *h_addr,
  564. void *srcs,
  565. u32 nsrcs,
  566. size_t addr_size,
  567. bool to_report)
  568. {
  569. bool changed;
  570. changed = __eht_inc_exc(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
  571. MCAST_INCLUDE, to_report);
  572. br_eht_convert_host_filter_mode(brmctx, pg, h_addr, MCAST_INCLUDE);
  573. return changed;
  574. }
  575. static bool br_multicast_eht_exc(const struct net_bridge_mcast *brmctx,
  576. struct net_bridge_port_group *pg,
  577. union net_bridge_eht_addr *h_addr,
  578. void *srcs,
  579. u32 nsrcs,
  580. size_t addr_size,
  581. bool to_report)
  582. {
  583. bool changed;
  584. changed = __eht_inc_exc(brmctx, pg, h_addr, srcs, nsrcs, addr_size,
  585. MCAST_EXCLUDE, to_report);
  586. br_eht_convert_host_filter_mode(brmctx, pg, h_addr, MCAST_EXCLUDE);
  587. return changed;
  588. }
  589. static bool __eht_ip4_handle(const struct net_bridge_mcast *brmctx,
  590. struct net_bridge_port_group *pg,
  591. union net_bridge_eht_addr *h_addr,
  592. void *srcs,
  593. u32 nsrcs,
  594. int grec_type)
  595. {
  596. bool changed = false, to_report = false;
  597. switch (grec_type) {
  598. case IGMPV3_ALLOW_NEW_SOURCES:
  599. br_multicast_eht_allow(brmctx, pg, h_addr, srcs, nsrcs,
  600. sizeof(__be32));
  601. break;
  602. case IGMPV3_BLOCK_OLD_SOURCES:
  603. changed = br_multicast_eht_block(brmctx, pg, h_addr, srcs, nsrcs,
  604. sizeof(__be32));
  605. break;
  606. case IGMPV3_CHANGE_TO_INCLUDE:
  607. to_report = true;
  608. fallthrough;
  609. case IGMPV3_MODE_IS_INCLUDE:
  610. changed = br_multicast_eht_inc(brmctx, pg, h_addr, srcs, nsrcs,
  611. sizeof(__be32), to_report);
  612. break;
  613. case IGMPV3_CHANGE_TO_EXCLUDE:
  614. to_report = true;
  615. fallthrough;
  616. case IGMPV3_MODE_IS_EXCLUDE:
  617. changed = br_multicast_eht_exc(brmctx, pg, h_addr, srcs, nsrcs,
  618. sizeof(__be32), to_report);
  619. break;
  620. }
  621. return changed;
  622. }
  623. #if IS_ENABLED(CONFIG_IPV6)
  624. static bool __eht_ip6_handle(const struct net_bridge_mcast *brmctx,
  625. struct net_bridge_port_group *pg,
  626. union net_bridge_eht_addr *h_addr,
  627. void *srcs,
  628. u32 nsrcs,
  629. int grec_type)
  630. {
  631. bool changed = false, to_report = false;
  632. switch (grec_type) {
  633. case MLD2_ALLOW_NEW_SOURCES:
  634. br_multicast_eht_allow(brmctx, pg, h_addr, srcs, nsrcs,
  635. sizeof(struct in6_addr));
  636. break;
  637. case MLD2_BLOCK_OLD_SOURCES:
  638. changed = br_multicast_eht_block(brmctx, pg, h_addr, srcs, nsrcs,
  639. sizeof(struct in6_addr));
  640. break;
  641. case MLD2_CHANGE_TO_INCLUDE:
  642. to_report = true;
  643. fallthrough;
  644. case MLD2_MODE_IS_INCLUDE:
  645. changed = br_multicast_eht_inc(brmctx, pg, h_addr, srcs, nsrcs,
  646. sizeof(struct in6_addr),
  647. to_report);
  648. break;
  649. case MLD2_CHANGE_TO_EXCLUDE:
  650. to_report = true;
  651. fallthrough;
  652. case MLD2_MODE_IS_EXCLUDE:
  653. changed = br_multicast_eht_exc(brmctx, pg, h_addr, srcs, nsrcs,
  654. sizeof(struct in6_addr),
  655. to_report);
  656. break;
  657. }
  658. return changed;
  659. }
  660. #endif
  661. /* true means an entry was deleted */
  662. bool br_multicast_eht_handle(const struct net_bridge_mcast *brmctx,
  663. struct net_bridge_port_group *pg,
  664. void *h_addr,
  665. void *srcs,
  666. u32 nsrcs,
  667. size_t addr_size,
  668. int grec_type)
  669. {
  670. bool eht_enabled = !!(pg->key.port->flags & BR_MULTICAST_FAST_LEAVE);
  671. union net_bridge_eht_addr eht_host_addr;
  672. bool changed = false;
  673. if (!eht_enabled)
  674. goto out;
  675. memset(&eht_host_addr, 0, sizeof(eht_host_addr));
  676. memcpy(&eht_host_addr, h_addr, addr_size);
  677. if (addr_size == sizeof(__be32))
  678. changed = __eht_ip4_handle(brmctx, pg, &eht_host_addr, srcs,
  679. nsrcs, grec_type);
  680. #if IS_ENABLED(CONFIG_IPV6)
  681. else
  682. changed = __eht_ip6_handle(brmctx, pg, &eht_host_addr, srcs,
  683. nsrcs, grec_type);
  684. #endif
  685. out:
  686. return changed;
  687. }
  688. int br_multicast_eht_set_hosts_limit(struct net_bridge_port *p,
  689. u32 eht_hosts_limit)
  690. {
  691. struct net_bridge *br = p->br;
  692. if (!eht_hosts_limit)
  693. return -EINVAL;
  694. spin_lock_bh(&br->multicast_lock);
  695. p->multicast_eht_hosts_limit = eht_hosts_limit;
  696. spin_unlock_bh(&br->multicast_lock);
  697. return 0;
  698. }