linux/net/batman-adv/multicast.c
<<
>>
Prefs
   1/* Copyright (C) 2014-2017  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/bug.h>
  24#include <linux/byteorder/generic.h>
  25#include <linux/errno.h>
  26#include <linux/etherdevice.h>
  27#include <linux/fs.h>
  28#include <linux/icmpv6.h>
  29#include <linux/if_bridge.h>
  30#include <linux/if_ether.h>
  31#include <linux/igmp.h>
  32#include <linux/in.h>
  33#include <linux/in6.h>
  34#include <linux/ip.h>
  35#include <linux/ipv6.h>
  36#include <linux/jiffies.h>
  37#include <linux/kernel.h>
  38#include <linux/kref.h>
  39#include <linux/list.h>
  40#include <linux/lockdep.h>
  41#include <linux/netdevice.h>
  42#include <linux/printk.h>
  43#include <linux/rculist.h>
  44#include <linux/rcupdate.h>
  45#include <linux/seq_file.h>
  46#include <linux/skbuff.h>
  47#include <linux/slab.h>
  48#include <linux/spinlock.h>
  49#include <linux/stddef.h>
  50#include <linux/string.h>
  51#include <linux/types.h>
  52#include <linux/workqueue.h>
  53#include <net/addrconf.h>
  54#include <net/if_inet6.h>
  55#include <net/ip.h>
  56#include <net/ipv6.h>
  57
  58#include "hard-interface.h"
  59#include "hash.h"
  60#include "log.h"
  61#include "packet.h"
  62#include "translation-table.h"
  63#include "tvlv.h"
  64
  65static void batadv_mcast_mla_update(struct work_struct *work);
  66
  67/**
  68 * batadv_mcast_start_timer - schedule the multicast periodic worker
  69 * @bat_priv: the bat priv with all the soft interface information
  70 */
  71static void batadv_mcast_start_timer(struct batadv_priv *bat_priv)
  72{
  73        queue_delayed_work(batadv_event_workqueue, &bat_priv->mcast.work,
  74                           msecs_to_jiffies(BATADV_MCAST_WORK_PERIOD));
  75}
  76
  77/**
  78 * batadv_mcast_get_bridge - get the bridge on top of the softif if it exists
  79 * @soft_iface: netdev struct of the mesh interface
  80 *
  81 * If the given soft interface has a bridge on top then the refcount
  82 * of the according net device is increased.
  83 *
  84 * Return: NULL if no such bridge exists. Otherwise the net device of the
  85 * bridge.
  86 */
  87static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
  88{
  89        struct net_device *upper = soft_iface;
  90
  91        rcu_read_lock();
  92        do {
  93                upper = netdev_master_upper_dev_get_rcu(upper);
  94        } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
  95
  96        if (upper)
  97                dev_hold(upper);
  98        rcu_read_unlock();
  99
 100        return upper;
 101}
 102
 103/**
 104 * batadv_mcast_mla_softif_get - get softif multicast listeners
 105 * @dev: the device to collect multicast addresses from
 106 * @mcast_list: a list to put found addresses into
 107 *
 108 * Collects multicast addresses of multicast listeners residing
 109 * on this kernel on the given soft interface, dev, in
 110 * the given mcast_list. In general, multicast listeners provided by
 111 * your multicast receiving applications run directly on this node.
 112 *
 113 * If there is a bridge interface on top of dev, collects from that one
 114 * instead. Just like with IP addresses and routes, multicast listeners
 115 * will(/should) register to the bridge interface instead of an
 116 * enslaved bat0.
 117 *
 118 * Return: -ENOMEM on memory allocation error or the number of
 119 * items added to the mcast_list otherwise.
 120 */
 121static int batadv_mcast_mla_softif_get(struct net_device *dev,
 122                                       struct hlist_head *mcast_list)
 123{
 124        struct net_device *bridge = batadv_mcast_get_bridge(dev);
 125        struct netdev_hw_addr *mc_list_entry;
 126        struct batadv_hw_addr *new;
 127        int ret = 0;
 128
 129        netif_addr_lock_bh(bridge ? bridge : dev);
 130        netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
 131                new = kmalloc(sizeof(*new), GFP_ATOMIC);
 132                if (!new) {
 133                        ret = -ENOMEM;
 134                        break;
 135                }
 136
 137                ether_addr_copy(new->addr, mc_list_entry->addr);
 138                hlist_add_head(&new->list, mcast_list);
 139                ret++;
 140        }
 141        netif_addr_unlock_bh(bridge ? bridge : dev);
 142
 143        if (bridge)
 144                dev_put(bridge);
 145
 146        return ret;
 147}
 148
 149/**
 150 * batadv_mcast_mla_is_duplicate - check whether an address is in a list
 151 * @mcast_addr: the multicast address to check
 152 * @mcast_list: the list with multicast addresses to search in
 153 *
 154 * Return: true if the given address is already in the given list.
 155 * Otherwise returns false.
 156 */
 157static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,
 158                                          struct hlist_head *mcast_list)
 159{
 160        struct batadv_hw_addr *mcast_entry;
 161
 162        hlist_for_each_entry(mcast_entry, mcast_list, list)
 163                if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
 164                        return true;
 165
 166        return false;
 167}
 168
 169/**
 170 * batadv_mcast_mla_br_addr_cpy - copy a bridge multicast address
 171 * @dst: destination to write to - a multicast MAC address
 172 * @src: source to read from - a multicast IP address
 173 *
 174 * Converts a given multicast IPv4/IPv6 address from a bridge
 175 * to its matching multicast MAC address and copies it into the given
 176 * destination buffer.
 177 *
 178 * Caller needs to make sure the destination buffer can hold
 179 * at least ETH_ALEN bytes.
 180 */
 181static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
 182{
 183        if (src->proto == htons(ETH_P_IP))
 184                ip_eth_mc_map(src->u.ip4, dst);
 185#if IS_ENABLED(CONFIG_IPV6)
 186        else if (src->proto == htons(ETH_P_IPV6))
 187                ipv6_eth_mc_map(&src->u.ip6, dst);
 188#endif
 189        else
 190                eth_zero_addr(dst);
 191}
 192
 193/**
 194 * batadv_mcast_mla_bridge_get - get bridged-in multicast listeners
 195 * @dev: a bridge slave whose bridge to collect multicast addresses from
 196 * @mcast_list: a list to put found addresses into
 197 *
 198 * Collects multicast addresses of multicast listeners residing
 199 * on foreign, non-mesh devices which we gave access to our mesh via
 200 * a bridge on top of the given soft interface, dev, in the given
 201 * mcast_list.
 202 *
 203 * Return: -ENOMEM on memory allocation error or the number of
 204 * items added to the mcast_list otherwise.
 205 */
 206static int batadv_mcast_mla_bridge_get(struct net_device *dev,
 207                                       struct hlist_head *mcast_list)
 208{
 209        struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
 210        struct br_ip_list *br_ip_entry, *tmp;
 211        struct batadv_hw_addr *new;
 212        u8 mcast_addr[ETH_ALEN];
 213        int ret;
 214
 215        /* we don't need to detect these devices/listeners, the IGMP/MLD
 216         * snooping code of the Linux bridge already does that for us
 217         */
 218        ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
 219        if (ret < 0)
 220                goto out;
 221
 222        list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
 223                batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
 224                if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
 225                        continue;
 226
 227                new = kmalloc(sizeof(*new), GFP_ATOMIC);
 228                if (!new) {
 229                        ret = -ENOMEM;
 230                        break;
 231                }
 232
 233                ether_addr_copy(new->addr, mcast_addr);
 234                hlist_add_head(&new->list, mcast_list);
 235        }
 236
 237out:
 238        list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
 239                list_del(&br_ip_entry->list);
 240                kfree(br_ip_entry);
 241        }
 242
 243        return ret;
 244}
 245
 246/**
 247 * batadv_mcast_mla_list_free - free a list of multicast addresses
 248 * @mcast_list: the list to free
 249 *
 250 * Removes and frees all items in the given mcast_list.
 251 */
 252static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
 253{
 254        struct batadv_hw_addr *mcast_entry;
 255        struct hlist_node *tmp;
 256
 257        hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
 258                hlist_del(&mcast_entry->list);
 259                kfree(mcast_entry);
 260        }
 261}
 262
 263/**
 264 * batadv_mcast_mla_tt_retract - clean up multicast listener announcements
 265 * @bat_priv: the bat priv with all the soft interface information
 266 * @mcast_list: a list of addresses which should _not_ be removed
 267 *
 268 * Retracts the announcement of any multicast listener from the
 269 * translation table except the ones listed in the given mcast_list.
 270 *
 271 * If mcast_list is NULL then all are retracted.
 272 *
 273 * Do not call outside of the mcast worker! (or cancel mcast worker first)
 274 */
 275static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
 276                                        struct hlist_head *mcast_list)
 277{
 278        struct batadv_hw_addr *mcast_entry;
 279        struct hlist_node *tmp;
 280
 281        WARN_ON(delayed_work_pending(&bat_priv->mcast.work));
 282
 283        hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
 284                                  list) {
 285                if (mcast_list &&
 286                    batadv_mcast_mla_is_duplicate(mcast_entry->addr,
 287                                                  mcast_list))
 288                        continue;
 289
 290                batadv_tt_local_remove(bat_priv, mcast_entry->addr,
 291                                       BATADV_NO_FLAGS,
 292                                       "mcast TT outdated", false);
 293
 294                hlist_del(&mcast_entry->list);
 295                kfree(mcast_entry);
 296        }
 297}
 298
 299/**
 300 * batadv_mcast_mla_tt_add - add multicast listener announcements
 301 * @bat_priv: the bat priv with all the soft interface information
 302 * @mcast_list: a list of addresses which are going to get added
 303 *
 304 * Adds multicast listener announcements from the given mcast_list to the
 305 * translation table if they have not been added yet.
 306 *
 307 * Do not call outside of the mcast worker! (or cancel mcast worker first)
 308 */
 309static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
 310                                    struct hlist_head *mcast_list)
 311{
 312        struct batadv_hw_addr *mcast_entry;
 313        struct hlist_node *tmp;
 314
 315        WARN_ON(delayed_work_pending(&bat_priv->mcast.work));
 316
 317        if (!mcast_list)
 318                return;
 319
 320        hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
 321                if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
 322                                                  &bat_priv->mcast.mla_list))
 323                        continue;
 324
 325                if (!batadv_tt_local_add(bat_priv->soft_iface,
 326                                         mcast_entry->addr, BATADV_NO_FLAGS,
 327                                         BATADV_NULL_IFINDEX, BATADV_NO_MARK))
 328                        continue;
 329
 330                hlist_del(&mcast_entry->list);
 331                hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
 332        }
 333}
 334
 335/**
 336 * batadv_mcast_has_bridge - check whether the soft-iface is bridged
 337 * @bat_priv: the bat priv with all the soft interface information
 338 *
 339 * Checks whether there is a bridge on top of our soft interface.
 340 *
 341 * Return: true if there is a bridge, false otherwise.
 342 */
 343static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
 344{
 345        struct net_device *upper = bat_priv->soft_iface;
 346
 347        rcu_read_lock();
 348        do {
 349                upper = netdev_master_upper_dev_get_rcu(upper);
 350        } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
 351        rcu_read_unlock();
 352
 353        return upper;
 354}
 355
 356/**
 357 * batadv_mcast_querier_log - debug output regarding the querier status on link
 358 * @bat_priv: the bat priv with all the soft interface information
 359 * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")
 360 * @old_state: the previous querier state on our link
 361 * @new_state: the new querier state on our link
 362 *
 363 * Outputs debug messages to the logging facility with log level 'mcast'
 364 * regarding changes to the querier status on the link which are relevant
 365 * to our multicast optimizations.
 366 *
 367 * Usually this is about whether a querier appeared or vanished in
 368 * our mesh or whether the querier is in the suboptimal position of being
 369 * behind our local bridge segment: Snooping switches will directly
 370 * forward listener reports to the querier, therefore batman-adv and
 371 * the bridge will potentially not see these listeners - the querier is
 372 * potentially shadowing listeners from us then.
 373 *
 374 * This is only interesting for nodes with a bridge on top of their
 375 * soft interface.
 376 */
 377static void
 378batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,
 379                         struct batadv_mcast_querier_state *old_state,
 380                         struct batadv_mcast_querier_state *new_state)
 381{
 382        if (!old_state->exists && new_state->exists)
 383                batadv_info(bat_priv->soft_iface, "%s Querier appeared\n",
 384                            str_proto);
 385        else if (old_state->exists && !new_state->exists)
 386                batadv_info(bat_priv->soft_iface,
 387                            "%s Querier disappeared - multicast optimizations disabled\n",
 388                            str_proto);
 389        else if (!bat_priv->mcast.bridged && !new_state->exists)
 390                batadv_info(bat_priv->soft_iface,
 391                            "No %s Querier present - multicast optimizations disabled\n",
 392                            str_proto);
 393
 394        if (new_state->exists) {
 395                if ((!old_state->shadowing && new_state->shadowing) ||
 396                    (!old_state->exists && new_state->shadowing))
 397                        batadv_dbg(BATADV_DBG_MCAST, bat_priv,
 398                                   "%s Querier is behind our bridged segment: Might shadow listeners\n",
 399                                   str_proto);
 400                else if (old_state->shadowing && !new_state->shadowing)
 401                        batadv_dbg(BATADV_DBG_MCAST, bat_priv,
 402                                   "%s Querier is not behind our bridged segment\n",
 403                                   str_proto);
 404        }
 405}
 406
 407/**
 408 * batadv_mcast_bridge_log - debug output for topology changes in bridged setups
 409 * @bat_priv: the bat priv with all the soft interface information
 410 * @bridged: a flag about whether the soft interface is currently bridged or not
 411 * @querier_ipv4: (maybe) new status of a potential, selected IGMP querier
 412 * @querier_ipv6: (maybe) new status of a potential, selected MLD querier
 413 *
 414 * If no bridges are ever used on this node, then this function does nothing.
 415 *
 416 * Otherwise this function outputs debug information to the 'mcast' log level
 417 * which might be relevant to our multicast optimizations.
 418 *
 419 * More precisely, it outputs information when a bridge interface is added or
 420 * removed from a soft interface. And when a bridge is present, it further
 421 * outputs information about the querier state which is relevant for the
 422 * multicast flags this node is going to set.
 423 */
 424static void
 425batadv_mcast_bridge_log(struct batadv_priv *bat_priv, bool bridged,
 426                        struct batadv_mcast_querier_state *querier_ipv4,
 427                        struct batadv_mcast_querier_state *querier_ipv6)
 428{
 429        if (!bat_priv->mcast.bridged && bridged)
 430                batadv_dbg(BATADV_DBG_MCAST, bat_priv,
 431                           "Bridge added: Setting Unsnoopables(U)-flag\n");
 432        else if (bat_priv->mcast.bridged && !bridged)
 433                batadv_dbg(BATADV_DBG_MCAST, bat_priv,
 434                           "Bridge removed: Unsetting Unsnoopables(U)-flag\n");
 435
 436        if (bridged) {
 437                batadv_mcast_querier_log(bat_priv, "IGMP",
 438                                         &bat_priv->mcast.querier_ipv4,
 439                                         querier_ipv4);
 440                batadv_mcast_querier_log(bat_priv, "MLD",
 441                                         &bat_priv->mcast.querier_ipv6,
 442                                         querier_ipv6);
 443        }
 444}
 445
 446/**
 447 * batadv_mcast_flags_logs - output debug information about mcast flag changes
 448 * @bat_priv: the bat priv with all the soft interface information
 449 * @flags: flags indicating the new multicast state
 450 *
 451 * Whenever the multicast flags this nodes announces changes (@mcast_flags vs.
 452 * bat_priv->mcast.flags), this notifies userspace via the 'mcast' log level.
 453 */
 454static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
 455{
 456        u8 old_flags = bat_priv->mcast.flags;
 457        char str_old_flags[] = "[...]";
 458
 459        sprintf(str_old_flags, "[%c%c%c]",
 460                (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
 461                (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
 462                (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
 463
 464        batadv_dbg(BATADV_DBG_MCAST, bat_priv,
 465                   "Changing multicast flags from '%s' to '[%c%c%c]'\n",
 466                   bat_priv->mcast.enabled ? str_old_flags : "<undefined>",
 467                   (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
 468                   (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
 469                   (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
 470}
 471
 472/**
 473 * batadv_mcast_mla_tvlv_update - update multicast tvlv
 474 * @bat_priv: the bat priv with all the soft interface information
 475 *
 476 * Updates the own multicast tvlv with our current multicast related settings,
 477 * capabilities and inabilities.
 478 *
 479 * Return: false if we want all IPv4 && IPv6 multicast traffic and true
 480 * otherwise.
 481 */
 482static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
 483{
 484        struct batadv_tvlv_mcast_data mcast_data;
 485        struct batadv_mcast_querier_state querier4 = {false, false};
 486        struct batadv_mcast_querier_state querier6 = {false, false};
 487        struct net_device *dev = bat_priv->soft_iface;
 488        bool bridged;
 489
 490        mcast_data.flags = BATADV_NO_FLAGS;
 491        memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
 492
 493        bridged = batadv_mcast_has_bridge(bat_priv);
 494        if (!bridged)
 495                goto update;
 496
 497        if (!IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING))
 498                pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");
 499
 500        querier4.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);
 501        querier4.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);
 502
 503        querier6.exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);
 504        querier6.shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);
 505
 506        mcast_data.flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
 507
 508        /* 1) If no querier exists at all, then multicast listeners on
 509         *    our local TT clients behind the bridge will keep silent.
 510         * 2) If the selected querier is on one of our local TT clients,
 511         *    behind the bridge, then this querier might shadow multicast
 512         *    listeners on our local TT clients, behind this bridge.
 513         *
 514         * In both cases, we will signalize other batman nodes that
 515         * we need all multicast traffic of the according protocol.
 516         */
 517        if (!querier4.exists || querier4.shadowing)
 518                mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV4;
 519
 520        if (!querier6.exists || querier6.shadowing)
 521                mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV6;
 522
 523update:
 524        batadv_mcast_bridge_log(bat_priv, bridged, &querier4, &querier6);
 525
 526        bat_priv->mcast.querier_ipv4.exists = querier4.exists;
 527        bat_priv->mcast.querier_ipv4.shadowing = querier4.shadowing;
 528
 529        bat_priv->mcast.querier_ipv6.exists = querier6.exists;
 530        bat_priv->mcast.querier_ipv6.shadowing = querier6.shadowing;
 531
 532        bat_priv->mcast.bridged = bridged;
 533
 534        if (!bat_priv->mcast.enabled ||
 535            mcast_data.flags != bat_priv->mcast.flags) {
 536                batadv_mcast_flags_log(bat_priv, mcast_data.flags);
 537                batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,
 538                                               &mcast_data, sizeof(mcast_data));
 539                bat_priv->mcast.flags = mcast_data.flags;
 540                bat_priv->mcast.enabled = true;
 541        }
 542
 543        return !(mcast_data.flags &
 544                 (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6));
 545}
 546
 547/**
 548 * __batadv_mcast_mla_update - update the own MLAs
 549 * @bat_priv: the bat priv with all the soft interface information
 550 *
 551 * Updates the own multicast listener announcements in the translation
 552 * table as well as the own, announced multicast tvlv container.
 553 *
 554 * Note that non-conflicting reads and writes to bat_priv->mcast.mla_list
 555 * in batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add() are
 556 * ensured by the non-parallel execution of the worker this function
 557 * belongs to.
 558 */
 559static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)
 560{
 561        struct net_device *soft_iface = bat_priv->soft_iface;
 562        struct hlist_head mcast_list = HLIST_HEAD_INIT;
 563        int ret;
 564
 565        if (!batadv_mcast_mla_tvlv_update(bat_priv))
 566                goto update;
 567
 568        ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
 569        if (ret < 0)
 570                goto out;
 571
 572        ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
 573        if (ret < 0)
 574                goto out;
 575
 576update:
 577        batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
 578        batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
 579
 580out:
 581        batadv_mcast_mla_list_free(&mcast_list);
 582}
 583
 584/**
 585 * batadv_mcast_mla_update - update the own MLAs
 586 * @work: kernel work struct
 587 *
 588 * Updates the own multicast listener announcements in the translation
 589 * table as well as the own, announced multicast tvlv container.
 590 *
 591 * In the end, reschedules the work timer.
 592 */
 593static void batadv_mcast_mla_update(struct work_struct *work)
 594{
 595        struct delayed_work *delayed_work;
 596        struct batadv_priv_mcast *priv_mcast;
 597        struct batadv_priv *bat_priv;
 598
 599        delayed_work = to_delayed_work(work);
 600        priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work);
 601        bat_priv = container_of(priv_mcast, struct batadv_priv, mcast);
 602
 603        __batadv_mcast_mla_update(bat_priv);
 604        batadv_mcast_start_timer(bat_priv);
 605}
 606
 607/**
 608 * batadv_mcast_is_report_ipv4 - check for IGMP reports
 609 * @skb: the ethernet frame destined for the mesh
 610 *
 611 * This call might reallocate skb data.
 612 *
 613 * Checks whether the given frame is a valid IGMP report.
 614 *
 615 * Return: If so then true, otherwise false.
 616 */
 617static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)
 618{
 619        if (ip_mc_check_igmp(skb, NULL) < 0)
 620                return false;
 621
 622        switch (igmp_hdr(skb)->type) {
 623        case IGMP_HOST_MEMBERSHIP_REPORT:
 624        case IGMPV2_HOST_MEMBERSHIP_REPORT:
 625        case IGMPV3_HOST_MEMBERSHIP_REPORT:
 626                return true;
 627        }
 628
 629        return false;
 630}
 631
 632/**
 633 * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential
 634 * @bat_priv: the bat priv with all the soft interface information
 635 * @skb: the IPv4 packet to check
 636 * @is_unsnoopable: stores whether the destination is snoopable
 637 *
 638 * Checks whether the given IPv4 packet has the potential to be forwarded with a
 639 * mode more optimal than classic flooding.
 640 *
 641 * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory
 642 * allocation failure.
 643 */
 644static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
 645                                             struct sk_buff *skb,
 646                                             bool *is_unsnoopable)
 647{
 648        struct iphdr *iphdr;
 649
 650        /* We might fail due to out-of-memory -> drop it */
 651        if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
 652                return -ENOMEM;
 653
 654        if (batadv_mcast_is_report_ipv4(skb))
 655                return -EINVAL;
 656
 657        iphdr = ip_hdr(skb);
 658
 659        /* TODO: Implement Multicast Router Discovery (RFC4286),
 660         * then allow scope > link local, too
 661         */
 662        if (!ipv4_is_local_multicast(iphdr->daddr))
 663                return -EINVAL;
 664
 665        /* link-local multicast listeners behind a bridge are
 666         * not snoopable (see RFC4541, section 2.1.2.2)
 667         */
 668        *is_unsnoopable = true;
 669
 670        return 0;
 671}
 672
 673/**
 674 * batadv_mcast_is_report_ipv6 - check for MLD reports
 675 * @skb: the ethernet frame destined for the mesh
 676 *
 677 * This call might reallocate skb data.
 678 *
 679 * Checks whether the given frame is a valid MLD report.
 680 *
 681 * Return: If so then true, otherwise false.
 682 */
 683static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)
 684{
 685        if (ipv6_mc_check_mld(skb, NULL) < 0)
 686                return false;
 687
 688        switch (icmp6_hdr(skb)->icmp6_type) {
 689        case ICMPV6_MGM_REPORT:
 690        case ICMPV6_MLD2_REPORT:
 691                return true;
 692        }
 693
 694        return false;
 695}
 696
 697/**
 698 * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
 699 * @bat_priv: the bat priv with all the soft interface information
 700 * @skb: the IPv6 packet to check
 701 * @is_unsnoopable: stores whether the destination is snoopable
 702 *
 703 * Checks whether the given IPv6 packet has the potential to be forwarded with a
 704 * mode more optimal than classic flooding.
 705 *
 706 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
 707 */
 708static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
 709                                             struct sk_buff *skb,
 710                                             bool *is_unsnoopable)
 711{
 712        struct ipv6hdr *ip6hdr;
 713
 714        /* We might fail due to out-of-memory -> drop it */
 715        if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
 716                return -ENOMEM;
 717
 718        if (batadv_mcast_is_report_ipv6(skb))
 719                return -EINVAL;
 720
 721        ip6hdr = ipv6_hdr(skb);
 722
 723        /* TODO: Implement Multicast Router Discovery (RFC4286),
 724         * then allow scope > link local, too
 725         */
 726        if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) != IPV6_ADDR_SCOPE_LINKLOCAL)
 727                return -EINVAL;
 728
 729        /* link-local-all-nodes multicast listeners behind a bridge are
 730         * not snoopable (see RFC4541, section 3, paragraph 3)
 731         */
 732        if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
 733                *is_unsnoopable = true;
 734
 735        return 0;
 736}
 737
 738/**
 739 * batadv_mcast_forw_mode_check - check for optimized forwarding potential
 740 * @bat_priv: the bat priv with all the soft interface information
 741 * @skb: the multicast frame to check
 742 * @is_unsnoopable: stores whether the destination is snoopable
 743 *
 744 * Checks whether the given multicast ethernet frame has the potential to be
 745 * forwarded with a mode more optimal than classic flooding.
 746 *
 747 * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
 748 */
 749static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
 750                                        struct sk_buff *skb,
 751                                        bool *is_unsnoopable)
 752{
 753        struct ethhdr *ethhdr = eth_hdr(skb);
 754
 755        if (!atomic_read(&bat_priv->multicast_mode))
 756                return -EINVAL;
 757
 758        if (atomic_read(&bat_priv->mcast.num_disabled))
 759                return -EINVAL;
 760
 761        switch (ntohs(ethhdr->h_proto)) {
 762        case ETH_P_IP:
 763                return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
 764                                                         is_unsnoopable);
 765        case ETH_P_IPV6:
 766                if (!IS_ENABLED(CONFIG_IPV6))
 767                        return -EINVAL;
 768
 769                return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
 770                                                         is_unsnoopable);
 771        default:
 772                return -EINVAL;
 773        }
 774}
 775
 776/**
 777 * batadv_mcast_forw_want_all_ip_count - count nodes with unspecific mcast
 778 *  interest
 779 * @bat_priv: the bat priv with all the soft interface information
 780 * @ethhdr: ethernet header of a packet
 781 *
 782 * Return: the number of nodes which want all IPv4 multicast traffic if the
 783 * given ethhdr is from an IPv4 packet or the number of nodes which want all
 784 * IPv6 traffic if it matches an IPv6 packet.
 785 */
 786static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,
 787                                               struct ethhdr *ethhdr)
 788{
 789        switch (ntohs(ethhdr->h_proto)) {
 790        case ETH_P_IP:
 791                return atomic_read(&bat_priv->mcast.num_want_all_ipv4);
 792        case ETH_P_IPV6:
 793                return atomic_read(&bat_priv->mcast.num_want_all_ipv6);
 794        default:
 795                /* we shouldn't be here... */
 796                return 0;
 797        }
 798}
 799
 800/**
 801 * batadv_mcast_forw_tt_node_get - get a multicast tt node
 802 * @bat_priv: the bat priv with all the soft interface information
 803 * @ethhdr: the ether header containing the multicast destination
 804 *
 805 * Return: an orig_node matching the multicast address provided by ethhdr
 806 * via a translation table lookup. This increases the returned nodes refcount.
 807 */
 808static struct batadv_orig_node *
 809batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
 810                              struct ethhdr *ethhdr)
 811{
 812        return batadv_transtable_search(bat_priv, ethhdr->h_source,
 813                                        ethhdr->h_dest, BATADV_NO_FLAGS);
 814}
 815
 816/**
 817 * batadv_mcast_forw_ipv4_node_get - get a node with an ipv4 flag
 818 * @bat_priv: the bat priv with all the soft interface information
 819 *
 820 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
 821 * increases its refcount.
 822 */
 823static struct batadv_orig_node *
 824batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
 825{
 826        struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
 827
 828        rcu_read_lock();
 829        hlist_for_each_entry_rcu(tmp_orig_node,
 830                                 &bat_priv->mcast.want_all_ipv4_list,
 831                                 mcast_want_all_ipv4_node) {
 832                if (!kref_get_unless_zero(&tmp_orig_node->refcount))
 833                        continue;
 834
 835                orig_node = tmp_orig_node;
 836                break;
 837        }
 838        rcu_read_unlock();
 839
 840        return orig_node;
 841}
 842
 843/**
 844 * batadv_mcast_forw_ipv6_node_get - get a node with an ipv6 flag
 845 * @bat_priv: the bat priv with all the soft interface information
 846 *
 847 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
 848 * and increases its refcount.
 849 */
 850static struct batadv_orig_node *
 851batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
 852{
 853        struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
 854
 855        rcu_read_lock();
 856        hlist_for_each_entry_rcu(tmp_orig_node,
 857                                 &bat_priv->mcast.want_all_ipv6_list,
 858                                 mcast_want_all_ipv6_node) {
 859                if (!kref_get_unless_zero(&tmp_orig_node->refcount))
 860                        continue;
 861
 862                orig_node = tmp_orig_node;
 863                break;
 864        }
 865        rcu_read_unlock();
 866
 867        return orig_node;
 868}
 869
 870/**
 871 * batadv_mcast_forw_ip_node_get - get a node with an ipv4/ipv6 flag
 872 * @bat_priv: the bat priv with all the soft interface information
 873 * @ethhdr: an ethernet header to determine the protocol family from
 874 *
 875 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
 876 * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and
 877 * increases its refcount.
 878 */
 879static struct batadv_orig_node *
 880batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
 881                              struct ethhdr *ethhdr)
 882{
 883        switch (ntohs(ethhdr->h_proto)) {
 884        case ETH_P_IP:
 885                return batadv_mcast_forw_ipv4_node_get(bat_priv);
 886        case ETH_P_IPV6:
 887                return batadv_mcast_forw_ipv6_node_get(bat_priv);
 888        default:
 889                /* we shouldn't be here... */
 890                return NULL;
 891        }
 892}
 893
 894/**
 895 * batadv_mcast_forw_unsnoop_node_get - get a node with an unsnoopable flag
 896 * @bat_priv: the bat priv with all the soft interface information
 897 *
 898 * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
 899 * set and increases its refcount.
 900 */
 901static struct batadv_orig_node *
 902batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
 903{
 904        struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
 905
 906        rcu_read_lock();
 907        hlist_for_each_entry_rcu(tmp_orig_node,
 908                                 &bat_priv->mcast.want_all_unsnoopables_list,
 909                                 mcast_want_all_unsnoopables_node) {
 910                if (!kref_get_unless_zero(&tmp_orig_node->refcount))
 911                        continue;
 912
 913                orig_node = tmp_orig_node;
 914                break;
 915        }
 916        rcu_read_unlock();
 917
 918        return orig_node;
 919}
 920
 921/**
 922 * batadv_mcast_forw_mode - check on how to forward a multicast packet
 923 * @bat_priv: the bat priv with all the soft interface information
 924 * @skb: The multicast packet to check
 925 * @orig: an originator to be set to forward the skb to
 926 *
 927 * Return: the forwarding mode as enum batadv_forw_mode and in case of
 928 * BATADV_FORW_SINGLE set the orig to the single originator the skb
 929 * should be forwarded to.
 930 */
 931enum batadv_forw_mode
 932batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
 933                       struct batadv_orig_node **orig)
 934{
 935        int ret, tt_count, ip_count, unsnoop_count, total_count;
 936        bool is_unsnoopable = false;
 937        struct ethhdr *ethhdr;
 938
 939        ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable);
 940        if (ret == -ENOMEM)
 941                return BATADV_FORW_NONE;
 942        else if (ret < 0)
 943                return BATADV_FORW_ALL;
 944
 945        ethhdr = eth_hdr(skb);
 946
 947        tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
 948                                               BATADV_NO_FLAGS);
 949        ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
 950        unsnoop_count = !is_unsnoopable ? 0 :
 951                        atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
 952
 953        total_count = tt_count + ip_count + unsnoop_count;
 954
 955        switch (total_count) {
 956        case 1:
 957                if (tt_count)
 958                        *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
 959                else if (ip_count)
 960                        *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
 961                else if (unsnoop_count)
 962                        *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
 963
 964                if (*orig)
 965                        return BATADV_FORW_SINGLE;
 966
 967                /* fall through */
 968        case 0:
 969                return BATADV_FORW_NONE;
 970        default:
 971                return BATADV_FORW_ALL;
 972        }
 973}
 974
 975/**
 976 * batadv_mcast_want_unsnoop_update - update unsnoop counter and list
 977 * @bat_priv: the bat priv with all the soft interface information
 978 * @orig: the orig_node which multicast state might have changed of
 979 * @mcast_flags: flags indicating the new multicast state
 980 *
 981 * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
 982 * orig, has toggled then this method updates counter and list accordingly.
 983 *
 984 * Caller needs to hold orig->mcast_handler_lock.
 985 */
 986static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
 987                                             struct batadv_orig_node *orig,
 988                                             u8 mcast_flags)
 989{
 990        struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
 991        struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
 992
 993        lockdep_assert_held(&orig->mcast_handler_lock);
 994
 995        /* switched from flag unset to set */
 996        if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
 997            !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
 998                atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
 999
1000                spin_lock_bh(&bat_priv->mcast.want_lists_lock);
1001                /* flag checks above + mcast_handler_lock prevents this */
1002                WARN_ON(!hlist_unhashed(node));
1003
1004                hlist_add_head_rcu(node, head);
1005                spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1006        /* switched from flag set to unset */
1007        } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
1008                   orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {
1009                atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
1010
1011                spin_lock_bh(&bat_priv->mcast.want_lists_lock);
1012                /* flag checks above + mcast_handler_lock prevents this */
1013                WARN_ON(hlist_unhashed(node));
1014
1015                hlist_del_init_rcu(node);
1016                spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1017        }
1018}
1019
1020/**
1021 * batadv_mcast_want_ipv4_update - update want-all-ipv4 counter and list
1022 * @bat_priv: the bat priv with all the soft interface information
1023 * @orig: the orig_node which multicast state might have changed of
1024 * @mcast_flags: flags indicating the new multicast state
1025 *
1026 * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
1027 * toggled then this method updates counter and list accordingly.
1028 *
1029 * Caller needs to hold orig->mcast_handler_lock.
1030 */
1031static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
1032                                          struct batadv_orig_node *orig,
1033                                          u8 mcast_flags)
1034{
1035        struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
1036        struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
1037
1038        lockdep_assert_held(&orig->mcast_handler_lock);
1039
1040        /* switched from flag unset to set */
1041        if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
1042            !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
1043                atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
1044
1045                spin_lock_bh(&bat_priv->mcast.want_lists_lock);
1046                /* flag checks above + mcast_handler_lock prevents this */
1047                WARN_ON(!hlist_unhashed(node));
1048
1049                hlist_add_head_rcu(node, head);
1050                spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1051        /* switched from flag set to unset */
1052        } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
1053                   orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {
1054                atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
1055
1056                spin_lock_bh(&bat_priv->mcast.want_lists_lock);
1057                /* flag checks above + mcast_handler_lock prevents this */
1058                WARN_ON(hlist_unhashed(node));
1059
1060                hlist_del_init_rcu(node);
1061                spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1062        }
1063}
1064
1065/**
1066 * batadv_mcast_want_ipv6_update - update want-all-ipv6 counter and list
1067 * @bat_priv: the bat priv with all the soft interface information
1068 * @orig: the orig_node which multicast state might have changed of
1069 * @mcast_flags: flags indicating the new multicast state
1070 *
1071 * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
1072 * toggled then this method updates counter and list accordingly.
1073 *
1074 * Caller needs to hold orig->mcast_handler_lock.
1075 */
1076static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
1077                                          struct batadv_orig_node *orig,
1078                                          u8 mcast_flags)
1079{
1080        struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
1081        struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
1082
1083        lockdep_assert_held(&orig->mcast_handler_lock);
1084
1085        /* switched from flag unset to set */
1086        if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
1087            !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
1088                atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
1089
1090                spin_lock_bh(&bat_priv->mcast.want_lists_lock);
1091                /* flag checks above + mcast_handler_lock prevents this */
1092                WARN_ON(!hlist_unhashed(node));
1093
1094                hlist_add_head_rcu(node, head);
1095                spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1096        /* switched from flag set to unset */
1097        } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
1098                   orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {
1099                atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
1100
1101                spin_lock_bh(&bat_priv->mcast.want_lists_lock);
1102                /* flag checks above + mcast_handler_lock prevents this */
1103                WARN_ON(hlist_unhashed(node));
1104
1105                hlist_del_init_rcu(node);
1106                spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
1107        }
1108}
1109
1110/**
1111 * batadv_mcast_tvlv_ogm_handler - process incoming multicast tvlv container
1112 * @bat_priv: the bat priv with all the soft interface information
1113 * @orig: the orig_node of the ogm
1114 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
1115 * @tvlv_value: tvlv buffer containing the multicast data
1116 * @tvlv_value_len: tvlv buffer length
1117 */
1118static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
1119                                          struct batadv_orig_node *orig,
1120                                          u8 flags,
1121                                          void *tvlv_value,
1122                                          u16 tvlv_value_len)
1123{
1124        bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
1125        u8 mcast_flags = BATADV_NO_FLAGS;
1126        bool orig_initialized;
1127
1128        if (orig_mcast_enabled && tvlv_value &&
1129            tvlv_value_len >= sizeof(mcast_flags))
1130                mcast_flags = *(u8 *)tvlv_value;
1131
1132        spin_lock_bh(&orig->mcast_handler_lock);
1133        orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1134                                    &orig->capa_initialized);
1135
1136        /* If mcast support is turned on decrease the disabled mcast node
1137         * counter only if we had increased it for this node before. If this
1138         * is a completely new orig_node no need to decrease the counter.
1139         */
1140        if (orig_mcast_enabled &&
1141            !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
1142                if (orig_initialized)
1143                        atomic_dec(&bat_priv->mcast.num_disabled);
1144                set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
1145        /* If mcast support is being switched off or if this is an initial
1146         * OGM without mcast support then increase the disabled mcast
1147         * node counter.
1148         */
1149        } else if (!orig_mcast_enabled &&
1150                   (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) ||
1151                    !orig_initialized)) {
1152                atomic_inc(&bat_priv->mcast.num_disabled);
1153                clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
1154        }
1155
1156        set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
1157
1158        batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
1159        batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
1160        batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
1161
1162        orig->mcast_flags = mcast_flags;
1163        spin_unlock_bh(&orig->mcast_handler_lock);
1164}
1165
1166/**
1167 * batadv_mcast_init - initialize the multicast optimizations structures
1168 * @bat_priv: the bat priv with all the soft interface information
1169 */
1170void batadv_mcast_init(struct batadv_priv *bat_priv)
1171{
1172        batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
1173                                     NULL, BATADV_TVLV_MCAST, 2,
1174                                     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
1175
1176        INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);
1177        batadv_mcast_start_timer(bat_priv);
1178}
1179
1180#ifdef CONFIG_BATMAN_ADV_DEBUGFS
1181/**
1182 * batadv_mcast_flags_print_header - print own mcast flags to debugfs table
1183 * @bat_priv: the bat priv with all the soft interface information
1184 * @seq: debugfs table seq_file struct
1185 *
1186 * Prints our own multicast flags including a more specific reason why
1187 * they are set, that is prints the bridge and querier state too, to
1188 * the debugfs table specified via @seq.
1189 */
1190static void batadv_mcast_flags_print_header(struct batadv_priv *bat_priv,
1191                                            struct seq_file *seq)
1192{
1193        u8 flags = bat_priv->mcast.flags;
1194        char querier4, querier6, shadowing4, shadowing6;
1195        bool bridged = bat_priv->mcast.bridged;
1196
1197        if (bridged) {
1198                querier4 = bat_priv->mcast.querier_ipv4.exists ? '.' : '4';
1199                querier6 = bat_priv->mcast.querier_ipv6.exists ? '.' : '6';
1200                shadowing4 = bat_priv->mcast.querier_ipv4.shadowing ? '4' : '.';
1201                shadowing6 = bat_priv->mcast.querier_ipv6.shadowing ? '6' : '.';
1202        } else {
1203                querier4 = '?';
1204                querier6 = '?';
1205                shadowing4 = '?';
1206                shadowing6 = '?';
1207        }
1208
1209        seq_printf(seq, "Multicast flags (own flags: [%c%c%c])\n",
1210                   (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
1211                   (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
1212                   (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.');
1213        seq_printf(seq, "* Bridged [U]\t\t\t\t%c\n", bridged ? 'U' : '.');
1214        seq_printf(seq, "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n",
1215                   querier4, querier6);
1216        seq_printf(seq, "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n",
1217                   shadowing4, shadowing6);
1218        seq_puts(seq, "-------------------------------------------\n");
1219        seq_printf(seq, "       %-10s %s\n", "Originator", "Flags");
1220}
1221
1222/**
1223 * batadv_mcast_flags_seq_print_text - print the mcast flags of other nodes
1224 * @seq: seq file to print on
1225 * @offset: not used
1226 *
1227 * This prints a table of (primary) originators and their according
1228 * multicast flags, including (in the header) our own.
1229 *
1230 * Return: always 0
1231 */
1232int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
1233{
1234        struct net_device *net_dev = (struct net_device *)seq->private;
1235        struct batadv_priv *bat_priv = netdev_priv(net_dev);
1236        struct batadv_hard_iface *primary_if;
1237        struct batadv_hashtable *hash = bat_priv->orig_hash;
1238        struct batadv_orig_node *orig_node;
1239        struct hlist_head *head;
1240        u8 flags;
1241        u32 i;
1242
1243        primary_if = batadv_seq_print_text_primary_if_get(seq);
1244        if (!primary_if)
1245                return 0;
1246
1247        batadv_mcast_flags_print_header(bat_priv, seq);
1248
1249        for (i = 0; i < hash->size; i++) {
1250                head = &hash->table[i];
1251
1252                rcu_read_lock();
1253                hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1254                        if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1255                                      &orig_node->capa_initialized))
1256                                continue;
1257
1258                        if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1259                                      &orig_node->capabilities)) {
1260                                seq_printf(seq, "%pM -\n", orig_node->orig);
1261                                continue;
1262                        }
1263
1264                        flags = orig_node->mcast_flags;
1265
1266                        seq_printf(seq, "%pM [%c%c%c]\n", orig_node->orig,
1267                                   (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)
1268                                   ? 'U' : '.',
1269                                   (flags & BATADV_MCAST_WANT_ALL_IPV4)
1270                                   ? '4' : '.',
1271                                   (flags & BATADV_MCAST_WANT_ALL_IPV6)
1272                                   ? '6' : '.');
1273                }
1274                rcu_read_unlock();
1275        }
1276
1277        batadv_hardif_put(primary_if);
1278
1279        return 0;
1280}
1281#endif
1282
1283/**
1284 * batadv_mcast_free - free the multicast optimizations structures
1285 * @bat_priv: the bat priv with all the soft interface information
1286 */
1287void batadv_mcast_free(struct batadv_priv *bat_priv)
1288{
1289        cancel_delayed_work_sync(&bat_priv->mcast.work);
1290
1291        batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
1292        batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
1293
1294        /* safely calling outside of worker, as worker was canceled above */
1295        batadv_mcast_mla_tt_retract(bat_priv, NULL);
1296}
1297
1298/**
1299 * batadv_mcast_purge_orig - reset originator global mcast state modifications
1300 * @orig: the originator which is going to get purged
1301 */
1302void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
1303{
1304        struct batadv_priv *bat_priv = orig->bat_priv;
1305
1306        spin_lock_bh(&orig->mcast_handler_lock);
1307
1308        if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) &&
1309            test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized))
1310                atomic_dec(&bat_priv->mcast.num_disabled);
1311
1312        batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
1313        batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
1314        batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
1315
1316        spin_unlock_bh(&orig->mcast_handler_lock);
1317}
1318