blob: 45757faafbd7a40e6eff313085b4f829fcddbf25 [file] [log] [blame]
Sven Eckelmann0046b042016-01-01 00:01:03 +01001/* Copyright (C) 2014-2016 B.A.T.M.A.N. contributors:
Linus Lüssingc5caf4e2014-02-15 17:47:49 +01002 *
3 * Linus Lüssing
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
Linus Lüssingc5caf4e2014-02-15 17:47:49 +010018#include "multicast.h"
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020019#include "main.h"
20
21#include <linux/atomic.h>
Linus Lüssing9c936e32015-06-16 17:10:25 +020022#include <linux/bitops.h>
Linus Lüssing8a4023c2015-06-16 17:10:26 +020023#include <linux/bug.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020024#include <linux/byteorder/generic.h>
25#include <linux/errno.h>
26#include <linux/etherdevice.h>
27#include <linux/fs.h>
Linus Lüssingbd2a9792016-05-10 18:41:24 +020028#include <linux/icmpv6.h>
Linus Lüssing687937a2016-05-10 18:41:25 +020029#include <linux/if_bridge.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020030#include <linux/if_ether.h>
Linus Lüssingbd2a9792016-05-10 18:41:24 +020031#include <linux/igmp.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020032#include <linux/in.h>
Linus Lüssingbd2a9792016-05-10 18:41:24 +020033#include <linux/in6.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020034#include <linux/ip.h>
35#include <linux/ipv6.h>
Linus Lüssing72f7b2d2016-05-10 18:41:26 +020036#include <linux/kernel.h>
Sven Eckelmann7c124392016-01-16 10:29:56 +010037#include <linux/kref.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020038#include <linux/list.h>
Sven Eckelmann2c72d652015-06-21 14:45:14 +020039#include <linux/lockdep.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020040#include <linux/netdevice.h>
Linus Lüssing687937a2016-05-10 18:41:25 +020041#include <linux/printk.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020042#include <linux/rculist.h>
43#include <linux/rcupdate.h>
Linus Lüssing4e3e8232016-05-10 18:41:27 +020044#include <linux/seq_file.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020045#include <linux/skbuff.h>
46#include <linux/slab.h>
47#include <linux/spinlock.h>
48#include <linux/stddef.h>
49#include <linux/string.h>
50#include <linux/types.h>
51#include <net/addrconf.h>
Linus Lüssing687937a2016-05-10 18:41:25 +020052#include <net/if_inet6.h>
53#include <net/ip.h>
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020054#include <net/ipv6.h>
55
Linus Lüssing4e3e8232016-05-10 18:41:27 +020056#include "hard-interface.h"
57#include "hash.h"
Sven Eckelmannba412082016-05-15 23:48:31 +020058#include "log.h"
Sven Eckelmann1e2c2a42015-04-17 19:40:28 +020059#include "packet.h"
Linus Lüssingc5caf4e2014-02-15 17:47:49 +010060#include "translation-table.h"
Markus Pargmann1f8dce42016-05-15 11:07:43 +020061#include "tvlv.h"
Linus Lüssingc5caf4e2014-02-15 17:47:49 +010062
63/**
Linus Lüssing687937a2016-05-10 18:41:25 +020064 * batadv_mcast_get_bridge - get the bridge on top of the softif if it exists
65 * @soft_iface: netdev struct of the mesh interface
66 *
67 * If the given soft interface has a bridge on top then the refcount
68 * of the according net device is increased.
69 *
70 * Return: NULL if no such bridge exists. Otherwise the net device of the
71 * bridge.
72 */
73static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
74{
75 struct net_device *upper = soft_iface;
76
77 rcu_read_lock();
78 do {
79 upper = netdev_master_upper_dev_get_rcu(upper);
80 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
81
82 if (upper)
83 dev_hold(upper);
84 rcu_read_unlock();
85
86 return upper;
87}
88
89/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +010090 * batadv_mcast_mla_softif_get - get softif multicast listeners
91 * @dev: the device to collect multicast addresses from
92 * @mcast_list: a list to put found addresses into
93 *
Linus Lüssing687937a2016-05-10 18:41:25 +020094 * Collects multicast addresses of multicast listeners residing
95 * on this kernel on the given soft interface, dev, in
96 * the given mcast_list. In general, multicast listeners provided by
97 * your multicast receiving applications run directly on this node.
98 *
99 * If there is a bridge interface on top of dev, collects from that one
100 * instead. Just like with IP addresses and routes, multicast listeners
101 * will(/should) register to the bridge interface instead of an
102 * enslaved bat0.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100103 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200104 * Return: -ENOMEM on memory allocation error or the number of
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100105 * items added to the mcast_list otherwise.
106 */
107static int batadv_mcast_mla_softif_get(struct net_device *dev,
108 struct hlist_head *mcast_list)
109{
Linus Lüssing687937a2016-05-10 18:41:25 +0200110 struct net_device *bridge = batadv_mcast_get_bridge(dev);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100111 struct netdev_hw_addr *mc_list_entry;
112 struct batadv_hw_addr *new;
113 int ret = 0;
114
Linus Lüssing687937a2016-05-10 18:41:25 +0200115 netif_addr_lock_bh(bridge ? bridge : dev);
116 netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100117 new = kmalloc(sizeof(*new), GFP_ATOMIC);
118 if (!new) {
119 ret = -ENOMEM;
120 break;
121 }
122
123 ether_addr_copy(new->addr, mc_list_entry->addr);
124 hlist_add_head(&new->list, mcast_list);
125 ret++;
126 }
Linus Lüssing687937a2016-05-10 18:41:25 +0200127 netif_addr_unlock_bh(bridge ? bridge : dev);
128
129 if (bridge)
130 dev_put(bridge);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100131
132 return ret;
133}
134
135/**
136 * batadv_mcast_mla_is_duplicate - check whether an address is in a list
137 * @mcast_addr: the multicast address to check
138 * @mcast_list: the list with multicast addresses to search in
139 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200140 * Return: true if the given address is already in the given list.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100141 * Otherwise returns false.
142 */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200143static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100144 struct hlist_head *mcast_list)
145{
146 struct batadv_hw_addr *mcast_entry;
147
148 hlist_for_each_entry(mcast_entry, mcast_list, list)
149 if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
150 return true;
151
152 return false;
153}
154
155/**
Linus Lüssing687937a2016-05-10 18:41:25 +0200156 * batadv_mcast_mla_br_addr_cpy - copy a bridge multicast address
157 * @dst: destination to write to - a multicast MAC address
158 * @src: source to read from - a multicast IP address
159 *
160 * Converts a given multicast IPv4/IPv6 address from a bridge
161 * to its matching multicast MAC address and copies it into the given
162 * destination buffer.
163 *
164 * Caller needs to make sure the destination buffer can hold
165 * at least ETH_ALEN bytes.
166 */
167static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
168{
169 if (src->proto == htons(ETH_P_IP))
170 ip_eth_mc_map(src->u.ip4, dst);
171#if IS_ENABLED(CONFIG_IPV6)
172 else if (src->proto == htons(ETH_P_IPV6))
173 ipv6_eth_mc_map(&src->u.ip6, dst);
174#endif
175 else
176 eth_zero_addr(dst);
177}
178
179/**
180 * batadv_mcast_mla_bridge_get - get bridged-in multicast listeners
181 * @dev: a bridge slave whose bridge to collect multicast addresses from
182 * @mcast_list: a list to put found addresses into
183 *
184 * Collects multicast addresses of multicast listeners residing
185 * on foreign, non-mesh devices which we gave access to our mesh via
186 * a bridge on top of the given soft interface, dev, in the given
187 * mcast_list.
188 *
189 * Return: -ENOMEM on memory allocation error or the number of
190 * items added to the mcast_list otherwise.
191 */
192static int batadv_mcast_mla_bridge_get(struct net_device *dev,
193 struct hlist_head *mcast_list)
194{
195 struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
196 struct br_ip_list *br_ip_entry, *tmp;
197 struct batadv_hw_addr *new;
198 u8 mcast_addr[ETH_ALEN];
199 int ret;
200
201 /* we don't need to detect these devices/listeners, the IGMP/MLD
202 * snooping code of the Linux bridge already does that for us
203 */
204 ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
205 if (ret < 0)
206 goto out;
207
208 list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
209 batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
210 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
211 continue;
212
213 new = kmalloc(sizeof(*new), GFP_ATOMIC);
214 if (!new) {
215 ret = -ENOMEM;
216 break;
217 }
218
219 ether_addr_copy(new->addr, mcast_addr);
220 hlist_add_head(&new->list, mcast_list);
221 }
222
223out:
224 list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
225 list_del(&br_ip_entry->list);
226 kfree(br_ip_entry);
227 }
228
229 return ret;
230}
231
232/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100233 * batadv_mcast_mla_list_free - free a list of multicast addresses
234 * @mcast_list: the list to free
235 *
236 * Removes and frees all items in the given mcast_list.
237 */
Linus Lüssingb7769762016-08-06 22:23:15 +0200238static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100239{
240 struct batadv_hw_addr *mcast_entry;
241 struct hlist_node *tmp;
242
243 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
244 hlist_del(&mcast_entry->list);
245 kfree(mcast_entry);
246 }
247}
248
249/**
250 * batadv_mcast_mla_tt_retract - clean up multicast listener announcements
251 * @bat_priv: the bat priv with all the soft interface information
252 * @mcast_list: a list of addresses which should _not_ be removed
253 *
254 * Retracts the announcement of any multicast listener from the
255 * translation table except the ones listed in the given mcast_list.
256 *
257 * If mcast_list is NULL then all are retracted.
258 */
259static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
260 struct hlist_head *mcast_list)
261{
262 struct batadv_hw_addr *mcast_entry;
263 struct hlist_node *tmp;
264
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200265 lockdep_assert_held(&bat_priv->tt.commit_lock);
266
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100267 hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
268 list) {
269 if (mcast_list &&
270 batadv_mcast_mla_is_duplicate(mcast_entry->addr,
271 mcast_list))
272 continue;
273
274 batadv_tt_local_remove(bat_priv, mcast_entry->addr,
275 BATADV_NO_FLAGS,
276 "mcast TT outdated", false);
277
278 hlist_del(&mcast_entry->list);
279 kfree(mcast_entry);
280 }
281}
282
283/**
284 * batadv_mcast_mla_tt_add - add multicast listener announcements
285 * @bat_priv: the bat priv with all the soft interface information
286 * @mcast_list: a list of addresses which are going to get added
287 *
288 * Adds multicast listener announcements from the given mcast_list to the
289 * translation table if they have not been added yet.
290 */
291static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
292 struct hlist_head *mcast_list)
293{
294 struct batadv_hw_addr *mcast_entry;
295 struct hlist_node *tmp;
296
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200297 lockdep_assert_held(&bat_priv->tt.commit_lock);
298
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100299 if (!mcast_list)
300 return;
301
302 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
303 if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
304 &bat_priv->mcast.mla_list))
305 continue;
306
307 if (!batadv_tt_local_add(bat_priv->soft_iface,
308 mcast_entry->addr, BATADV_NO_FLAGS,
309 BATADV_NULL_IFINDEX, BATADV_NO_MARK))
310 continue;
311
312 hlist_del(&mcast_entry->list);
313 hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
314 }
315}
316
317/**
318 * batadv_mcast_has_bridge - check whether the soft-iface is bridged
319 * @bat_priv: the bat priv with all the soft interface information
320 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200321 * Checks whether there is a bridge on top of our soft interface.
322 *
323 * Return: true if there is a bridge, false otherwise.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100324 */
325static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
326{
327 struct net_device *upper = bat_priv->soft_iface;
328
329 rcu_read_lock();
330 do {
331 upper = netdev_master_upper_dev_get_rcu(upper);
332 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
333 rcu_read_unlock();
334
335 return upper;
336}
337
338/**
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200339 * batadv_mcast_querier_log - debug output regarding the querier status on link
340 * @bat_priv: the bat priv with all the soft interface information
341 * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")
342 * @old_state: the previous querier state on our link
343 * @new_state: the new querier state on our link
344 *
345 * Outputs debug messages to the logging facility with log level 'mcast'
346 * regarding changes to the querier status on the link which are relevant
347 * to our multicast optimizations.
348 *
349 * Usually this is about whether a querier appeared or vanished in
350 * our mesh or whether the querier is in the suboptimal position of being
351 * behind our local bridge segment: Snooping switches will directly
352 * forward listener reports to the querier, therefore batman-adv and
353 * the bridge will potentially not see these listeners - the querier is
354 * potentially shadowing listeners from us then.
355 *
356 * This is only interesting for nodes with a bridge on top of their
357 * soft interface.
358 */
359static void
360batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,
361 struct batadv_mcast_querier_state *old_state,
362 struct batadv_mcast_querier_state *new_state)
363{
364 if (!old_state->exists && new_state->exists)
365 batadv_info(bat_priv->soft_iface, "%s Querier appeared\n",
366 str_proto);
367 else if (old_state->exists && !new_state->exists)
368 batadv_info(bat_priv->soft_iface,
369 "%s Querier disappeared - multicast optimizations disabled\n",
370 str_proto);
371 else if (!bat_priv->mcast.bridged && !new_state->exists)
372 batadv_info(bat_priv->soft_iface,
373 "No %s Querier present - multicast optimizations disabled\n",
374 str_proto);
375
376 if (new_state->exists) {
377 if ((!old_state->shadowing && new_state->shadowing) ||
378 (!old_state->exists && new_state->shadowing))
379 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
380 "%s Querier is behind our bridged segment: Might shadow listeners\n",
381 str_proto);
382 else if (old_state->shadowing && !new_state->shadowing)
383 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
384 "%s Querier is not behind our bridged segment\n",
385 str_proto);
386 }
387}
388
389/**
390 * batadv_mcast_bridge_log - debug output for topology changes in bridged setups
391 * @bat_priv: the bat priv with all the soft interface information
392 * @bridged: a flag about whether the soft interface is currently bridged or not
393 * @querier_ipv4: (maybe) new status of a potential, selected IGMP querier
394 * @querier_ipv6: (maybe) new status of a potential, selected MLD querier
395 *
396 * If no bridges are ever used on this node, then this function does nothing.
397 *
398 * Otherwise this function outputs debug information to the 'mcast' log level
399 * which might be relevant to our multicast optimizations.
400 *
401 * More precisely, it outputs information when a bridge interface is added or
402 * removed from a soft interface. And when a bridge is present, it further
403 * outputs information about the querier state which is relevant for the
404 * multicast flags this node is going to set.
405 */
406static void
407batadv_mcast_bridge_log(struct batadv_priv *bat_priv, bool bridged,
408 struct batadv_mcast_querier_state *querier_ipv4,
409 struct batadv_mcast_querier_state *querier_ipv6)
410{
411 if (!bat_priv->mcast.bridged && bridged)
412 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
413 "Bridge added: Setting Unsnoopables(U)-flag\n");
414 else if (bat_priv->mcast.bridged && !bridged)
415 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
416 "Bridge removed: Unsetting Unsnoopables(U)-flag\n");
417
418 if (bridged) {
419 batadv_mcast_querier_log(bat_priv, "IGMP",
420 &bat_priv->mcast.querier_ipv4,
421 querier_ipv4);
422 batadv_mcast_querier_log(bat_priv, "MLD",
423 &bat_priv->mcast.querier_ipv6,
424 querier_ipv6);
425 }
426}
427
428/**
429 * batadv_mcast_flags_logs - output debug information about mcast flag changes
430 * @bat_priv: the bat priv with all the soft interface information
431 * @flags: flags indicating the new multicast state
432 *
433 * Whenever the multicast flags this nodes announces changes (@mcast_flags vs.
434 * bat_priv->mcast.flags), this notifies userspace via the 'mcast' log level.
435 */
436static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
437{
438 u8 old_flags = bat_priv->mcast.flags;
439 char str_old_flags[] = "[...]";
440
441 sprintf(str_old_flags, "[%c%c%c]",
442 (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
443 (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
444 (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
445
446 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
447 "Changing multicast flags from '%s' to '[%c%c%c]'\n",
448 bat_priv->mcast.enabled ? str_old_flags : "<undefined>",
449 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
450 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
451 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
452}
453
454/**
Linus Lüssing60432d72014-02-15 17:47:51 +0100455 * batadv_mcast_mla_tvlv_update - update multicast tvlv
456 * @bat_priv: the bat priv with all the soft interface information
457 *
458 * Updates the own multicast tvlv with our current multicast related settings,
459 * capabilities and inabilities.
460 *
Linus Lüssing687937a2016-05-10 18:41:25 +0200461 * Return: false if we want all IPv4 && IPv6 multicast traffic and true
462 * otherwise.
Linus Lüssing60432d72014-02-15 17:47:51 +0100463 */
464static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
465{
466 struct batadv_tvlv_mcast_data mcast_data;
Linus Lüssing687937a2016-05-10 18:41:25 +0200467 struct batadv_mcast_querier_state querier4 = {false, false};
468 struct batadv_mcast_querier_state querier6 = {false, false};
469 struct net_device *dev = bat_priv->soft_iface;
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200470 bool bridged;
Linus Lüssing60432d72014-02-15 17:47:51 +0100471
472 mcast_data.flags = BATADV_NO_FLAGS;
473 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
474
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200475 bridged = batadv_mcast_has_bridge(bat_priv);
476 if (!bridged)
Linus Lüssing687937a2016-05-10 18:41:25 +0200477 goto update;
478
479#if !IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
480 pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");
481#endif
482
483 querier4.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);
484 querier4.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);
485
486 querier6.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);
487 querier6.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);
488
489 mcast_data.flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
490
491 /* 1) If no querier exists at all, then multicast listeners on
492 * our local TT clients behind the bridge will keep silent.
493 * 2) If the selected querier is on one of our local TT clients,
494 * behind the bridge, then this querier might shadow multicast
495 * listeners on our local TT clients, behind this bridge.
496 *
497 * In both cases, we will signalize other batman nodes that
498 * we need all multicast traffic of the according protocol.
Linus Lüssing60432d72014-02-15 17:47:51 +0100499 */
Linus Lüssing687937a2016-05-10 18:41:25 +0200500 if (!querier4.exists || querier4.shadowing)
501 mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV4;
Linus Lüssing60432d72014-02-15 17:47:51 +0100502
Linus Lüssing687937a2016-05-10 18:41:25 +0200503 if (!querier6.exists || querier6.shadowing)
504 mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV6;
Linus Lüssing60432d72014-02-15 17:47:51 +0100505
Linus Lüssing687937a2016-05-10 18:41:25 +0200506update:
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200507 batadv_mcast_bridge_log(bat_priv, bridged, &querier4, &querier6);
508
509 bat_priv->mcast.querier_ipv4.exists = querier4.exists;
510 bat_priv->mcast.querier_ipv4.shadowing = querier4.shadowing;
511
512 bat_priv->mcast.querier_ipv6.exists = querier6.exists;
513 bat_priv->mcast.querier_ipv6.shadowing = querier6.shadowing;
514
515 bat_priv->mcast.bridged = bridged;
516
Linus Lüssing60432d72014-02-15 17:47:51 +0100517 if (!bat_priv->mcast.enabled ||
518 mcast_data.flags != bat_priv->mcast.flags) {
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200519 batadv_mcast_flags_log(bat_priv, mcast_data.flags);
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200520 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,
Linus Lüssing60432d72014-02-15 17:47:51 +0100521 &mcast_data, sizeof(mcast_data));
522 bat_priv->mcast.flags = mcast_data.flags;
523 bat_priv->mcast.enabled = true;
524 }
525
Linus Lüssing687937a2016-05-10 18:41:25 +0200526 return !(mcast_data.flags &
Linus Lüssing4d7de482016-07-11 11:16:36 +0200527 (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6));
Linus Lüssing60432d72014-02-15 17:47:51 +0100528}
529
530/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100531 * batadv_mcast_mla_update - update the own MLAs
532 * @bat_priv: the bat priv with all the soft interface information
533 *
Linus Lüssing60432d72014-02-15 17:47:51 +0100534 * Updates the own multicast listener announcements in the translation
535 * table as well as the own, announced multicast tvlv container.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100536 */
537void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
538{
539 struct net_device *soft_iface = bat_priv->soft_iface;
540 struct hlist_head mcast_list = HLIST_HEAD_INIT;
541 int ret;
542
Linus Lüssing60432d72014-02-15 17:47:51 +0100543 if (!batadv_mcast_mla_tvlv_update(bat_priv))
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100544 goto update;
545
546 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
547 if (ret < 0)
548 goto out;
549
Linus Lüssing687937a2016-05-10 18:41:25 +0200550 ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
551 if (ret < 0)
552 goto out;
553
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100554update:
555 batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
556 batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
557
558out:
Linus Lüssingb7769762016-08-06 22:23:15 +0200559 batadv_mcast_mla_list_free(&mcast_list);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100560}
561
562/**
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200563 * batadv_mcast_is_report_ipv4 - check for IGMP reports
564 * @skb: the ethernet frame destined for the mesh
565 *
566 * This call might reallocate skb data.
567 *
568 * Checks whether the given frame is a valid IGMP report.
569 *
570 * Return: If so then true, otherwise false.
571 */
572static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)
573{
574 if (ip_mc_check_igmp(skb, NULL) < 0)
575 return false;
576
577 switch (igmp_hdr(skb)->type) {
578 case IGMP_HOST_MEMBERSHIP_REPORT:
579 case IGMPV2_HOST_MEMBERSHIP_REPORT:
580 case IGMPV3_HOST_MEMBERSHIP_REPORT:
581 return true;
582 }
583
584 return false;
585}
586
587/**
Linus Lüssingab498862014-02-15 17:47:53 +0100588 * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential
589 * @bat_priv: the bat priv with all the soft interface information
590 * @skb: the IPv4 packet to check
591 * @is_unsnoopable: stores whether the destination is snoopable
592 *
593 * Checks whether the given IPv4 packet has the potential to be forwarded with a
594 * mode more optimal than classic flooding.
595 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200596 * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory
597 * allocation failure.
Linus Lüssingab498862014-02-15 17:47:53 +0100598 */
599static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
600 struct sk_buff *skb,
601 bool *is_unsnoopable)
602{
603 struct iphdr *iphdr;
604
605 /* We might fail due to out-of-memory -> drop it */
606 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
607 return -ENOMEM;
608
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200609 if (batadv_mcast_is_report_ipv4(skb))
610 return -EINVAL;
611
Linus Lüssingab498862014-02-15 17:47:53 +0100612 iphdr = ip_hdr(skb);
613
614 /* TODO: Implement Multicast Router Discovery (RFC4286),
615 * then allow scope > link local, too
616 */
617 if (!ipv4_is_local_multicast(iphdr->daddr))
618 return -EINVAL;
619
620 /* link-local multicast listeners behind a bridge are
621 * not snoopable (see RFC4541, section 2.1.2.2)
622 */
623 *is_unsnoopable = true;
624
625 return 0;
626}
627
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200628#if IS_ENABLED(CONFIG_IPV6)
629/**
630 * batadv_mcast_is_report_ipv6 - check for MLD reports
631 * @skb: the ethernet frame destined for the mesh
632 *
633 * This call might reallocate skb data.
634 *
635 * Checks whether the given frame is a valid MLD report.
636 *
637 * Return: If so then true, otherwise false.
638 */
639static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)
640{
641 if (ipv6_mc_check_mld(skb, NULL) < 0)
642 return false;
643
644 switch (icmp6_hdr(skb)->icmp6_type) {
645 case ICMPV6_MGM_REPORT:
646 case ICMPV6_MLD2_REPORT:
647 return true;
648 }
649
650 return false;
651}
652
Linus Lüssingab498862014-02-15 17:47:53 +0100653/**
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100654 * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
655 * @bat_priv: the bat priv with all the soft interface information
656 * @skb: the IPv6 packet to check
Linus Lüssingab498862014-02-15 17:47:53 +0100657 * @is_unsnoopable: stores whether the destination is snoopable
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100658 *
659 * Checks whether the given IPv6 packet has the potential to be forwarded with a
660 * mode more optimal than classic flooding.
661 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200662 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100663 */
664static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
Linus Lüssingab498862014-02-15 17:47:53 +0100665 struct sk_buff *skb,
666 bool *is_unsnoopable)
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100667{
668 struct ipv6hdr *ip6hdr;
669
670 /* We might fail due to out-of-memory -> drop it */
671 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
672 return -ENOMEM;
673
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200674 if (batadv_mcast_is_report_ipv6(skb))
675 return -EINVAL;
676
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100677 ip6hdr = ipv6_hdr(skb);
678
679 /* TODO: Implement Multicast Router Discovery (RFC4286),
680 * then allow scope > link local, too
681 */
682 if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) != IPV6_ADDR_SCOPE_LINKLOCAL)
683 return -EINVAL;
684
685 /* link-local-all-nodes multicast listeners behind a bridge are
686 * not snoopable (see RFC4541, section 3, paragraph 3)
687 */
688 if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
Linus Lüssingab498862014-02-15 17:47:53 +0100689 *is_unsnoopable = true;
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100690
691 return 0;
692}
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200693#endif
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100694
695/**
696 * batadv_mcast_forw_mode_check - check for optimized forwarding potential
697 * @bat_priv: the bat priv with all the soft interface information
698 * @skb: the multicast frame to check
Linus Lüssingab498862014-02-15 17:47:53 +0100699 * @is_unsnoopable: stores whether the destination is snoopable
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100700 *
701 * Checks whether the given multicast ethernet frame has the potential to be
702 * forwarded with a mode more optimal than classic flooding.
703 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200704 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100705 */
706static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
Linus Lüssingab498862014-02-15 17:47:53 +0100707 struct sk_buff *skb,
708 bool *is_unsnoopable)
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100709{
710 struct ethhdr *ethhdr = eth_hdr(skb);
711
712 if (!atomic_read(&bat_priv->multicast_mode))
713 return -EINVAL;
714
715 if (atomic_read(&bat_priv->mcast.num_disabled))
716 return -EINVAL;
717
718 switch (ntohs(ethhdr->h_proto)) {
Linus Lüssingab498862014-02-15 17:47:53 +0100719 case ETH_P_IP:
720 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
721 is_unsnoopable);
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200722#if IS_ENABLED(CONFIG_IPV6)
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100723 case ETH_P_IPV6:
Linus Lüssingab498862014-02-15 17:47:53 +0100724 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
725 is_unsnoopable);
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200726#endif
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100727 default:
728 return -EINVAL;
729 }
730}
731
732/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100733 * batadv_mcast_forw_want_all_ip_count - count nodes with unspecific mcast
734 * interest
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100735 * @bat_priv: the bat priv with all the soft interface information
736 * @ethhdr: ethernet header of a packet
737 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200738 * Return: the number of nodes which want all IPv4 multicast traffic if the
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100739 * given ethhdr is from an IPv4 packet or the number of nodes which want all
740 * IPv6 traffic if it matches an IPv6 packet.
741 */
742static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,
743 struct ethhdr *ethhdr)
744{
745 switch (ntohs(ethhdr->h_proto)) {
746 case ETH_P_IP:
747 return atomic_read(&bat_priv->mcast.num_want_all_ipv4);
748 case ETH_P_IPV6:
749 return atomic_read(&bat_priv->mcast.num_want_all_ipv6);
750 default:
751 /* we shouldn't be here... */
752 return 0;
753 }
754}
755
756/**
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100757 * batadv_mcast_forw_tt_node_get - get a multicast tt node
758 * @bat_priv: the bat priv with all the soft interface information
759 * @ethhdr: the ether header containing the multicast destination
760 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200761 * Return: an orig_node matching the multicast address provided by ethhdr
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100762 * via a translation table lookup. This increases the returned nodes refcount.
763 */
764static struct batadv_orig_node *
765batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
766 struct ethhdr *ethhdr)
767{
768 return batadv_transtable_search(bat_priv, ethhdr->h_source,
769 ethhdr->h_dest, BATADV_NO_FLAGS);
770}
771
772/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100773 * batadv_mcast_forw_ipv4_node_get - get a node with an ipv4 flag
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100774 * @bat_priv: the bat priv with all the soft interface information
775 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200776 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100777 * increases its refcount.
778 */
779static struct batadv_orig_node *
780batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
781{
782 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
783
784 rcu_read_lock();
785 hlist_for_each_entry_rcu(tmp_orig_node,
786 &bat_priv->mcast.want_all_ipv4_list,
787 mcast_want_all_ipv4_node) {
Sven Eckelmann7c124392016-01-16 10:29:56 +0100788 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100789 continue;
790
791 orig_node = tmp_orig_node;
792 break;
793 }
794 rcu_read_unlock();
795
796 return orig_node;
797}
798
799/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100800 * batadv_mcast_forw_ipv6_node_get - get a node with an ipv6 flag
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100801 * @bat_priv: the bat priv with all the soft interface information
802 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200803 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100804 * and increases its refcount.
805 */
806static struct batadv_orig_node *
807batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
808{
809 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
810
811 rcu_read_lock();
812 hlist_for_each_entry_rcu(tmp_orig_node,
813 &bat_priv->mcast.want_all_ipv6_list,
814 mcast_want_all_ipv6_node) {
Sven Eckelmann7c124392016-01-16 10:29:56 +0100815 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100816 continue;
817
818 orig_node = tmp_orig_node;
819 break;
820 }
821 rcu_read_unlock();
822
823 return orig_node;
824}
825
826/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100827 * batadv_mcast_forw_ip_node_get - get a node with an ipv4/ipv6 flag
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100828 * @bat_priv: the bat priv with all the soft interface information
829 * @ethhdr: an ethernet header to determine the protocol family from
830 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200831 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100832 * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and
833 * increases its refcount.
834 */
835static struct batadv_orig_node *
836batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
837 struct ethhdr *ethhdr)
838{
839 switch (ntohs(ethhdr->h_proto)) {
840 case ETH_P_IP:
841 return batadv_mcast_forw_ipv4_node_get(bat_priv);
842 case ETH_P_IPV6:
843 return batadv_mcast_forw_ipv6_node_get(bat_priv);
844 default:
845 /* we shouldn't be here... */
846 return NULL;
847 }
848}
849
850/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100851 * batadv_mcast_forw_unsnoop_node_get - get a node with an unsnoopable flag
Linus Lüssingab498862014-02-15 17:47:53 +0100852 * @bat_priv: the bat priv with all the soft interface information
853 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200854 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
Linus Lüssingab498862014-02-15 17:47:53 +0100855 * set and increases its refcount.
856 */
857static struct batadv_orig_node *
858batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
859{
860 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
861
862 rcu_read_lock();
863 hlist_for_each_entry_rcu(tmp_orig_node,
864 &bat_priv->mcast.want_all_unsnoopables_list,
865 mcast_want_all_unsnoopables_node) {
Sven Eckelmann7c124392016-01-16 10:29:56 +0100866 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
Linus Lüssingab498862014-02-15 17:47:53 +0100867 continue;
868
869 orig_node = tmp_orig_node;
870 break;
871 }
872 rcu_read_unlock();
873
874 return orig_node;
875}
876
877/**
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100878 * batadv_mcast_forw_mode - check on how to forward a multicast packet
879 * @bat_priv: the bat priv with all the soft interface information
880 * @skb: The multicast packet to check
881 * @orig: an originator to be set to forward the skb to
882 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200883 * Return: the forwarding mode as enum batadv_forw_mode and in case of
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100884 * BATADV_FORW_SINGLE set the orig to the single originator the skb
885 * should be forwarded to.
886 */
887enum batadv_forw_mode
888batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
889 struct batadv_orig_node **orig)
890{
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100891 int ret, tt_count, ip_count, unsnoop_count, total_count;
Linus Lüssingab498862014-02-15 17:47:53 +0100892 bool is_unsnoopable = false;
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100893 struct ethhdr *ethhdr;
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100894
Linus Lüssingab498862014-02-15 17:47:53 +0100895 ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable);
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100896 if (ret == -ENOMEM)
897 return BATADV_FORW_NONE;
898 else if (ret < 0)
899 return BATADV_FORW_ALL;
900
901 ethhdr = eth_hdr(skb);
902
903 tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
904 BATADV_NO_FLAGS);
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100905 ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
Linus Lüssingab498862014-02-15 17:47:53 +0100906 unsnoop_count = !is_unsnoopable ? 0 :
907 atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100908
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100909 total_count = tt_count + ip_count + unsnoop_count;
Linus Lüssingab498862014-02-15 17:47:53 +0100910
911 switch (total_count) {
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100912 case 1:
Linus Lüssingab498862014-02-15 17:47:53 +0100913 if (tt_count)
914 *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100915 else if (ip_count)
916 *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
Linus Lüssingab498862014-02-15 17:47:53 +0100917 else if (unsnoop_count)
918 *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
919
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100920 if (*orig)
921 return BATADV_FORW_SINGLE;
922
923 /* fall through */
924 case 0:
925 return BATADV_FORW_NONE;
926 default:
927 return BATADV_FORW_ALL;
928 }
929}
930
931/**
Linus Lüssingab498862014-02-15 17:47:53 +0100932 * batadv_mcast_want_unsnoop_update - update unsnoop counter and list
933 * @bat_priv: the bat priv with all the soft interface information
934 * @orig: the orig_node which multicast state might have changed of
935 * @mcast_flags: flags indicating the new multicast state
936 *
937 * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
938 * orig, has toggled then this method updates counter and list accordingly.
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200939 *
940 * Caller needs to hold orig->mcast_handler_lock.
Linus Lüssingab498862014-02-15 17:47:53 +0100941 */
942static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
943 struct batadv_orig_node *orig,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200944 u8 mcast_flags)
Linus Lüssingab498862014-02-15 17:47:53 +0100945{
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200946 struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
947 struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
948
Sven Eckelmann5274cd62015-06-21 14:45:15 +0200949 lockdep_assert_held(&orig->mcast_handler_lock);
950
Linus Lüssingab498862014-02-15 17:47:53 +0100951 /* switched from flag unset to set */
952 if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
953 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
954 atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
955
956 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200957 /* flag checks above + mcast_handler_lock prevents this */
958 WARN_ON(!hlist_unhashed(node));
959
960 hlist_add_head_rcu(node, head);
Linus Lüssingab498862014-02-15 17:47:53 +0100961 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
962 /* switched from flag set to unset */
963 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
964 orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {
965 atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
966
967 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200968 /* flag checks above + mcast_handler_lock prevents this */
969 WARN_ON(hlist_unhashed(node));
970
971 hlist_del_init_rcu(node);
Linus Lüssingab498862014-02-15 17:47:53 +0100972 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
973 }
974}
975
976/**
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100977 * batadv_mcast_want_ipv4_update - update want-all-ipv4 counter and list
978 * @bat_priv: the bat priv with all the soft interface information
979 * @orig: the orig_node which multicast state might have changed of
980 * @mcast_flags: flags indicating the new multicast state
981 *
982 * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
983 * toggled then this method updates counter and list accordingly.
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200984 *
985 * Caller needs to hold orig->mcast_handler_lock.
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100986 */
987static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
988 struct batadv_orig_node *orig,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200989 u8 mcast_flags)
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100990{
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200991 struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
992 struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
993
Sven Eckelmann5274cd62015-06-21 14:45:15 +0200994 lockdep_assert_held(&orig->mcast_handler_lock);
995
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100996 /* switched from flag unset to set */
997 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
998 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
999 atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
1000
1001 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001002 /* flag checks above + mcast_handler_lock prevents this */
1003 WARN_ON(!hlist_unhashed(node));
1004
1005 hlist_add_head_rcu(node, head);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001006 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1007 /* switched from flag set to unset */
1008 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
1009 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {
1010 atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
1011
1012 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001013 /* flag checks above + mcast_handler_lock prevents this */
1014 WARN_ON(hlist_unhashed(node));
1015
1016 hlist_del_init_rcu(node);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001017 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1018 }
1019}
1020
1021/**
1022 * batadv_mcast_want_ipv6_update - update want-all-ipv6 counter and list
1023 * @bat_priv: the bat priv with all the soft interface information
1024 * @orig: the orig_node which multicast state might have changed of
1025 * @mcast_flags: flags indicating the new multicast state
1026 *
1027 * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
1028 * toggled then this method updates counter and list accordingly.
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001029 *
1030 * Caller needs to hold orig->mcast_handler_lock.
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001031 */
1032static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
1033 struct batadv_orig_node *orig,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001034 u8 mcast_flags)
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001035{
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001036 struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
1037 struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
1038
Sven Eckelmann5274cd62015-06-21 14:45:15 +02001039 lockdep_assert_held(&orig->mcast_handler_lock);
1040
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001041 /* switched from flag unset to set */
1042 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
1043 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
1044 atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
1045
1046 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001047 /* flag checks above + mcast_handler_lock prevents this */
1048 WARN_ON(!hlist_unhashed(node));
1049
1050 hlist_add_head_rcu(node, head);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001051 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1052 /* switched from flag set to unset */
1053 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
1054 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {
1055 atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
1056
1057 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001058 /* flag checks above + mcast_handler_lock prevents this */
1059 WARN_ON(hlist_unhashed(node));
1060
1061 hlist_del_init_rcu(node);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001062 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1063 }
1064}
1065
1066/**
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001067 * batadv_mcast_tvlv_ogm_handler - process incoming multicast tvlv container
Linus Lüssing60432d72014-02-15 17:47:51 +01001068 * @bat_priv: the bat priv with all the soft interface information
1069 * @orig: the orig_node of the ogm
1070 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
1071 * @tvlv_value: tvlv buffer containing the multicast data
1072 * @tvlv_value_len: tvlv buffer length
1073 */
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001074static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
1075 struct batadv_orig_node *orig,
1076 u8 flags,
1077 void *tvlv_value,
1078 u16 tvlv_value_len)
Linus Lüssing60432d72014-02-15 17:47:51 +01001079{
1080 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001081 u8 mcast_flags = BATADV_NO_FLAGS;
Linus Lüssing60432d72014-02-15 17:47:51 +01001082 bool orig_initialized;
1083
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001084 if (orig_mcast_enabled && tvlv_value &&
1085 (tvlv_value_len >= sizeof(mcast_flags)))
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001086 mcast_flags = *(u8 *)tvlv_value;
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001087
1088 spin_lock_bh(&orig->mcast_handler_lock);
Linus Lüssing9c936e32015-06-16 17:10:25 +02001089 orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1090 &orig->capa_initialized);
Linus Lüssing60432d72014-02-15 17:47:51 +01001091
1092 /* If mcast support is turned on decrease the disabled mcast node
1093 * counter only if we had increased it for this node before. If this
1094 * is a completely new orig_node no need to decrease the counter.
1095 */
1096 if (orig_mcast_enabled &&
Linus Lüssing9c936e32015-06-16 17:10:25 +02001097 !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
Linus Lüssing60432d72014-02-15 17:47:51 +01001098 if (orig_initialized)
1099 atomic_dec(&bat_priv->mcast.num_disabled);
Linus Lüssing9c936e32015-06-16 17:10:25 +02001100 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
Linus Lüssinge8829f02014-10-30 05:40:46 +01001101 /* If mcast support is being switched off or if this is an initial
1102 * OGM without mcast support then increase the disabled mcast
1103 * node counter.
Linus Lüssing60432d72014-02-15 17:47:51 +01001104 */
1105 } else if (!orig_mcast_enabled &&
Linus Lüssing9c936e32015-06-16 17:10:25 +02001106 (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) ||
Linus Lüssinge8829f02014-10-30 05:40:46 +01001107 !orig_initialized)) {
Linus Lüssing60432d72014-02-15 17:47:51 +01001108 atomic_inc(&bat_priv->mcast.num_disabled);
Linus Lüssing9c936e32015-06-16 17:10:25 +02001109 clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
Linus Lüssing60432d72014-02-15 17:47:51 +01001110 }
1111
Linus Lüssing9c936e32015-06-16 17:10:25 +02001112 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
Linus Lüssing60432d72014-02-15 17:47:51 +01001113
Linus Lüssingab498862014-02-15 17:47:53 +01001114 batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001115 batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
1116 batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
Linus Lüssingab498862014-02-15 17:47:53 +01001117
Linus Lüssing60432d72014-02-15 17:47:51 +01001118 orig->mcast_flags = mcast_flags;
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001119 spin_unlock_bh(&orig->mcast_handler_lock);
Linus Lüssing60432d72014-02-15 17:47:51 +01001120}
1121
1122/**
1123 * batadv_mcast_init - initialize the multicast optimizations structures
1124 * @bat_priv: the bat priv with all the soft interface information
1125 */
1126void batadv_mcast_init(struct batadv_priv *bat_priv)
1127{
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001128 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
1129 NULL, BATADV_TVLV_MCAST, 2,
Linus Lüssing60432d72014-02-15 17:47:51 +01001130 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
1131}
1132
Sven Eckelmanndc1cbd12016-07-16 09:31:20 +02001133#ifdef CONFIG_BATMAN_ADV_DEBUGFS
Linus Lüssing60432d72014-02-15 17:47:51 +01001134/**
Linus Lüssing4e3e8232016-05-10 18:41:27 +02001135 * batadv_mcast_flags_print_header - print own mcast flags to debugfs table
1136 * @bat_priv: the bat priv with all the soft interface information
1137 * @seq: debugfs table seq_file struct
1138 *
1139 * Prints our own multicast flags including a more specific reason why
1140 * they are set, that is prints the bridge and querier state too, to
1141 * the debugfs table specified via @seq.
1142 */
1143static void batadv_mcast_flags_print_header(struct batadv_priv *bat_priv,
1144 struct seq_file *seq)
1145{
1146 u8 flags = bat_priv->mcast.flags;
1147 char querier4, querier6, shadowing4, shadowing6;
1148 bool bridged = bat_priv->mcast.bridged;
1149
1150 if (bridged) {
1151 querier4 = bat_priv->mcast.querier_ipv4.exists ? '.' : '4';
1152 querier6 = bat_priv->mcast.querier_ipv6.exists ? '.' : '6';
1153 shadowing4 = bat_priv->mcast.querier_ipv4.shadowing ? '4' : '.';
1154 shadowing6 = bat_priv->mcast.querier_ipv6.shadowing ? '6' : '.';
1155 } else {
1156 querier4 = '?';
1157 querier6 = '?';
1158 shadowing4 = '?';
1159 shadowing6 = '?';
1160 }
1161
1162 seq_printf(seq, "Multicast flags (own flags: [%c%c%c])\n",
1163 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
1164 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
1165 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
1166 seq_printf(seq, "* Bridged [U]\t\t\t\t%c\n", bridged ? 'U' : '.');
1167 seq_printf(seq, "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n",
1168 querier4, querier6);
1169 seq_printf(seq, "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n",
1170 shadowing4, shadowing6);
1171 seq_puts(seq, "-------------------------------------------\n");
1172 seq_printf(seq, " %-10s %s\n", "Originator", "Flags");
1173}
1174
1175/**
1176 * batadv_mcast_flags_seq_print_text - print the mcast flags of other nodes
1177 * @seq: seq file to print on
1178 * @offset: not used
1179 *
1180 * This prints a table of (primary) originators and their according
1181 * multicast flags, including (in the header) our own.
1182 *
1183 * Return: always 0
1184 */
1185int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
1186{
1187 struct net_device *net_dev = (struct net_device *)seq->private;
1188 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1189 struct batadv_hard_iface *primary_if;
1190 struct batadv_hashtable *hash = bat_priv->orig_hash;
1191 struct batadv_orig_node *orig_node;
1192 struct hlist_head *head;
1193 u8 flags;
1194 u32 i;
1195
1196 primary_if = batadv_seq_print_text_primary_if_get(seq);
1197 if (!primary_if)
1198 return 0;
1199
1200 batadv_mcast_flags_print_header(bat_priv, seq);
1201
1202 for (i = 0; i < hash->size; i++) {
1203 head = &hash->table[i];
1204
1205 rcu_read_lock();
1206 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1207 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1208 &orig_node->capa_initialized))
1209 continue;
1210
1211 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1212 &orig_node->capabilities)) {
1213 seq_printf(seq, "%pM -\n", orig_node->orig);
1214 continue;
1215 }
1216
1217 flags = orig_node->mcast_flags;
1218
1219 seq_printf(seq, "%pM [%c%c%c]\n", orig_node->orig,
1220 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)
1221 ? 'U' : '.',
1222 (flags & BATADV_MCAST_WANT_ALL_IPV4)
1223 ? '4' : '.',
1224 (flags & BATADV_MCAST_WANT_ALL_IPV6)
1225 ? '6' : '.');
1226 }
1227 rcu_read_unlock();
1228 }
1229
1230 batadv_hardif_put(primary_if);
1231
1232 return 0;
1233}
Sven Eckelmanndc1cbd12016-07-16 09:31:20 +02001234#endif
Linus Lüssing4e3e8232016-05-10 18:41:27 +02001235
1236/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +01001237 * batadv_mcast_free - free the multicast optimizations structures
1238 * @bat_priv: the bat priv with all the soft interface information
1239 */
1240void batadv_mcast_free(struct batadv_priv *bat_priv)
1241{
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001242 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
1243 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
Linus Lüssing60432d72014-02-15 17:47:51 +01001244
Simon Wunderlichaf63cf52015-11-30 17:34:01 +01001245 spin_lock_bh(&bat_priv->tt.commit_lock);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +01001246 batadv_mcast_mla_tt_retract(bat_priv, NULL);
Simon Wunderlichaf63cf52015-11-30 17:34:01 +01001247 spin_unlock_bh(&bat_priv->tt.commit_lock);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +01001248}
Linus Lüssing60432d72014-02-15 17:47:51 +01001249
1250/**
1251 * batadv_mcast_purge_orig - reset originator global mcast state modifications
1252 * @orig: the originator which is going to get purged
1253 */
1254void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
1255{
1256 struct batadv_priv *bat_priv = orig->bat_priv;
1257
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001258 spin_lock_bh(&orig->mcast_handler_lock);
1259
Linus Lüssing9c936e32015-06-16 17:10:25 +02001260 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) &&
1261 test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized))
Linus Lüssing60432d72014-02-15 17:47:51 +01001262 atomic_dec(&bat_priv->mcast.num_disabled);
Linus Lüssingab498862014-02-15 17:47:53 +01001263
1264 batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001265 batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
1266 batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001267
1268 spin_unlock_bh(&orig->mcast_handler_lock);
Linus Lüssing60432d72014-02-15 17:47:51 +01001269}