batman-adv: Make MCAST capability changes atomic
[cascardo/linux.git] / net / batman-adv / multicast.c
1 /* Copyright (C) 2014-2015 B.A.T.M.A.N. contributors:
2  *
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
18 #include "multicast.h"
19 #include "main.h"
20
21 #include <linux/atomic.h>
22 #include <linux/bitops.h>
23 #include <linux/byteorder/generic.h>
24 #include <linux/errno.h>
25 #include <linux/etherdevice.h>
26 #include <linux/fs.h>
27 #include <linux/if_ether.h>
28 #include <linux/in6.h>
29 #include <linux/in.h>
30 #include <linux/ip.h>
31 #include <linux/ipv6.h>
32 #include <linux/list.h>
33 #include <linux/netdevice.h>
34 #include <linux/rculist.h>
35 #include <linux/rcupdate.h>
36 #include <linux/skbuff.h>
37 #include <linux/slab.h>
38 #include <linux/spinlock.h>
39 #include <linux/stddef.h>
40 #include <linux/string.h>
41 #include <linux/types.h>
42 #include <net/addrconf.h>
43 #include <net/ipv6.h>
44
45 #include "packet.h"
46 #include "translation-table.h"
47
48 /**
49  * batadv_mcast_mla_softif_get - get softif multicast listeners
50  * @dev: the device to collect multicast addresses from
51  * @mcast_list: a list to put found addresses into
52  *
53  * Collect multicast addresses of the local multicast listeners
54  * on the given soft interface, dev, in the given mcast_list.
55  *
56  * Returns -ENOMEM on memory allocation error or the number of
57  * items added to the mcast_list otherwise.
58  */
59 static int batadv_mcast_mla_softif_get(struct net_device *dev,
60                                        struct hlist_head *mcast_list)
61 {
62         struct netdev_hw_addr *mc_list_entry;
63         struct batadv_hw_addr *new;
64         int ret = 0;
65
66         netif_addr_lock_bh(dev);
67         netdev_for_each_mc_addr(mc_list_entry, dev) {
68                 new = kmalloc(sizeof(*new), GFP_ATOMIC);
69                 if (!new) {
70                         ret = -ENOMEM;
71                         break;
72                 }
73
74                 ether_addr_copy(new->addr, mc_list_entry->addr);
75                 hlist_add_head(&new->list, mcast_list);
76                 ret++;
77         }
78         netif_addr_unlock_bh(dev);
79
80         return ret;
81 }
82
83 /**
84  * batadv_mcast_mla_is_duplicate - check whether an address is in a list
85  * @mcast_addr: the multicast address to check
86  * @mcast_list: the list with multicast addresses to search in
87  *
88  * Returns true if the given address is already in the given list.
89  * Otherwise returns false.
90  */
91 static bool batadv_mcast_mla_is_duplicate(uint8_t *mcast_addr,
92                                           struct hlist_head *mcast_list)
93 {
94         struct batadv_hw_addr *mcast_entry;
95
96         hlist_for_each_entry(mcast_entry, mcast_list, list)
97                 if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
98                         return true;
99
100         return false;
101 }
102
103 /**
104  * batadv_mcast_mla_list_free - free a list of multicast addresses
105  * @mcast_list: the list to free
106  *
107  * Removes and frees all items in the given mcast_list.
108  */
109 static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
110 {
111         struct batadv_hw_addr *mcast_entry;
112         struct hlist_node *tmp;
113
114         hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
115                 hlist_del(&mcast_entry->list);
116                 kfree(mcast_entry);
117         }
118 }
119
120 /**
121  * batadv_mcast_mla_tt_retract - clean up multicast listener announcements
122  * @bat_priv: the bat priv with all the soft interface information
123  * @mcast_list: a list of addresses which should _not_ be removed
124  *
125  * Retracts the announcement of any multicast listener from the
126  * translation table except the ones listed in the given mcast_list.
127  *
128  * If mcast_list is NULL then all are retracted.
129  */
130 static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
131                                         struct hlist_head *mcast_list)
132 {
133         struct batadv_hw_addr *mcast_entry;
134         struct hlist_node *tmp;
135
136         hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
137                                   list) {
138                 if (mcast_list &&
139                     batadv_mcast_mla_is_duplicate(mcast_entry->addr,
140                                                   mcast_list))
141                         continue;
142
143                 batadv_tt_local_remove(bat_priv, mcast_entry->addr,
144                                        BATADV_NO_FLAGS,
145                                        "mcast TT outdated", false);
146
147                 hlist_del(&mcast_entry->list);
148                 kfree(mcast_entry);
149         }
150 }
151
152 /**
153  * batadv_mcast_mla_tt_add - add multicast listener announcements
154  * @bat_priv: the bat priv with all the soft interface information
155  * @mcast_list: a list of addresses which are going to get added
156  *
157  * Adds multicast listener announcements from the given mcast_list to the
158  * translation table if they have not been added yet.
159  */
160 static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
161                                     struct hlist_head *mcast_list)
162 {
163         struct batadv_hw_addr *mcast_entry;
164         struct hlist_node *tmp;
165
166         if (!mcast_list)
167                 return;
168
169         hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
170                 if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
171                                                   &bat_priv->mcast.mla_list))
172                         continue;
173
174                 if (!batadv_tt_local_add(bat_priv->soft_iface,
175                                          mcast_entry->addr, BATADV_NO_FLAGS,
176                                          BATADV_NULL_IFINDEX, BATADV_NO_MARK))
177                         continue;
178
179                 hlist_del(&mcast_entry->list);
180                 hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
181         }
182 }
183
184 /**
185  * batadv_mcast_has_bridge - check whether the soft-iface is bridged
186  * @bat_priv: the bat priv with all the soft interface information
187  *
188  * Checks whether there is a bridge on top of our soft interface. Returns
189  * true if so, false otherwise.
190  */
191 static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
192 {
193         struct net_device *upper = bat_priv->soft_iface;
194
195         rcu_read_lock();
196         do {
197                 upper = netdev_master_upper_dev_get_rcu(upper);
198         } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
199         rcu_read_unlock();
200
201         return upper;
202 }
203
204 /**
205  * batadv_mcast_mla_tvlv_update - update multicast tvlv
206  * @bat_priv: the bat priv with all the soft interface information
207  *
208  * Updates the own multicast tvlv with our current multicast related settings,
209  * capabilities and inabilities.
210  *
211  * Returns true if the tvlv container is registered afterwards. Otherwise
212  * returns false.
213  */
214 static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
215 {
216         struct batadv_tvlv_mcast_data mcast_data;
217
218         mcast_data.flags = BATADV_NO_FLAGS;
219         memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
220
221         /* Avoid attaching MLAs, if there is a bridge on top of our soft
222          * interface, we don't support that yet (TODO)
223          */
224         if (batadv_mcast_has_bridge(bat_priv)) {
225                 if (bat_priv->mcast.enabled) {
226                         batadv_tvlv_container_unregister(bat_priv,
227                                                          BATADV_TVLV_MCAST, 1);
228                         bat_priv->mcast.enabled = false;
229                 }
230
231                 return false;
232         }
233
234         if (!bat_priv->mcast.enabled ||
235             mcast_data.flags != bat_priv->mcast.flags) {
236                 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 1,
237                                                &mcast_data, sizeof(mcast_data));
238                 bat_priv->mcast.flags = mcast_data.flags;
239                 bat_priv->mcast.enabled = true;
240         }
241
242         return true;
243 }
244
245 /**
246  * batadv_mcast_mla_update - update the own MLAs
247  * @bat_priv: the bat priv with all the soft interface information
248  *
249  * Updates the own multicast listener announcements in the translation
250  * table as well as the own, announced multicast tvlv container.
251  */
252 void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
253 {
254         struct net_device *soft_iface = bat_priv->soft_iface;
255         struct hlist_head mcast_list = HLIST_HEAD_INIT;
256         int ret;
257
258         if (!batadv_mcast_mla_tvlv_update(bat_priv))
259                 goto update;
260
261         ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
262         if (ret < 0)
263                 goto out;
264
265 update:
266         batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
267         batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
268
269 out:
270         batadv_mcast_mla_list_free(&mcast_list);
271 }
272
273 /**
274  * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential
275  * @bat_priv: the bat priv with all the soft interface information
276  * @skb: the IPv4 packet to check
277  * @is_unsnoopable: stores whether the destination is snoopable
278  *
279  * Checks whether the given IPv4 packet has the potential to be forwarded with a
280  * mode more optimal than classic flooding.
281  *
282  * If so then returns 0. Otherwise -EINVAL is returned or -ENOMEM in case of
283  * memory allocation failure.
284  */
285 static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
286                                              struct sk_buff *skb,
287                                              bool *is_unsnoopable)
288 {
289         struct iphdr *iphdr;
290
291         /* We might fail due to out-of-memory -> drop it */
292         if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
293                 return -ENOMEM;
294
295         iphdr = ip_hdr(skb);
296
297         /* TODO: Implement Multicast Router Discovery (RFC4286),
298          * then allow scope > link local, too
299          */
300         if (!ipv4_is_local_multicast(iphdr->daddr))
301                 return -EINVAL;
302
303         /* link-local multicast listeners behind a bridge are
304          * not snoopable (see RFC4541, section 2.1.2.2)
305          */
306         *is_unsnoopable = true;
307
308         return 0;
309 }
310
311 /**
312  * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
313  * @bat_priv: the bat priv with all the soft interface information
314  * @skb: the IPv6 packet to check
315  * @is_unsnoopable: stores whether the destination is snoopable
316  *
317  * Checks whether the given IPv6 packet has the potential to be forwarded with a
318  * mode more optimal than classic flooding.
319  *
320  * If so then returns 0. Otherwise -EINVAL is returned or -ENOMEM if we are out
321  * of memory.
322  */
323 static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
324                                              struct sk_buff *skb,
325                                              bool *is_unsnoopable)
326 {
327         struct ipv6hdr *ip6hdr;
328
329         /* We might fail due to out-of-memory -> drop it */
330         if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
331                 return -ENOMEM;
332
333         ip6hdr = ipv6_hdr(skb);
334
335         /* TODO: Implement Multicast Router Discovery (RFC4286),
336          * then allow scope > link local, too
337          */
338         if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) != IPV6_ADDR_SCOPE_LINKLOCAL)
339                 return -EINVAL;
340
341         /* link-local-all-nodes multicast listeners behind a bridge are
342          * not snoopable (see RFC4541, section 3, paragraph 3)
343          */
344         if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
345                 *is_unsnoopable = true;
346
347         return 0;
348 }
349
350 /**
351  * batadv_mcast_forw_mode_check - check for optimized forwarding potential
352  * @bat_priv: the bat priv with all the soft interface information
353  * @skb: the multicast frame to check
354  * @is_unsnoopable: stores whether the destination is snoopable
355  *
356  * Checks whether the given multicast ethernet frame has the potential to be
357  * forwarded with a mode more optimal than classic flooding.
358  *
359  * If so then returns 0. Otherwise -EINVAL is returned or -ENOMEM if we are out
360  * of memory.
361  */
362 static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
363                                         struct sk_buff *skb,
364                                         bool *is_unsnoopable)
365 {
366         struct ethhdr *ethhdr = eth_hdr(skb);
367
368         if (!atomic_read(&bat_priv->multicast_mode))
369                 return -EINVAL;
370
371         if (atomic_read(&bat_priv->mcast.num_disabled))
372                 return -EINVAL;
373
374         switch (ntohs(ethhdr->h_proto)) {
375         case ETH_P_IP:
376                 return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
377                                                          is_unsnoopable);
378         case ETH_P_IPV6:
379                 return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
380                                                          is_unsnoopable);
381         default:
382                 return -EINVAL;
383         }
384 }
385
386 /**
387  * batadv_mcast_want_all_ip_count - count nodes with unspecific mcast interest
388  * @bat_priv: the bat priv with all the soft interface information
389  * @ethhdr: ethernet header of a packet
390  *
391  * Returns the number of nodes which want all IPv4 multicast traffic if the
392  * given ethhdr is from an IPv4 packet or the number of nodes which want all
393  * IPv6 traffic if it matches an IPv6 packet.
394  */
395 static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,
396                                                struct ethhdr *ethhdr)
397 {
398         switch (ntohs(ethhdr->h_proto)) {
399         case ETH_P_IP:
400                 return atomic_read(&bat_priv->mcast.num_want_all_ipv4);
401         case ETH_P_IPV6:
402                 return atomic_read(&bat_priv->mcast.num_want_all_ipv6);
403         default:
404                 /* we shouldn't be here... */
405                 return 0;
406         }
407 }
408
409 /**
410  * batadv_mcast_forw_tt_node_get - get a multicast tt node
411  * @bat_priv: the bat priv with all the soft interface information
412  * @ethhdr: the ether header containing the multicast destination
413  *
414  * Returns an orig_node matching the multicast address provided by ethhdr
415  * via a translation table lookup. This increases the returned nodes refcount.
416  */
417 static struct batadv_orig_node *
418 batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
419                               struct ethhdr *ethhdr)
420 {
421         return batadv_transtable_search(bat_priv, ethhdr->h_source,
422                                         ethhdr->h_dest, BATADV_NO_FLAGS);
423 }
424
425 /**
426  * batadv_mcast_want_forw_ipv4_node_get - get a node with an ipv4 flag
427  * @bat_priv: the bat priv with all the soft interface information
428  *
429  * Returns an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
430  * increases its refcount.
431  */
432 static struct batadv_orig_node *
433 batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
434 {
435         struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
436
437         rcu_read_lock();
438         hlist_for_each_entry_rcu(tmp_orig_node,
439                                  &bat_priv->mcast.want_all_ipv4_list,
440                                  mcast_want_all_ipv4_node) {
441                 if (!atomic_inc_not_zero(&tmp_orig_node->refcount))
442                         continue;
443
444                 orig_node = tmp_orig_node;
445                 break;
446         }
447         rcu_read_unlock();
448
449         return orig_node;
450 }
451
452 /**
453  * batadv_mcast_want_forw_ipv6_node_get - get a node with an ipv6 flag
454  * @bat_priv: the bat priv with all the soft interface information
455  *
456  * Returns an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
457  * and increases its refcount.
458  */
459 static struct batadv_orig_node *
460 batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
461 {
462         struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
463
464         rcu_read_lock();
465         hlist_for_each_entry_rcu(tmp_orig_node,
466                                  &bat_priv->mcast.want_all_ipv6_list,
467                                  mcast_want_all_ipv6_node) {
468                 if (!atomic_inc_not_zero(&tmp_orig_node->refcount))
469                         continue;
470
471                 orig_node = tmp_orig_node;
472                 break;
473         }
474         rcu_read_unlock();
475
476         return orig_node;
477 }
478
479 /**
480  * batadv_mcast_want_forw_ip_node_get - get a node with an ipv4/ipv6 flag
481  * @bat_priv: the bat priv with all the soft interface information
482  * @ethhdr: an ethernet header to determine the protocol family from
483  *
484  * Returns an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
485  * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and
486  * increases its refcount.
487  */
488 static struct batadv_orig_node *
489 batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
490                               struct ethhdr *ethhdr)
491 {
492         switch (ntohs(ethhdr->h_proto)) {
493         case ETH_P_IP:
494                 return batadv_mcast_forw_ipv4_node_get(bat_priv);
495         case ETH_P_IPV6:
496                 return batadv_mcast_forw_ipv6_node_get(bat_priv);
497         default:
498                 /* we shouldn't be here... */
499                 return NULL;
500         }
501 }
502
503 /**
504  * batadv_mcast_want_forw_unsnoop_node_get - get a node with an unsnoopable flag
505  * @bat_priv: the bat priv with all the soft interface information
506  *
507  * Returns an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
508  * set and increases its refcount.
509  */
510 static struct batadv_orig_node *
511 batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
512 {
513         struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
514
515         rcu_read_lock();
516         hlist_for_each_entry_rcu(tmp_orig_node,
517                                  &bat_priv->mcast.want_all_unsnoopables_list,
518                                  mcast_want_all_unsnoopables_node) {
519                 if (!atomic_inc_not_zero(&tmp_orig_node->refcount))
520                         continue;
521
522                 orig_node = tmp_orig_node;
523                 break;
524         }
525         rcu_read_unlock();
526
527         return orig_node;
528 }
529
530 /**
531  * batadv_mcast_forw_mode - check on how to forward a multicast packet
532  * @bat_priv: the bat priv with all the soft interface information
533  * @skb: The multicast packet to check
534  * @orig: an originator to be set to forward the skb to
535  *
536  * Returns the forwarding mode as enum batadv_forw_mode and in case of
537  * BATADV_FORW_SINGLE set the orig to the single originator the skb
538  * should be forwarded to.
539  */
540 enum batadv_forw_mode
541 batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
542                        struct batadv_orig_node **orig)
543 {
544         int ret, tt_count, ip_count, unsnoop_count, total_count;
545         bool is_unsnoopable = false;
546         struct ethhdr *ethhdr;
547
548         ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable);
549         if (ret == -ENOMEM)
550                 return BATADV_FORW_NONE;
551         else if (ret < 0)
552                 return BATADV_FORW_ALL;
553
554         ethhdr = eth_hdr(skb);
555
556         tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
557                                                BATADV_NO_FLAGS);
558         ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
559         unsnoop_count = !is_unsnoopable ? 0 :
560                         atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
561
562         total_count = tt_count + ip_count + unsnoop_count;
563
564         switch (total_count) {
565         case 1:
566                 if (tt_count)
567                         *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
568                 else if (ip_count)
569                         *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
570                 else if (unsnoop_count)
571                         *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
572
573                 if (*orig)
574                         return BATADV_FORW_SINGLE;
575
576                 /* fall through */
577         case 0:
578                 return BATADV_FORW_NONE;
579         default:
580                 return BATADV_FORW_ALL;
581         }
582 }
583
584 /**
585  * batadv_mcast_want_unsnoop_update - update unsnoop counter and list
586  * @bat_priv: the bat priv with all the soft interface information
587  * @orig: the orig_node which multicast state might have changed of
588  * @mcast_flags: flags indicating the new multicast state
589  *
590  * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
591  * orig, has toggled then this method updates counter and list accordingly.
592  */
593 static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
594                                              struct batadv_orig_node *orig,
595                                              uint8_t mcast_flags)
596 {
597         /* switched from flag unset to set */
598         if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
599             !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
600                 atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
601
602                 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
603                 hlist_add_head_rcu(&orig->mcast_want_all_unsnoopables_node,
604                                    &bat_priv->mcast.want_all_unsnoopables_list);
605                 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
606         /* switched from flag set to unset */
607         } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
608                    orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {
609                 atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
610
611                 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
612                 hlist_del_rcu(&orig->mcast_want_all_unsnoopables_node);
613                 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
614         }
615 }
616
617 /**
618  * batadv_mcast_want_ipv4_update - update want-all-ipv4 counter and list
619  * @bat_priv: the bat priv with all the soft interface information
620  * @orig: the orig_node which multicast state might have changed of
621  * @mcast_flags: flags indicating the new multicast state
622  *
623  * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
624  * toggled then this method updates counter and list accordingly.
625  */
626 static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
627                                           struct batadv_orig_node *orig,
628                                           uint8_t mcast_flags)
629 {
630         /* switched from flag unset to set */
631         if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
632             !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
633                 atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
634
635                 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
636                 hlist_add_head_rcu(&orig->mcast_want_all_ipv4_node,
637                                    &bat_priv->mcast.want_all_ipv4_list);
638                 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
639         /* switched from flag set to unset */
640         } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
641                    orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {
642                 atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
643
644                 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
645                 hlist_del_rcu(&orig->mcast_want_all_ipv4_node);
646                 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
647         }
648 }
649
650 /**
651  * batadv_mcast_want_ipv6_update - update want-all-ipv6 counter and list
652  * @bat_priv: the bat priv with all the soft interface information
653  * @orig: the orig_node which multicast state might have changed of
654  * @mcast_flags: flags indicating the new multicast state
655  *
656  * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
657  * toggled then this method updates counter and list accordingly.
658  */
659 static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
660                                           struct batadv_orig_node *orig,
661                                           uint8_t mcast_flags)
662 {
663         /* switched from flag unset to set */
664         if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
665             !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
666                 atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
667
668                 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
669                 hlist_add_head_rcu(&orig->mcast_want_all_ipv6_node,
670                                    &bat_priv->mcast.want_all_ipv6_list);
671                 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
672         /* switched from flag set to unset */
673         } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
674                    orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {
675                 atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
676
677                 spin_lock_bh(&bat_priv->mcast.want_lists_lock);
678                 hlist_del_rcu(&orig->mcast_want_all_ipv6_node);
679                 spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
680         }
681 }
682
683 /**
684  * batadv_mcast_tvlv_ogm_handler_v1 - process incoming multicast tvlv container
685  * @bat_priv: the bat priv with all the soft interface information
686  * @orig: the orig_node of the ogm
687  * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
688  * @tvlv_value: tvlv buffer containing the multicast data
689  * @tvlv_value_len: tvlv buffer length
690  */
691 static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
692                                              struct batadv_orig_node *orig,
693                                              uint8_t flags,
694                                              void *tvlv_value,
695                                              uint16_t tvlv_value_len)
696 {
697         bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
698         uint8_t mcast_flags = BATADV_NO_FLAGS;
699         bool orig_initialized;
700
701         orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
702                                     &orig->capa_initialized);
703
704         /* If mcast support is turned on decrease the disabled mcast node
705          * counter only if we had increased it for this node before. If this
706          * is a completely new orig_node no need to decrease the counter.
707          */
708         if (orig_mcast_enabled &&
709             !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
710                 if (orig_initialized)
711                         atomic_dec(&bat_priv->mcast.num_disabled);
712                 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
713         /* If mcast support is being switched off or if this is an initial
714          * OGM without mcast support then increase the disabled mcast
715          * node counter.
716          */
717         } else if (!orig_mcast_enabled &&
718                    (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) ||
719                     !orig_initialized)) {
720                 atomic_inc(&bat_priv->mcast.num_disabled);
721                 clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
722         }
723
724         set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
725
726         if (orig_mcast_enabled && tvlv_value &&
727             (tvlv_value_len >= sizeof(mcast_flags)))
728                 mcast_flags = *(uint8_t *)tvlv_value;
729
730         batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
731         batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
732         batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
733
734         orig->mcast_flags = mcast_flags;
735 }
736
737 /**
738  * batadv_mcast_init - initialize the multicast optimizations structures
739  * @bat_priv: the bat priv with all the soft interface information
740  */
741 void batadv_mcast_init(struct batadv_priv *bat_priv)
742 {
743         batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler_v1,
744                                      NULL, BATADV_TVLV_MCAST, 1,
745                                      BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
746 }
747
748 /**
749  * batadv_mcast_free - free the multicast optimizations structures
750  * @bat_priv: the bat priv with all the soft interface information
751  */
752 void batadv_mcast_free(struct batadv_priv *bat_priv)
753 {
754         batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
755         batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
756
757         batadv_mcast_mla_tt_retract(bat_priv, NULL);
758 }
759
760 /**
761  * batadv_mcast_purge_orig - reset originator global mcast state modifications
762  * @orig: the originator which is going to get purged
763  */
764 void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
765 {
766         struct batadv_priv *bat_priv = orig->bat_priv;
767
768         if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) &&
769             test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized))
770                 atomic_dec(&bat_priv->mcast.num_disabled);
771
772         batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
773         batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
774         batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
775 }