// SPDX-License-Identifier: GPL-2.01/* Copyright (C) B.A.T.M.A.N. contributors:2*3* Linus Lüssing4*/56#include "multicast.h"7#include "main.h"89#include <linux/atomic.h>10#include <linux/bitops.h>11#include <linux/bug.h>12#include <linux/byteorder/generic.h>13#include <linux/container_of.h>14#include <linux/err.h>15#include <linux/errno.h>16#include <linux/etherdevice.h>17#include <linux/gfp.h>18#include <linux/icmpv6.h>19#include <linux/if_bridge.h>20#include <linux/if_ether.h>21#include <linux/igmp.h>22#include <linux/in.h>23#include <linux/in6.h>24#include <linux/inetdevice.h>25#include <linux/ip.h>26#include <linux/ipv6.h>27#include <linux/jiffies.h>28#include <linux/list.h>29#include <linux/lockdep.h>30#include <linux/netdevice.h>31#include <linux/netlink.h>32#include <linux/printk.h>33#include <linux/rculist.h>34#include <linux/rcupdate.h>35#include <linux/skbuff.h>36#include <linux/slab.h>37#include <linux/spinlock.h>38#include <linux/sprintf.h>39#include <linux/stddef.h>40#include <linux/string.h>41#include <linux/types.h>42#include <linux/workqueue.h>43#include <net/addrconf.h>44#include <net/genetlink.h>45#include <net/if_inet6.h>46#include <net/ip.h>47#include <net/ipv6.h>48#include <net/netlink.h>49#include <uapi/linux/batadv_packet.h>50#include <uapi/linux/batman_adv.h>5152#include "bridge_loop_avoidance.h"53#include "hard-interface.h"54#include "hash.h"55#include "log.h"56#include "netlink.h"57#include "send.h"58#include "translation-table.h"59#include "tvlv.h"6061static void batadv_mcast_mla_update(struct work_struct *work);6263/**64* batadv_mcast_start_timer() - schedule the multicast periodic worker65* @bat_priv: the bat priv with all the mesh interface information66*/67static void batadv_mcast_start_timer(struct batadv_priv *bat_priv)68{69queue_delayed_work(batadv_event_workqueue, &bat_priv->mcast.work,70msecs_to_jiffies(BATADV_MCAST_WORK_PERIOD));71}7273/**74* batadv_mcast_get_bridge() - get the bridge on top of the meshif if it exists75* @mesh_iface: netdev struct of the mesh interface76*77* If the given mesh interface has a bridge on top then the refcount78* of the according net device is increased.79*80* Return: NULL if no such bridge exists. Otherwise the net device of the81* bridge.82*/83static struct net_device *batadv_mcast_get_bridge(struct net_device *mesh_iface)84{85struct net_device *upper = mesh_iface;8687rcu_read_lock();88do {89upper = netdev_master_upper_dev_get_rcu(upper);90} while (upper && !netif_is_bridge_master(upper));9192dev_hold(upper);93rcu_read_unlock();9495return upper;96}9798/**99* batadv_mcast_mla_rtr_flags_meshif_get_ipv4() - get mcast router flags from100* node for IPv4101* @dev: the interface to check102*103* Checks the presence of an IPv4 multicast router on this node.104*105* Caller needs to hold rcu read lock.106*107* Return: BATADV_NO_FLAGS if present, BATADV_MCAST_WANT_NO_RTR4 otherwise.108*/109static u8 batadv_mcast_mla_rtr_flags_meshif_get_ipv4(struct net_device *dev)110{111struct in_device *in_dev = __in_dev_get_rcu(dev);112113if (in_dev && IN_DEV_MFORWARD(in_dev))114return BATADV_NO_FLAGS;115else116return BATADV_MCAST_WANT_NO_RTR4;117}118119/**120* batadv_mcast_mla_rtr_flags_meshif_get_ipv6() - get mcast router flags from121* node for IPv6122* @dev: the interface to check123*124* Checks the presence of an IPv6 multicast router on this node.125*126* Caller needs to hold rcu read lock.127*128* Return: BATADV_NO_FLAGS if present, BATADV_MCAST_WANT_NO_RTR6 otherwise.129*/130#if IS_ENABLED(CONFIG_IPV6_MROUTE)131static u8 batadv_mcast_mla_rtr_flags_meshif_get_ipv6(struct net_device *dev)132{133struct inet6_dev *in6_dev = __in6_dev_get(dev);134135if (in6_dev && atomic_read(&in6_dev->cnf.mc_forwarding))136return BATADV_NO_FLAGS;137else138return BATADV_MCAST_WANT_NO_RTR6;139}140#else141static inline u8142batadv_mcast_mla_rtr_flags_meshif_get_ipv6(struct net_device *dev)143{144return BATADV_MCAST_WANT_NO_RTR6;145}146#endif147148/**149* batadv_mcast_mla_rtr_flags_meshif_get() - get mcast router flags from node150* @bat_priv: the bat priv with all the mesh interface information151* @bridge: bridge interface on top of the mesh_iface if present,152* otherwise pass NULL153*154* Checks the presence of IPv4 and IPv6 multicast routers on this155* node.156*157* Return:158* BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present159* BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present160* BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present161* The former two OR'd: no multicast router is present162*/163static u8 batadv_mcast_mla_rtr_flags_meshif_get(struct batadv_priv *bat_priv,164struct net_device *bridge)165{166struct net_device *dev = bridge ? bridge : bat_priv->mesh_iface;167u8 flags = BATADV_NO_FLAGS;168169rcu_read_lock();170171flags |= batadv_mcast_mla_rtr_flags_meshif_get_ipv4(dev);172flags |= batadv_mcast_mla_rtr_flags_meshif_get_ipv6(dev);173174rcu_read_unlock();175176return flags;177}178179/**180* batadv_mcast_mla_rtr_flags_bridge_get() - get mcast router flags from bridge181* @bat_priv: the bat priv with all the mesh interface information182* @bridge: bridge interface on top of the mesh_iface if present,183* otherwise pass NULL184*185* Checks the presence of IPv4 and IPv6 multicast routers behind a bridge.186*187* Return:188* BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present189* BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present190* BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present191* The former two OR'd: no multicast router is present192*/193static u8 batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv,194struct net_device *bridge)195{196struct net_device *dev = bat_priv->mesh_iface;197u8 flags = BATADV_NO_FLAGS;198199if (!bridge)200return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;201202if (!br_multicast_has_router_adjacent(dev, ETH_P_IP))203flags |= BATADV_MCAST_WANT_NO_RTR4;204if (!br_multicast_has_router_adjacent(dev, ETH_P_IPV6))205flags |= BATADV_MCAST_WANT_NO_RTR6;206207return flags;208}209210/**211* batadv_mcast_mla_rtr_flags_get() - get multicast router flags212* @bat_priv: the bat priv with all the mesh interface information213* @bridge: bridge interface on top of the mesh_iface if present,214* otherwise pass NULL215*216* Checks the presence of IPv4 and IPv6 multicast routers on this217* node or behind its bridge.218*219* Return:220* BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present221* BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present222* BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present223* The former two OR'd: no multicast router is present224*/225static u8 batadv_mcast_mla_rtr_flags_get(struct batadv_priv *bat_priv,226struct net_device *bridge)227{228u8 flags = BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;229230flags &= batadv_mcast_mla_rtr_flags_meshif_get(bat_priv, bridge);231flags &= batadv_mcast_mla_rtr_flags_bridge_get(bat_priv, bridge);232233return flags;234}235236/**237* batadv_mcast_mla_forw_flags_get() - get multicast forwarding flags238* @bat_priv: the bat priv with all the mesh interface information239*240* Checks if all active hard interfaces have an MTU larger or equal to 1280241* bytes (IPv6 minimum MTU).242*243* Return: BATADV_MCAST_HAVE_MC_PTYPE_CAPA if yes, BATADV_NO_FLAGS otherwise.244*/245static u8 batadv_mcast_mla_forw_flags_get(struct batadv_priv *bat_priv)246{247const struct batadv_hard_iface *hard_iface;248struct list_head *iter;249250rcu_read_lock();251netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {252if (hard_iface->if_status != BATADV_IF_ACTIVE)253continue;254255if (hard_iface->net_dev->mtu < IPV6_MIN_MTU) {256rcu_read_unlock();257return BATADV_NO_FLAGS;258}259}260rcu_read_unlock();261262return BATADV_MCAST_HAVE_MC_PTYPE_CAPA;263}264265/**266* batadv_mcast_mla_flags_get() - get the new multicast flags267* @bat_priv: the bat priv with all the mesh interface information268*269* Return: A set of flags for the current/next TVLV, querier and270* bridge state.271*/272static struct batadv_mcast_mla_flags273batadv_mcast_mla_flags_get(struct batadv_priv *bat_priv)274{275struct net_device *dev = bat_priv->mesh_iface;276struct batadv_mcast_querier_state *qr4, *qr6;277struct batadv_mcast_mla_flags mla_flags;278struct net_device *bridge;279280bridge = batadv_mcast_get_bridge(dev);281282memset(&mla_flags, 0, sizeof(mla_flags));283mla_flags.enabled = 1;284mla_flags.tvlv_flags |= batadv_mcast_mla_rtr_flags_get(bat_priv,285bridge);286mla_flags.tvlv_flags |= batadv_mcast_mla_forw_flags_get(bat_priv);287288if (!bridge)289return mla_flags;290291dev_put(bridge);292293mla_flags.bridged = 1;294qr4 = &mla_flags.querier_ipv4;295qr6 = &mla_flags.querier_ipv6;296297if (!IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING))298pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");299300qr4->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);301qr4->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);302303qr6->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);304qr6->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);305306mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;307308/* 1) If no querier exists at all, then multicast listeners on309* our local TT clients behind the bridge will keep silent.310* 2) If the selected querier is on one of our local TT clients,311* behind the bridge, then this querier might shadow multicast312* listeners on our local TT clients, behind this bridge.313*314* In both cases, we will signalize other batman nodes that315* we need all multicast traffic of the according protocol.316*/317if (!qr4->exists || qr4->shadowing) {318mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV4;319mla_flags.tvlv_flags &= ~BATADV_MCAST_WANT_NO_RTR4;320}321322if (!qr6->exists || qr6->shadowing) {323mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV6;324mla_flags.tvlv_flags &= ~BATADV_MCAST_WANT_NO_RTR6;325}326327return mla_flags;328}329330/**331* batadv_mcast_mla_is_duplicate() - check whether an address is in a list332* @mcast_addr: the multicast address to check333* @mcast_list: the list with multicast addresses to search in334*335* Return: true if the given address is already in the given list.336* Otherwise returns false.337*/338static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,339struct hlist_head *mcast_list)340{341struct batadv_hw_addr *mcast_entry;342343hlist_for_each_entry(mcast_entry, mcast_list, list)344if (batadv_compare_eth(mcast_entry->addr, mcast_addr))345return true;346347return false;348}349350/**351* batadv_mcast_mla_meshif_get_ipv4() - get meshif IPv4 multicast listeners352* @dev: the device to collect multicast addresses from353* @mcast_list: a list to put found addresses into354* @flags: flags indicating the new multicast state355*356* Collects multicast addresses of IPv4 multicast listeners residing357* on this kernel on the given mesh interface, dev, in358* the given mcast_list. In general, multicast listeners provided by359* your multicast receiving applications run directly on this node.360*361* Return: -ENOMEM on memory allocation error or the number of362* items added to the mcast_list otherwise.363*/364static int365batadv_mcast_mla_meshif_get_ipv4(struct net_device *dev,366struct hlist_head *mcast_list,367struct batadv_mcast_mla_flags *flags)368{369struct batadv_hw_addr *new;370struct in_device *in_dev;371u8 mcast_addr[ETH_ALEN];372struct ip_mc_list *pmc;373int ret = 0;374375if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4)376return 0;377378rcu_read_lock();379380in_dev = __in_dev_get_rcu(dev);381if (!in_dev) {382rcu_read_unlock();383return 0;384}385386for (pmc = rcu_dereference(in_dev->mc_list); pmc;387pmc = rcu_dereference(pmc->next_rcu)) {388if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&389ipv4_is_local_multicast(pmc->multiaddr))390continue;391392if (!(flags->tvlv_flags & BATADV_MCAST_WANT_NO_RTR4) &&393!ipv4_is_local_multicast(pmc->multiaddr))394continue;395396ip_eth_mc_map(pmc->multiaddr, mcast_addr);397398if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))399continue;400401new = kmalloc(sizeof(*new), GFP_ATOMIC);402if (!new) {403ret = -ENOMEM;404break;405}406407ether_addr_copy(new->addr, mcast_addr);408hlist_add_head(&new->list, mcast_list);409ret++;410}411rcu_read_unlock();412413return ret;414}415416/**417* batadv_mcast_mla_meshif_get_ipv6() - get meshif IPv6 multicast listeners418* @dev: the device to collect multicast addresses from419* @mcast_list: a list to put found addresses into420* @flags: flags indicating the new multicast state421*422* Collects multicast addresses of IPv6 multicast listeners residing423* on this kernel on the given mesh interface, dev, in424* the given mcast_list. In general, multicast listeners provided by425* your multicast receiving applications run directly on this node.426*427* Return: -ENOMEM on memory allocation error or the number of428* items added to the mcast_list otherwise.429*/430#if IS_ENABLED(CONFIG_IPV6)431static int432batadv_mcast_mla_meshif_get_ipv6(struct net_device *dev,433struct hlist_head *mcast_list,434struct batadv_mcast_mla_flags *flags)435{436struct batadv_hw_addr *new;437struct inet6_dev *in6_dev;438u8 mcast_addr[ETH_ALEN];439struct ifmcaddr6 *pmc6;440int ret = 0;441442if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6)443return 0;444445rcu_read_lock();446447in6_dev = __in6_dev_get(dev);448if (!in6_dev) {449rcu_read_unlock();450return 0;451}452453for (pmc6 = rcu_dereference(in6_dev->mc_list);454pmc6;455pmc6 = rcu_dereference(pmc6->next)) {456if (IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) <457IPV6_ADDR_SCOPE_LINKLOCAL)458continue;459460if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&461ipv6_addr_is_ll_all_nodes(&pmc6->mca_addr))462continue;463464if (!(flags->tvlv_flags & BATADV_MCAST_WANT_NO_RTR6) &&465IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) >466IPV6_ADDR_SCOPE_LINKLOCAL)467continue;468469ipv6_eth_mc_map(&pmc6->mca_addr, mcast_addr);470471if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))472continue;473474new = kmalloc(sizeof(*new), GFP_ATOMIC);475if (!new) {476ret = -ENOMEM;477break;478}479480ether_addr_copy(new->addr, mcast_addr);481hlist_add_head(&new->list, mcast_list);482ret++;483}484rcu_read_unlock();485486return ret;487}488#else489static inline int490batadv_mcast_mla_meshif_get_ipv6(struct net_device *dev,491struct hlist_head *mcast_list,492struct batadv_mcast_mla_flags *flags)493{494return 0;495}496#endif497498/**499* batadv_mcast_mla_meshif_get() - get meshif multicast listeners500* @dev: the device to collect multicast addresses from501* @mcast_list: a list to put found addresses into502* @flags: flags indicating the new multicast state503*504* Collects multicast addresses of multicast listeners residing505* on this kernel on the given mesh interface, dev, in506* the given mcast_list. In general, multicast listeners provided by507* your multicast receiving applications run directly on this node.508*509* If there is a bridge interface on top of dev, collect from that one510* instead. Just like with IP addresses and routes, multicast listeners511* will(/should) register to the bridge interface instead of an512* enslaved bat0.513*514* Return: -ENOMEM on memory allocation error or the number of515* items added to the mcast_list otherwise.516*/517static int518batadv_mcast_mla_meshif_get(struct net_device *dev,519struct hlist_head *mcast_list,520struct batadv_mcast_mla_flags *flags)521{522struct net_device *bridge = batadv_mcast_get_bridge(dev);523int ret4, ret6 = 0;524525if (bridge)526dev = bridge;527528ret4 = batadv_mcast_mla_meshif_get_ipv4(dev, mcast_list, flags);529if (ret4 < 0)530goto out;531532ret6 = batadv_mcast_mla_meshif_get_ipv6(dev, mcast_list, flags);533if (ret6 < 0) {534ret4 = 0;535goto out;536}537538out:539dev_put(bridge);540541return ret4 + ret6;542}543544/**545* batadv_mcast_mla_br_addr_cpy() - copy a bridge multicast address546* @dst: destination to write to - a multicast MAC address547* @src: source to read from - a multicast IP address548*549* Converts a given multicast IPv4/IPv6 address from a bridge550* to its matching multicast MAC address and copies it into the given551* destination buffer.552*553* Caller needs to make sure the destination buffer can hold554* at least ETH_ALEN bytes.555*/556static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)557{558if (src->proto == htons(ETH_P_IP))559ip_eth_mc_map(src->dst.ip4, dst);560#if IS_ENABLED(CONFIG_IPV6)561else if (src->proto == htons(ETH_P_IPV6))562ipv6_eth_mc_map(&src->dst.ip6, dst);563#endif564else565eth_zero_addr(dst);566}567568/**569* batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners570* @dev: a bridge slave whose bridge to collect multicast addresses from571* @mcast_list: a list to put found addresses into572* @flags: flags indicating the new multicast state573*574* Collects multicast addresses of multicast listeners residing575* on foreign, non-mesh devices which we gave access to our mesh via576* a bridge on top of the given mesh interface, dev, in the given577* mcast_list.578*579* Return: -ENOMEM on memory allocation error or the number of580* items added to the mcast_list otherwise.581*/582static int batadv_mcast_mla_bridge_get(struct net_device *dev,583struct hlist_head *mcast_list,584struct batadv_mcast_mla_flags *flags)585{586struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);587struct br_ip_list *br_ip_entry, *tmp;588u8 tvlv_flags = flags->tvlv_flags;589struct batadv_hw_addr *new;590u8 mcast_addr[ETH_ALEN];591int ret;592593/* we don't need to detect these devices/listeners, the IGMP/MLD594* snooping code of the Linux bridge already does that for us595*/596ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);597if (ret < 0)598goto out;599600list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {601if (br_ip_entry->addr.proto == htons(ETH_P_IP)) {602if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4)603continue;604605if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&606ipv4_is_local_multicast(br_ip_entry->addr.dst.ip4))607continue;608609if (!(tvlv_flags & BATADV_MCAST_WANT_NO_RTR4) &&610!ipv4_is_local_multicast(br_ip_entry->addr.dst.ip4))611continue;612}613614#if IS_ENABLED(CONFIG_IPV6)615if (br_ip_entry->addr.proto == htons(ETH_P_IPV6)) {616if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6)617continue;618619if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&620ipv6_addr_is_ll_all_nodes(&br_ip_entry->addr.dst.ip6))621continue;622623if (!(tvlv_flags & BATADV_MCAST_WANT_NO_RTR6) &&624IPV6_ADDR_MC_SCOPE(&br_ip_entry->addr.dst.ip6) >625IPV6_ADDR_SCOPE_LINKLOCAL)626continue;627}628#endif629630batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);631if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))632continue;633634new = kmalloc(sizeof(*new), GFP_ATOMIC);635if (!new) {636ret = -ENOMEM;637break;638}639640ether_addr_copy(new->addr, mcast_addr);641hlist_add_head(&new->list, mcast_list);642}643644out:645list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {646list_del(&br_ip_entry->list);647kfree(br_ip_entry);648}649650return ret;651}652653/**654* batadv_mcast_mla_list_free() - free a list of multicast addresses655* @mcast_list: the list to free656*657* Removes and frees all items in the given mcast_list.658*/659static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)660{661struct batadv_hw_addr *mcast_entry;662struct hlist_node *tmp;663664hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {665hlist_del(&mcast_entry->list);666kfree(mcast_entry);667}668}669670/**671* batadv_mcast_mla_tt_retract() - clean up multicast listener announcements672* @bat_priv: the bat priv with all the mesh interface information673* @mcast_list: a list of addresses which should _not_ be removed674*675* Retracts the announcement of any multicast listener from the676* translation table except the ones listed in the given mcast_list.677*678* If mcast_list is NULL then all are retracted.679*/680static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,681struct hlist_head *mcast_list)682{683struct batadv_hw_addr *mcast_entry;684struct hlist_node *tmp;685686hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,687list) {688if (mcast_list &&689batadv_mcast_mla_is_duplicate(mcast_entry->addr,690mcast_list))691continue;692693batadv_tt_local_remove(bat_priv, mcast_entry->addr,694BATADV_NO_FLAGS,695"mcast TT outdated", false);696697hlist_del(&mcast_entry->list);698kfree(mcast_entry);699}700}701702/**703* batadv_mcast_mla_tt_add() - add multicast listener announcements704* @bat_priv: the bat priv with all the mesh interface information705* @mcast_list: a list of addresses which are going to get added706*707* Adds multicast listener announcements from the given mcast_list to the708* translation table if they have not been added yet.709*/710static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,711struct hlist_head *mcast_list)712{713struct batadv_hw_addr *mcast_entry;714struct hlist_node *tmp;715716if (!mcast_list)717return;718719hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {720if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,721&bat_priv->mcast.mla_list))722continue;723724if (!batadv_tt_local_add(bat_priv->mesh_iface,725mcast_entry->addr, BATADV_NO_FLAGS,726BATADV_NULL_IFINDEX, BATADV_NO_MARK))727continue;728729hlist_del(&mcast_entry->list);730hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);731}732}733734/**735* batadv_mcast_querier_log() - debug output regarding the querier status on736* link737* @bat_priv: the bat priv with all the mesh interface information738* @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")739* @old_state: the previous querier state on our link740* @new_state: the new querier state on our link741*742* Outputs debug messages to the logging facility with log level 'mcast'743* regarding changes to the querier status on the link which are relevant744* to our multicast optimizations.745*746* Usually this is about whether a querier appeared or vanished in747* our mesh or whether the querier is in the suboptimal position of being748* behind our local bridge segment: Snooping switches will directly749* forward listener reports to the querier, therefore batman-adv and750* the bridge will potentially not see these listeners - the querier is751* potentially shadowing listeners from us then.752*753* This is only interesting for nodes with a bridge on top of their754* mesh interface.755*/756static void757batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,758struct batadv_mcast_querier_state *old_state,759struct batadv_mcast_querier_state *new_state)760{761if (!old_state->exists && new_state->exists)762batadv_info(bat_priv->mesh_iface, "%s Querier appeared\n",763str_proto);764else if (old_state->exists && !new_state->exists)765batadv_info(bat_priv->mesh_iface,766"%s Querier disappeared - multicast optimizations disabled\n",767str_proto);768else if (!bat_priv->mcast.mla_flags.bridged && !new_state->exists)769batadv_info(bat_priv->mesh_iface,770"No %s Querier present - multicast optimizations disabled\n",771str_proto);772773if (new_state->exists) {774if ((!old_state->shadowing && new_state->shadowing) ||775(!old_state->exists && new_state->shadowing))776batadv_dbg(BATADV_DBG_MCAST, bat_priv,777"%s Querier is behind our bridged segment: Might shadow listeners\n",778str_proto);779else if (old_state->shadowing && !new_state->shadowing)780batadv_dbg(BATADV_DBG_MCAST, bat_priv,781"%s Querier is not behind our bridged segment\n",782str_proto);783}784}785786/**787* batadv_mcast_bridge_log() - debug output for topology changes in bridged788* setups789* @bat_priv: the bat priv with all the mesh interface information790* @new_flags: flags indicating the new multicast state791*792* If no bridges are ever used on this node, then this function does nothing.793*794* Otherwise this function outputs debug information to the 'mcast' log level795* which might be relevant to our multicast optimizations.796*797* More precisely, it outputs information when a bridge interface is added or798* removed from a mesh interface. And when a bridge is present, it further799* outputs information about the querier state which is relevant for the800* multicast flags this node is going to set.801*/802static void803batadv_mcast_bridge_log(struct batadv_priv *bat_priv,804struct batadv_mcast_mla_flags *new_flags)805{806struct batadv_mcast_mla_flags *old_flags = &bat_priv->mcast.mla_flags;807808if (!old_flags->bridged && new_flags->bridged)809batadv_dbg(BATADV_DBG_MCAST, bat_priv,810"Bridge added: Setting Unsnoopables(U)-flag\n");811else if (old_flags->bridged && !new_flags->bridged)812batadv_dbg(BATADV_DBG_MCAST, bat_priv,813"Bridge removed: Unsetting Unsnoopables(U)-flag\n");814815if (new_flags->bridged) {816batadv_mcast_querier_log(bat_priv, "IGMP",817&old_flags->querier_ipv4,818&new_flags->querier_ipv4);819batadv_mcast_querier_log(bat_priv, "MLD",820&old_flags->querier_ipv6,821&new_flags->querier_ipv6);822}823}824825/**826* batadv_mcast_flags_log() - output debug information about mcast flag changes827* @bat_priv: the bat priv with all the mesh interface information828* @flags: TVLV flags indicating the new multicast state829*830* Whenever the multicast TVLV flags this node announces change, this function831* should be used to notify userspace about the change.832*/833static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)834{835bool old_enabled = bat_priv->mcast.mla_flags.enabled;836u8 old_flags = bat_priv->mcast.mla_flags.tvlv_flags;837char str_old_flags[] = "[.... . .]";838839sprintf(str_old_flags, "[%c%c%c%s%s%c]",840(old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',841(old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',842(old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',843!(old_flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",844!(old_flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",845!(old_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');846847batadv_dbg(BATADV_DBG_MCAST, bat_priv,848"Changing multicast flags from '%s' to '[%c%c%c%s%s%c]'\n",849old_enabled ? str_old_flags : "<undefined>",850(flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',851(flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',852(flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',853!(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",854!(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",855!(flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');856}857858/**859* batadv_mcast_mla_flags_update() - update multicast flags860* @bat_priv: the bat priv with all the mesh interface information861* @flags: flags indicating the new multicast state862*863* Updates the own multicast tvlv with our current multicast related settings,864* capabilities and inabilities.865*/866static void867batadv_mcast_mla_flags_update(struct batadv_priv *bat_priv,868struct batadv_mcast_mla_flags *flags)869{870struct batadv_tvlv_mcast_data mcast_data;871872if (!memcmp(flags, &bat_priv->mcast.mla_flags, sizeof(*flags)))873return;874875batadv_mcast_bridge_log(bat_priv, flags);876batadv_mcast_flags_log(bat_priv, flags->tvlv_flags);877878mcast_data.flags = flags->tvlv_flags;879memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));880881batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,882&mcast_data, sizeof(mcast_data));883884bat_priv->mcast.mla_flags = *flags;885}886887/**888* __batadv_mcast_mla_update() - update the own MLAs889* @bat_priv: the bat priv with all the mesh interface information890*891* Updates the own multicast listener announcements in the translation892* table as well as the own, announced multicast tvlv container.893*894* Note that non-conflicting reads and writes to bat_priv->mcast.mla_list895* in batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add() are896* ensured by the non-parallel execution of the worker this function897* belongs to.898*/899static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)900{901struct net_device *mesh_iface = bat_priv->mesh_iface;902struct hlist_head mcast_list = HLIST_HEAD_INIT;903struct batadv_mcast_mla_flags flags;904int ret;905906flags = batadv_mcast_mla_flags_get(bat_priv);907908ret = batadv_mcast_mla_meshif_get(mesh_iface, &mcast_list, &flags);909if (ret < 0)910goto out;911912ret = batadv_mcast_mla_bridge_get(mesh_iface, &mcast_list, &flags);913if (ret < 0)914goto out;915916spin_lock(&bat_priv->mcast.mla_lock);917batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);918batadv_mcast_mla_tt_add(bat_priv, &mcast_list);919batadv_mcast_mla_flags_update(bat_priv, &flags);920spin_unlock(&bat_priv->mcast.mla_lock);921922out:923batadv_mcast_mla_list_free(&mcast_list);924}925926/**927* batadv_mcast_mla_update() - update the own MLAs928* @work: kernel work struct929*930* Updates the own multicast listener announcements in the translation931* table as well as the own, announced multicast tvlv container.932*933* In the end, reschedules the work timer.934*/935static void batadv_mcast_mla_update(struct work_struct *work)936{937struct delayed_work *delayed_work;938struct batadv_priv_mcast *priv_mcast;939struct batadv_priv *bat_priv;940941delayed_work = to_delayed_work(work);942priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work);943bat_priv = container_of(priv_mcast, struct batadv_priv, mcast);944945__batadv_mcast_mla_update(bat_priv);946batadv_mcast_start_timer(bat_priv);947}948949/**950* batadv_mcast_is_report_ipv4() - check for IGMP reports951* @skb: the ethernet frame destined for the mesh952*953* This call might reallocate skb data.954*955* Checks whether the given frame is a valid IGMP report.956*957* Return: If so then true, otherwise false.958*/959static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)960{961if (ip_mc_check_igmp(skb) < 0)962return false;963964switch (igmp_hdr(skb)->type) {965case IGMP_HOST_MEMBERSHIP_REPORT:966case IGMPV2_HOST_MEMBERSHIP_REPORT:967case IGMPV3_HOST_MEMBERSHIP_REPORT:968return true;969}970971return false;972}973974/**975* batadv_mcast_forw_mode_check_ipv4() - check for optimized forwarding976* potential977* @bat_priv: the bat priv with all the mesh interface information978* @skb: the IPv4 packet to check979* @is_unsnoopable: stores whether the destination is snoopable980* @is_routable: stores whether the destination is routable981*982* Checks whether the given IPv4 packet has the potential to be forwarded with a983* mode more optimal than classic flooding.984*985* Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory986* allocation failure.987*/988static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,989struct sk_buff *skb,990bool *is_unsnoopable,991int *is_routable)992{993struct iphdr *iphdr;994995/* We might fail due to out-of-memory -> drop it */996if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))997return -ENOMEM;998999if (batadv_mcast_is_report_ipv4(skb))1000return -EINVAL;10011002iphdr = ip_hdr(skb);10031004/* link-local multicast listeners behind a bridge are1005* not snoopable (see RFC4541, section 2.1.2.2)1006*/1007if (ipv4_is_local_multicast(iphdr->daddr))1008*is_unsnoopable = true;1009else1010*is_routable = ETH_P_IP;10111012return 0;1013}10141015/**1016* batadv_mcast_is_report_ipv6() - check for MLD reports1017* @skb: the ethernet frame destined for the mesh1018*1019* This call might reallocate skb data.1020*1021* Checks whether the given frame is a valid MLD report.1022*1023* Return: If so then true, otherwise false.1024*/1025static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)1026{1027if (ipv6_mc_check_mld(skb) < 0)1028return false;10291030switch (icmp6_hdr(skb)->icmp6_type) {1031case ICMPV6_MGM_REPORT:1032case ICMPV6_MLD2_REPORT:1033return true;1034}10351036return false;1037}10381039/**1040* batadv_mcast_forw_mode_check_ipv6() - check for optimized forwarding1041* potential1042* @bat_priv: the bat priv with all the mesh interface information1043* @skb: the IPv6 packet to check1044* @is_unsnoopable: stores whether the destination is snoopable1045* @is_routable: stores whether the destination is routable1046*1047* Checks whether the given IPv6 packet has the potential to be forwarded with a1048* mode more optimal than classic flooding.1049*1050* Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory1051*/1052static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,1053struct sk_buff *skb,1054bool *is_unsnoopable,1055int *is_routable)1056{1057struct ipv6hdr *ip6hdr;10581059/* We might fail due to out-of-memory -> drop it */1060if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))1061return -ENOMEM;10621063if (batadv_mcast_is_report_ipv6(skb))1064return -EINVAL;10651066ip6hdr = ipv6_hdr(skb);10671068if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) < IPV6_ADDR_SCOPE_LINKLOCAL)1069return -EINVAL;10701071/* link-local-all-nodes multicast listeners behind a bridge are1072* not snoopable (see RFC4541, section 3, paragraph 3)1073*/1074if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))1075*is_unsnoopable = true;1076else if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) > IPV6_ADDR_SCOPE_LINKLOCAL)1077*is_routable = ETH_P_IPV6;10781079return 0;1080}10811082/**1083* batadv_mcast_forw_mode_check() - check for optimized forwarding potential1084* @bat_priv: the bat priv with all the mesh interface information1085* @skb: the multicast frame to check1086* @is_unsnoopable: stores whether the destination is snoopable1087* @is_routable: stores whether the destination is routable1088*1089* Checks whether the given multicast ethernet frame has the potential to be1090* forwarded with a mode more optimal than classic flooding.1091*1092* Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory1093*/1094static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,1095struct sk_buff *skb,1096bool *is_unsnoopable,1097int *is_routable)1098{1099struct ethhdr *ethhdr = eth_hdr(skb);11001101if (!atomic_read(&bat_priv->multicast_mode))1102return -EINVAL;11031104switch (ntohs(ethhdr->h_proto)) {1105case ETH_P_IP:1106return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,1107is_unsnoopable,1108is_routable);1109case ETH_P_IPV6:1110if (!IS_ENABLED(CONFIG_IPV6))1111return -EINVAL;11121113return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,1114is_unsnoopable,1115is_routable);1116default:1117return -EINVAL;1118}1119}11201121/**1122* batadv_mcast_forw_want_all_ip_count() - count nodes with unspecific mcast1123* interest1124* @bat_priv: the bat priv with all the mesh interface information1125* @ethhdr: ethernet header of a packet1126*1127* Return: the number of nodes which want all IPv4 multicast traffic if the1128* given ethhdr is from an IPv4 packet or the number of nodes which want all1129* IPv6 traffic if it matches an IPv6 packet.1130*/1131static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,1132struct ethhdr *ethhdr)1133{1134switch (ntohs(ethhdr->h_proto)) {1135case ETH_P_IP:1136return atomic_read(&bat_priv->mcast.num_want_all_ipv4);1137case ETH_P_IPV6:1138return atomic_read(&bat_priv->mcast.num_want_all_ipv6);1139default:1140/* we shouldn't be here... */1141return 0;1142}1143}11441145/**1146* batadv_mcast_forw_rtr_count() - count nodes with a multicast router1147* @bat_priv: the bat priv with all the mesh interface information1148* @protocol: the ethernet protocol type to count multicast routers for1149*1150* Return: the number of nodes which want all routable IPv4 multicast traffic1151* if the protocol is ETH_P_IP or the number of nodes which want all routable1152* IPv6 traffic if the protocol is ETH_P_IPV6. Otherwise returns 0.1153*/11541155static int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv,1156int protocol)1157{1158switch (protocol) {1159case ETH_P_IP:1160return atomic_read(&bat_priv->mcast.num_want_all_rtr4);1161case ETH_P_IPV6:1162return atomic_read(&bat_priv->mcast.num_want_all_rtr6);1163default:1164return 0;1165}1166}11671168/**1169* batadv_mcast_forw_mode_by_count() - get forwarding mode by count1170* @bat_priv: the bat priv with all the mesh interface information1171* @skb: the multicast packet to check1172* @vid: the vlan identifier1173* @is_routable: stores whether the destination is routable1174* @count: the number of originators the multicast packet need to be sent to1175*1176* For a multicast packet with multiple destination originators, checks which1177* mode to use. For BATADV_FORW_MCAST it also encapsulates the packet with a1178* complete batman-adv multicast header.1179*1180* Return:1181* BATADV_FORW_MCAST: If all nodes have multicast packet routing1182* capabilities and an MTU >= 1280 on all hard interfaces (including us)1183* and the encapsulated multicast packet with all destination addresses1184* would still fit into an 1280 bytes batman-adv multicast packet1185* (excluding the outer ethernet frame) and we could successfully push1186* the full batman-adv multicast packet header.1187* BATADV_FORW_UCASTS: If the packet cannot be sent in a batman-adv1188* multicast packet and the amount of batman-adv unicast packets needed1189* is smaller or equal to the configured multicast fanout.1190* BATADV_FORW_BCAST: Otherwise.1191*/1192static enum batadv_forw_mode1193batadv_mcast_forw_mode_by_count(struct batadv_priv *bat_priv,1194struct sk_buff *skb, unsigned short vid,1195int is_routable, int count)1196{1197unsigned int mcast_hdrlen = batadv_mcast_forw_packet_hdrlen(count);1198u8 own_tvlv_flags = bat_priv->mcast.mla_flags.tvlv_flags;11991200if (!atomic_read(&bat_priv->mcast.num_no_mc_ptype_capa) &&1201own_tvlv_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA &&1202skb->len + mcast_hdrlen <= IPV6_MIN_MTU &&1203batadv_mcast_forw_push(bat_priv, skb, vid, is_routable, count))1204return BATADV_FORW_MCAST;12051206if (count <= atomic_read(&bat_priv->multicast_fanout))1207return BATADV_FORW_UCASTS;12081209return BATADV_FORW_BCAST;1210}12111212/**1213* batadv_mcast_forw_mode() - check on how to forward a multicast packet1214* @bat_priv: the bat priv with all the mesh interface information1215* @skb: the multicast packet to check1216* @vid: the vlan identifier1217* @is_routable: stores whether the destination is routable1218*1219* Return: The forwarding mode as enum batadv_forw_mode.1220*/1221enum batadv_forw_mode1222batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,1223unsigned short vid, int *is_routable)1224{1225int ret, tt_count, ip_count, unsnoop_count, total_count;1226bool is_unsnoopable = false;1227struct ethhdr *ethhdr;1228int rtr_count = 0;12291230ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable,1231is_routable);1232if (ret == -ENOMEM)1233return BATADV_FORW_NONE;1234else if (ret < 0)1235return BATADV_FORW_BCAST;12361237ethhdr = eth_hdr(skb);12381239tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,1240BATADV_NO_FLAGS);1241ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);1242unsnoop_count = !is_unsnoopable ? 0 :1243atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);1244rtr_count = batadv_mcast_forw_rtr_count(bat_priv, *is_routable);12451246total_count = tt_count + ip_count + unsnoop_count + rtr_count;12471248if (!total_count)1249return BATADV_FORW_NONE;1250else if (unsnoop_count)1251return BATADV_FORW_BCAST;12521253return batadv_mcast_forw_mode_by_count(bat_priv, skb, vid, *is_routable,1254total_count);1255}12561257/**1258* batadv_mcast_forw_send_orig() - send a multicast packet to an originator1259* @bat_priv: the bat priv with all the mesh interface information1260* @skb: the multicast packet to send1261* @vid: the vlan identifier1262* @orig_node: the originator to send the packet to1263*1264* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.1265*/1266static int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,1267struct sk_buff *skb,1268unsigned short vid,1269struct batadv_orig_node *orig_node)1270{1271/* Avoid sending multicast-in-unicast packets to other BLA1272* gateways - they already got the frame from the LAN side1273* we share with them.1274* TODO: Refactor to take BLA into account earlier, to avoid1275* reducing the mcast_fanout count.1276*/1277if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {1278dev_kfree_skb(skb);1279return NET_XMIT_SUCCESS;1280}12811282return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,1283orig_node, vid);1284}12851286/**1287* batadv_mcast_forw_tt() - forwards a packet to multicast listeners1288* @bat_priv: the bat priv with all the mesh interface information1289* @skb: the multicast packet to transmit1290* @vid: the vlan identifier1291*1292* Sends copies of a frame with multicast destination to any multicast1293* listener registered in the translation table. A transmission is performed1294* via a batman-adv unicast packet for each such destination node.1295*1296* Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS1297* otherwise.1298*/1299static int1300batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,1301unsigned short vid)1302{1303int ret = NET_XMIT_SUCCESS;1304struct sk_buff *newskb;13051306struct batadv_tt_orig_list_entry *orig_entry;13071308struct batadv_tt_global_entry *tt_global;1309const u8 *addr = eth_hdr(skb)->h_dest;13101311tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);1312if (!tt_global)1313goto out;13141315rcu_read_lock();1316hlist_for_each_entry_rcu(orig_entry, &tt_global->orig_list, list) {1317newskb = skb_copy(skb, GFP_ATOMIC);1318if (!newskb) {1319ret = NET_XMIT_DROP;1320break;1321}13221323batadv_mcast_forw_send_orig(bat_priv, newskb, vid,1324orig_entry->orig_node);1325}1326rcu_read_unlock();13271328batadv_tt_global_entry_put(tt_global);13291330out:1331return ret;1332}13331334/**1335* batadv_mcast_forw_want_all_ipv4() - forward to nodes with want-all-ipv41336* @bat_priv: the bat priv with all the mesh interface information1337* @skb: the multicast packet to transmit1338* @vid: the vlan identifier1339*1340* Sends copies of a frame with multicast destination to any node with a1341* BATADV_MCAST_WANT_ALL_IPV4 flag set. A transmission is performed via a1342* batman-adv unicast packet for each such destination node.1343*1344* Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS1345* otherwise.1346*/1347static int1348batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,1349struct sk_buff *skb, unsigned short vid)1350{1351struct batadv_orig_node *orig_node;1352int ret = NET_XMIT_SUCCESS;1353struct sk_buff *newskb;13541355rcu_read_lock();1356hlist_for_each_entry_rcu(orig_node,1357&bat_priv->mcast.want_all_ipv4_list,1358mcast_want_all_ipv4_node) {1359newskb = skb_copy(skb, GFP_ATOMIC);1360if (!newskb) {1361ret = NET_XMIT_DROP;1362break;1363}13641365batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);1366}1367rcu_read_unlock();1368return ret;1369}13701371/**1372* batadv_mcast_forw_want_all_ipv6() - forward to nodes with want-all-ipv61373* @bat_priv: the bat priv with all the mesh interface information1374* @skb: The multicast packet to transmit1375* @vid: the vlan identifier1376*1377* Sends copies of a frame with multicast destination to any node with a1378* BATADV_MCAST_WANT_ALL_IPV6 flag set. A transmission is performed via a1379* batman-adv unicast packet for each such destination node.1380*1381* Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS1382* otherwise.1383*/1384static int1385batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,1386struct sk_buff *skb, unsigned short vid)1387{1388struct batadv_orig_node *orig_node;1389int ret = NET_XMIT_SUCCESS;1390struct sk_buff *newskb;13911392rcu_read_lock();1393hlist_for_each_entry_rcu(orig_node,1394&bat_priv->mcast.want_all_ipv6_list,1395mcast_want_all_ipv6_node) {1396newskb = skb_copy(skb, GFP_ATOMIC);1397if (!newskb) {1398ret = NET_XMIT_DROP;1399break;1400}14011402batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);1403}1404rcu_read_unlock();1405return ret;1406}14071408/**1409* batadv_mcast_forw_want_all() - forward packet to nodes in a want-all list1410* @bat_priv: the bat priv with all the mesh interface information1411* @skb: the multicast packet to transmit1412* @vid: the vlan identifier1413*1414* Sends copies of a frame with multicast destination to any node with a1415* BATADV_MCAST_WANT_ALL_IPV4 or BATADV_MCAST_WANT_ALL_IPV6 flag set. A1416* transmission is performed via a batman-adv unicast packet for each such1417* destination node.1418*1419* Return: NET_XMIT_DROP on memory allocation failure or if the protocol family1420* is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.1421*/1422static int1423batadv_mcast_forw_want_all(struct batadv_priv *bat_priv,1424struct sk_buff *skb, unsigned short vid)1425{1426switch (ntohs(eth_hdr(skb)->h_proto)) {1427case ETH_P_IP:1428return batadv_mcast_forw_want_all_ipv4(bat_priv, skb, vid);1429case ETH_P_IPV6:1430return batadv_mcast_forw_want_all_ipv6(bat_priv, skb, vid);1431default:1432/* we shouldn't be here... */1433return NET_XMIT_DROP;1434}1435}14361437/**1438* batadv_mcast_forw_want_all_rtr4() - forward to nodes with want-all-rtr41439* @bat_priv: the bat priv with all the mesh interface information1440* @skb: the multicast packet to transmit1441* @vid: the vlan identifier1442*1443* Sends copies of a frame with multicast destination to any node with a1444* BATADV_MCAST_WANT_NO_RTR4 flag unset. A transmission is performed via a1445* batman-adv unicast packet for each such destination node.1446*1447* Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS1448* otherwise.1449*/1450static int1451batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv,1452struct sk_buff *skb, unsigned short vid)1453{1454struct batadv_orig_node *orig_node;1455int ret = NET_XMIT_SUCCESS;1456struct sk_buff *newskb;14571458rcu_read_lock();1459hlist_for_each_entry_rcu(orig_node,1460&bat_priv->mcast.want_all_rtr4_list,1461mcast_want_all_rtr4_node) {1462newskb = skb_copy(skb, GFP_ATOMIC);1463if (!newskb) {1464ret = NET_XMIT_DROP;1465break;1466}14671468batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);1469}1470rcu_read_unlock();1471return ret;1472}14731474/**1475* batadv_mcast_forw_want_all_rtr6() - forward to nodes with want-all-rtr61476* @bat_priv: the bat priv with all the mesh interface information1477* @skb: The multicast packet to transmit1478* @vid: the vlan identifier1479*1480* Sends copies of a frame with multicast destination to any node with a1481* BATADV_MCAST_WANT_NO_RTR6 flag unset. A transmission is performed via a1482* batman-adv unicast packet for each such destination node.1483*1484* Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS1485* otherwise.1486*/1487static int1488batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv,1489struct sk_buff *skb, unsigned short vid)1490{1491struct batadv_orig_node *orig_node;1492int ret = NET_XMIT_SUCCESS;1493struct sk_buff *newskb;14941495rcu_read_lock();1496hlist_for_each_entry_rcu(orig_node,1497&bat_priv->mcast.want_all_rtr6_list,1498mcast_want_all_rtr6_node) {1499newskb = skb_copy(skb, GFP_ATOMIC);1500if (!newskb) {1501ret = NET_XMIT_DROP;1502break;1503}15041505batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);1506}1507rcu_read_unlock();1508return ret;1509}15101511/**1512* batadv_mcast_forw_want_rtr() - forward packet to nodes in a want-all-rtr list1513* @bat_priv: the bat priv with all the mesh interface information1514* @skb: the multicast packet to transmit1515* @vid: the vlan identifier1516*1517* Sends copies of a frame with multicast destination to any node with a1518* BATADV_MCAST_WANT_NO_RTR4 or BATADV_MCAST_WANT_NO_RTR6 flag unset. A1519* transmission is performed via a batman-adv unicast packet for each such1520* destination node.1521*1522* Return: NET_XMIT_DROP on memory allocation failure or if the protocol family1523* is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.1524*/1525static int1526batadv_mcast_forw_want_rtr(struct batadv_priv *bat_priv,1527struct sk_buff *skb, unsigned short vid)1528{1529switch (ntohs(eth_hdr(skb)->h_proto)) {1530case ETH_P_IP:1531return batadv_mcast_forw_want_all_rtr4(bat_priv, skb, vid);1532case ETH_P_IPV6:1533return batadv_mcast_forw_want_all_rtr6(bat_priv, skb, vid);1534default:1535/* we shouldn't be here... */1536return NET_XMIT_DROP;1537}1538}15391540/**1541* batadv_mcast_forw_send() - send packet to any detected multicast recipient1542* @bat_priv: the bat priv with all the mesh interface information1543* @skb: the multicast packet to transmit1544* @vid: the vlan identifier1545* @is_routable: stores whether the destination is routable1546*1547* Sends copies of a frame with multicast destination to any node that signaled1548* interest in it, that is either via the translation table or the according1549* want-all flags. A transmission is performed via a batman-adv unicast packet1550* for each such destination node.1551*1552* The given skb is consumed/freed.1553*1554* Return: NET_XMIT_DROP on memory allocation failure or if the protocol family1555* is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.1556*/1557int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,1558unsigned short vid, int is_routable)1559{1560int ret;15611562ret = batadv_mcast_forw_tt(bat_priv, skb, vid);1563if (ret != NET_XMIT_SUCCESS) {1564kfree_skb(skb);1565return ret;1566}15671568ret = batadv_mcast_forw_want_all(bat_priv, skb, vid);1569if (ret != NET_XMIT_SUCCESS) {1570kfree_skb(skb);1571return ret;1572}15731574if (!is_routable)1575goto skip_mc_router;15761577ret = batadv_mcast_forw_want_rtr(bat_priv, skb, vid);1578if (ret != NET_XMIT_SUCCESS) {1579kfree_skb(skb);1580return ret;1581}15821583skip_mc_router:1584consume_skb(skb);1585return ret;1586}15871588/**1589* batadv_mcast_want_unsnoop_update() - update unsnoop counter and list1590* @bat_priv: the bat priv with all the mesh interface information1591* @orig: the orig_node which multicast state might have changed of1592* @mcast_flags: flags indicating the new multicast state1593*1594* If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,1595* orig, has toggled then this method updates the counter and the list1596* accordingly.1597*1598* Caller needs to hold orig->mcast_handler_lock.1599*/1600static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,1601struct batadv_orig_node *orig,1602u8 mcast_flags)1603{1604struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;1605struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;16061607lockdep_assert_held(&orig->mcast_handler_lock);16081609/* switched from flag unset to set */1610if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&1611!(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {1612atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);16131614spin_lock_bh(&bat_priv->mcast.want_lists_lock);1615/* flag checks above + mcast_handler_lock prevents this */1616WARN_ON(!hlist_unhashed(node));16171618hlist_add_head_rcu(node, head);1619spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1620/* switched from flag set to unset */1621} else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&1622orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {1623atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);16241625spin_lock_bh(&bat_priv->mcast.want_lists_lock);1626/* flag checks above + mcast_handler_lock prevents this */1627WARN_ON(hlist_unhashed(node));16281629hlist_del_init_rcu(node);1630spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1631}1632}16331634/**1635* batadv_mcast_want_ipv4_update() - update want-all-ipv4 counter and list1636* @bat_priv: the bat priv with all the mesh interface information1637* @orig: the orig_node which multicast state might have changed of1638* @mcast_flags: flags indicating the new multicast state1639*1640* If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has1641* toggled then this method updates the counter and the list accordingly.1642*1643* Caller needs to hold orig->mcast_handler_lock.1644*/1645static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,1646struct batadv_orig_node *orig,1647u8 mcast_flags)1648{1649struct hlist_node *node = &orig->mcast_want_all_ipv4_node;1650struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;16511652lockdep_assert_held(&orig->mcast_handler_lock);16531654/* switched from flag unset to set */1655if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&1656!(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {1657atomic_inc(&bat_priv->mcast.num_want_all_ipv4);16581659spin_lock_bh(&bat_priv->mcast.want_lists_lock);1660/* flag checks above + mcast_handler_lock prevents this */1661WARN_ON(!hlist_unhashed(node));16621663hlist_add_head_rcu(node, head);1664spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1665/* switched from flag set to unset */1666} else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&1667orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {1668atomic_dec(&bat_priv->mcast.num_want_all_ipv4);16691670spin_lock_bh(&bat_priv->mcast.want_lists_lock);1671/* flag checks above + mcast_handler_lock prevents this */1672WARN_ON(hlist_unhashed(node));16731674hlist_del_init_rcu(node);1675spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1676}1677}16781679/**1680* batadv_mcast_want_ipv6_update() - update want-all-ipv6 counter and list1681* @bat_priv: the bat priv with all the mesh interface information1682* @orig: the orig_node which multicast state might have changed of1683* @mcast_flags: flags indicating the new multicast state1684*1685* If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has1686* toggled then this method updates the counter and the list accordingly.1687*1688* Caller needs to hold orig->mcast_handler_lock.1689*/1690static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,1691struct batadv_orig_node *orig,1692u8 mcast_flags)1693{1694struct hlist_node *node = &orig->mcast_want_all_ipv6_node;1695struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;16961697lockdep_assert_held(&orig->mcast_handler_lock);16981699/* switched from flag unset to set */1700if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&1701!(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {1702atomic_inc(&bat_priv->mcast.num_want_all_ipv6);17031704spin_lock_bh(&bat_priv->mcast.want_lists_lock);1705/* flag checks above + mcast_handler_lock prevents this */1706WARN_ON(!hlist_unhashed(node));17071708hlist_add_head_rcu(node, head);1709spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1710/* switched from flag set to unset */1711} else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&1712orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {1713atomic_dec(&bat_priv->mcast.num_want_all_ipv6);17141715spin_lock_bh(&bat_priv->mcast.want_lists_lock);1716/* flag checks above + mcast_handler_lock prevents this */1717WARN_ON(hlist_unhashed(node));17181719hlist_del_init_rcu(node);1720spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1721}1722}17231724/**1725* batadv_mcast_want_rtr4_update() - update want-all-rtr4 counter and list1726* @bat_priv: the bat priv with all the mesh interface information1727* @orig: the orig_node which multicast state might have changed of1728* @mcast_flags: flags indicating the new multicast state1729*1730* If the BATADV_MCAST_WANT_NO_RTR4 flag of this originator, orig, has1731* toggled then this method updates the counter and the list accordingly.1732*1733* Caller needs to hold orig->mcast_handler_lock.1734*/1735static void batadv_mcast_want_rtr4_update(struct batadv_priv *bat_priv,1736struct batadv_orig_node *orig,1737u8 mcast_flags)1738{1739struct hlist_node *node = &orig->mcast_want_all_rtr4_node;1740struct hlist_head *head = &bat_priv->mcast.want_all_rtr4_list;17411742lockdep_assert_held(&orig->mcast_handler_lock);17431744/* switched from flag set to unset */1745if (!(mcast_flags & BATADV_MCAST_WANT_NO_RTR4) &&1746orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR4) {1747atomic_inc(&bat_priv->mcast.num_want_all_rtr4);17481749spin_lock_bh(&bat_priv->mcast.want_lists_lock);1750/* flag checks above + mcast_handler_lock prevents this */1751WARN_ON(!hlist_unhashed(node));17521753hlist_add_head_rcu(node, head);1754spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1755/* switched from flag unset to set */1756} else if (mcast_flags & BATADV_MCAST_WANT_NO_RTR4 &&1757!(orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR4)) {1758atomic_dec(&bat_priv->mcast.num_want_all_rtr4);17591760spin_lock_bh(&bat_priv->mcast.want_lists_lock);1761/* flag checks above + mcast_handler_lock prevents this */1762WARN_ON(hlist_unhashed(node));17631764hlist_del_init_rcu(node);1765spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1766}1767}17681769/**1770* batadv_mcast_want_rtr6_update() - update want-all-rtr6 counter and list1771* @bat_priv: the bat priv with all the mesh interface information1772* @orig: the orig_node which multicast state might have changed of1773* @mcast_flags: flags indicating the new multicast state1774*1775* If the BATADV_MCAST_WANT_NO_RTR6 flag of this originator, orig, has1776* toggled then this method updates the counter and the list accordingly.1777*1778* Caller needs to hold orig->mcast_handler_lock.1779*/1780static void batadv_mcast_want_rtr6_update(struct batadv_priv *bat_priv,1781struct batadv_orig_node *orig,1782u8 mcast_flags)1783{1784struct hlist_node *node = &orig->mcast_want_all_rtr6_node;1785struct hlist_head *head = &bat_priv->mcast.want_all_rtr6_list;17861787lockdep_assert_held(&orig->mcast_handler_lock);17881789/* switched from flag set to unset */1790if (!(mcast_flags & BATADV_MCAST_WANT_NO_RTR6) &&1791orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR6) {1792atomic_inc(&bat_priv->mcast.num_want_all_rtr6);17931794spin_lock_bh(&bat_priv->mcast.want_lists_lock);1795/* flag checks above + mcast_handler_lock prevents this */1796WARN_ON(!hlist_unhashed(node));17971798hlist_add_head_rcu(node, head);1799spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1800/* switched from flag unset to set */1801} else if (mcast_flags & BATADV_MCAST_WANT_NO_RTR6 &&1802!(orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR6)) {1803atomic_dec(&bat_priv->mcast.num_want_all_rtr6);18041805spin_lock_bh(&bat_priv->mcast.want_lists_lock);1806/* flag checks above + mcast_handler_lock prevents this */1807WARN_ON(hlist_unhashed(node));18081809hlist_del_init_rcu(node);1810spin_unlock_bh(&bat_priv->mcast.want_lists_lock);1811}1812}18131814/**1815* batadv_mcast_have_mc_ptype_update() - update multicast packet type counter1816* @bat_priv: the bat priv with all the mesh interface information1817* @orig: the orig_node which multicast state might have changed of1818* @mcast_flags: flags indicating the new multicast state1819*1820* If the BATADV_MCAST_HAVE_MC_PTYPE_CAPA flag of this originator, orig, has1821* toggled then this method updates the counter accordingly.1822*/1823static void batadv_mcast_have_mc_ptype_update(struct batadv_priv *bat_priv,1824struct batadv_orig_node *orig,1825u8 mcast_flags)1826{1827lockdep_assert_held(&orig->mcast_handler_lock);18281829/* switched from flag set to unset */1830if (!(mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) &&1831orig->mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA)1832atomic_inc(&bat_priv->mcast.num_no_mc_ptype_capa);1833/* switched from flag unset to set */1834else if (mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA &&1835!(orig->mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA))1836atomic_dec(&bat_priv->mcast.num_no_mc_ptype_capa);1837}18381839/**1840* batadv_mcast_tvlv_flags_get() - get multicast flags from an OGM TVLV1841* @enabled: whether the originator has multicast TVLV support enabled1842* @tvlv_value: tvlv buffer containing the multicast flags1843* @tvlv_value_len: tvlv buffer length1844*1845* Return: multicast flags for the given tvlv buffer1846*/1847static u81848batadv_mcast_tvlv_flags_get(bool enabled, void *tvlv_value, u16 tvlv_value_len)1849{1850u8 mcast_flags = BATADV_NO_FLAGS;18511852if (enabled && tvlv_value && tvlv_value_len >= sizeof(mcast_flags))1853mcast_flags = *(u8 *)tvlv_value;18541855if (!enabled) {1856mcast_flags |= BATADV_MCAST_WANT_ALL_IPV4;1857mcast_flags |= BATADV_MCAST_WANT_ALL_IPV6;1858}18591860/* remove redundant flags to avoid sending duplicate packets later */1861if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)1862mcast_flags |= BATADV_MCAST_WANT_NO_RTR4;18631864if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)1865mcast_flags |= BATADV_MCAST_WANT_NO_RTR6;18661867return mcast_flags;1868}18691870/**1871* batadv_mcast_tvlv_ogm_handler() - process incoming multicast tvlv container1872* @bat_priv: the bat priv with all the mesh interface information1873* @orig: the orig_node of the ogm1874* @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)1875* @tvlv_value: tvlv buffer containing the multicast data1876* @tvlv_value_len: tvlv buffer length1877*/1878static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,1879struct batadv_orig_node *orig,1880u8 flags,1881void *tvlv_value,1882u16 tvlv_value_len)1883{1884bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);1885u8 mcast_flags;18861887mcast_flags = batadv_mcast_tvlv_flags_get(orig_mcast_enabled,1888tvlv_value, tvlv_value_len);18891890spin_lock_bh(&orig->mcast_handler_lock);18911892if (orig_mcast_enabled &&1893!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {1894set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);1895} else if (!orig_mcast_enabled &&1896test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {1897clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);1898}18991900set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);19011902batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);1903batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);1904batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);1905batadv_mcast_want_rtr4_update(bat_priv, orig, mcast_flags);1906batadv_mcast_want_rtr6_update(bat_priv, orig, mcast_flags);1907batadv_mcast_have_mc_ptype_update(bat_priv, orig, mcast_flags);19081909orig->mcast_flags = mcast_flags;1910spin_unlock_bh(&orig->mcast_handler_lock);1911}19121913/**1914* batadv_mcast_init() - initialize the multicast optimizations structures1915* @bat_priv: the bat priv with all the mesh interface information1916*/1917void batadv_mcast_init(struct batadv_priv *bat_priv)1918{1919batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,1920NULL, NULL, BATADV_TVLV_MCAST, 2,1921BATADV_TVLV_HANDLER_OGM_CIFNOTFND);1922batadv_tvlv_handler_register(bat_priv, NULL, NULL,1923batadv_mcast_forw_tracker_tvlv_handler,1924BATADV_TVLV_MCAST_TRACKER, 1,1925BATADV_TVLV_HANDLER_OGM_CIFNOTFND);19261927INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);1928batadv_mcast_start_timer(bat_priv);1929}19301931/**1932* batadv_mcast_mesh_info_put() - put multicast info into a netlink message1933* @msg: buffer for the message1934* @bat_priv: the bat priv with all the mesh interface information1935*1936* Return: 0 or error code.1937*/1938int batadv_mcast_mesh_info_put(struct sk_buff *msg,1939struct batadv_priv *bat_priv)1940{1941u32 flags = bat_priv->mcast.mla_flags.tvlv_flags;1942u32 flags_priv = BATADV_NO_FLAGS;19431944if (bat_priv->mcast.mla_flags.bridged) {1945flags_priv |= BATADV_MCAST_FLAGS_BRIDGED;19461947if (bat_priv->mcast.mla_flags.querier_ipv4.exists)1948flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS;1949if (bat_priv->mcast.mla_flags.querier_ipv6.exists)1950flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS;1951if (bat_priv->mcast.mla_flags.querier_ipv4.shadowing)1952flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING;1953if (bat_priv->mcast.mla_flags.querier_ipv6.shadowing)1954flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING;1955}19561957if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) ||1958nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv))1959return -EMSGSIZE;19601961return 0;1962}19631964/**1965* batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table1966* to a netlink socket1967* @msg: buffer for the message1968* @portid: netlink port1969* @cb: Control block containing additional options1970* @orig_node: originator to dump the multicast flags of1971*1972* Return: 0 or error code.1973*/1974static int1975batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid,1976struct netlink_callback *cb,1977struct batadv_orig_node *orig_node)1978{1979void *hdr;19801981hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,1982&batadv_netlink_family, NLM_F_MULTI,1983BATADV_CMD_GET_MCAST_FLAGS);1984if (!hdr)1985return -ENOBUFS;19861987genl_dump_check_consistent(cb, hdr);19881989if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,1990orig_node->orig)) {1991genlmsg_cancel(msg, hdr);1992return -EMSGSIZE;1993}19941995if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST,1996&orig_node->capabilities)) {1997if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS,1998orig_node->mcast_flags)) {1999genlmsg_cancel(msg, hdr);2000return -EMSGSIZE;2001}2002}20032004genlmsg_end(msg, hdr);2005return 0;2006}20072008/**2009* batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags2010* table to a netlink socket2011* @msg: buffer for the message2012* @portid: netlink port2013* @cb: Control block containing additional options2014* @hash: hash to dump2015* @bucket: bucket index to dump2016* @idx_skip: How many entries to skip2017*2018* Return: 0 or error code.2019*/2020static int2021batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid,2022struct netlink_callback *cb,2023struct batadv_hashtable *hash,2024unsigned int bucket, long *idx_skip)2025{2026struct batadv_orig_node *orig_node;2027long idx = 0;20282029spin_lock_bh(&hash->list_locks[bucket]);2030cb->seq = atomic_read(&hash->generation) << 1 | 1;20312032hlist_for_each_entry(orig_node, &hash->table[bucket], hash_entry) {2033if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,2034&orig_node->capa_initialized))2035continue;20362037if (idx < *idx_skip)2038goto skip;20392040if (batadv_mcast_flags_dump_entry(msg, portid, cb, orig_node)) {2041spin_unlock_bh(&hash->list_locks[bucket]);2042*idx_skip = idx;20432044return -EMSGSIZE;2045}20462047skip:2048idx++;2049}2050spin_unlock_bh(&hash->list_locks[bucket]);20512052return 0;2053}20542055/**2056* __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket2057* @msg: buffer for the message2058* @portid: netlink port2059* @cb: Control block containing additional options2060* @bat_priv: the bat priv with all the mesh interface information2061* @bucket: current bucket to dump2062* @idx: index in current bucket to the next entry to dump2063*2064* Return: 0 or error code.2065*/2066static int2067__batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid,2068struct netlink_callback *cb,2069struct batadv_priv *bat_priv, long *bucket, long *idx)2070{2071struct batadv_hashtable *hash = bat_priv->orig_hash;2072long bucket_tmp = *bucket;2073long idx_tmp = *idx;20742075while (bucket_tmp < hash->size) {2076if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash,2077bucket_tmp, &idx_tmp))2078break;20792080bucket_tmp++;2081idx_tmp = 0;2082}20832084*bucket = bucket_tmp;2085*idx = idx_tmp;20862087return msg->len;2088}20892090/**2091* batadv_mcast_netlink_get_primary() - get primary interface from netlink2092* callback2093* @cb: netlink callback structure2094* @primary_if: the primary interface pointer to return the result in2095*2096* Return: 0 or error code.2097*/2098static int2099batadv_mcast_netlink_get_primary(struct netlink_callback *cb,2100struct batadv_hard_iface **primary_if)2101{2102struct batadv_hard_iface *hard_iface = NULL;2103struct net_device *mesh_iface;2104struct batadv_priv *bat_priv;2105int ret = 0;21062107mesh_iface = batadv_netlink_get_meshif(cb);2108if (IS_ERR(mesh_iface))2109return PTR_ERR(mesh_iface);21102111bat_priv = netdev_priv(mesh_iface);21122113hard_iface = batadv_primary_if_get_selected(bat_priv);2114if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) {2115ret = -ENOENT;2116goto out;2117}21182119out:2120dev_put(mesh_iface);21212122if (!ret && primary_if)2123*primary_if = hard_iface;2124else2125batadv_hardif_put(hard_iface);21262127return ret;2128}21292130/**2131* batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket2132* @msg: buffer for the message2133* @cb: callback structure containing arguments2134*2135* Return: message length.2136*/2137int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb)2138{2139struct batadv_hard_iface *primary_if = NULL;2140int portid = NETLINK_CB(cb->skb).portid;2141struct batadv_priv *bat_priv;2142long *bucket = &cb->args[0];2143long *idx = &cb->args[1];2144int ret;21452146ret = batadv_mcast_netlink_get_primary(cb, &primary_if);2147if (ret)2148return ret;21492150bat_priv = netdev_priv(primary_if->mesh_iface);2151ret = __batadv_mcast_flags_dump(msg, portid, cb, bat_priv, bucket, idx);21522153batadv_hardif_put(primary_if);2154return ret;2155}21562157/**2158* batadv_mcast_free() - free the multicast optimizations structures2159* @bat_priv: the bat priv with all the mesh interface information2160*/2161void batadv_mcast_free(struct batadv_priv *bat_priv)2162{2163cancel_delayed_work_sync(&bat_priv->mcast.work);21642165batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);2166batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST_TRACKER, 1);2167batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);21682169/* safely calling outside of worker, as worker was canceled above */2170batadv_mcast_mla_tt_retract(bat_priv, NULL);2171}21722173/**2174* batadv_mcast_purge_orig() - reset originator global mcast state modifications2175* @orig: the originator which is going to get purged2176*/2177void batadv_mcast_purge_orig(struct batadv_orig_node *orig)2178{2179struct batadv_priv *bat_priv = orig->bat_priv;21802181spin_lock_bh(&orig->mcast_handler_lock);21822183batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);2184batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);2185batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);2186batadv_mcast_want_rtr4_update(bat_priv, orig,2187BATADV_MCAST_WANT_NO_RTR4);2188batadv_mcast_want_rtr6_update(bat_priv, orig,2189BATADV_MCAST_WANT_NO_RTR6);2190batadv_mcast_have_mc_ptype_update(bat_priv, orig,2191BATADV_MCAST_HAVE_MC_PTYPE_CAPA);21922193spin_unlock_bh(&orig->mcast_handler_lock);2194}219521962197