]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/batman-adv/multicast.c
batman-adv: no need to check return value of debugfs_create functions
[mirror_ubuntu-hirsute-kernel.git] / net / batman-adv / multicast.c
CommitLineData
7db7d9f3 1// SPDX-License-Identifier: GPL-2.0
7a79d717 2/* Copyright (C) 2014-2019 B.A.T.M.A.N. contributors:
c5caf4ef
LL
3 *
4 * Linus Lüssing
c5caf4ef
LL
5 */
6
c5caf4ef 7#include "multicast.h"
1e2c2a4f
SE
8#include "main.h"
9
10#include <linux/atomic.h>
9c936e3f 11#include <linux/bitops.h>
8a4023c5 12#include <linux/bug.h>
1e2c2a4f
SE
13#include <linux/byteorder/generic.h>
14#include <linux/errno.h>
15#include <linux/etherdevice.h>
b92b94ac 16#include <linux/gfp.h>
bd2a979e 17#include <linux/icmpv6.h>
687937ab 18#include <linux/if_bridge.h>
1e2c2a4f 19#include <linux/if_ether.h>
bd2a979e 20#include <linux/igmp.h>
1e2c2a4f 21#include <linux/in.h>
bd2a979e 22#include <linux/in6.h>
5c506802 23#include <linux/inetdevice.h>
1e2c2a4f
SE
24#include <linux/ip.h>
25#include <linux/ipv6.h>
cbebd363 26#include <linux/jiffies.h>
72f7b2de 27#include <linux/kernel.h>
7c124391 28#include <linux/kref.h>
1e2c2a4f 29#include <linux/list.h>
2c72d655 30#include <linux/lockdep.h>
1e2c2a4f 31#include <linux/netdevice.h>
53dd9a68 32#include <linux/netlink.h>
687937ab 33#include <linux/printk.h>
1e2c2a4f
SE
34#include <linux/rculist.h>
35#include <linux/rcupdate.h>
4e3e823b 36#include <linux/seq_file.h>
1e2c2a4f
SE
37#include <linux/skbuff.h>
38#include <linux/slab.h>
39#include <linux/spinlock.h>
40#include <linux/stddef.h>
41#include <linux/string.h>
42#include <linux/types.h>
cbebd363 43#include <linux/workqueue.h>
1e2c2a4f 44#include <net/addrconf.h>
53dd9a68 45#include <net/genetlink.h>
687937ab
LL
46#include <net/if_inet6.h>
47#include <net/ip.h>
1e2c2a4f 48#include <net/ipv6.h>
53dd9a68
LL
49#include <net/netlink.h>
50#include <net/sock.h>
fec149f5 51#include <uapi/linux/batadv_packet.h>
53dd9a68 52#include <uapi/linux/batman_adv.h>
1e2c2a4f 53
4e3e823b
LL
54#include "hard-interface.h"
55#include "hash.h"
ba412080 56#include "log.h"
53dd9a68 57#include "netlink.h"
32e72744 58#include "send.h"
53dd9a68 59#include "soft-interface.h"
c5caf4ef 60#include "translation-table.h"
1f8dce49 61#include "tvlv.h"
c5caf4ef 62
cbebd363
LL
63static void batadv_mcast_mla_update(struct work_struct *work);
64
65/**
7e9a8c2c 66 * batadv_mcast_start_timer() - schedule the multicast periodic worker
cbebd363
LL
67 * @bat_priv: the bat priv with all the soft interface information
68 */
69static void batadv_mcast_start_timer(struct batadv_priv *bat_priv)
70{
71 queue_delayed_work(batadv_event_workqueue, &bat_priv->mcast.work,
72 msecs_to_jiffies(BATADV_MCAST_WORK_PERIOD));
73}
74
6bc45440
LL
75/**
76 * batadv_mcast_has_bridge() - check whether the soft-iface is bridged
77 * @bat_priv: the bat priv with all the soft interface information
78 *
79 * Checks whether there is a bridge on top of our soft interface.
80 *
81 * Return: true if there is a bridge, false otherwise.
82 */
83static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
84{
85 struct net_device *upper = bat_priv->soft_iface;
86
87 rcu_read_lock();
88 do {
89 upper = netdev_master_upper_dev_get_rcu(upper);
90 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
91 rcu_read_unlock();
92
93 return upper;
94}
95
96/**
97 * batadv_mcast_mla_flags_get() - get the new multicast flags
98 * @bat_priv: the bat priv with all the soft interface information
99 *
100 * Return: A set of flags for the current/next TVLV, querier and
101 * bridge state.
102 */
103static struct batadv_mcast_mla_flags
104batadv_mcast_mla_flags_get(struct batadv_priv *bat_priv)
105{
106 struct net_device *dev = bat_priv->soft_iface;
107 struct batadv_mcast_querier_state *qr4, *qr6;
108 struct batadv_mcast_mla_flags mla_flags;
109
110 memset(&mla_flags, 0, sizeof(mla_flags));
111 mla_flags.enabled = 1;
112
113 if (!batadv_mcast_has_bridge(bat_priv))
114 return mla_flags;
115
116 mla_flags.bridged = 1;
117 qr4 = &mla_flags.querier_ipv4;
118 qr6 = &mla_flags.querier_ipv6;
119
120 if (!IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING))
121 pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");
122
123 qr4->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);
124 qr4->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);
125
126 qr6->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);
127 qr6->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);
128
129 mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
130
131 /* 1) If no querier exists at all, then multicast listeners on
132 * our local TT clients behind the bridge will keep silent.
133 * 2) If the selected querier is on one of our local TT clients,
134 * behind the bridge, then this querier might shadow multicast
135 * listeners on our local TT clients, behind this bridge.
136 *
137 * In both cases, we will signalize other batman nodes that
138 * we need all multicast traffic of the according protocol.
139 */
140 if (!qr4->exists || qr4->shadowing)
141 mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV4;
142
143 if (!qr6->exists || qr6->shadowing)
144 mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV6;
145
146 return mla_flags;
147}
148
687937ab 149/**
7e9a8c2c 150 * batadv_mcast_get_bridge() - get the bridge on top of the softif if it exists
687937ab
LL
151 * @soft_iface: netdev struct of the mesh interface
152 *
153 * If the given soft interface has a bridge on top then the refcount
154 * of the according net device is increased.
155 *
156 * Return: NULL if no such bridge exists. Otherwise the net device of the
157 * bridge.
158 */
159static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
160{
161 struct net_device *upper = soft_iface;
162
163 rcu_read_lock();
164 do {
165 upper = netdev_master_upper_dev_get_rcu(upper);
166 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
167
168 if (upper)
169 dev_hold(upper);
170 rcu_read_unlock();
171
172 return upper;
173}
174
6b253603 175/**
5c506802
LL
176 * batadv_mcast_mla_is_duplicate() - check whether an address is in a list
177 * @mcast_addr: the multicast address to check
178 * @mcast_list: the list with multicast addresses to search in
6b253603 179 *
5c506802
LL
180 * Return: true if the given address is already in the given list.
181 * Otherwise returns false.
6b253603 182 */
5c506802
LL
183static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,
184 struct hlist_head *mcast_list)
6b253603 185{
5c506802 186 struct batadv_hw_addr *mcast_entry;
6b253603 187
5c506802
LL
188 hlist_for_each_entry(mcast_entry, mcast_list, list)
189 if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
190 return true;
191
192 return false;
6b253603
LL
193}
194
195/**
5c506802
LL
196 * batadv_mcast_mla_softif_get_ipv4() - get softif IPv4 multicast listeners
197 * @dev: the device to collect multicast addresses from
198 * @mcast_list: a list to put found addresses into
199 * @flags: flags indicating the new multicast state
6b253603 200 *
5c506802
LL
201 * Collects multicast addresses of IPv4 multicast listeners residing
202 * on this kernel on the given soft interface, dev, in
203 * the given mcast_list. In general, multicast listeners provided by
204 * your multicast receiving applications run directly on this node.
205 *
206 * Return: -ENOMEM on memory allocation error or the number of
207 * items added to the mcast_list otherwise.
6b253603 208 */
5c506802
LL
209static int
210batadv_mcast_mla_softif_get_ipv4(struct net_device *dev,
211 struct hlist_head *mcast_list,
212 struct batadv_mcast_mla_flags *flags)
6b253603 213{
5c506802
LL
214 struct batadv_hw_addr *new;
215 struct in_device *in_dev;
216 u8 mcast_addr[ETH_ALEN];
217 struct ip_mc_list *pmc;
218 int ret = 0;
219
220 if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4)
221 return 0;
222
223 rcu_read_lock();
6b253603 224
5c506802
LL
225 in_dev = __in_dev_get_rcu(dev);
226 if (!in_dev) {
227 rcu_read_unlock();
228 return 0;
229 }
230
231 for (pmc = rcu_dereference(in_dev->mc_list); pmc;
232 pmc = rcu_dereference(pmc->next_rcu)) {
390dcd48
LL
233 if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
234 ipv4_is_local_multicast(pmc->multiaddr))
235 continue;
236
5c506802
LL
237 ip_eth_mc_map(pmc->multiaddr, mcast_addr);
238
239 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
240 continue;
241
242 new = kmalloc(sizeof(*new), GFP_ATOMIC);
243 if (!new) {
244 ret = -ENOMEM;
245 break;
246 }
247
248 ether_addr_copy(new->addr, mcast_addr);
249 hlist_add_head(&new->list, mcast_list);
250 ret++;
251 }
252 rcu_read_unlock();
253
254 return ret;
6b253603
LL
255}
256
c5caf4ef 257/**
5c506802 258 * batadv_mcast_mla_softif_get_ipv6() - get softif IPv6 multicast listeners
c5caf4ef
LL
259 * @dev: the device to collect multicast addresses from
260 * @mcast_list: a list to put found addresses into
6bc45440 261 * @flags: flags indicating the new multicast state
c5caf4ef 262 *
5c506802 263 * Collects multicast addresses of IPv6 multicast listeners residing
687937ab
LL
264 * on this kernel on the given soft interface, dev, in
265 * the given mcast_list. In general, multicast listeners provided by
266 * your multicast receiving applications run directly on this node.
267 *
62fe710f 268 * Return: -ENOMEM on memory allocation error or the number of
c5caf4ef
LL
269 * items added to the mcast_list otherwise.
270 */
5c506802 271#if IS_ENABLED(CONFIG_IPV6)
6bc45440 272static int
5c506802
LL
273batadv_mcast_mla_softif_get_ipv6(struct net_device *dev,
274 struct hlist_head *mcast_list,
275 struct batadv_mcast_mla_flags *flags)
c5caf4ef 276{
c5caf4ef 277 struct batadv_hw_addr *new;
5c506802
LL
278 struct inet6_dev *in6_dev;
279 u8 mcast_addr[ETH_ALEN];
280 struct ifmcaddr6 *pmc6;
c5caf4ef
LL
281 int ret = 0;
282
5c506802
LL
283 if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6)
284 return 0;
285
286 rcu_read_lock();
287
288 in6_dev = __in6_dev_get(dev);
289 if (!in6_dev) {
290 rcu_read_unlock();
291 return 0;
292 }
293
294 read_lock_bh(&in6_dev->lock);
295 for (pmc6 = in6_dev->mc_list; pmc6; pmc6 = pmc6->next) {
296 if (IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) <
297 IPV6_ADDR_SCOPE_LINKLOCAL)
6b253603
LL
298 continue;
299
390dcd48
LL
300 if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
301 ipv6_addr_is_ll_all_nodes(&pmc6->mca_addr))
302 continue;
303
5c506802
LL
304 ipv6_eth_mc_map(&pmc6->mca_addr, mcast_addr);
305
306 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
6b253603
LL
307 continue;
308
c5caf4ef
LL
309 new = kmalloc(sizeof(*new), GFP_ATOMIC);
310 if (!new) {
311 ret = -ENOMEM;
312 break;
313 }
314
5c506802 315 ether_addr_copy(new->addr, mcast_addr);
c5caf4ef
LL
316 hlist_add_head(&new->list, mcast_list);
317 ret++;
318 }
5c506802
LL
319 read_unlock_bh(&in6_dev->lock);
320 rcu_read_unlock();
c5caf4ef
LL
321
322 return ret;
323}
5c506802
LL
324#else
325static inline int
326batadv_mcast_mla_softif_get_ipv6(struct net_device *dev,
327 struct hlist_head *mcast_list,
328 struct batadv_mcast_mla_flags *flags)
329{
330 return 0;
331}
332#endif
c5caf4ef
LL
333
334/**
5c506802
LL
335 * batadv_mcast_mla_softif_get() - get softif multicast listeners
336 * @dev: the device to collect multicast addresses from
337 * @mcast_list: a list to put found addresses into
338 * @flags: flags indicating the new multicast state
c5caf4ef 339 *
5c506802
LL
340 * Collects multicast addresses of multicast listeners residing
341 * on this kernel on the given soft interface, dev, in
342 * the given mcast_list. In general, multicast listeners provided by
343 * your multicast receiving applications run directly on this node.
344 *
345 * If there is a bridge interface on top of dev, collects from that one
346 * instead. Just like with IP addresses and routes, multicast listeners
347 * will(/should) register to the bridge interface instead of an
348 * enslaved bat0.
349 *
350 * Return: -ENOMEM on memory allocation error or the number of
351 * items added to the mcast_list otherwise.
c5caf4ef 352 */
5c506802
LL
353static int
354batadv_mcast_mla_softif_get(struct net_device *dev,
355 struct hlist_head *mcast_list,
356 struct batadv_mcast_mla_flags *flags)
c5caf4ef 357{
5c506802
LL
358 struct net_device *bridge = batadv_mcast_get_bridge(dev);
359 int ret4, ret6 = 0;
c5caf4ef 360
5c506802
LL
361 if (bridge)
362 dev = bridge;
c5caf4ef 363
5c506802
LL
364 ret4 = batadv_mcast_mla_softif_get_ipv4(dev, mcast_list, flags);
365 if (ret4 < 0)
366 goto out;
367
368 ret6 = batadv_mcast_mla_softif_get_ipv6(dev, mcast_list, flags);
369 if (ret6 < 0) {
370 ret4 = 0;
371 goto out;
372 }
373
374out:
375 if (bridge)
376 dev_put(bridge);
377
378 return ret4 + ret6;
c5caf4ef
LL
379}
380
687937ab 381/**
7e9a8c2c 382 * batadv_mcast_mla_br_addr_cpy() - copy a bridge multicast address
687937ab
LL
383 * @dst: destination to write to - a multicast MAC address
384 * @src: source to read from - a multicast IP address
385 *
386 * Converts a given multicast IPv4/IPv6 address from a bridge
387 * to its matching multicast MAC address and copies it into the given
388 * destination buffer.
389 *
390 * Caller needs to make sure the destination buffer can hold
391 * at least ETH_ALEN bytes.
392 */
393static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
394{
395 if (src->proto == htons(ETH_P_IP))
396 ip_eth_mc_map(src->u.ip4, dst);
397#if IS_ENABLED(CONFIG_IPV6)
398 else if (src->proto == htons(ETH_P_IPV6))
399 ipv6_eth_mc_map(&src->u.ip6, dst);
400#endif
401 else
402 eth_zero_addr(dst);
403}
404
405/**
7e9a8c2c 406 * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners
687937ab
LL
407 * @dev: a bridge slave whose bridge to collect multicast addresses from
408 * @mcast_list: a list to put found addresses into
6bc45440 409 * @flags: flags indicating the new multicast state
687937ab
LL
410 *
411 * Collects multicast addresses of multicast listeners residing
412 * on foreign, non-mesh devices which we gave access to our mesh via
413 * a bridge on top of the given soft interface, dev, in the given
414 * mcast_list.
415 *
416 * Return: -ENOMEM on memory allocation error or the number of
417 * items added to the mcast_list otherwise.
418 */
6bc45440
LL
419static int batadv_mcast_mla_bridge_get(struct net_device *dev,
420 struct hlist_head *mcast_list,
421 struct batadv_mcast_mla_flags *flags)
687937ab
LL
422{
423 struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
424 struct br_ip_list *br_ip_entry, *tmp;
390dcd48 425 u8 tvlv_flags = flags->tvlv_flags;
687937ab
LL
426 struct batadv_hw_addr *new;
427 u8 mcast_addr[ETH_ALEN];
428 int ret;
429
430 /* we don't need to detect these devices/listeners, the IGMP/MLD
431 * snooping code of the Linux bridge already does that for us
432 */
433 ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
434 if (ret < 0)
435 goto out;
436
437 list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
390dcd48
LL
438 if (br_ip_entry->addr.proto == htons(ETH_P_IP)) {
439 if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4)
440 continue;
6b253603 441
390dcd48
LL
442 if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
443 ipv4_is_local_multicast(br_ip_entry->addr.u.ip4))
444 continue;
445 }
446
447#if IS_ENABLED(CONFIG_IPV6)
448 if (br_ip_entry->addr.proto == htons(ETH_P_IPV6)) {
449 if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6)
450 continue;
451
452 if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
453 ipv6_addr_is_ll_all_nodes(&br_ip_entry->addr.u.ip6))
454 continue;
455 }
456#endif
6b253603 457
687937ab
LL
458 batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
459 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
460 continue;
461
462 new = kmalloc(sizeof(*new), GFP_ATOMIC);
463 if (!new) {
464 ret = -ENOMEM;
465 break;
466 }
467
468 ether_addr_copy(new->addr, mcast_addr);
469 hlist_add_head(&new->list, mcast_list);
470 }
471
472out:
473 list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
474 list_del(&br_ip_entry->list);
475 kfree(br_ip_entry);
476 }
477
478 return ret;
479}
480
c5caf4ef 481/**
7e9a8c2c 482 * batadv_mcast_mla_list_free() - free a list of multicast addresses
c5caf4ef
LL
483 * @mcast_list: the list to free
484 *
485 * Removes and frees all items in the given mcast_list.
486 */
b7769763 487static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
c5caf4ef
LL
488{
489 struct batadv_hw_addr *mcast_entry;
490 struct hlist_node *tmp;
491
492 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
493 hlist_del(&mcast_entry->list);
494 kfree(mcast_entry);
495 }
496}
497
498/**
7e9a8c2c 499 * batadv_mcast_mla_tt_retract() - clean up multicast listener announcements
c5caf4ef
LL
500 * @bat_priv: the bat priv with all the soft interface information
501 * @mcast_list: a list of addresses which should _not_ be removed
502 *
503 * Retracts the announcement of any multicast listener from the
504 * translation table except the ones listed in the given mcast_list.
505 *
506 * If mcast_list is NULL then all are retracted.
507 */
508static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
509 struct hlist_head *mcast_list)
510{
511 struct batadv_hw_addr *mcast_entry;
512 struct hlist_node *tmp;
513
514 hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
515 list) {
516 if (mcast_list &&
517 batadv_mcast_mla_is_duplicate(mcast_entry->addr,
518 mcast_list))
519 continue;
520
521 batadv_tt_local_remove(bat_priv, mcast_entry->addr,
522 BATADV_NO_FLAGS,
523 "mcast TT outdated", false);
524
525 hlist_del(&mcast_entry->list);
526 kfree(mcast_entry);
527 }
528}
529
530/**
7e9a8c2c 531 * batadv_mcast_mla_tt_add() - add multicast listener announcements
c5caf4ef
LL
532 * @bat_priv: the bat priv with all the soft interface information
533 * @mcast_list: a list of addresses which are going to get added
534 *
535 * Adds multicast listener announcements from the given mcast_list to the
536 * translation table if they have not been added yet.
537 */
538static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
539 struct hlist_head *mcast_list)
540{
541 struct batadv_hw_addr *mcast_entry;
542 struct hlist_node *tmp;
543
544 if (!mcast_list)
545 return;
546
547 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
548 if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
549 &bat_priv->mcast.mla_list))
550 continue;
551
552 if (!batadv_tt_local_add(bat_priv->soft_iface,
553 mcast_entry->addr, BATADV_NO_FLAGS,
554 BATADV_NULL_IFINDEX, BATADV_NO_MARK))
555 continue;
556
557 hlist_del(&mcast_entry->list);
558 hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
559 }
560}
561
72f7b2de 562/**
7e9a8c2c
SE
563 * batadv_mcast_querier_log() - debug output regarding the querier status on
564 * link
72f7b2de
LL
565 * @bat_priv: the bat priv with all the soft interface information
566 * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")
567 * @old_state: the previous querier state on our link
568 * @new_state: the new querier state on our link
569 *
570 * Outputs debug messages to the logging facility with log level 'mcast'
571 * regarding changes to the querier status on the link which are relevant
572 * to our multicast optimizations.
573 *
574 * Usually this is about whether a querier appeared or vanished in
575 * our mesh or whether the querier is in the suboptimal position of being
576 * behind our local bridge segment: Snooping switches will directly
577 * forward listener reports to the querier, therefore batman-adv and
578 * the bridge will potentially not see these listeners - the querier is
579 * potentially shadowing listeners from us then.
580 *
581 * This is only interesting for nodes with a bridge on top of their
582 * soft interface.
583 */
584static void
585batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,
586 struct batadv_mcast_querier_state *old_state,
587 struct batadv_mcast_querier_state *new_state)
588{
589 if (!old_state->exists && new_state->exists)
590 batadv_info(bat_priv->soft_iface, "%s Querier appeared\n",
591 str_proto);
592 else if (old_state->exists && !new_state->exists)
593 batadv_info(bat_priv->soft_iface,
594 "%s Querier disappeared - multicast optimizations disabled\n",
595 str_proto);
6bc45440 596 else if (!bat_priv->mcast.mla_flags.bridged && !new_state->exists)
72f7b2de
LL
597 batadv_info(bat_priv->soft_iface,
598 "No %s Querier present - multicast optimizations disabled\n",
599 str_proto);
600
601 if (new_state->exists) {
602 if ((!old_state->shadowing && new_state->shadowing) ||
603 (!old_state->exists && new_state->shadowing))
604 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
605 "%s Querier is behind our bridged segment: Might shadow listeners\n",
606 str_proto);
607 else if (old_state->shadowing && !new_state->shadowing)
608 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
609 "%s Querier is not behind our bridged segment\n",
610 str_proto);
611 }
612}
613
614/**
7e9a8c2c
SE
615 * batadv_mcast_bridge_log() - debug output for topology changes in bridged
616 * setups
72f7b2de 617 * @bat_priv: the bat priv with all the soft interface information
6bc45440 618 * @new_flags: flags indicating the new multicast state
72f7b2de
LL
619 *
620 * If no bridges are ever used on this node, then this function does nothing.
621 *
622 * Otherwise this function outputs debug information to the 'mcast' log level
623 * which might be relevant to our multicast optimizations.
624 *
625 * More precisely, it outputs information when a bridge interface is added or
626 * removed from a soft interface. And when a bridge is present, it further
627 * outputs information about the querier state which is relevant for the
628 * multicast flags this node is going to set.
629 */
630static void
6bc45440
LL
631batadv_mcast_bridge_log(struct batadv_priv *bat_priv,
632 struct batadv_mcast_mla_flags *new_flags)
72f7b2de 633{
6bc45440
LL
634 struct batadv_mcast_mla_flags *old_flags = &bat_priv->mcast.mla_flags;
635
636 if (!old_flags->bridged && new_flags->bridged)
72f7b2de
LL
637 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
638 "Bridge added: Setting Unsnoopables(U)-flag\n");
6bc45440 639 else if (old_flags->bridged && !new_flags->bridged)
72f7b2de
LL
640 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
641 "Bridge removed: Unsetting Unsnoopables(U)-flag\n");
642
6bc45440 643 if (new_flags->bridged) {
72f7b2de 644 batadv_mcast_querier_log(bat_priv, "IGMP",
6bc45440
LL
645 &old_flags->querier_ipv4,
646 &new_flags->querier_ipv4);
72f7b2de 647 batadv_mcast_querier_log(bat_priv, "MLD",
6bc45440
LL
648 &old_flags->querier_ipv6,
649 &new_flags->querier_ipv6);
72f7b2de
LL
650 }
651}
652
653/**
7e9a8c2c 654 * batadv_mcast_flags_logs() - output debug information about mcast flag changes
72f7b2de 655 * @bat_priv: the bat priv with all the soft interface information
6bc45440 656 * @flags: TVLV flags indicating the new multicast state
72f7b2de 657 *
6bc45440
LL
658 * Whenever the multicast TVLV flags this nodes announces change this notifies
659 * userspace via the 'mcast' log level.
72f7b2de
LL
660 */
661static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
662{
6bc45440
LL
663 bool old_enabled = bat_priv->mcast.mla_flags.enabled;
664 u8 old_flags = bat_priv->mcast.mla_flags.tvlv_flags;
72f7b2de
LL
665 char str_old_flags[] = "[...]";
666
667 sprintf(str_old_flags, "[%c%c%c]",
668 (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
669 (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
670 (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
671
672 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
673 "Changing multicast flags from '%s' to '[%c%c%c]'\n",
6bc45440 674 old_enabled ? str_old_flags : "<undefined>",
72f7b2de
LL
675 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
676 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
677 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
678}
679
60432d75 680/**
6bc45440 681 * batadv_mcast_mla_flags_update() - update multicast flags
60432d75 682 * @bat_priv: the bat priv with all the soft interface information
6bc45440 683 * @flags: flags indicating the new multicast state
60432d75
LL
684 *
685 * Updates the own multicast tvlv with our current multicast related settings,
686 * capabilities and inabilities.
60432d75 687 */
6bc45440
LL
688static void
689batadv_mcast_mla_flags_update(struct batadv_priv *bat_priv,
690 struct batadv_mcast_mla_flags *flags)
60432d75
LL
691{
692 struct batadv_tvlv_mcast_data mcast_data;
60432d75 693
6bc45440
LL
694 if (!memcmp(flags, &bat_priv->mcast.mla_flags, sizeof(*flags)))
695 return;
72f7b2de 696
6bc45440
LL
697 batadv_mcast_bridge_log(bat_priv, flags);
698 batadv_mcast_flags_log(bat_priv, flags->tvlv_flags);
72f7b2de 699
6bc45440
LL
700 mcast_data.flags = flags->tvlv_flags;
701 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
72f7b2de 702
6bc45440
LL
703 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,
704 &mcast_data, sizeof(mcast_data));
60432d75 705
6bc45440 706 bat_priv->mcast.mla_flags = *flags;
60432d75
LL
707}
708
c5caf4ef 709/**
7e9a8c2c 710 * __batadv_mcast_mla_update() - update the own MLAs
c5caf4ef
LL
711 * @bat_priv: the bat priv with all the soft interface information
712 *
60432d75
LL
713 * Updates the own multicast listener announcements in the translation
714 * table as well as the own, announced multicast tvlv container.
cbebd363
LL
715 *
716 * Note that non-conflicting reads and writes to bat_priv->mcast.mla_list
717 * in batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add() are
718 * ensured by the non-parallel execution of the worker this function
719 * belongs to.
c5caf4ef 720 */
cbebd363 721static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)
c5caf4ef
LL
722{
723 struct net_device *soft_iface = bat_priv->soft_iface;
724 struct hlist_head mcast_list = HLIST_HEAD_INIT;
6bc45440 725 struct batadv_mcast_mla_flags flags;
c5caf4ef
LL
726 int ret;
727
6bc45440 728 flags = batadv_mcast_mla_flags_get(bat_priv);
c5caf4ef 729
6bc45440 730 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list, &flags);
c5caf4ef
LL
731 if (ret < 0)
732 goto out;
733
6bc45440 734 ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list, &flags);
687937ab
LL
735 if (ret < 0)
736 goto out;
737
6bc45440 738 spin_lock(&bat_priv->mcast.mla_lock);
c5caf4ef
LL
739 batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
740 batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
6bc45440
LL
741 batadv_mcast_mla_flags_update(bat_priv, &flags);
742 spin_unlock(&bat_priv->mcast.mla_lock);
c5caf4ef
LL
743
744out:
b7769763 745 batadv_mcast_mla_list_free(&mcast_list);
c5caf4ef
LL
746}
747
cbebd363 748/**
7e9a8c2c 749 * batadv_mcast_mla_update() - update the own MLAs
cbebd363
LL
750 * @work: kernel work struct
751 *
752 * Updates the own multicast listener announcements in the translation
753 * table as well as the own, announced multicast tvlv container.
754 *
755 * In the end, reschedules the work timer.
756 */
757static void batadv_mcast_mla_update(struct work_struct *work)
758{
759 struct delayed_work *delayed_work;
760 struct batadv_priv_mcast *priv_mcast;
761 struct batadv_priv *bat_priv;
762
763 delayed_work = to_delayed_work(work);
764 priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work);
765 bat_priv = container_of(priv_mcast, struct batadv_priv, mcast);
766
767 __batadv_mcast_mla_update(bat_priv);
768 batadv_mcast_start_timer(bat_priv);
769}
770
bd2a979e 771/**
7e9a8c2c 772 * batadv_mcast_is_report_ipv4() - check for IGMP reports
bd2a979e
LL
773 * @skb: the ethernet frame destined for the mesh
774 *
775 * This call might reallocate skb data.
776 *
777 * Checks whether the given frame is a valid IGMP report.
778 *
779 * Return: If so then true, otherwise false.
780 */
781static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)
782{
ba5ea614 783 if (ip_mc_check_igmp(skb) < 0)
bd2a979e
LL
784 return false;
785
786 switch (igmp_hdr(skb)->type) {
787 case IGMP_HOST_MEMBERSHIP_REPORT:
788 case IGMPV2_HOST_MEMBERSHIP_REPORT:
789 case IGMPV3_HOST_MEMBERSHIP_REPORT:
790 return true;
791 }
792
793 return false;
794}
795
ab49886e 796/**
7e9a8c2c
SE
797 * batadv_mcast_forw_mode_check_ipv4() - check for optimized forwarding
798 * potential
ab49886e
LL
799 * @bat_priv: the bat priv with all the soft interface information
800 * @skb: the IPv4 packet to check
801 * @is_unsnoopable: stores whether the destination is snoopable
802 *
803 * Checks whether the given IPv4 packet has the potential to be forwarded with a
804 * mode more optimal than classic flooding.
805 *
62fe710f
SE
806 * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory
807 * allocation failure.
ab49886e
LL
808 */
809static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
810 struct sk_buff *skb,
811 bool *is_unsnoopable)
812{
813 struct iphdr *iphdr;
814
815 /* We might fail due to out-of-memory -> drop it */
816 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
817 return -ENOMEM;
818
bd2a979e
LL
819 if (batadv_mcast_is_report_ipv4(skb))
820 return -EINVAL;
821
ab49886e
LL
822 iphdr = ip_hdr(skb);
823
824 /* TODO: Implement Multicast Router Discovery (RFC4286),
825 * then allow scope > link local, too
826 */
827 if (!ipv4_is_local_multicast(iphdr->daddr))
828 return -EINVAL;
829
830 /* link-local multicast listeners behind a bridge are
831 * not snoopable (see RFC4541, section 2.1.2.2)
832 */
833 *is_unsnoopable = true;
834
835 return 0;
836}
837
bd2a979e 838/**
7e9a8c2c 839 * batadv_mcast_is_report_ipv6() - check for MLD reports
bd2a979e
LL
840 * @skb: the ethernet frame destined for the mesh
841 *
842 * This call might reallocate skb data.
843 *
844 * Checks whether the given frame is a valid MLD report.
845 *
846 * Return: If so then true, otherwise false.
847 */
848static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)
849{
ba5ea614 850 if (ipv6_mc_check_mld(skb) < 0)
bd2a979e
LL
851 return false;
852
853 switch (icmp6_hdr(skb)->icmp6_type) {
854 case ICMPV6_MGM_REPORT:
855 case ICMPV6_MLD2_REPORT:
856 return true;
857 }
858
859 return false;
860}
861
1d8ab8d3 862/**
7e9a8c2c
SE
863 * batadv_mcast_forw_mode_check_ipv6() - check for optimized forwarding
864 * potential
1d8ab8d3
LL
865 * @bat_priv: the bat priv with all the soft interface information
866 * @skb: the IPv6 packet to check
ab49886e 867 * @is_unsnoopable: stores whether the destination is snoopable
1d8ab8d3
LL
868 *
869 * Checks whether the given IPv6 packet has the potential to be forwarded with a
870 * mode more optimal than classic flooding.
871 *
62fe710f 872 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
1d8ab8d3
LL
873 */
874static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
ab49886e
LL
875 struct sk_buff *skb,
876 bool *is_unsnoopable)
1d8ab8d3
LL
877{
878 struct ipv6hdr *ip6hdr;
879
880 /* We might fail due to out-of-memory -> drop it */
881 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
882 return -ENOMEM;
883
bd2a979e
LL
884 if (batadv_mcast_is_report_ipv6(skb))
885 return -EINVAL;
886
1d8ab8d3
LL
887 ip6hdr = ipv6_hdr(skb);
888
889 /* TODO: Implement Multicast Router Discovery (RFC4286),
890 * then allow scope > link local, too
891 */
892 if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) != IPV6_ADDR_SCOPE_LINKLOCAL)
893 return -EINVAL;
894
895 /* link-local-all-nodes multicast listeners behind a bridge are
896 * not snoopable (see RFC4541, section 3, paragraph 3)
897 */
898 if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
ab49886e 899 *is_unsnoopable = true;
1d8ab8d3
LL
900
901 return 0;
902}
903
904/**
7e9a8c2c 905 * batadv_mcast_forw_mode_check() - check for optimized forwarding potential
1d8ab8d3
LL
906 * @bat_priv: the bat priv with all the soft interface information
907 * @skb: the multicast frame to check
ab49886e 908 * @is_unsnoopable: stores whether the destination is snoopable
1d8ab8d3
LL
909 *
910 * Checks whether the given multicast ethernet frame has the potential to be
911 * forwarded with a mode more optimal than classic flooding.
912 *
62fe710f 913 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
1d8ab8d3
LL
914 */
915static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
ab49886e
LL
916 struct sk_buff *skb,
917 bool *is_unsnoopable)
1d8ab8d3
LL
918{
919 struct ethhdr *ethhdr = eth_hdr(skb);
920
921 if (!atomic_read(&bat_priv->multicast_mode))
922 return -EINVAL;
923
1d8ab8d3 924 switch (ntohs(ethhdr->h_proto)) {
ab49886e
LL
925 case ETH_P_IP:
926 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
927 is_unsnoopable);
1d8ab8d3 928 case ETH_P_IPV6:
c1bacea0
SE
929 if (!IS_ENABLED(CONFIG_IPV6))
930 return -EINVAL;
931
ab49886e
LL
932 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
933 is_unsnoopable);
1d8ab8d3
LL
934 default:
935 return -EINVAL;
936 }
937}
938
4c8755d6 939/**
7e9a8c2c 940 * batadv_mcast_forw_want_all_ip_count() - count nodes with unspecific mcast
6d030de8 941 * interest
4c8755d6
LL
942 * @bat_priv: the bat priv with all the soft interface information
943 * @ethhdr: ethernet header of a packet
944 *
62fe710f 945 * Return: the number of nodes which want all IPv4 multicast traffic if the
4c8755d6
LL
946 * given ethhdr is from an IPv4 packet or the number of nodes which want all
947 * IPv6 traffic if it matches an IPv6 packet.
948 */
949static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,
950 struct ethhdr *ethhdr)
951{
952 switch (ntohs(ethhdr->h_proto)) {
953 case ETH_P_IP:
954 return atomic_read(&bat_priv->mcast.num_want_all_ipv4);
955 case ETH_P_IPV6:
956 return atomic_read(&bat_priv->mcast.num_want_all_ipv6);
957 default:
958 /* we shouldn't be here... */
959 return 0;
960 }
961}
962
1d8ab8d3 963/**
7e9a8c2c 964 * batadv_mcast_forw_tt_node_get() - get a multicast tt node
1d8ab8d3
LL
965 * @bat_priv: the bat priv with all the soft interface information
966 * @ethhdr: the ether header containing the multicast destination
967 *
62fe710f 968 * Return: an orig_node matching the multicast address provided by ethhdr
1d8ab8d3
LL
969 * via a translation table lookup. This increases the returned nodes refcount.
970 */
971static struct batadv_orig_node *
972batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
973 struct ethhdr *ethhdr)
974{
f8fb3419
LL
975 return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest,
976 BATADV_NO_FLAGS);
1d8ab8d3
LL
977}
978
4c8755d6 979/**
7e9a8c2c 980 * batadv_mcast_forw_ipv4_node_get() - get a node with an ipv4 flag
4c8755d6
LL
981 * @bat_priv: the bat priv with all the soft interface information
982 *
62fe710f 983 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
4c8755d6
LL
984 * increases its refcount.
985 */
986static struct batadv_orig_node *
987batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
988{
989 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
990
991 rcu_read_lock();
992 hlist_for_each_entry_rcu(tmp_orig_node,
993 &bat_priv->mcast.want_all_ipv4_list,
994 mcast_want_all_ipv4_node) {
7c124391 995 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
4c8755d6
LL
996 continue;
997
998 orig_node = tmp_orig_node;
999 break;
1000 }
1001 rcu_read_unlock();
1002
1003 return orig_node;
1004}
1005
1006/**
7e9a8c2c 1007 * batadv_mcast_forw_ipv6_node_get() - get a node with an ipv6 flag
4c8755d6
LL
1008 * @bat_priv: the bat priv with all the soft interface information
1009 *
62fe710f 1010 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
4c8755d6
LL
1011 * and increases its refcount.
1012 */
1013static struct batadv_orig_node *
1014batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
1015{
1016 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
1017
1018 rcu_read_lock();
1019 hlist_for_each_entry_rcu(tmp_orig_node,
1020 &bat_priv->mcast.want_all_ipv6_list,
1021 mcast_want_all_ipv6_node) {
7c124391 1022 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
4c8755d6
LL
1023 continue;
1024
1025 orig_node = tmp_orig_node;
1026 break;
1027 }
1028 rcu_read_unlock();
1029
1030 return orig_node;
1031}
1032
1033/**
7e9a8c2c 1034 * batadv_mcast_forw_ip_node_get() - get a node with an ipv4/ipv6 flag
4c8755d6
LL
1035 * @bat_priv: the bat priv with all the soft interface information
1036 * @ethhdr: an ethernet header to determine the protocol family from
1037 *
62fe710f 1038 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
4c8755d6
LL
1039 * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and
1040 * increases its refcount.
1041 */
1042static struct batadv_orig_node *
1043batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
1044 struct ethhdr *ethhdr)
1045{
1046 switch (ntohs(ethhdr->h_proto)) {
1047 case ETH_P_IP:
1048 return batadv_mcast_forw_ipv4_node_get(bat_priv);
1049 case ETH_P_IPV6:
1050 return batadv_mcast_forw_ipv6_node_get(bat_priv);
1051 default:
1052 /* we shouldn't be here... */
1053 return NULL;
1054 }
1055}
1056
ab49886e 1057/**
7e9a8c2c 1058 * batadv_mcast_forw_unsnoop_node_get() - get a node with an unsnoopable flag
ab49886e
LL
1059 * @bat_priv: the bat priv with all the soft interface information
1060 *
62fe710f 1061 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
ab49886e
LL
1062 * set and increases its refcount.
1063 */
1064static struct batadv_orig_node *
1065batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
1066{
1067 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
1068
1069 rcu_read_lock();
1070 hlist_for_each_entry_rcu(tmp_orig_node,
1071 &bat_priv->mcast.want_all_unsnoopables_list,
1072 mcast_want_all_unsnoopables_node) {
7c124391 1073 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
ab49886e
LL
1074 continue;
1075
1076 orig_node = tmp_orig_node;
1077 break;
1078 }
1079 rcu_read_unlock();
1080
1081 return orig_node;
1082}
1083
1d8ab8d3 1084/**
7e9a8c2c 1085 * batadv_mcast_forw_mode() - check on how to forward a multicast packet
1d8ab8d3
LL
1086 * @bat_priv: the bat priv with all the soft interface information
1087 * @skb: The multicast packet to check
1088 * @orig: an originator to be set to forward the skb to
1089 *
62fe710f 1090 * Return: the forwarding mode as enum batadv_forw_mode and in case of
1d8ab8d3
LL
1091 * BATADV_FORW_SINGLE set the orig to the single originator the skb
1092 * should be forwarded to.
1093 */
1094enum batadv_forw_mode
1095batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
1096 struct batadv_orig_node **orig)
1097{
4c8755d6 1098 int ret, tt_count, ip_count, unsnoop_count, total_count;
ab49886e 1099 bool is_unsnoopable = false;
32e72744 1100 unsigned int mcast_fanout;
1d8ab8d3 1101 struct ethhdr *ethhdr;
1d8ab8d3 1102
ab49886e 1103 ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable);
1d8ab8d3
LL
1104 if (ret == -ENOMEM)
1105 return BATADV_FORW_NONE;
1106 else if (ret < 0)
1107 return BATADV_FORW_ALL;
1108
1109 ethhdr = eth_hdr(skb);
1110
1111 tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
1112 BATADV_NO_FLAGS);
4c8755d6 1113 ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
ab49886e
LL
1114 unsnoop_count = !is_unsnoopable ? 0 :
1115 atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
1116
4c8755d6 1117 total_count = tt_count + ip_count + unsnoop_count;
1d8ab8d3 1118
ab49886e 1119 switch (total_count) {
1d8ab8d3 1120 case 1:
ab49886e
LL
1121 if (tt_count)
1122 *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
4c8755d6
LL
1123 else if (ip_count)
1124 *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
ab49886e
LL
1125 else if (unsnoop_count)
1126 *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
1127
1d8ab8d3
LL
1128 if (*orig)
1129 return BATADV_FORW_SINGLE;
1130
1131 /* fall through */
1132 case 0:
1133 return BATADV_FORW_NONE;
1134 default:
32e72744
LL
1135 mcast_fanout = atomic_read(&bat_priv->multicast_fanout);
1136
1137 if (!unsnoop_count && total_count <= mcast_fanout)
1138 return BATADV_FORW_SOME;
1139 }
1140
1141 return BATADV_FORW_ALL;
1142}
1143
1144/**
1145 * batadv_mcast_forw_tt() - forwards a packet to multicast listeners
1146 * @bat_priv: the bat priv with all the soft interface information
1147 * @skb: the multicast packet to transmit
1148 * @vid: the vlan identifier
1149 *
1150 * Sends copies of a frame with multicast destination to any multicast
1151 * listener registered in the translation table. A transmission is performed
1152 * via a batman-adv unicast packet for each such destination node.
1153 *
1154 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
1155 * otherwise.
1156 */
1157static int
1158batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,
1159 unsigned short vid)
1160{
1161 int ret = NET_XMIT_SUCCESS;
1162 struct sk_buff *newskb;
1163
1164 struct batadv_tt_orig_list_entry *orig_entry;
1165
1166 struct batadv_tt_global_entry *tt_global;
1167 const u8 *addr = eth_hdr(skb)->h_dest;
1168
1169 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
1170 if (!tt_global)
1171 goto out;
1172
1173 rcu_read_lock();
1174 hlist_for_each_entry_rcu(orig_entry, &tt_global->orig_list, list) {
1175 newskb = skb_copy(skb, GFP_ATOMIC);
1176 if (!newskb) {
1177 ret = NET_XMIT_DROP;
1178 break;
1179 }
1180
1181 batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1182 orig_entry->orig_node, vid);
1183 }
1184 rcu_read_unlock();
1185
1186 batadv_tt_global_entry_put(tt_global);
1187
1188out:
1189 return ret;
1190}
1191
1192/**
1193 * batadv_mcast_forw_want_all_ipv4() - forward to nodes with want-all-ipv4
1194 * @bat_priv: the bat priv with all the soft interface information
1195 * @skb: the multicast packet to transmit
1196 * @vid: the vlan identifier
1197 *
1198 * Sends copies of a frame with multicast destination to any node with a
1199 * BATADV_MCAST_WANT_ALL_IPV4 flag set. A transmission is performed via a
1200 * batman-adv unicast packet for each such destination node.
1201 *
1202 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
1203 * otherwise.
1204 */
1205static int
1206batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,
1207 struct sk_buff *skb, unsigned short vid)
1208{
1209 struct batadv_orig_node *orig_node;
1210 int ret = NET_XMIT_SUCCESS;
1211 struct sk_buff *newskb;
1212
1213 rcu_read_lock();
1214 hlist_for_each_entry_rcu(orig_node,
1215 &bat_priv->mcast.want_all_ipv4_list,
1216 mcast_want_all_ipv4_node) {
1217 newskb = skb_copy(skb, GFP_ATOMIC);
1218 if (!newskb) {
1219 ret = NET_XMIT_DROP;
1220 break;
1221 }
1222
1223 batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1224 orig_node, vid);
1225 }
1226 rcu_read_unlock();
1227 return ret;
1228}
1229
1230/**
1231 * batadv_mcast_forw_want_all_ipv6() - forward to nodes with want-all-ipv6
1232 * @bat_priv: the bat priv with all the soft interface information
1233 * @skb: The multicast packet to transmit
1234 * @vid: the vlan identifier
1235 *
1236 * Sends copies of a frame with multicast destination to any node with a
1237 * BATADV_MCAST_WANT_ALL_IPV6 flag set. A transmission is performed via a
1238 * batman-adv unicast packet for each such destination node.
1239 *
1240 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
1241 * otherwise.
1242 */
1243static int
1244batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,
1245 struct sk_buff *skb, unsigned short vid)
1246{
1247 struct batadv_orig_node *orig_node;
1248 int ret = NET_XMIT_SUCCESS;
1249 struct sk_buff *newskb;
1250
1251 rcu_read_lock();
1252 hlist_for_each_entry_rcu(orig_node,
1253 &bat_priv->mcast.want_all_ipv6_list,
1254 mcast_want_all_ipv6_node) {
1255 newskb = skb_copy(skb, GFP_ATOMIC);
1256 if (!newskb) {
1257 ret = NET_XMIT_DROP;
1258 break;
1259 }
1260
1261 batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
1262 orig_node, vid);
1d8ab8d3 1263 }
32e72744
LL
1264 rcu_read_unlock();
1265 return ret;
1266}
1267
1268/**
1269 * batadv_mcast_forw_want_all() - forward packet to nodes in a want-all list
1270 * @bat_priv: the bat priv with all the soft interface information
1271 * @skb: the multicast packet to transmit
1272 * @vid: the vlan identifier
1273 *
1274 * Sends copies of a frame with multicast destination to any node with a
1275 * BATADV_MCAST_WANT_ALL_IPV4 or BATADV_MCAST_WANT_ALL_IPV6 flag set. A
1276 * transmission is performed via a batman-adv unicast packet for each such
1277 * destination node.
1278 *
1279 * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family
1280 * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.
1281 */
1282static int
1283batadv_mcast_forw_want_all(struct batadv_priv *bat_priv,
1284 struct sk_buff *skb, unsigned short vid)
1285{
1286 switch (ntohs(eth_hdr(skb)->h_proto)) {
1287 case ETH_P_IP:
1288 return batadv_mcast_forw_want_all_ipv4(bat_priv, skb, vid);
1289 case ETH_P_IPV6:
1290 return batadv_mcast_forw_want_all_ipv6(bat_priv, skb, vid);
1291 default:
1292 /* we shouldn't be here... */
1293 return NET_XMIT_DROP;
1294 }
1295}
1296
1297/**
1298 * batadv_mcast_forw_send() - send packet to any detected multicast recpient
1299 * @bat_priv: the bat priv with all the soft interface information
1300 * @skb: the multicast packet to transmit
1301 * @vid: the vlan identifier
1302 *
1303 * Sends copies of a frame with multicast destination to any node that signaled
1304 * interest in it, that is either via the translation table or the according
1305 * want-all flags. A transmission is performed via a batman-adv unicast packet
1306 * for each such destination node.
1307 *
1308 * The given skb is consumed/freed.
1309 *
1310 * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family
1311 * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.
1312 */
1313int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
1314 unsigned short vid)
1315{
1316 int ret;
1317
1318 ret = batadv_mcast_forw_tt(bat_priv, skb, vid);
1319 if (ret != NET_XMIT_SUCCESS) {
1320 kfree_skb(skb);
1321 return ret;
1322 }
1323
1324 ret = batadv_mcast_forw_want_all(bat_priv, skb, vid);
1325 if (ret != NET_XMIT_SUCCESS) {
1326 kfree_skb(skb);
1327 return ret;
1328 }
1329
1330 consume_skb(skb);
1331 return ret;
1d8ab8d3
LL
1332}
1333
ab49886e 1334/**
7e9a8c2c 1335 * batadv_mcast_want_unsnoop_update() - update unsnoop counter and list
ab49886e
LL
1336 * @bat_priv: the bat priv with all the soft interface information
1337 * @orig: the orig_node which multicast state might have changed of
1338 * @mcast_flags: flags indicating the new multicast state
1339 *
1340 * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
1341 * orig, has toggled then this method updates counter and list accordingly.
8a4023c5
LL
1342 *
1343 * Caller needs to hold orig->mcast_handler_lock.
ab49886e
LL
1344 */
1345static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
1346 struct batadv_orig_node *orig,
6b5e971a 1347 u8 mcast_flags)
ab49886e 1348{
8a4023c5
LL
1349 struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
1350 struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
1351
5274cd68
SE
1352 lockdep_assert_held(&orig->mcast_handler_lock);
1353
ab49886e
LL
1354 /* switched from flag unset to set */
1355 if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
1356 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
1357 atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
1358
1359 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
8a4023c5
LL
1360 /* flag checks above + mcast_handler_lock prevents this */
1361 WARN_ON(!hlist_unhashed(node));
1362
1363 hlist_add_head_rcu(node, head);
ab49886e
LL
1364 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1365 /* switched from flag set to unset */
1366 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
1367 orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {
1368 atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
1369
1370 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
8a4023c5
LL
1371 /* flag checks above + mcast_handler_lock prevents this */
1372 WARN_ON(hlist_unhashed(node));
1373
1374 hlist_del_init_rcu(node);
ab49886e
LL
1375 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1376 }
1377}
1378
4c8755d6 1379/**
7e9a8c2c 1380 * batadv_mcast_want_ipv4_update() - update want-all-ipv4 counter and list
4c8755d6
LL
1381 * @bat_priv: the bat priv with all the soft interface information
1382 * @orig: the orig_node which multicast state might have changed of
1383 * @mcast_flags: flags indicating the new multicast state
1384 *
1385 * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
1386 * toggled then this method updates counter and list accordingly.
8a4023c5
LL
1387 *
1388 * Caller needs to hold orig->mcast_handler_lock.
4c8755d6
LL
1389 */
1390static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
1391 struct batadv_orig_node *orig,
6b5e971a 1392 u8 mcast_flags)
4c8755d6 1393{
8a4023c5
LL
1394 struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
1395 struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
1396
5274cd68
SE
1397 lockdep_assert_held(&orig->mcast_handler_lock);
1398
4c8755d6
LL
1399 /* switched from flag unset to set */
1400 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
1401 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
1402 atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
1403
1404 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
8a4023c5
LL
1405 /* flag checks above + mcast_handler_lock prevents this */
1406 WARN_ON(!hlist_unhashed(node));
1407
1408 hlist_add_head_rcu(node, head);
4c8755d6
LL
1409 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1410 /* switched from flag set to unset */
1411 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
1412 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {
1413 atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
1414
1415 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
8a4023c5
LL
1416 /* flag checks above + mcast_handler_lock prevents this */
1417 WARN_ON(hlist_unhashed(node));
1418
1419 hlist_del_init_rcu(node);
4c8755d6
LL
1420 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1421 }
1422}
1423
1424/**
7e9a8c2c 1425 * batadv_mcast_want_ipv6_update() - update want-all-ipv6 counter and list
4c8755d6
LL
1426 * @bat_priv: the bat priv with all the soft interface information
1427 * @orig: the orig_node which multicast state might have changed of
1428 * @mcast_flags: flags indicating the new multicast state
1429 *
1430 * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
1431 * toggled then this method updates counter and list accordingly.
8a4023c5
LL
1432 *
1433 * Caller needs to hold orig->mcast_handler_lock.
4c8755d6
LL
1434 */
1435static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
1436 struct batadv_orig_node *orig,
6b5e971a 1437 u8 mcast_flags)
4c8755d6 1438{
8a4023c5
LL
1439 struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
1440 struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
1441
5274cd68
SE
1442 lockdep_assert_held(&orig->mcast_handler_lock);
1443
4c8755d6
LL
1444 /* switched from flag unset to set */
1445 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
1446 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
1447 atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
1448
1449 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
8a4023c5
LL
1450 /* flag checks above + mcast_handler_lock prevents this */
1451 WARN_ON(!hlist_unhashed(node));
1452
1453 hlist_add_head_rcu(node, head);
4c8755d6
LL
1454 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1455 /* switched from flag set to unset */
1456 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
1457 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {
1458 atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
1459
1460 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
8a4023c5
LL
1461 /* flag checks above + mcast_handler_lock prevents this */
1462 WARN_ON(hlist_unhashed(node));
1463
1464 hlist_del_init_rcu(node);
4c8755d6
LL
1465 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1466 }
1467}
1468
60432d75 1469/**
7e9a8c2c 1470 * batadv_mcast_tvlv_ogm_handler() - process incoming multicast tvlv container
60432d75
LL
1471 * @bat_priv: the bat priv with all the soft interface information
1472 * @orig: the orig_node of the ogm
1473 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
1474 * @tvlv_value: tvlv buffer containing the multicast data
1475 * @tvlv_value_len: tvlv buffer length
1476 */
bd2a979e
LL
1477static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
1478 struct batadv_orig_node *orig,
1479 u8 flags,
1480 void *tvlv_value,
1481 u16 tvlv_value_len)
60432d75
LL
1482{
1483 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
6b5e971a 1484 u8 mcast_flags = BATADV_NO_FLAGS;
60432d75 1485
8a4023c5 1486 if (orig_mcast_enabled && tvlv_value &&
825ffe1f 1487 tvlv_value_len >= sizeof(mcast_flags))
6b5e971a 1488 mcast_flags = *(u8 *)tvlv_value;
8a4023c5 1489
f26e4e98
LL
1490 if (!orig_mcast_enabled) {
1491 mcast_flags |= BATADV_MCAST_WANT_ALL_IPV4;
1492 mcast_flags |= BATADV_MCAST_WANT_ALL_IPV6;
1493 }
1494
8a4023c5 1495 spin_lock_bh(&orig->mcast_handler_lock);
60432d75 1496
60432d75 1497 if (orig_mcast_enabled &&
9c936e3f 1498 !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
9c936e3f 1499 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
60432d75 1500 } else if (!orig_mcast_enabled &&
f26e4e98 1501 test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
9c936e3f 1502 clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
60432d75
LL
1503 }
1504
9c936e3f 1505 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
60432d75 1506
ab49886e 1507 batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
4c8755d6
LL
1508 batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
1509 batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
ab49886e 1510
60432d75 1511 orig->mcast_flags = mcast_flags;
8a4023c5 1512 spin_unlock_bh(&orig->mcast_handler_lock);
60432d75
LL
1513}
1514
1515/**
7e9a8c2c 1516 * batadv_mcast_init() - initialize the multicast optimizations structures
60432d75
LL
1517 * @bat_priv: the bat priv with all the soft interface information
1518 */
1519void batadv_mcast_init(struct batadv_priv *bat_priv)
1520{
bd2a979e
LL
1521 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
1522 NULL, BATADV_TVLV_MCAST, 2,
60432d75 1523 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
cbebd363
LL
1524
1525 INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);
1526 batadv_mcast_start_timer(bat_priv);
60432d75
LL
1527}
1528
dc1cbd14 1529#ifdef CONFIG_BATMAN_ADV_DEBUGFS
4e3e823b 1530/**
7e9a8c2c 1531 * batadv_mcast_flags_print_header() - print own mcast flags to debugfs table
4e3e823b
LL
1532 * @bat_priv: the bat priv with all the soft interface information
1533 * @seq: debugfs table seq_file struct
1534 *
1535 * Prints our own multicast flags including a more specific reason why
1536 * they are set, that is prints the bridge and querier state too, to
1537 * the debugfs table specified via @seq.
1538 */
1539static void batadv_mcast_flags_print_header(struct batadv_priv *bat_priv,
1540 struct seq_file *seq)
1541{
6bc45440 1542 struct batadv_mcast_mla_flags *mla_flags = &bat_priv->mcast.mla_flags;
4e3e823b 1543 char querier4, querier6, shadowing4, shadowing6;
6bc45440
LL
1544 bool bridged = mla_flags->bridged;
1545 u8 flags = mla_flags->tvlv_flags;
4e3e823b
LL
1546
1547 if (bridged) {
6bc45440
LL
1548 querier4 = mla_flags->querier_ipv4.exists ? '.' : '4';
1549 querier6 = mla_flags->querier_ipv6.exists ? '.' : '6';
1550 shadowing4 = mla_flags->querier_ipv4.shadowing ? '4' : '.';
1551 shadowing6 = mla_flags->querier_ipv6.shadowing ? '6' : '.';
4e3e823b
LL
1552 } else {
1553 querier4 = '?';
1554 querier6 = '?';
1555 shadowing4 = '?';
1556 shadowing6 = '?';
1557 }
1558
1559 seq_printf(seq, "Multicast flags (own flags: [%c%c%c])\n",
1560 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
1561 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
1562 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
1563 seq_printf(seq, "* Bridged [U]\t\t\t\t%c\n", bridged ? 'U' : '.');
1564 seq_printf(seq, "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n",
1565 querier4, querier6);
1566 seq_printf(seq, "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n",
1567 shadowing4, shadowing6);
1568 seq_puts(seq, "-------------------------------------------\n");
1569 seq_printf(seq, " %-10s %s\n", "Originator", "Flags");
1570}
1571
1572/**
7e9a8c2c 1573 * batadv_mcast_flags_seq_print_text() - print the mcast flags of other nodes
4e3e823b
LL
1574 * @seq: seq file to print on
1575 * @offset: not used
1576 *
1577 * This prints a table of (primary) originators and their according
1578 * multicast flags, including (in the header) our own.
1579 *
1580 * Return: always 0
1581 */
1582int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
1583{
1584 struct net_device *net_dev = (struct net_device *)seq->private;
1585 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1586 struct batadv_hard_iface *primary_if;
1587 struct batadv_hashtable *hash = bat_priv->orig_hash;
1588 struct batadv_orig_node *orig_node;
1589 struct hlist_head *head;
1590 u8 flags;
1591 u32 i;
1592
1593 primary_if = batadv_seq_print_text_primary_if_get(seq);
1594 if (!primary_if)
1595 return 0;
1596
1597 batadv_mcast_flags_print_header(bat_priv, seq);
1598
1599 for (i = 0; i < hash->size; i++) {
1600 head = &hash->table[i];
1601
1602 rcu_read_lock();
1603 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1604 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1605 &orig_node->capa_initialized))
1606 continue;
1607
1608 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1609 &orig_node->capabilities)) {
1610 seq_printf(seq, "%pM -\n", orig_node->orig);
1611 continue;
1612 }
1613
1614 flags = orig_node->mcast_flags;
1615
1616 seq_printf(seq, "%pM [%c%c%c]\n", orig_node->orig,
1617 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)
1618 ? 'U' : '.',
1619 (flags & BATADV_MCAST_WANT_ALL_IPV4)
1620 ? '4' : '.',
1621 (flags & BATADV_MCAST_WANT_ALL_IPV6)
1622 ? '6' : '.');
1623 }
1624 rcu_read_unlock();
1625 }
1626
1627 batadv_hardif_put(primary_if);
1628
1629 return 0;
1630}
dc1cbd14 1631#endif
4e3e823b 1632
53dd9a68
LL
1633/**
1634 * batadv_mcast_mesh_info_put() - put multicast info into a netlink message
1635 * @msg: buffer for the message
1636 * @bat_priv: the bat priv with all the soft interface information
1637 *
1638 * Return: 0 or error code.
1639 */
1640int batadv_mcast_mesh_info_put(struct sk_buff *msg,
1641 struct batadv_priv *bat_priv)
1642{
6bc45440 1643 u32 flags = bat_priv->mcast.mla_flags.tvlv_flags;
53dd9a68
LL
1644 u32 flags_priv = BATADV_NO_FLAGS;
1645
6bc45440 1646 if (bat_priv->mcast.mla_flags.bridged) {
53dd9a68
LL
1647 flags_priv |= BATADV_MCAST_FLAGS_BRIDGED;
1648
6bc45440 1649 if (bat_priv->mcast.mla_flags.querier_ipv4.exists)
53dd9a68 1650 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS;
6bc45440 1651 if (bat_priv->mcast.mla_flags.querier_ipv6.exists)
53dd9a68 1652 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS;
6bc45440 1653 if (bat_priv->mcast.mla_flags.querier_ipv4.shadowing)
53dd9a68 1654 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING;
6bc45440 1655 if (bat_priv->mcast.mla_flags.querier_ipv6.shadowing)
53dd9a68
LL
1656 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING;
1657 }
1658
1659 if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) ||
1660 nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv))
1661 return -EMSGSIZE;
1662
1663 return 0;
1664}
1665
1666/**
1667 * batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table
1668 * to a netlink socket
1669 * @msg: buffer for the message
1670 * @portid: netlink port
d2d489b7 1671 * @cb: Control block containing additional options
53dd9a68
LL
1672 * @orig_node: originator to dump the multicast flags of
1673 *
1674 * Return: 0 or error code.
1675 */
1676static int
d2d489b7
SE
1677batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid,
1678 struct netlink_callback *cb,
53dd9a68
LL
1679 struct batadv_orig_node *orig_node)
1680{
1681 void *hdr;
1682
d2d489b7
SE
1683 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
1684 &batadv_netlink_family, NLM_F_MULTI,
1685 BATADV_CMD_GET_MCAST_FLAGS);
53dd9a68
LL
1686 if (!hdr)
1687 return -ENOBUFS;
1688
d2d489b7
SE
1689 genl_dump_check_consistent(cb, hdr);
1690
53dd9a68
LL
1691 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
1692 orig_node->orig)) {
1693 genlmsg_cancel(msg, hdr);
1694 return -EMSGSIZE;
1695 }
1696
1697 if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1698 &orig_node->capabilities)) {
1699 if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS,
1700 orig_node->mcast_flags)) {
1701 genlmsg_cancel(msg, hdr);
1702 return -EMSGSIZE;
1703 }
1704 }
1705
1706 genlmsg_end(msg, hdr);
1707 return 0;
1708}
1709
1710/**
1711 * batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags
1712 * table to a netlink socket
1713 * @msg: buffer for the message
1714 * @portid: netlink port
d2d489b7
SE
1715 * @cb: Control block containing additional options
1716 * @hash: hash to dump
1717 * @bucket: bucket index to dump
53dd9a68
LL
1718 * @idx_skip: How many entries to skip
1719 *
1720 * Return: 0 or error code.
1721 */
1722static int
d2d489b7
SE
1723batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid,
1724 struct netlink_callback *cb,
1725 struct batadv_hashtable *hash,
1726 unsigned int bucket, long *idx_skip)
53dd9a68
LL
1727{
1728 struct batadv_orig_node *orig_node;
1729 long idx = 0;
1730
d2d489b7
SE
1731 spin_lock_bh(&hash->list_locks[bucket]);
1732 cb->seq = atomic_read(&hash->generation) << 1 | 1;
1733
1734 hlist_for_each_entry(orig_node, &hash->table[bucket], hash_entry) {
53dd9a68
LL
1735 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1736 &orig_node->capa_initialized))
1737 continue;
1738
1739 if (idx < *idx_skip)
1740 goto skip;
1741
d2d489b7
SE
1742 if (batadv_mcast_flags_dump_entry(msg, portid, cb, orig_node)) {
1743 spin_unlock_bh(&hash->list_locks[bucket]);
53dd9a68
LL
1744 *idx_skip = idx;
1745
1746 return -EMSGSIZE;
1747 }
1748
1749skip:
1750 idx++;
1751 }
d2d489b7 1752 spin_unlock_bh(&hash->list_locks[bucket]);
53dd9a68
LL
1753
1754 return 0;
1755}
1756
1757/**
1758 * __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
1759 * @msg: buffer for the message
1760 * @portid: netlink port
d2d489b7 1761 * @cb: Control block containing additional options
53dd9a68
LL
1762 * @bat_priv: the bat priv with all the soft interface information
1763 * @bucket: current bucket to dump
1764 * @idx: index in current bucket to the next entry to dump
1765 *
1766 * Return: 0 or error code.
1767 */
1768static int
d2d489b7
SE
1769__batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid,
1770 struct netlink_callback *cb,
53dd9a68
LL
1771 struct batadv_priv *bat_priv, long *bucket, long *idx)
1772{
1773 struct batadv_hashtable *hash = bat_priv->orig_hash;
1774 long bucket_tmp = *bucket;
53dd9a68
LL
1775 long idx_tmp = *idx;
1776
1777 while (bucket_tmp < hash->size) {
d2d489b7
SE
1778 if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash,
1779 *bucket, &idx_tmp))
53dd9a68
LL
1780 break;
1781
1782 bucket_tmp++;
1783 idx_tmp = 0;
1784 }
1785
1786 *bucket = bucket_tmp;
1787 *idx = idx_tmp;
1788
1789 return msg->len;
1790}
1791
1792/**
1793 * batadv_mcast_netlink_get_primary() - get primary interface from netlink
1794 * callback
1795 * @cb: netlink callback structure
1796 * @primary_if: the primary interface pointer to return the result in
1797 *
1798 * Return: 0 or error code.
1799 */
1800static int
1801batadv_mcast_netlink_get_primary(struct netlink_callback *cb,
1802 struct batadv_hard_iface **primary_if)
1803{
1804 struct batadv_hard_iface *hard_iface = NULL;
1805 struct net *net = sock_net(cb->skb->sk);
1806 struct net_device *soft_iface;
1807 struct batadv_priv *bat_priv;
1808 int ifindex;
1809 int ret = 0;
1810
1811 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
1812 if (!ifindex)
1813 return -EINVAL;
1814
1815 soft_iface = dev_get_by_index(net, ifindex);
1816 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
1817 ret = -ENODEV;
1818 goto out;
1819 }
1820
1821 bat_priv = netdev_priv(soft_iface);
1822
1823 hard_iface = batadv_primary_if_get_selected(bat_priv);
1824 if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) {
1825 ret = -ENOENT;
1826 goto out;
1827 }
1828
1829out:
1830 if (soft_iface)
1831 dev_put(soft_iface);
1832
1833 if (!ret && primary_if)
1834 *primary_if = hard_iface;
65cc02a8 1835 else if (hard_iface)
53dd9a68
LL
1836 batadv_hardif_put(hard_iface);
1837
1838 return ret;
1839}
1840
1841/**
1842 * batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
1843 * @msg: buffer for the message
1844 * @cb: callback structure containing arguments
1845 *
1846 * Return: message length.
1847 */
1848int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb)
1849{
1850 struct batadv_hard_iface *primary_if = NULL;
1851 int portid = NETLINK_CB(cb->skb).portid;
1852 struct batadv_priv *bat_priv;
1853 long *bucket = &cb->args[0];
1854 long *idx = &cb->args[1];
1855 int ret;
1856
1857 ret = batadv_mcast_netlink_get_primary(cb, &primary_if);
1858 if (ret)
1859 return ret;
1860
1861 bat_priv = netdev_priv(primary_if->soft_iface);
d2d489b7 1862 ret = __batadv_mcast_flags_dump(msg, portid, cb, bat_priv, bucket, idx);
53dd9a68
LL
1863
1864 batadv_hardif_put(primary_if);
1865 return ret;
1866}
1867
c5caf4ef 1868/**
7e9a8c2c 1869 * batadv_mcast_free() - free the multicast optimizations structures
c5caf4ef
LL
1870 * @bat_priv: the bat priv with all the soft interface information
1871 */
1872void batadv_mcast_free(struct batadv_priv *bat_priv)
1873{
cbebd363
LL
1874 cancel_delayed_work_sync(&bat_priv->mcast.work);
1875
bd2a979e
LL
1876 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
1877 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
60432d75 1878
cbebd363 1879 /* safely calling outside of worker, as worker was canceled above */
c5caf4ef
LL
1880 batadv_mcast_mla_tt_retract(bat_priv, NULL);
1881}
60432d75
LL
1882
1883/**
7e9a8c2c 1884 * batadv_mcast_purge_orig() - reset originator global mcast state modifications
60432d75
LL
1885 * @orig: the originator which is going to get purged
1886 */
1887void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
1888{
1889 struct batadv_priv *bat_priv = orig->bat_priv;
1890
8a4023c5
LL
1891 spin_lock_bh(&orig->mcast_handler_lock);
1892
ab49886e 1893 batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
4c8755d6
LL
1894 batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
1895 batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
8a4023c5
LL
1896
1897 spin_unlock_bh(&orig->mcast_handler_lock);
60432d75 1898}