blob: d3222db60fd04366b7b18de57954b5345b330778 [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 Eckelmann1e2c2a42015-04-17 19:40:28 +020058#include "packet.h"
Linus Lüssingc5caf4e2014-02-15 17:47:49 +010059#include "translation-table.h"
60
61/**
Linus Lüssing687937a2016-05-10 18:41:25 +020062 * batadv_mcast_get_bridge - get the bridge on top of the softif if it exists
63 * @soft_iface: netdev struct of the mesh interface
64 *
65 * If the given soft interface has a bridge on top then the refcount
66 * of the according net device is increased.
67 *
68 * Return: NULL if no such bridge exists. Otherwise the net device of the
69 * bridge.
70 */
71static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
72{
73 struct net_device *upper = soft_iface;
74
75 rcu_read_lock();
76 do {
77 upper = netdev_master_upper_dev_get_rcu(upper);
78 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
79
80 if (upper)
81 dev_hold(upper);
82 rcu_read_unlock();
83
84 return upper;
85}
86
87/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +010088 * batadv_mcast_mla_softif_get - get softif multicast listeners
89 * @dev: the device to collect multicast addresses from
90 * @mcast_list: a list to put found addresses into
91 *
Linus Lüssing687937a2016-05-10 18:41:25 +020092 * Collects multicast addresses of multicast listeners residing
93 * on this kernel on the given soft interface, dev, in
94 * the given mcast_list. In general, multicast listeners provided by
95 * your multicast receiving applications run directly on this node.
96 *
97 * If there is a bridge interface on top of dev, collects from that one
98 * instead. Just like with IP addresses and routes, multicast listeners
99 * will(/should) register to the bridge interface instead of an
100 * enslaved bat0.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100101 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200102 * Return: -ENOMEM on memory allocation error or the number of
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100103 * items added to the mcast_list otherwise.
104 */
105static int batadv_mcast_mla_softif_get(struct net_device *dev,
106 struct hlist_head *mcast_list)
107{
Linus Lüssing687937a2016-05-10 18:41:25 +0200108 struct net_device *bridge = batadv_mcast_get_bridge(dev);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100109 struct netdev_hw_addr *mc_list_entry;
110 struct batadv_hw_addr *new;
111 int ret = 0;
112
Linus Lüssing687937a2016-05-10 18:41:25 +0200113 netif_addr_lock_bh(bridge ? bridge : dev);
114 netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100115 new = kmalloc(sizeof(*new), GFP_ATOMIC);
116 if (!new) {
117 ret = -ENOMEM;
118 break;
119 }
120
121 ether_addr_copy(new->addr, mc_list_entry->addr);
122 hlist_add_head(&new->list, mcast_list);
123 ret++;
124 }
Linus Lüssing687937a2016-05-10 18:41:25 +0200125 netif_addr_unlock_bh(bridge ? bridge : dev);
126
127 if (bridge)
128 dev_put(bridge);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100129
130 return ret;
131}
132
133/**
134 * batadv_mcast_mla_is_duplicate - check whether an address is in a list
135 * @mcast_addr: the multicast address to check
136 * @mcast_list: the list with multicast addresses to search in
137 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200138 * Return: true if the given address is already in the given list.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100139 * Otherwise returns false.
140 */
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200141static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100142 struct hlist_head *mcast_list)
143{
144 struct batadv_hw_addr *mcast_entry;
145
146 hlist_for_each_entry(mcast_entry, mcast_list, list)
147 if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
148 return true;
149
150 return false;
151}
152
153/**
Linus Lüssing687937a2016-05-10 18:41:25 +0200154 * batadv_mcast_mla_br_addr_cpy - copy a bridge multicast address
155 * @dst: destination to write to - a multicast MAC address
156 * @src: source to read from - a multicast IP address
157 *
158 * Converts a given multicast IPv4/IPv6 address from a bridge
159 * to its matching multicast MAC address and copies it into the given
160 * destination buffer.
161 *
162 * Caller needs to make sure the destination buffer can hold
163 * at least ETH_ALEN bytes.
164 */
165static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
166{
167 if (src->proto == htons(ETH_P_IP))
168 ip_eth_mc_map(src->u.ip4, dst);
169#if IS_ENABLED(CONFIG_IPV6)
170 else if (src->proto == htons(ETH_P_IPV6))
171 ipv6_eth_mc_map(&src->u.ip6, dst);
172#endif
173 else
174 eth_zero_addr(dst);
175}
176
177/**
178 * batadv_mcast_mla_bridge_get - get bridged-in multicast listeners
179 * @dev: a bridge slave whose bridge to collect multicast addresses from
180 * @mcast_list: a list to put found addresses into
181 *
182 * Collects multicast addresses of multicast listeners residing
183 * on foreign, non-mesh devices which we gave access to our mesh via
184 * a bridge on top of the given soft interface, dev, in the given
185 * mcast_list.
186 *
187 * Return: -ENOMEM on memory allocation error or the number of
188 * items added to the mcast_list otherwise.
189 */
190static int batadv_mcast_mla_bridge_get(struct net_device *dev,
191 struct hlist_head *mcast_list)
192{
193 struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
194 struct br_ip_list *br_ip_entry, *tmp;
195 struct batadv_hw_addr *new;
196 u8 mcast_addr[ETH_ALEN];
197 int ret;
198
199 /* we don't need to detect these devices/listeners, the IGMP/MLD
200 * snooping code of the Linux bridge already does that for us
201 */
202 ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
203 if (ret < 0)
204 goto out;
205
206 list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
207 batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
208 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
209 continue;
210
211 new = kmalloc(sizeof(*new), GFP_ATOMIC);
212 if (!new) {
213 ret = -ENOMEM;
214 break;
215 }
216
217 ether_addr_copy(new->addr, mcast_addr);
218 hlist_add_head(&new->list, mcast_list);
219 }
220
221out:
222 list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
223 list_del(&br_ip_entry->list);
224 kfree(br_ip_entry);
225 }
226
227 return ret;
228}
229
230/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100231 * batadv_mcast_mla_list_free - free a list of multicast addresses
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200232 * @bat_priv: the bat priv with all the soft interface information
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100233 * @mcast_list: the list to free
234 *
235 * Removes and frees all items in the given mcast_list.
236 */
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200237static void batadv_mcast_mla_list_free(struct batadv_priv *bat_priv,
238 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
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200243 lockdep_assert_held(&bat_priv->tt.commit_lock);
244
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100245 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
246 hlist_del(&mcast_entry->list);
247 kfree(mcast_entry);
248 }
249}
250
251/**
252 * batadv_mcast_mla_tt_retract - clean up multicast listener announcements
253 * @bat_priv: the bat priv with all the soft interface information
254 * @mcast_list: a list of addresses which should _not_ be removed
255 *
256 * Retracts the announcement of any multicast listener from the
257 * translation table except the ones listed in the given mcast_list.
258 *
259 * If mcast_list is NULL then all are retracted.
260 */
261static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
262 struct hlist_head *mcast_list)
263{
264 struct batadv_hw_addr *mcast_entry;
265 struct hlist_node *tmp;
266
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200267 lockdep_assert_held(&bat_priv->tt.commit_lock);
268
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100269 hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
270 list) {
271 if (mcast_list &&
272 batadv_mcast_mla_is_duplicate(mcast_entry->addr,
273 mcast_list))
274 continue;
275
276 batadv_tt_local_remove(bat_priv, mcast_entry->addr,
277 BATADV_NO_FLAGS,
278 "mcast TT outdated", false);
279
280 hlist_del(&mcast_entry->list);
281 kfree(mcast_entry);
282 }
283}
284
285/**
286 * batadv_mcast_mla_tt_add - add multicast listener announcements
287 * @bat_priv: the bat priv with all the soft interface information
288 * @mcast_list: a list of addresses which are going to get added
289 *
290 * Adds multicast listener announcements from the given mcast_list to the
291 * translation table if they have not been added yet.
292 */
293static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
294 struct hlist_head *mcast_list)
295{
296 struct batadv_hw_addr *mcast_entry;
297 struct hlist_node *tmp;
298
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200299 lockdep_assert_held(&bat_priv->tt.commit_lock);
300
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100301 if (!mcast_list)
302 return;
303
304 hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
305 if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
306 &bat_priv->mcast.mla_list))
307 continue;
308
309 if (!batadv_tt_local_add(bat_priv->soft_iface,
310 mcast_entry->addr, BATADV_NO_FLAGS,
311 BATADV_NULL_IFINDEX, BATADV_NO_MARK))
312 continue;
313
314 hlist_del(&mcast_entry->list);
315 hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
316 }
317}
318
319/**
320 * batadv_mcast_has_bridge - check whether the soft-iface is bridged
321 * @bat_priv: the bat priv with all the soft interface information
322 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200323 * Checks whether there is a bridge on top of our soft interface.
324 *
325 * Return: true if there is a bridge, false otherwise.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100326 */
327static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
328{
329 struct net_device *upper = bat_priv->soft_iface;
330
331 rcu_read_lock();
332 do {
333 upper = netdev_master_upper_dev_get_rcu(upper);
334 } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
335 rcu_read_unlock();
336
337 return upper;
338}
339
340/**
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200341 * batadv_mcast_querier_log - debug output regarding the querier status on link
342 * @bat_priv: the bat priv with all the soft interface information
343 * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")
344 * @old_state: the previous querier state on our link
345 * @new_state: the new querier state on our link
346 *
347 * Outputs debug messages to the logging facility with log level 'mcast'
348 * regarding changes to the querier status on the link which are relevant
349 * to our multicast optimizations.
350 *
351 * Usually this is about whether a querier appeared or vanished in
352 * our mesh or whether the querier is in the suboptimal position of being
353 * behind our local bridge segment: Snooping switches will directly
354 * forward listener reports to the querier, therefore batman-adv and
355 * the bridge will potentially not see these listeners - the querier is
356 * potentially shadowing listeners from us then.
357 *
358 * This is only interesting for nodes with a bridge on top of their
359 * soft interface.
360 */
361static void
362batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,
363 struct batadv_mcast_querier_state *old_state,
364 struct batadv_mcast_querier_state *new_state)
365{
366 if (!old_state->exists && new_state->exists)
367 batadv_info(bat_priv->soft_iface, "%s Querier appeared\n",
368 str_proto);
369 else if (old_state->exists && !new_state->exists)
370 batadv_info(bat_priv->soft_iface,
371 "%s Querier disappeared - multicast optimizations disabled\n",
372 str_proto);
373 else if (!bat_priv->mcast.bridged && !new_state->exists)
374 batadv_info(bat_priv->soft_iface,
375 "No %s Querier present - multicast optimizations disabled\n",
376 str_proto);
377
378 if (new_state->exists) {
379 if ((!old_state->shadowing && new_state->shadowing) ||
380 (!old_state->exists && new_state->shadowing))
381 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
382 "%s Querier is behind our bridged segment: Might shadow listeners\n",
383 str_proto);
384 else if (old_state->shadowing && !new_state->shadowing)
385 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
386 "%s Querier is not behind our bridged segment\n",
387 str_proto);
388 }
389}
390
391/**
392 * batadv_mcast_bridge_log - debug output for topology changes in bridged setups
393 * @bat_priv: the bat priv with all the soft interface information
394 * @bridged: a flag about whether the soft interface is currently bridged or not
395 * @querier_ipv4: (maybe) new status of a potential, selected IGMP querier
396 * @querier_ipv6: (maybe) new status of a potential, selected MLD querier
397 *
398 * If no bridges are ever used on this node, then this function does nothing.
399 *
400 * Otherwise this function outputs debug information to the 'mcast' log level
401 * which might be relevant to our multicast optimizations.
402 *
403 * More precisely, it outputs information when a bridge interface is added or
404 * removed from a soft interface. And when a bridge is present, it further
405 * outputs information about the querier state which is relevant for the
406 * multicast flags this node is going to set.
407 */
408static void
409batadv_mcast_bridge_log(struct batadv_priv *bat_priv, bool bridged,
410 struct batadv_mcast_querier_state *querier_ipv4,
411 struct batadv_mcast_querier_state *querier_ipv6)
412{
413 if (!bat_priv->mcast.bridged && bridged)
414 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
415 "Bridge added: Setting Unsnoopables(U)-flag\n");
416 else if (bat_priv->mcast.bridged && !bridged)
417 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
418 "Bridge removed: Unsetting Unsnoopables(U)-flag\n");
419
420 if (bridged) {
421 batadv_mcast_querier_log(bat_priv, "IGMP",
422 &bat_priv->mcast.querier_ipv4,
423 querier_ipv4);
424 batadv_mcast_querier_log(bat_priv, "MLD",
425 &bat_priv->mcast.querier_ipv6,
426 querier_ipv6);
427 }
428}
429
430/**
431 * batadv_mcast_flags_logs - output debug information about mcast flag changes
432 * @bat_priv: the bat priv with all the soft interface information
433 * @flags: flags indicating the new multicast state
434 *
435 * Whenever the multicast flags this nodes announces changes (@mcast_flags vs.
436 * bat_priv->mcast.flags), this notifies userspace via the 'mcast' log level.
437 */
438static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
439{
440 u8 old_flags = bat_priv->mcast.flags;
441 char str_old_flags[] = "[...]";
442
443 sprintf(str_old_flags, "[%c%c%c]",
444 (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
445 (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
446 (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
447
448 batadv_dbg(BATADV_DBG_MCAST, bat_priv,
449 "Changing multicast flags from '%s' to '[%c%c%c]'\n",
450 bat_priv->mcast.enabled ? str_old_flags : "<undefined>",
451 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
452 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
453 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
454}
455
456/**
Linus Lüssing60432d72014-02-15 17:47:51 +0100457 * batadv_mcast_mla_tvlv_update - update multicast tvlv
458 * @bat_priv: the bat priv with all the soft interface information
459 *
460 * Updates the own multicast tvlv with our current multicast related settings,
461 * capabilities and inabilities.
462 *
Linus Lüssing687937a2016-05-10 18:41:25 +0200463 * Return: false if we want all IPv4 && IPv6 multicast traffic and true
464 * otherwise.
Linus Lüssing60432d72014-02-15 17:47:51 +0100465 */
466static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
467{
468 struct batadv_tvlv_mcast_data mcast_data;
Linus Lüssing687937a2016-05-10 18:41:25 +0200469 struct batadv_mcast_querier_state querier4 = {false, false};
470 struct batadv_mcast_querier_state querier6 = {false, false};
471 struct net_device *dev = bat_priv->soft_iface;
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200472 bool bridged;
Linus Lüssing60432d72014-02-15 17:47:51 +0100473
474 mcast_data.flags = BATADV_NO_FLAGS;
475 memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
476
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200477 bridged = batadv_mcast_has_bridge(bat_priv);
478 if (!bridged)
Linus Lüssing687937a2016-05-10 18:41:25 +0200479 goto update;
480
481#if !IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
482 pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");
483#endif
484
485 querier4.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);
486 querier4.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);
487
488 querier6.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);
489 querier6.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);
490
491 mcast_data.flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
492
493 /* 1) If no querier exists at all, then multicast listeners on
494 * our local TT clients behind the bridge will keep silent.
495 * 2) If the selected querier is on one of our local TT clients,
496 * behind the bridge, then this querier might shadow multicast
497 * listeners on our local TT clients, behind this bridge.
498 *
499 * In both cases, we will signalize other batman nodes that
500 * we need all multicast traffic of the according protocol.
Linus Lüssing60432d72014-02-15 17:47:51 +0100501 */
Linus Lüssing687937a2016-05-10 18:41:25 +0200502 if (!querier4.exists || querier4.shadowing)
503 mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV4;
Linus Lüssing60432d72014-02-15 17:47:51 +0100504
Linus Lüssing687937a2016-05-10 18:41:25 +0200505 if (!querier6.exists || querier6.shadowing)
506 mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV6;
Linus Lüssing60432d72014-02-15 17:47:51 +0100507
Linus Lüssing687937a2016-05-10 18:41:25 +0200508update:
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200509 batadv_mcast_bridge_log(bat_priv, bridged, &querier4, &querier6);
510
511 bat_priv->mcast.querier_ipv4.exists = querier4.exists;
512 bat_priv->mcast.querier_ipv4.shadowing = querier4.shadowing;
513
514 bat_priv->mcast.querier_ipv6.exists = querier6.exists;
515 bat_priv->mcast.querier_ipv6.shadowing = querier6.shadowing;
516
517 bat_priv->mcast.bridged = bridged;
518
Linus Lüssing60432d72014-02-15 17:47:51 +0100519 if (!bat_priv->mcast.enabled ||
520 mcast_data.flags != bat_priv->mcast.flags) {
Linus Lüssing72f7b2d2016-05-10 18:41:26 +0200521 batadv_mcast_flags_log(bat_priv, mcast_data.flags);
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200522 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,
Linus Lüssing60432d72014-02-15 17:47:51 +0100523 &mcast_data, sizeof(mcast_data));
524 bat_priv->mcast.flags = mcast_data.flags;
525 bat_priv->mcast.enabled = true;
526 }
527
Linus Lüssing687937a2016-05-10 18:41:25 +0200528 return !(mcast_data.flags &
529 (BATADV_MCAST_WANT_ALL_IPV4 + BATADV_MCAST_WANT_ALL_IPV6));
Linus Lüssing60432d72014-02-15 17:47:51 +0100530}
531
532/**
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100533 * batadv_mcast_mla_update - update the own MLAs
534 * @bat_priv: the bat priv with all the soft interface information
535 *
Linus Lüssing60432d72014-02-15 17:47:51 +0100536 * Updates the own multicast listener announcements in the translation
537 * table as well as the own, announced multicast tvlv container.
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100538 */
539void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
540{
541 struct net_device *soft_iface = bat_priv->soft_iface;
542 struct hlist_head mcast_list = HLIST_HEAD_INIT;
543 int ret;
544
Linus Lüssing60432d72014-02-15 17:47:51 +0100545 if (!batadv_mcast_mla_tvlv_update(bat_priv))
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100546 goto update;
547
548 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
549 if (ret < 0)
550 goto out;
551
Linus Lüssing687937a2016-05-10 18:41:25 +0200552 ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
553 if (ret < 0)
554 goto out;
555
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100556update:
557 batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
558 batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
559
560out:
Sven Eckelmann2c72d652015-06-21 14:45:14 +0200561 batadv_mcast_mla_list_free(bat_priv, &mcast_list);
Linus Lüssingc5caf4e2014-02-15 17:47:49 +0100562}
563
564/**
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200565 * batadv_mcast_is_report_ipv4 - check for IGMP reports
566 * @skb: the ethernet frame destined for the mesh
567 *
568 * This call might reallocate skb data.
569 *
570 * Checks whether the given frame is a valid IGMP report.
571 *
572 * Return: If so then true, otherwise false.
573 */
574static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)
575{
576 if (ip_mc_check_igmp(skb, NULL) < 0)
577 return false;
578
579 switch (igmp_hdr(skb)->type) {
580 case IGMP_HOST_MEMBERSHIP_REPORT:
581 case IGMPV2_HOST_MEMBERSHIP_REPORT:
582 case IGMPV3_HOST_MEMBERSHIP_REPORT:
583 return true;
584 }
585
586 return false;
587}
588
589/**
Linus Lüssingab498862014-02-15 17:47:53 +0100590 * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential
591 * @bat_priv: the bat priv with all the soft interface information
592 * @skb: the IPv4 packet to check
593 * @is_unsnoopable: stores whether the destination is snoopable
594 *
595 * Checks whether the given IPv4 packet has the potential to be forwarded with a
596 * mode more optimal than classic flooding.
597 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200598 * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory
599 * allocation failure.
Linus Lüssingab498862014-02-15 17:47:53 +0100600 */
601static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
602 struct sk_buff *skb,
603 bool *is_unsnoopable)
604{
605 struct iphdr *iphdr;
606
607 /* We might fail due to out-of-memory -> drop it */
608 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
609 return -ENOMEM;
610
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200611 if (batadv_mcast_is_report_ipv4(skb))
612 return -EINVAL;
613
Linus Lüssingab498862014-02-15 17:47:53 +0100614 iphdr = ip_hdr(skb);
615
616 /* TODO: Implement Multicast Router Discovery (RFC4286),
617 * then allow scope > link local, too
618 */
619 if (!ipv4_is_local_multicast(iphdr->daddr))
620 return -EINVAL;
621
622 /* link-local multicast listeners behind a bridge are
623 * not snoopable (see RFC4541, section 2.1.2.2)
624 */
625 *is_unsnoopable = true;
626
627 return 0;
628}
629
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200630#if IS_ENABLED(CONFIG_IPV6)
631/**
632 * batadv_mcast_is_report_ipv6 - check for MLD reports
633 * @skb: the ethernet frame destined for the mesh
634 *
635 * This call might reallocate skb data.
636 *
637 * Checks whether the given frame is a valid MLD report.
638 *
639 * Return: If so then true, otherwise false.
640 */
641static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)
642{
643 if (ipv6_mc_check_mld(skb, NULL) < 0)
644 return false;
645
646 switch (icmp6_hdr(skb)->icmp6_type) {
647 case ICMPV6_MGM_REPORT:
648 case ICMPV6_MLD2_REPORT:
649 return true;
650 }
651
652 return false;
653}
654
Linus Lüssingab498862014-02-15 17:47:53 +0100655/**
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100656 * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
657 * @bat_priv: the bat priv with all the soft interface information
658 * @skb: the IPv6 packet to check
Linus Lüssingab498862014-02-15 17:47:53 +0100659 * @is_unsnoopable: stores whether the destination is snoopable
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100660 *
661 * Checks whether the given IPv6 packet has the potential to be forwarded with a
662 * mode more optimal than classic flooding.
663 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200664 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100665 */
666static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
Linus Lüssingab498862014-02-15 17:47:53 +0100667 struct sk_buff *skb,
668 bool *is_unsnoopable)
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100669{
670 struct ipv6hdr *ip6hdr;
671
672 /* We might fail due to out-of-memory -> drop it */
673 if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
674 return -ENOMEM;
675
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200676 if (batadv_mcast_is_report_ipv6(skb))
677 return -EINVAL;
678
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100679 ip6hdr = ipv6_hdr(skb);
680
681 /* TODO: Implement Multicast Router Discovery (RFC4286),
682 * then allow scope > link local, too
683 */
684 if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) != IPV6_ADDR_SCOPE_LINKLOCAL)
685 return -EINVAL;
686
687 /* link-local-all-nodes multicast listeners behind a bridge are
688 * not snoopable (see RFC4541, section 3, paragraph 3)
689 */
690 if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
Linus Lüssingab498862014-02-15 17:47:53 +0100691 *is_unsnoopable = true;
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100692
693 return 0;
694}
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200695#endif
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100696
697/**
698 * batadv_mcast_forw_mode_check - check for optimized forwarding potential
699 * @bat_priv: the bat priv with all the soft interface information
700 * @skb: the multicast frame to check
Linus Lüssingab498862014-02-15 17:47:53 +0100701 * @is_unsnoopable: stores whether the destination is snoopable
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100702 *
703 * Checks whether the given multicast ethernet frame has the potential to be
704 * forwarded with a mode more optimal than classic flooding.
705 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200706 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100707 */
708static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
Linus Lüssingab498862014-02-15 17:47:53 +0100709 struct sk_buff *skb,
710 bool *is_unsnoopable)
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100711{
712 struct ethhdr *ethhdr = eth_hdr(skb);
713
714 if (!atomic_read(&bat_priv->multicast_mode))
715 return -EINVAL;
716
717 if (atomic_read(&bat_priv->mcast.num_disabled))
718 return -EINVAL;
719
720 switch (ntohs(ethhdr->h_proto)) {
Linus Lüssingab498862014-02-15 17:47:53 +0100721 case ETH_P_IP:
722 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
723 is_unsnoopable);
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200724#if IS_ENABLED(CONFIG_IPV6)
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100725 case ETH_P_IPV6:
Linus Lüssingab498862014-02-15 17:47:53 +0100726 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
727 is_unsnoopable);
Linus Lüssingbd2a9792016-05-10 18:41:24 +0200728#endif
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100729 default:
730 return -EINVAL;
731 }
732}
733
734/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100735 * batadv_mcast_forw_want_all_ip_count - count nodes with unspecific mcast
736 * interest
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100737 * @bat_priv: the bat priv with all the soft interface information
738 * @ethhdr: ethernet header of a packet
739 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200740 * Return: the number of nodes which want all IPv4 multicast traffic if the
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100741 * given ethhdr is from an IPv4 packet or the number of nodes which want all
742 * IPv6 traffic if it matches an IPv6 packet.
743 */
744static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,
745 struct ethhdr *ethhdr)
746{
747 switch (ntohs(ethhdr->h_proto)) {
748 case ETH_P_IP:
749 return atomic_read(&bat_priv->mcast.num_want_all_ipv4);
750 case ETH_P_IPV6:
751 return atomic_read(&bat_priv->mcast.num_want_all_ipv6);
752 default:
753 /* we shouldn't be here... */
754 return 0;
755 }
756}
757
758/**
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100759 * batadv_mcast_forw_tt_node_get - get a multicast tt node
760 * @bat_priv: the bat priv with all the soft interface information
761 * @ethhdr: the ether header containing the multicast destination
762 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200763 * Return: an orig_node matching the multicast address provided by ethhdr
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100764 * via a translation table lookup. This increases the returned nodes refcount.
765 */
766static struct batadv_orig_node *
767batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
768 struct ethhdr *ethhdr)
769{
770 return batadv_transtable_search(bat_priv, ethhdr->h_source,
771 ethhdr->h_dest, BATADV_NO_FLAGS);
772}
773
774/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100775 * batadv_mcast_forw_ipv4_node_get - get a node with an ipv4 flag
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100776 * @bat_priv: the bat priv with all the soft interface information
777 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200778 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100779 * increases its refcount.
780 */
781static struct batadv_orig_node *
782batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
783{
784 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
785
786 rcu_read_lock();
787 hlist_for_each_entry_rcu(tmp_orig_node,
788 &bat_priv->mcast.want_all_ipv4_list,
789 mcast_want_all_ipv4_node) {
Sven Eckelmann7c124392016-01-16 10:29:56 +0100790 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100791 continue;
792
793 orig_node = tmp_orig_node;
794 break;
795 }
796 rcu_read_unlock();
797
798 return orig_node;
799}
800
801/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100802 * batadv_mcast_forw_ipv6_node_get - get a node with an ipv6 flag
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100803 * @bat_priv: the bat priv with all the soft interface information
804 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200805 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100806 * and increases its refcount.
807 */
808static struct batadv_orig_node *
809batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
810{
811 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
812
813 rcu_read_lock();
814 hlist_for_each_entry_rcu(tmp_orig_node,
815 &bat_priv->mcast.want_all_ipv6_list,
816 mcast_want_all_ipv6_node) {
Sven Eckelmann7c124392016-01-16 10:29:56 +0100817 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100818 continue;
819
820 orig_node = tmp_orig_node;
821 break;
822 }
823 rcu_read_unlock();
824
825 return orig_node;
826}
827
828/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100829 * batadv_mcast_forw_ip_node_get - get a node with an ipv4/ipv6 flag
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100830 * @bat_priv: the bat priv with all the soft interface information
831 * @ethhdr: an ethernet header to determine the protocol family from
832 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200833 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100834 * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and
835 * increases its refcount.
836 */
837static struct batadv_orig_node *
838batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
839 struct ethhdr *ethhdr)
840{
841 switch (ntohs(ethhdr->h_proto)) {
842 case ETH_P_IP:
843 return batadv_mcast_forw_ipv4_node_get(bat_priv);
844 case ETH_P_IPV6:
845 return batadv_mcast_forw_ipv6_node_get(bat_priv);
846 default:
847 /* we shouldn't be here... */
848 return NULL;
849 }
850}
851
852/**
Antonio Quartulli6d030de2016-03-11 16:36:19 +0100853 * batadv_mcast_forw_unsnoop_node_get - get a node with an unsnoopable flag
Linus Lüssingab498862014-02-15 17:47:53 +0100854 * @bat_priv: the bat priv with all the soft interface information
855 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200856 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
Linus Lüssingab498862014-02-15 17:47:53 +0100857 * set and increases its refcount.
858 */
859static struct batadv_orig_node *
860batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
861{
862 struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
863
864 rcu_read_lock();
865 hlist_for_each_entry_rcu(tmp_orig_node,
866 &bat_priv->mcast.want_all_unsnoopables_list,
867 mcast_want_all_unsnoopables_node) {
Sven Eckelmann7c124392016-01-16 10:29:56 +0100868 if (!kref_get_unless_zero(&tmp_orig_node->refcount))
Linus Lüssingab498862014-02-15 17:47:53 +0100869 continue;
870
871 orig_node = tmp_orig_node;
872 break;
873 }
874 rcu_read_unlock();
875
876 return orig_node;
877}
878
879/**
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100880 * batadv_mcast_forw_mode - check on how to forward a multicast packet
881 * @bat_priv: the bat priv with all the soft interface information
882 * @skb: The multicast packet to check
883 * @orig: an originator to be set to forward the skb to
884 *
Sven Eckelmann62fe7102015-09-15 19:00:48 +0200885 * Return: the forwarding mode as enum batadv_forw_mode and in case of
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100886 * BATADV_FORW_SINGLE set the orig to the single originator the skb
887 * should be forwarded to.
888 */
889enum batadv_forw_mode
890batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
891 struct batadv_orig_node **orig)
892{
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100893 int ret, tt_count, ip_count, unsnoop_count, total_count;
Linus Lüssingab498862014-02-15 17:47:53 +0100894 bool is_unsnoopable = false;
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100895 struct ethhdr *ethhdr;
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100896
Linus Lüssingab498862014-02-15 17:47:53 +0100897 ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable);
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100898 if (ret == -ENOMEM)
899 return BATADV_FORW_NONE;
900 else if (ret < 0)
901 return BATADV_FORW_ALL;
902
903 ethhdr = eth_hdr(skb);
904
905 tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
906 BATADV_NO_FLAGS);
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100907 ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
Linus Lüssingab498862014-02-15 17:47:53 +0100908 unsnoop_count = !is_unsnoopable ? 0 :
909 atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100910
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100911 total_count = tt_count + ip_count + unsnoop_count;
Linus Lüssingab498862014-02-15 17:47:53 +0100912
913 switch (total_count) {
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100914 case 1:
Linus Lüssingab498862014-02-15 17:47:53 +0100915 if (tt_count)
916 *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100917 else if (ip_count)
918 *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
Linus Lüssingab498862014-02-15 17:47:53 +0100919 else if (unsnoop_count)
920 *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
921
Linus Lüssing1d8ab8d2014-02-15 17:47:52 +0100922 if (*orig)
923 return BATADV_FORW_SINGLE;
924
925 /* fall through */
926 case 0:
927 return BATADV_FORW_NONE;
928 default:
929 return BATADV_FORW_ALL;
930 }
931}
932
933/**
Linus Lüssingab498862014-02-15 17:47:53 +0100934 * batadv_mcast_want_unsnoop_update - update unsnoop counter and list
935 * @bat_priv: the bat priv with all the soft interface information
936 * @orig: the orig_node which multicast state might have changed of
937 * @mcast_flags: flags indicating the new multicast state
938 *
939 * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
940 * orig, has toggled then this method updates counter and list accordingly.
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200941 *
942 * Caller needs to hold orig->mcast_handler_lock.
Linus Lüssingab498862014-02-15 17:47:53 +0100943 */
944static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
945 struct batadv_orig_node *orig,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200946 u8 mcast_flags)
Linus Lüssingab498862014-02-15 17:47:53 +0100947{
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200948 struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
949 struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
950
Sven Eckelmann5274cd62015-06-21 14:45:15 +0200951 lockdep_assert_held(&orig->mcast_handler_lock);
952
Linus Lüssingab498862014-02-15 17:47:53 +0100953 /* switched from flag unset to set */
954 if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
955 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
956 atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
957
958 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200959 /* flag checks above + mcast_handler_lock prevents this */
960 WARN_ON(!hlist_unhashed(node));
961
962 hlist_add_head_rcu(node, head);
Linus Lüssingab498862014-02-15 17:47:53 +0100963 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
964 /* switched from flag set to unset */
965 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
966 orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {
967 atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
968
969 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200970 /* flag checks above + mcast_handler_lock prevents this */
971 WARN_ON(hlist_unhashed(node));
972
973 hlist_del_init_rcu(node);
Linus Lüssingab498862014-02-15 17:47:53 +0100974 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
975 }
976}
977
978/**
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100979 * batadv_mcast_want_ipv4_update - update want-all-ipv4 counter and list
980 * @bat_priv: the bat priv with all the soft interface information
981 * @orig: the orig_node which multicast state might have changed of
982 * @mcast_flags: flags indicating the new multicast state
983 *
984 * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
985 * toggled then this method updates counter and list accordingly.
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200986 *
987 * Caller needs to hold orig->mcast_handler_lock.
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100988 */
989static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
990 struct batadv_orig_node *orig,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +0200991 u8 mcast_flags)
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100992{
Linus Lüssing8a4023c2015-06-16 17:10:26 +0200993 struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
994 struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
995
Sven Eckelmann5274cd62015-06-21 14:45:15 +0200996 lockdep_assert_held(&orig->mcast_handler_lock);
997
Linus Lüssing4c8755d2014-02-15 17:47:54 +0100998 /* switched from flag unset to set */
999 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
1000 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
1001 atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
1002
1003 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001004 /* flag checks above + mcast_handler_lock prevents this */
1005 WARN_ON(!hlist_unhashed(node));
1006
1007 hlist_add_head_rcu(node, head);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001008 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1009 /* switched from flag set to unset */
1010 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
1011 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {
1012 atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
1013
1014 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001015 /* flag checks above + mcast_handler_lock prevents this */
1016 WARN_ON(hlist_unhashed(node));
1017
1018 hlist_del_init_rcu(node);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001019 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1020 }
1021}
1022
1023/**
1024 * batadv_mcast_want_ipv6_update - update want-all-ipv6 counter and list
1025 * @bat_priv: the bat priv with all the soft interface information
1026 * @orig: the orig_node which multicast state might have changed of
1027 * @mcast_flags: flags indicating the new multicast state
1028 *
1029 * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
1030 * toggled then this method updates counter and list accordingly.
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001031 *
1032 * Caller needs to hold orig->mcast_handler_lock.
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001033 */
1034static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
1035 struct batadv_orig_node *orig,
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001036 u8 mcast_flags)
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001037{
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001038 struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
1039 struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
1040
Sven Eckelmann5274cd62015-06-21 14:45:15 +02001041 lockdep_assert_held(&orig->mcast_handler_lock);
1042
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001043 /* switched from flag unset to set */
1044 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
1045 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
1046 atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
1047
1048 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001049 /* flag checks above + mcast_handler_lock prevents this */
1050 WARN_ON(!hlist_unhashed(node));
1051
1052 hlist_add_head_rcu(node, head);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001053 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1054 /* switched from flag set to unset */
1055 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
1056 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {
1057 atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
1058
1059 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001060 /* flag checks above + mcast_handler_lock prevents this */
1061 WARN_ON(hlist_unhashed(node));
1062
1063 hlist_del_init_rcu(node);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001064 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1065 }
1066}
1067
1068/**
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001069 * batadv_mcast_tvlv_ogm_handler - process incoming multicast tvlv container
Linus Lüssing60432d72014-02-15 17:47:51 +01001070 * @bat_priv: the bat priv with all the soft interface information
1071 * @orig: the orig_node of the ogm
1072 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
1073 * @tvlv_value: tvlv buffer containing the multicast data
1074 * @tvlv_value_len: tvlv buffer length
1075 */
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001076static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
1077 struct batadv_orig_node *orig,
1078 u8 flags,
1079 void *tvlv_value,
1080 u16 tvlv_value_len)
Linus Lüssing60432d72014-02-15 17:47:51 +01001081{
1082 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001083 u8 mcast_flags = BATADV_NO_FLAGS;
Linus Lüssing60432d72014-02-15 17:47:51 +01001084 bool orig_initialized;
1085
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001086 if (orig_mcast_enabled && tvlv_value &&
1087 (tvlv_value_len >= sizeof(mcast_flags)))
Sven Eckelmann6b5e9712015-05-26 18:34:26 +02001088 mcast_flags = *(u8 *)tvlv_value;
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001089
1090 spin_lock_bh(&orig->mcast_handler_lock);
Linus Lüssing9c936e32015-06-16 17:10:25 +02001091 orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1092 &orig->capa_initialized);
Linus Lüssing60432d72014-02-15 17:47:51 +01001093
1094 /* If mcast support is turned on decrease the disabled mcast node
1095 * counter only if we had increased it for this node before. If this
1096 * is a completely new orig_node no need to decrease the counter.
1097 */
1098 if (orig_mcast_enabled &&
Linus Lüssing9c936e32015-06-16 17:10:25 +02001099 !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
Linus Lüssing60432d72014-02-15 17:47:51 +01001100 if (orig_initialized)
1101 atomic_dec(&bat_priv->mcast.num_disabled);
Linus Lüssing9c936e32015-06-16 17:10:25 +02001102 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
Linus Lüssinge8829f02014-10-30 05:40:46 +01001103 /* If mcast support is being switched off or if this is an initial
1104 * OGM without mcast support then increase the disabled mcast
1105 * node counter.
Linus Lüssing60432d72014-02-15 17:47:51 +01001106 */
1107 } else if (!orig_mcast_enabled &&
Linus Lüssing9c936e32015-06-16 17:10:25 +02001108 (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) ||
Linus Lüssinge8829f02014-10-30 05:40:46 +01001109 !orig_initialized)) {
Linus Lüssing60432d72014-02-15 17:47:51 +01001110 atomic_inc(&bat_priv->mcast.num_disabled);
Linus Lüssing9c936e32015-06-16 17:10:25 +02001111 clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
Linus Lüssing60432d72014-02-15 17:47:51 +01001112 }
1113
Linus Lüssing9c936e32015-06-16 17:10:25 +02001114 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
Linus Lüssing60432d72014-02-15 17:47:51 +01001115
Linus Lüssingab498862014-02-15 17:47:53 +01001116 batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
Linus Lüssing4c8755d2014-02-15 17:47:54 +01001117 batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
1118 batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
Linus Lüssingab498862014-02-15 17:47:53 +01001119
Linus Lüssing60432d72014-02-15 17:47:51 +01001120 orig->mcast_flags = mcast_flags;
Linus Lüssing8a4023c2015-06-16 17:10:26 +02001121 spin_unlock_bh(&orig->mcast_handler_lock);
Linus Lüssing60432d72014-02-15 17:47:51 +01001122}
1123
1124/**
1125 * batadv_mcast_init - initialize the multicast optimizations structures
1126 * @bat_priv: the bat priv with all the soft interface information
1127 */
1128void batadv_mcast_init(struct batadv_priv *bat_priv)
1129{
Linus Lüssingbd2a9792016-05-10 18:41:24 +02001130 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
1131 NULL, BATADV_TVLV_MCAST, 2,
Linus Lüssing60432d72014-02-15 17:47:51 +01001132 BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
1133}
1134
1135/**
Linus Lüssing4e3e8232016-05-10 18:41:27 +02001136 * batadv_mcast_flags_print_header - print own mcast flags to debugfs table
1137 * @bat_priv: the bat priv with all the soft interface information
1138 * @seq: debugfs table seq_file struct
1139 *
1140 * Prints our own multicast flags including a more specific reason why
1141 * they are set, that is prints the bridge and querier state too, to
1142 * the debugfs table specified via @seq.
1143 */
1144static void batadv_mcast_flags_print_header(struct batadv_priv *bat_priv,
1145 struct seq_file *seq)
1146{
1147 u8 flags = bat_priv->mcast.flags;
1148 char querier4, querier6, shadowing4, shadowing6;
1149 bool bridged = bat_priv->mcast.bridged;
1150
1151 if (bridged) {
1152 querier4 = bat_priv->mcast.querier_ipv4.exists ? '.' : '4';
1153 querier6 = bat_priv->mcast.querier_ipv6.exists ? '.' : '6';
1154 shadowing4 = bat_priv->mcast.querier_ipv4.shadowing ? '4' : '.';
1155 shadowing6 = bat_priv->mcast.querier_ipv6.shadowing ? '6' : '.';
1156 } else {
1157 querier4 = '?';
1158 querier6 = '?';
1159 shadowing4 = '?';
1160 shadowing6 = '?';
1161 }
1162
1163 seq_printf(seq, "Multicast flags (own flags: [%c%c%c])\n",
1164 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
1165 (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
1166 (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
1167 seq_printf(seq, "* Bridged [U]\t\t\t\t%c\n", bridged ? 'U' : '.');
1168 seq_printf(seq, "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n",
1169 querier4, querier6);
1170 seq_printf(seq, "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n",
1171 shadowing4, shadowing6);
1172 seq_puts(seq, "-------------------------------------------\n");
1173 seq_printf(seq, " %-10s %s\n", "Originator", "Flags");
1174}
1175
1176/**
1177 * batadv_mcast_flags_seq_print_text - print the mcast flags of other nodes
1178 * @seq: seq file to print on
1179 * @offset: not used
1180 *
1181 * This prints a table of (primary) originators and their according
1182 * multicast flags, including (in the header) our own.
1183 *
1184 * Return: always 0
1185 */
1186int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
1187{
1188 struct net_device *net_dev = (struct net_device *)seq->private;
1189 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1190 struct batadv_hard_iface *primary_if;
1191 struct batadv_hashtable *hash = bat_priv->orig_hash;
1192 struct batadv_orig_node *orig_node;
1193 struct hlist_head *head;
1194 u8 flags;
1195 u32 i;
1196
1197 primary_if = batadv_seq_print_text_primary_if_get(seq);
1198 if (!primary_if)
1199 return 0;
1200
1201 batadv_mcast_flags_print_header(bat_priv, seq);
1202
1203 for (i = 0; i < hash->size; i++) {
1204 head = &hash->table[i];
1205
1206 rcu_read_lock();
1207 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1208 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1209 &orig_node->capa_initialized))
1210 continue;
1211
1212 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1213 &orig_node->capabilities)) {
1214 seq_printf(seq, "%pM -\n", orig_node->orig);
1215 continue;
1216 }
1217
1218 flags = orig_node->mcast_flags;
1219
1220 seq_printf(seq, "%pM [%c%c%c]\n", orig_node->orig,
1221 (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)
1222 ? 'U' : '.',
1223 (flags & BATADV_MCAST_WANT_ALL_IPV4)
1224 ? '4' : '.',
1225 (flags & BATADV_MCAST_WANT_ALL_IPV6)
1226 ? '6' : '.');
1227 }
1228 rcu_read_unlock();
1229 }
1230
1231 batadv_hardif_put(primary_if);
1232
1233 return 0;
1234}
1235
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}