119370Spst// SPDX-License-Identifier: GPL-2.0 298944Sobrien/* Copyright (C) B.A.T.M.A.N. contributors: 3130803Smarcel * 419370Spst * Linus L��ssing 519370Spst */ 698944Sobrien 719370Spst#include "multicast.h" 898944Sobrien#include "main.h" 998944Sobrien 1098944Sobrien#include <linux/atomic.h> 1198944Sobrien#include <linux/bitops.h> 1219370Spst#include <linux/bug.h> 1398944Sobrien#include <linux/byteorder/generic.h> 1498944Sobrien#include <linux/container_of.h> 1598944Sobrien#include <linux/errno.h> 1698944Sobrien#include <linux/etherdevice.h> 1719370Spst#include <linux/gfp.h> 1898944Sobrien#include <linux/icmpv6.h> 1998944Sobrien#include <linux/if_bridge.h> 2098944Sobrien#include <linux/if_ether.h> 2198944Sobrien#include <linux/igmp.h> 2219370Spst#include <linux/in.h> 2319370Spst#include <linux/in6.h> 24130803Smarcel#include <linux/inetdevice.h> 2519370Spst#include <linux/ip.h> 2619370Spst#include <linux/ipv6.h> 2719370Spst#include <linux/jiffies.h> 2819370Spst#include <linux/list.h> 2919370Spst#include <linux/lockdep.h> 3019370Spst#include <linux/netdevice.h> 3119370Spst#include <linux/netlink.h> 3219370Spst#include <linux/printk.h> 3319370Spst#include <linux/rculist.h> 3419370Spst#include <linux/rcupdate.h> 3519370Spst#include <linux/skbuff.h> 3698944Sobrien#include <linux/slab.h> 3719370Spst#include <linux/spinlock.h> 3819370Spst#include <linux/sprintf.h> 3919370Spst#include <linux/stddef.h> 4019370Spst#include <linux/string.h> 4146283Sdfr#include <linux/types.h> 4246283Sdfr#include <linux/workqueue.h> 4346283Sdfr#include <net/addrconf.h> 44130803Smarcel#include <net/genetlink.h> 4598944Sobrien#include <net/if_inet6.h> 4698944Sobrien#include <net/ip.h> 4719370Spst#include <net/ipv6.h> 4898944Sobrien#include <net/netlink.h> 4919370Spst#include <net/sock.h> 5098944Sobrien#include <uapi/linux/batadv_packet.h> 5119370Spst#include <uapi/linux/batman_adv.h> 52130803Smarcel 53130803Smarcel#include "bridge_loop_avoidance.h" 5446283Sdfr#include "hard-interface.h" 5598944Sobrien#include "hash.h" 5698944Sobrien#include "log.h" 5798944Sobrien#include "netlink.h" 5819370Spst#include "send.h" 5919370Spst#include "soft-interface.h" 6019370Spst#include "translation-table.h" 6119370Spst#include "tvlv.h" 6219370Spst 6319370Spststatic void batadv_mcast_mla_update(struct work_struct *work); 6419370Spst 6598944Sobrien/** 6698944Sobrien * batadv_mcast_start_timer() - schedule the multicast periodic worker 6719370Spst * @bat_priv: the bat priv with all the soft interface information 68130803Smarcel */ 6919370Spststatic void batadv_mcast_start_timer(struct batadv_priv *bat_priv) 70130803Smarcel{ 7119370Spst queue_delayed_work(batadv_event_workqueue, &bat_priv->mcast.work, 7219370Spst msecs_to_jiffies(BATADV_MCAST_WORK_PERIOD)); 7319370Spst} 7419370Spst 7519370Spst/** 7619370Spst * batadv_mcast_get_bridge() - get the bridge on top of the softif if it exists 7719370Spst * @soft_iface: netdev struct of the mesh interface 7819370Spst * 7998944Sobrien * If the given soft interface has a bridge on top then the refcount 8098944Sobrien * of the according net device is increased. 8119370Spst * 8219370Spst * Return: NULL if no such bridge exists. Otherwise the net device of the 8319370Spst * bridge. 8419370Spst */ 8519370Spststatic struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface) 8619370Spst{ 8719370Spst struct net_device *upper = soft_iface; 8819370Spst 89130803Smarcel rcu_read_lock(); 90130803Smarcel do { 9119370Spst upper = netdev_master_upper_dev_get_rcu(upper); 9246283Sdfr } while (upper && !netif_is_bridge_master(upper)); 9346283Sdfr 9446283Sdfr dev_hold(upper); 9519370Spst rcu_read_unlock(); 9646283Sdfr 9798944Sobrien return upper; 9819370Spst} 9998944Sobrien 10046283Sdfr/** 10119370Spst * batadv_mcast_mla_rtr_flags_softif_get_ipv4() - get mcast router flags from 10219370Spst * node for IPv4 10398944Sobrien * @dev: the interface to check 10419370Spst * 10519370Spst * Checks the presence of an IPv4 multicast router on this node. 10619370Spst * 10719370Spst * Caller needs to hold rcu read lock. 10898944Sobrien * 10998944Sobrien * Return: BATADV_NO_FLAGS if present, BATADV_MCAST_WANT_NO_RTR4 otherwise. 11098944Sobrien */ 11119370Spststatic u8 batadv_mcast_mla_rtr_flags_softif_get_ipv4(struct net_device *dev) 11219370Spst{ 11319370Spst struct in_device *in_dev = __in_dev_get_rcu(dev); 11498944Sobrien 11598944Sobrien if (in_dev && IN_DEV_MFORWARD(in_dev)) 11698944Sobrien return BATADV_NO_FLAGS; 11719370Spst else 11819370Spst return BATADV_MCAST_WANT_NO_RTR4; 11919370Spst} 12019370Spst 12198944Sobrien/** 12298944Sobrien * batadv_mcast_mla_rtr_flags_softif_get_ipv6() - get mcast router flags from 12398944Sobrien * node for IPv6 12419370Spst * @dev: the interface to check 12519370Spst * 12646283Sdfr * Checks the presence of an IPv6 multicast router on this node. 12746283Sdfr * 12846283Sdfr * Caller needs to hold rcu read lock. 12946283Sdfr * 13019370Spst * Return: BATADV_NO_FLAGS if present, BATADV_MCAST_WANT_NO_RTR6 otherwise. 13119370Spst */ 13298944Sobrien#if IS_ENABLED(CONFIG_IPV6_MROUTE) 13319370Spststatic u8 batadv_mcast_mla_rtr_flags_softif_get_ipv6(struct net_device *dev) 13419370Spst{ 13519370Spst struct inet6_dev *in6_dev = __in6_dev_get(dev); 13619370Spst 13719370Spst if (in6_dev && atomic_read(&in6_dev->cnf.mc_forwarding)) 13819370Spst return BATADV_NO_FLAGS; 13919370Spst else 14019370Spst return BATADV_MCAST_WANT_NO_RTR6; 14198944Sobrien} 14298944Sobrien#else 14398944Sobrienstatic inline u8 14419370Spstbatadv_mcast_mla_rtr_flags_softif_get_ipv6(struct net_device *dev) 14519370Spst{ 14619370Spst return BATADV_MCAST_WANT_NO_RTR6; 14719370Spst} 14819370Spst#endif 14919370Spst 15019370Spst/** 15119370Spst * batadv_mcast_mla_rtr_flags_softif_get() - get mcast router flags from node 152130803Smarcel * @bat_priv: the bat priv with all the soft interface information 15346283Sdfr * @bridge: bridge interface on top of the soft_iface if present, 15498944Sobrien * otherwise pass NULL 15598944Sobrien * 156130803Smarcel * Checks the presence of IPv4 and IPv6 multicast routers on this 15798944Sobrien * node. 15846283Sdfr * 159130803Smarcel * Return: 160130803Smarcel * BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present 161130803Smarcel * BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present 16246283Sdfr * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present 16398944Sobrien * The former two OR'd: no multicast router is present 16446283Sdfr */ 16546283Sdfrstatic u8 batadv_mcast_mla_rtr_flags_softif_get(struct batadv_priv *bat_priv, 16646283Sdfr struct net_device *bridge) 167130803Smarcel{ 168130803Smarcel struct net_device *dev = bridge ? bridge : bat_priv->soft_iface; 169130803Smarcel u8 flags = BATADV_NO_FLAGS; 170130803Smarcel 17146283Sdfr rcu_read_lock(); 172130803Smarcel 17398944Sobrien flags |= batadv_mcast_mla_rtr_flags_softif_get_ipv4(dev); 174130803Smarcel flags |= batadv_mcast_mla_rtr_flags_softif_get_ipv6(dev); 175130803Smarcel 176130803Smarcel rcu_read_unlock(); 177130803Smarcel 178130803Smarcel return flags; 179130803Smarcel} 18098944Sobrien 18146283Sdfr/** 182130803Smarcel * batadv_mcast_mla_rtr_flags_bridge_get() - get mcast router flags from bridge 183130803Smarcel * @bat_priv: the bat priv with all the soft interface information 18446283Sdfr * @bridge: bridge interface on top of the soft_iface if present, 185130803Smarcel * otherwise pass NULL 18698944Sobrien * 18746283Sdfr * Checks the presence of IPv4 and IPv6 multicast routers behind a bridge. 18846283Sdfr * 18919370Spst * Return: 19046283Sdfr * BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present 19119370Spst * BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present 19219370Spst * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present 19319370Spst * The former two OR'd: no multicast router is present 19419370Spst */ 19519370Spststatic u8 batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv, 19619370Spst struct net_device *bridge) 197130803Smarcel{ 198130803Smarcel struct net_device *dev = bat_priv->soft_iface; 199130803Smarcel u8 flags = BATADV_NO_FLAGS; 200130803Smarcel 201130803Smarcel if (!bridge) 20219370Spst return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6; 20319370Spst 20498944Sobrien if (!br_multicast_has_router_adjacent(dev, ETH_P_IP)) 205130803Smarcel flags |= BATADV_MCAST_WANT_NO_RTR4; 20619370Spst if (!br_multicast_has_router_adjacent(dev, ETH_P_IPV6)) 20719370Spst flags |= BATADV_MCAST_WANT_NO_RTR6; 20819370Spst 20919370Spst return flags; 21019370Spst} 21119370Spst 21219370Spst/** 21319370Spst * batadv_mcast_mla_rtr_flags_get() - get multicast router flags 21419370Spst * @bat_priv: the bat priv with all the soft interface information 21519370Spst * @bridge: bridge interface on top of the soft_iface if present, 21619370Spst * otherwise pass NULL 21719370Spst * 21819370Spst * Checks the presence of IPv4 and IPv6 multicast routers on this 219130803Smarcel * node or behind its bridge. 22019370Spst * 221130803Smarcel * Return: 22219370Spst * BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present 22319370Spst * BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present 22419370Spst * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present 22519370Spst * The former two OR'd: no multicast router is present 22619370Spst */ 227130803Smarcelstatic u8 batadv_mcast_mla_rtr_flags_get(struct batadv_priv *bat_priv, 22819370Spst struct net_device *bridge) 22919370Spst{ 23019370Spst u8 flags = BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6; 23119370Spst 23219370Spst flags &= batadv_mcast_mla_rtr_flags_softif_get(bat_priv, bridge); 23398944Sobrien flags &= batadv_mcast_mla_rtr_flags_bridge_get(bat_priv, bridge); 23419370Spst 23519370Spst return flags; 23619370Spst} 23719370Spst 23819370Spst/** 23946283Sdfr * batadv_mcast_mla_forw_flags_get() - get multicast forwarding flags 240130803Smarcel * @bat_priv: the bat priv with all the soft interface information 24119370Spst * 24219370Spst * Checks if all active hard interfaces have an MTU larger or equal to 1280 24319370Spst * bytes (IPv6 minimum MTU). 24419370Spst * 24519370Spst * Return: BATADV_MCAST_HAVE_MC_PTYPE_CAPA if yes, BATADV_NO_FLAGS otherwise. 24619370Spst */ 24719370Spststatic u8 batadv_mcast_mla_forw_flags_get(struct batadv_priv *bat_priv) 24819370Spst{ 24919370Spst const struct batadv_hard_iface *hard_iface; 250130803Smarcel 25119370Spst rcu_read_lock(); 252130803Smarcel list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 25319370Spst if (hard_iface->if_status != BATADV_IF_ACTIVE) 25419370Spst continue; 25519370Spst 256130803Smarcel if (hard_iface->soft_iface != bat_priv->soft_iface) 25719370Spst continue; 25819370Spst 25919370Spst if (hard_iface->net_dev->mtu < IPV6_MIN_MTU) { 26019370Spst rcu_read_unlock(); 26119370Spst return BATADV_NO_FLAGS; 262130803Smarcel } 26319370Spst } 26419370Spst rcu_read_unlock(); 26519370Spst 26619370Spst return BATADV_MCAST_HAVE_MC_PTYPE_CAPA; 267130803Smarcel} 268130803Smarcel 269130803Smarcel/** 270130803Smarcel * batadv_mcast_mla_flags_get() - get the new multicast flags 27119370Spst * @bat_priv: the bat priv with all the soft interface information 27219370Spst * 27319370Spst * Return: A set of flags for the current/next TVLV, querier and 27419370Spst * bridge state. 27519370Spst */ 27619370Spststatic struct batadv_mcast_mla_flags 27719370Spstbatadv_mcast_mla_flags_get(struct batadv_priv *bat_priv) 27819370Spst{ 27919370Spst struct net_device *dev = bat_priv->soft_iface; 28019370Spst struct batadv_mcast_querier_state *qr4, *qr6; 28119370Spst struct batadv_mcast_mla_flags mla_flags; 28219370Spst struct net_device *bridge; 28319370Spst 28419370Spst bridge = batadv_mcast_get_bridge(dev); 28519370Spst 28698944Sobrien memset(&mla_flags, 0, sizeof(mla_flags)); 287130803Smarcel mla_flags.enabled = 1; 28819370Spst mla_flags.tvlv_flags |= batadv_mcast_mla_rtr_flags_get(bat_priv, 28998944Sobrien bridge); 29019370Spst mla_flags.tvlv_flags |= batadv_mcast_mla_forw_flags_get(bat_priv); 29198944Sobrien 29298944Sobrien if (!bridge) 29398944Sobrien return mla_flags; 29419370Spst 29519370Spst dev_put(bridge); 29619370Spst 29746283Sdfr mla_flags.bridged = 1; 29846283Sdfr qr4 = &mla_flags.querier_ipv4; 29946283Sdfr qr6 = &mla_flags.querier_ipv6; 30046283Sdfr 30146283Sdfr if (!IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)) 30219370Spst pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n"); 30398944Sobrien 30498944Sobrien qr4->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP); 30546283Sdfr qr4->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP); 30698944Sobrien 307130803Smarcel qr6->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6); 30898944Sobrien qr6->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6); 30998944Sobrien 31098944Sobrien mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES; 31198944Sobrien 31298944Sobrien /* 1) If no querier exists at all, then multicast listeners on 31398944Sobrien * our local TT clients behind the bridge will keep silent. 31446283Sdfr * 2) If the selected querier is on one of our local TT clients, 31546283Sdfr * behind the bridge, then this querier might shadow multicast 31698944Sobrien * listeners on our local TT clients, behind this bridge. 31746283Sdfr * 31898944Sobrien * In both cases, we will signalize other batman nodes that 31946283Sdfr * we need all multicast traffic of the according protocol. 32098944Sobrien */ 32146283Sdfr if (!qr4->exists || qr4->shadowing) { 32246283Sdfr mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV4; 32398944Sobrien mla_flags.tvlv_flags &= ~BATADV_MCAST_WANT_NO_RTR4; 32498944Sobrien } 32546283Sdfr 32698944Sobrien if (!qr6->exists || qr6->shadowing) { 32746283Sdfr mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV6; 32846283Sdfr mla_flags.tvlv_flags &= ~BATADV_MCAST_WANT_NO_RTR6; 329130803Smarcel } 33098944Sobrien 33198944Sobrien return mla_flags; 33298944Sobrien} 33398944Sobrien 33498944Sobrien/** 33598944Sobrien * batadv_mcast_mla_is_duplicate() - check whether an address is in a list 33698944Sobrien * @mcast_addr: the multicast address to check 33798944Sobrien * @mcast_list: the list with multicast addresses to search in 33898944Sobrien * 33946283Sdfr * Return: true if the given address is already in the given list. 34046283Sdfr * Otherwise returns false. 34146283Sdfr */ 34246283Sdfrstatic bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr, 34346283Sdfr struct hlist_head *mcast_list) 34446283Sdfr{ 34546283Sdfr struct batadv_hw_addr *mcast_entry; 34698944Sobrien 34719370Spst hlist_for_each_entry(mcast_entry, mcast_list, list) 34819370Spst if (batadv_compare_eth(mcast_entry->addr, mcast_addr)) 349130803Smarcel return true; 35019370Spst 35119370Spst return false; 352130803Smarcel} 35319370Spst 35419370Spst/** 355130803Smarcel * batadv_mcast_mla_softif_get_ipv4() - get softif IPv4 multicast listeners 356130803Smarcel * @dev: the device to collect multicast addresses from 357130803Smarcel * @mcast_list: a list to put found addresses into 358130803Smarcel * @flags: flags indicating the new multicast state 359130803Smarcel * 360130803Smarcel * Collects multicast addresses of IPv4 multicast listeners residing 36119370Spst * on this kernel on the given soft interface, dev, in 362130803Smarcel * the given mcast_list. In general, multicast listeners provided by 363130803Smarcel * your multicast receiving applications run directly on this node. 36419370Spst * 365130803Smarcel * Return: -ENOMEM on memory allocation error or the number of 366130803Smarcel * items added to the mcast_list otherwise. 36719370Spst */ 36819370Spststatic int 369130803Smarcelbatadv_mcast_mla_softif_get_ipv4(struct net_device *dev, 370130803Smarcel struct hlist_head *mcast_list, 371130803Smarcel struct batadv_mcast_mla_flags *flags) 372130803Smarcel{ 373130803Smarcel struct batadv_hw_addr *new; 37419370Spst struct in_device *in_dev; 37546283Sdfr u8 mcast_addr[ETH_ALEN]; 37646283Sdfr struct ip_mc_list *pmc; 37746283Sdfr int ret = 0; 37846283Sdfr 37998944Sobrien if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4) 38019370Spst return 0; 38119370Spst 38219370Spst rcu_read_lock(); 38398944Sobrien 38498944Sobrien in_dev = __in_dev_get_rcu(dev); 38598944Sobrien if (!in_dev) { 38698944Sobrien rcu_read_unlock(); 38798944Sobrien return 0; 38898944Sobrien } 38998944Sobrien 39098944Sobrien for (pmc = rcu_dereference(in_dev->mc_list); pmc; 39198944Sobrien pmc = rcu_dereference(pmc->next_rcu)) { 39298944Sobrien if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && 39398944Sobrien ipv4_is_local_multicast(pmc->multiaddr)) 39498944Sobrien continue; 39598944Sobrien 39698944Sobrien if (!(flags->tvlv_flags & BATADV_MCAST_WANT_NO_RTR4) && 39798944Sobrien !ipv4_is_local_multicast(pmc->multiaddr)) 39898944Sobrien continue; 39998944Sobrien 40098944Sobrien ip_eth_mc_map(pmc->multiaddr, mcast_addr); 40198944Sobrien 40298944Sobrien if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) 40398944Sobrien continue; 40498944Sobrien 40598944Sobrien new = kmalloc(sizeof(*new), GFP_ATOMIC); 40698944Sobrien if (!new) { 40798944Sobrien ret = -ENOMEM; 40898944Sobrien break; 40998944Sobrien } 41098944Sobrien 41198944Sobrien ether_addr_copy(new->addr, mcast_addr); 41298944Sobrien hlist_add_head(&new->list, mcast_list); 41398944Sobrien ret++; 41498944Sobrien } 41598944Sobrien rcu_read_unlock(); 41698944Sobrien 41798944Sobrien return ret; 41898944Sobrien} 41998944Sobrien 42098944Sobrien/** 42198944Sobrien * batadv_mcast_mla_softif_get_ipv6() - get softif IPv6 multicast listeners 42298944Sobrien * @dev: the device to collect multicast addresses from 42398944Sobrien * @mcast_list: a list to put found addresses into 42498944Sobrien * @flags: flags indicating the new multicast state 42598944Sobrien * 42698944Sobrien * Collects multicast addresses of IPv6 multicast listeners residing 42798944Sobrien * on this kernel on the given soft interface, dev, in 42898944Sobrien * the given mcast_list. In general, multicast listeners provided by 42998944Sobrien * your multicast receiving applications run directly on this node. 43098944Sobrien * 43198944Sobrien * Return: -ENOMEM on memory allocation error or the number of 43298944Sobrien * items added to the mcast_list otherwise. 43398944Sobrien */ 43498944Sobrien#if IS_ENABLED(CONFIG_IPV6) 43598944Sobrienstatic int 43698944Sobrienbatadv_mcast_mla_softif_get_ipv6(struct net_device *dev, 43798944Sobrien struct hlist_head *mcast_list, 43898944Sobrien struct batadv_mcast_mla_flags *flags) 43998944Sobrien{ 44098944Sobrien struct batadv_hw_addr *new; 44198944Sobrien struct inet6_dev *in6_dev; 44298944Sobrien u8 mcast_addr[ETH_ALEN]; 44398944Sobrien struct ifmcaddr6 *pmc6; 44498944Sobrien int ret = 0; 44598944Sobrien 44698944Sobrien if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6) 44798944Sobrien return 0; 44898944Sobrien 44998944Sobrien rcu_read_lock(); 45098944Sobrien 45198944Sobrien in6_dev = __in6_dev_get(dev); 45298944Sobrien if (!in6_dev) { 45398944Sobrien rcu_read_unlock(); 45498944Sobrien return 0; 45598944Sobrien } 45698944Sobrien 45798944Sobrien for (pmc6 = rcu_dereference(in6_dev->mc_list); 45898944Sobrien pmc6; 45998944Sobrien pmc6 = rcu_dereference(pmc6->next)) { 46098944Sobrien if (IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) < 46198944Sobrien IPV6_ADDR_SCOPE_LINKLOCAL) 46298944Sobrien continue; 46398944Sobrien 46498944Sobrien if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && 46598944Sobrien ipv6_addr_is_ll_all_nodes(&pmc6->mca_addr)) 46698944Sobrien continue; 46798944Sobrien 46898944Sobrien if (!(flags->tvlv_flags & BATADV_MCAST_WANT_NO_RTR6) && 46998944Sobrien IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) > 47098944Sobrien IPV6_ADDR_SCOPE_LINKLOCAL) 47198944Sobrien continue; 47298944Sobrien 47398944Sobrien ipv6_eth_mc_map(&pmc6->mca_addr, mcast_addr); 47498944Sobrien 47598944Sobrien if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) 47698944Sobrien continue; 47798944Sobrien 47898944Sobrien new = kmalloc(sizeof(*new), GFP_ATOMIC); 47998944Sobrien if (!new) { 48098944Sobrien ret = -ENOMEM; 48198944Sobrien break; 48298944Sobrien } 48398944Sobrien 48498944Sobrien ether_addr_copy(new->addr, mcast_addr); 48598944Sobrien hlist_add_head(&new->list, mcast_list); 48698944Sobrien ret++; 48798944Sobrien } 48898944Sobrien rcu_read_unlock(); 48998944Sobrien 49098944Sobrien return ret; 49198944Sobrien} 49298944Sobrien#else 49398944Sobrienstatic inline int 49498944Sobrienbatadv_mcast_mla_softif_get_ipv6(struct net_device *dev, 49598944Sobrien struct hlist_head *mcast_list, 49698944Sobrien struct batadv_mcast_mla_flags *flags) 49798944Sobrien{ 49898944Sobrien return 0; 49998944Sobrien} 50098944Sobrien#endif 50198944Sobrien 50298944Sobrien/** 50398944Sobrien * batadv_mcast_mla_softif_get() - get softif multicast listeners 50498944Sobrien * @dev: the device to collect multicast addresses from 50598944Sobrien * @mcast_list: a list to put found addresses into 50698944Sobrien * @flags: flags indicating the new multicast state 50798944Sobrien * 50898944Sobrien * Collects multicast addresses of multicast listeners residing 50998944Sobrien * on this kernel on the given soft interface, dev, in 51098944Sobrien * the given mcast_list. In general, multicast listeners provided by 51198944Sobrien * your multicast receiving applications run directly on this node. 51298944Sobrien * 51398944Sobrien * If there is a bridge interface on top of dev, collect from that one 51498944Sobrien * instead. Just like with IP addresses and routes, multicast listeners 51598944Sobrien * will(/should) register to the bridge interface instead of an 51698944Sobrien * enslaved bat0. 51798944Sobrien * 51898944Sobrien * Return: -ENOMEM on memory allocation error or the number of 51998944Sobrien * items added to the mcast_list otherwise. 52019370Spst */ 52119370Spststatic int 52219370Spstbatadv_mcast_mla_softif_get(struct net_device *dev, 52319370Spst struct hlist_head *mcast_list, 52446283Sdfr struct batadv_mcast_mla_flags *flags) 52598944Sobrien{ 52698944Sobrien struct net_device *bridge = batadv_mcast_get_bridge(dev); 52719370Spst int ret4, ret6 = 0; 52819370Spst 52919370Spst if (bridge) 53019370Spst dev = bridge; 53119370Spst 53219370Spst ret4 = batadv_mcast_mla_softif_get_ipv4(dev, mcast_list, flags); 53319370Spst if (ret4 < 0) 53419370Spst goto out; 53519370Spst 53619370Spst ret6 = batadv_mcast_mla_softif_get_ipv6(dev, mcast_list, flags); 53719370Spst if (ret6 < 0) { 53819370Spst ret4 = 0; 53919370Spst goto out; 54019370Spst } 54198944Sobrien 54219370Spstout: 54319370Spst dev_put(bridge); 54498944Sobrien 54519370Spst return ret4 + ret6; 54619370Spst} 54719370Spst 54819370Spst/** 54998944Sobrien * batadv_mcast_mla_br_addr_cpy() - copy a bridge multicast address 550130803Smarcel * @dst: destination to write to - a multicast MAC address 551130803Smarcel * @src: source to read from - a multicast IP address 55219370Spst * 55319370Spst * Converts a given multicast IPv4/IPv6 address from a bridge 55419370Spst * to its matching multicast MAC address and copies it into the given 55519370Spst * destination buffer. 55619370Spst * 557130803Smarcel * Caller needs to make sure the destination buffer can hold 558130803Smarcel * at least ETH_ALEN bytes. 55919370Spst */ 56019370Spststatic void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src) 56119370Spst{ 56219370Spst if (src->proto == htons(ETH_P_IP)) 56319370Spst ip_eth_mc_map(src->dst.ip4, dst); 564130803Smarcel#if IS_ENABLED(CONFIG_IPV6) 565130803Smarcel else if (src->proto == htons(ETH_P_IPV6)) 56619370Spst ipv6_eth_mc_map(&src->dst.ip6, dst); 56719370Spst#endif 56819370Spst else 56919370Spst eth_zero_addr(dst); 57019370Spst} 57119370Spst 57219370Spst/** 57319370Spst * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners 574130803Smarcel * @dev: a bridge slave whose bridge to collect multicast addresses from 575130803Smarcel * @mcast_list: a list to put found addresses into 57619370Spst * @flags: flags indicating the new multicast state 57719370Spst * 57819370Spst * Collects multicast addresses of multicast listeners residing 57919370Spst * on foreign, non-mesh devices which we gave access to our mesh via 58019370Spst * a bridge on top of the given soft interface, dev, in the given 58119370Spst * mcast_list. 58298944Sobrien * 58398944Sobrien * Return: -ENOMEM on memory allocation error or the number of 58419370Spst * items added to the mcast_list otherwise. 58598944Sobrien */ 58698944Sobrienstatic int batadv_mcast_mla_bridge_get(struct net_device *dev, 58798944Sobrien struct hlist_head *mcast_list, 58898944Sobrien struct batadv_mcast_mla_flags *flags) 58998944Sobrien{ 59098944Sobrien struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list); 59198944Sobrien struct br_ip_list *br_ip_entry, *tmp; 59298944Sobrien u8 tvlv_flags = flags->tvlv_flags; 59398944Sobrien struct batadv_hw_addr *new; 59498944Sobrien u8 mcast_addr[ETH_ALEN]; 59598944Sobrien int ret; 59698944Sobrien 59798944Sobrien /* we don't need to detect these devices/listeners, the IGMP/MLD 59898944Sobrien * snooping code of the Linux bridge already does that for us 59998944Sobrien */ 60098944Sobrien ret = br_multicast_list_adjacent(dev, &bridge_mcast_list); 60119370Spst if (ret < 0) 60219370Spst goto out; 603130803Smarcel 60419370Spst list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) { 60519370Spst if (br_ip_entry->addr.proto == htons(ETH_P_IP)) { 60619370Spst if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4) 607130803Smarcel continue; 608130803Smarcel 609130803Smarcel if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && 610130803Smarcel ipv4_is_local_multicast(br_ip_entry->addr.dst.ip4)) 611130803Smarcel continue; 61219370Spst 61319370Spst if (!(tvlv_flags & BATADV_MCAST_WANT_NO_RTR4) && 61419370Spst !ipv4_is_local_multicast(br_ip_entry->addr.dst.ip4)) 61519370Spst continue; 61619370Spst } 61719370Spst 61819370Spst#if IS_ENABLED(CONFIG_IPV6) 61919370Spst if (br_ip_entry->addr.proto == htons(ETH_P_IPV6)) { 62019370Spst if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6) 62119370Spst continue; 62219370Spst 62319370Spst if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && 62419370Spst ipv6_addr_is_ll_all_nodes(&br_ip_entry->addr.dst.ip6)) 62519370Spst continue; 62619370Spst 62798944Sobrien if (!(tvlv_flags & BATADV_MCAST_WANT_NO_RTR6) && 628130803Smarcel IPV6_ADDR_MC_SCOPE(&br_ip_entry->addr.dst.ip6) > 62919370Spst IPV6_ADDR_SCOPE_LINKLOCAL) 63098944Sobrien continue; 63119370Spst } 63298944Sobrien#endif 63398944Sobrien 63498944Sobrien batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr); 63519370Spst if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) 63619370Spst continue; 63719370Spst 63819370Spst new = kmalloc(sizeof(*new), GFP_ATOMIC); 63919370Spst if (!new) { 64019370Spst ret = -ENOMEM; 64119370Spst break; 64219370Spst } 64319370Spst 64419370Spst ether_addr_copy(new->addr, mcast_addr); 64519370Spst hlist_add_head(&new->list, mcast_list); 64619370Spst } 64719370Spst 64819370Spstout: 64919370Spst list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) { 65019370Spst list_del(&br_ip_entry->list); 65119370Spst kfree(br_ip_entry); 65219370Spst } 65319370Spst 65419370Spst return ret; 65598944Sobrien} 65698944Sobrien 65719370Spst/** 65898944Sobrien * batadv_mcast_mla_list_free() - free a list of multicast addresses 65998944Sobrien * @mcast_list: the list to free 66098944Sobrien * 66119370Spst * Removes and frees all items in the given mcast_list. 66219370Spst */ 66346283Sdfrstatic void batadv_mcast_mla_list_free(struct hlist_head *mcast_list) 66498944Sobrien{ 66598944Sobrien struct batadv_hw_addr *mcast_entry; 66698944Sobrien struct hlist_node *tmp; 66798944Sobrien 66898944Sobrien hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) { 66946283Sdfr hlist_del(&mcast_entry->list); 67046283Sdfr kfree(mcast_entry); 67146283Sdfr } 67219370Spst} 67319370Spst 67419370Spst/** 67519370Spst * batadv_mcast_mla_tt_retract() - clean up multicast listener announcements 67619370Spst * @bat_priv: the bat priv with all the soft interface information 67719370Spst * @mcast_list: a list of addresses which should _not_ be removed 67819370Spst * 67919370Spst * Retracts the announcement of any multicast listener from the 68019370Spst * translation table except the ones listed in the given mcast_list. 68119370Spst * 68219370Spst * If mcast_list is NULL then all are retracted. 68319370Spst */ 68419370Spststatic void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv, 68519370Spst struct hlist_head *mcast_list) 68619370Spst{ 68719370Spst struct batadv_hw_addr *mcast_entry; 68819370Spst struct hlist_node *tmp; 68919370Spst 69098944Sobrien hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list, 69119370Spst list) { 69219370Spst if (mcast_list && 69319370Spst batadv_mcast_mla_is_duplicate(mcast_entry->addr, 69419370Spst mcast_list)) 69519370Spst continue; 69698944Sobrien 69719370Spst batadv_tt_local_remove(bat_priv, mcast_entry->addr, 69819370Spst BATADV_NO_FLAGS, 69919370Spst "mcast TT outdated", false); 70019370Spst 70119370Spst hlist_del(&mcast_entry->list); 70219370Spst kfree(mcast_entry); 70319370Spst } 70419370Spst} 70519370Spst 70619370Spst/** 70719370Spst * batadv_mcast_mla_tt_add() - add multicast listener announcements 70819370Spst * @bat_priv: the bat priv with all the soft interface information 70919370Spst * @mcast_list: a list of addresses which are going to get added 71098944Sobrien * 71146283Sdfr * Adds multicast listener announcements from the given mcast_list to the 71246283Sdfr * translation table if they have not been added yet. 71346283Sdfr */ 71498944Sobrienstatic void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv, 71598944Sobrien struct hlist_head *mcast_list) 71698944Sobrien{ 71798944Sobrien struct batadv_hw_addr *mcast_entry; 71898944Sobrien struct hlist_node *tmp; 71998944Sobrien 72098944Sobrien if (!mcast_list) 72198944Sobrien return; 72298944Sobrien 72398944Sobrien hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) { 72498944Sobrien if (batadv_mcast_mla_is_duplicate(mcast_entry->addr, 72598944Sobrien &bat_priv->mcast.mla_list)) 72698944Sobrien continue; 72798944Sobrien 72898944Sobrien if (!batadv_tt_local_add(bat_priv->soft_iface, 72998944Sobrien mcast_entry->addr, BATADV_NO_FLAGS, 73098944Sobrien BATADV_NULL_IFINDEX, BATADV_NO_MARK)) 73198944Sobrien continue; 73298944Sobrien 73398944Sobrien hlist_del(&mcast_entry->list); 73498944Sobrien hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list); 73598944Sobrien } 73698944Sobrien} 73798944Sobrien 73898944Sobrien/** 73998944Sobrien * batadv_mcast_querier_log() - debug output regarding the querier status on 74019370Spst * link 74119370Spst * @bat_priv: the bat priv with all the soft interface information 74219370Spst * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD") 74398944Sobrien * @old_state: the previous querier state on our link 74419370Spst * @new_state: the new querier state on our link 74519370Spst * 74619370Spst * Outputs debug messages to the logging facility with log level 'mcast' 74746283Sdfr * regarding changes to the querier status on the link which are relevant 74846283Sdfr * to our multicast optimizations. 74946283Sdfr * 75046283Sdfr * Usually this is about whether a querier appeared or vanished in 75146283Sdfr * our mesh or whether the querier is in the suboptimal position of being 75246283Sdfr * behind our local bridge segment: Snooping switches will directly 75346283Sdfr * forward listener reports to the querier, therefore batman-adv and 75446283Sdfr * the bridge will potentially not see these listeners - the querier is 75598944Sobrien * potentially shadowing listeners from us then. 75619370Spst * 75719370Spst * This is only interesting for nodes with a bridge on top of their 75819370Spst * soft interface. 75919370Spst */ 76019370Spststatic void 76119370Spstbatadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto, 76219370Spst struct batadv_mcast_querier_state *old_state, 76319370Spst struct batadv_mcast_querier_state *new_state) 76419370Spst{ 76519370Spst if (!old_state->exists && new_state->exists) 76619370Spst batadv_info(bat_priv->soft_iface, "%s Querier appeared\n", 76719370Spst str_proto); 76819370Spst else if (old_state->exists && !new_state->exists) 76919370Spst batadv_info(bat_priv->soft_iface, 77019370Spst "%s Querier disappeared - multicast optimizations disabled\n", 77198944Sobrien str_proto); 77219370Spst else if (!bat_priv->mcast.mla_flags.bridged && !new_state->exists) 77319370Spst batadv_info(bat_priv->soft_iface, 77419370Spst "No %s Querier present - multicast optimizations disabled\n", 77598944Sobrien str_proto); 77619370Spst 77719370Spst if (new_state->exists) { 77819370Spst if ((!old_state->shadowing && new_state->shadowing) || 77919370Spst (!old_state->exists && new_state->shadowing)) 78019370Spst batadv_dbg(BATADV_DBG_MCAST, bat_priv, 78119370Spst "%s Querier is behind our bridged segment: Might shadow listeners\n", 78219370Spst str_proto); 78319370Spst else if (old_state->shadowing && !new_state->shadowing) 78419370Spst batadv_dbg(BATADV_DBG_MCAST, bat_priv, 78519370Spst "%s Querier is not behind our bridged segment\n", 78619370Spst str_proto); 78798944Sobrien } 78898944Sobrien} 78998944Sobrien 79098944Sobrien/** 79146283Sdfr * batadv_mcast_bridge_log() - debug output for topology changes in bridged 79298944Sobrien * setups 79398944Sobrien * @bat_priv: the bat priv with all the soft interface information 79498944Sobrien * @new_flags: flags indicating the new multicast state 79598944Sobrien * 79698944Sobrien * If no bridges are ever used on this node, then this function does nothing. 79798944Sobrien * 79898944Sobrien * Otherwise this function outputs debug information to the 'mcast' log level 79998944Sobrien * which might be relevant to our multicast optimizations. 80098944Sobrien * 80198944Sobrien * More precisely, it outputs information when a bridge interface is added or 80298944Sobrien * removed from a soft interface. And when a bridge is present, it further 80398944Sobrien * outputs information about the querier state which is relevant for the 80498944Sobrien * multicast flags this node is going to set. 80598944Sobrien */ 80698944Sobrienstatic void 80798944Sobrienbatadv_mcast_bridge_log(struct batadv_priv *bat_priv, 80898944Sobrien struct batadv_mcast_mla_flags *new_flags) 80998944Sobrien{ 81098944Sobrien struct batadv_mcast_mla_flags *old_flags = &bat_priv->mcast.mla_flags; 81198944Sobrien 81298944Sobrien if (!old_flags->bridged && new_flags->bridged) 81398944Sobrien batadv_dbg(BATADV_DBG_MCAST, bat_priv, 81498944Sobrien "Bridge added: Setting Unsnoopables(U)-flag\n"); 81598944Sobrien else if (old_flags->bridged && !new_flags->bridged) 81698944Sobrien batadv_dbg(BATADV_DBG_MCAST, bat_priv, 81798944Sobrien "Bridge removed: Unsetting Unsnoopables(U)-flag\n"); 81898944Sobrien 81998944Sobrien if (new_flags->bridged) { 82098944Sobrien batadv_mcast_querier_log(bat_priv, "IGMP", 82198944Sobrien &old_flags->querier_ipv4, 82298944Sobrien &new_flags->querier_ipv4); 82398944Sobrien batadv_mcast_querier_log(bat_priv, "MLD", 82498944Sobrien &old_flags->querier_ipv6, 82598944Sobrien &new_flags->querier_ipv6); 82698944Sobrien } 82798944Sobrien} 82898944Sobrien 82998944Sobrien/** 83098944Sobrien * batadv_mcast_flags_log() - output debug information about mcast flag changes 83198944Sobrien * @bat_priv: the bat priv with all the soft interface information 83298944Sobrien * @flags: TVLV flags indicating the new multicast state 83398944Sobrien * 83498944Sobrien * Whenever the multicast TVLV flags this node announces change, this function 83598944Sobrien * should be used to notify userspace about the change. 83698944Sobrien */ 83798944Sobrienstatic void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags) 83898944Sobrien{ 83998944Sobrien bool old_enabled = bat_priv->mcast.mla_flags.enabled; 84098944Sobrien u8 old_flags = bat_priv->mcast.mla_flags.tvlv_flags; 84198944Sobrien char str_old_flags[] = "[.... . .]"; 84298944Sobrien 84398944Sobrien sprintf(str_old_flags, "[%c%c%c%s%s%c]", 84498944Sobrien (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.', 84598944Sobrien (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.', 84698944Sobrien (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.', 84798944Sobrien !(old_flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ", 84898944Sobrien !(old_flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ", 84998944Sobrien !(old_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.'); 85098944Sobrien 85198944Sobrien batadv_dbg(BATADV_DBG_MCAST, bat_priv, 85246283Sdfr "Changing multicast flags from '%s' to '[%c%c%c%s%s%c]'\n", 85319370Spst old_enabled ? str_old_flags : "<undefined>", 85419370Spst (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.', 85519370Spst (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.', 85619370Spst (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.', 85719370Spst !(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ", 85819370Spst !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ", 85919370Spst !(flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.'); 86019370Spst} 86198944Sobrien 862130803Smarcel/** 863130803Smarcel * batadv_mcast_mla_flags_update() - update multicast flags 86498944Sobrien * @bat_priv: the bat priv with all the soft interface information 86598944Sobrien * @flags: flags indicating the new multicast state 866130803Smarcel * 86719370Spst * Updates the own multicast tvlv with our current multicast related settings, 86819370Spst * capabilities and inabilities. 86919370Spst */ 87019370Spststatic void 87198944Sobrienbatadv_mcast_mla_flags_update(struct batadv_priv *bat_priv, 87219370Spst struct batadv_mcast_mla_flags *flags) 87346283Sdfr{ 87419370Spst struct batadv_tvlv_mcast_data mcast_data; 87519370Spst 87619370Spst if (!memcmp(flags, &bat_priv->mcast.mla_flags, sizeof(*flags))) 87719370Spst return; 87819370Spst 87919370Spst batadv_mcast_bridge_log(bat_priv, flags); 88019370Spst batadv_mcast_flags_log(bat_priv, flags->tvlv_flags); 88119370Spst 88219370Spst mcast_data.flags = flags->tvlv_flags; 88319370Spst memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved)); 88419370Spst 88519370Spst batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2, 88619370Spst &mcast_data, sizeof(mcast_data)); 88719370Spst 88819370Spst bat_priv->mcast.mla_flags = *flags; 88919370Spst} 89019370Spst 89119370Spst/** 89219370Spst * __batadv_mcast_mla_update() - update the own MLAs 89319370Spst * @bat_priv: the bat priv with all the soft interface information 89419370Spst * 89519370Spst * Updates the own multicast listener announcements in the translation 89619370Spst * table as well as the own, announced multicast tvlv container. 89719370Spst * 89819370Spst * Note that non-conflicting reads and writes to bat_priv->mcast.mla_list 89919370Spst * in batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add() are 90019370Spst * ensured by the non-parallel execution of the worker this function 90119370Spst * belongs to. 90219370Spst */ 90319370Spststatic void __batadv_mcast_mla_update(struct batadv_priv *bat_priv) 90419370Spst{ 90519370Spst struct net_device *soft_iface = bat_priv->soft_iface; 90619370Spst struct hlist_head mcast_list = HLIST_HEAD_INIT; 90719370Spst struct batadv_mcast_mla_flags flags; 90819370Spst int ret; 90919370Spst 91019370Spst flags = batadv_mcast_mla_flags_get(bat_priv); 91119370Spst 91219370Spst ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list, &flags); 91319370Spst if (ret < 0) 91419370Spst goto out; 91519370Spst 91619370Spst ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list, &flags); 91719370Spst if (ret < 0) 91819370Spst goto out; 91919370Spst 92019370Spst spin_lock(&bat_priv->mcast.mla_lock); 92119370Spst batadv_mcast_mla_tt_retract(bat_priv, &mcast_list); 92219370Spst batadv_mcast_mla_tt_add(bat_priv, &mcast_list); 92319370Spst batadv_mcast_mla_flags_update(bat_priv, &flags); 92498944Sobrien spin_unlock(&bat_priv->mcast.mla_lock); 92598944Sobrien 92698944Sobrienout: 92719370Spst batadv_mcast_mla_list_free(&mcast_list); 92898944Sobrien} 92998944Sobrien 93098944Sobrien/** 93198944Sobrien * batadv_mcast_mla_update() - update the own MLAs 93298944Sobrien * @work: kernel work struct 93398944Sobrien * 93498944Sobrien * Updates the own multicast listener announcements in the translation 93598944Sobrien * table as well as the own, announced multicast tvlv container. 93698944Sobrien * 93798944Sobrien * In the end, reschedules the work timer. 93898944Sobrien */ 93998944Sobrienstatic void batadv_mcast_mla_update(struct work_struct *work) 94019370Spst{ 94119370Spst struct delayed_work *delayed_work; 94219370Spst struct batadv_priv_mcast *priv_mcast; 94319370Spst struct batadv_priv *bat_priv; 94419370Spst 94519370Spst delayed_work = to_delayed_work(work); 94619370Spst priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work); 94719370Spst bat_priv = container_of(priv_mcast, struct batadv_priv, mcast); 948130803Smarcel 94919370Spst __batadv_mcast_mla_update(bat_priv); 95019370Spst batadv_mcast_start_timer(bat_priv); 95119370Spst} 95298944Sobrien 95398944Sobrien/** 95498944Sobrien * batadv_mcast_is_report_ipv4() -���check for IGMP reports 95598944Sobrien * @skb: the ethernet frame destined for the mesh 95619370Spst * 95798944Sobrien * This call might reallocate skb data. 95898944Sobrien * 95998944Sobrien * Checks whether the given frame is a valid IGMP report. 96098944Sobrien * 96119370Spst * Return: If so then true, otherwise false. 96219370Spst */ 96319370Spststatic bool batadv_mcast_is_report_ipv4(struct sk_buff *skb) 96419370Spst{ 96519370Spst if (ip_mc_check_igmp(skb) < 0) 96619370Spst return false; 96719370Spst 96819370Spst switch (igmp_hdr(skb)->type) { 96919370Spst case IGMP_HOST_MEMBERSHIP_REPORT: 97019370Spst case IGMPV2_HOST_MEMBERSHIP_REPORT: 97119370Spst case IGMPV3_HOST_MEMBERSHIP_REPORT: 97219370Spst return true; 97319370Spst } 97419370Spst 97519370Spst return false; 97619370Spst} 97719370Spst 97819370Spst/** 97919370Spst * batadv_mcast_forw_mode_check_ipv4() - check for optimized forwarding 98019370Spst * potential 98119370Spst * @bat_priv: the bat priv with all the soft interface information 98219370Spst * @skb: the IPv4 packet to check 98319370Spst * @is_unsnoopable: stores whether the destination is snoopable 98419370Spst * @is_routable: stores whether the destination is routable 98519370Spst * 98619370Spst * Checks whether the given IPv4 packet has the potential to be forwarded with a 98719370Spst * mode more optimal than classic flooding. 98819370Spst * 98919370Spst * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory 99019370Spst * allocation failure. 99119370Spst */ 99219370Spststatic int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv, 99319370Spst struct sk_buff *skb, 99419370Spst bool *is_unsnoopable, 99519370Spst int *is_routable) 99646283Sdfr{ 99798944Sobrien struct iphdr *iphdr; 99819370Spst 99919370Spst /* We might fail due to out-of-memory -> drop it */ 100098944Sobrien if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr))) 100198944Sobrien return -ENOMEM; 100298944Sobrien 100319370Spst if (batadv_mcast_is_report_ipv4(skb)) 100419370Spst return -EINVAL; 100519370Spst 100619370Spst iphdr = ip_hdr(skb); 100719370Spst 100819370Spst /* link-local multicast listeners behind a bridge are 100946283Sdfr * not snoopable (see RFC4541, section 2.1.2.2) 101046283Sdfr */ 101146283Sdfr if (ipv4_is_local_multicast(iphdr->daddr)) 101246283Sdfr *is_unsnoopable = true; 101346283Sdfr else 101446283Sdfr *is_routable = ETH_P_IP; 101546283Sdfr 101646283Sdfr return 0; 101746283Sdfr} 101819370Spst 101946283Sdfr/** 102098944Sobrien * batadv_mcast_is_report_ipv6() - check for MLD reports 102198944Sobrien * @skb: the ethernet frame destined for the mesh 102298944Sobrien * 102398944Sobrien * This call might reallocate skb data. 102446283Sdfr * 1025130803Smarcel * Checks whether the given frame is a valid MLD report. 1026130803Smarcel * 1027130803Smarcel * Return: If so then true, otherwise false. 1028130803Smarcel */ 1029130803Smarcelstatic bool batadv_mcast_is_report_ipv6(struct sk_buff *skb) 1030130803Smarcel{ 1031130803Smarcel if (ipv6_mc_check_mld(skb) < 0) 1032130803Smarcel return false; 1033130803Smarcel 103446283Sdfr switch (icmp6_hdr(skb)->icmp6_type) { 103546283Sdfr case ICMPV6_MGM_REPORT: 103619370Spst case ICMPV6_MLD2_REPORT: 103746283Sdfr return true; 103846283Sdfr } 103946283Sdfr 104046283Sdfr return false; 104198944Sobrien} 104298944Sobrien 104398944Sobrien/** 104498944Sobrien * batadv_mcast_forw_mode_check_ipv6() - check for optimized forwarding 104546283Sdfr * potential 104646283Sdfr * @bat_priv: the bat priv with all the soft interface information 104746283Sdfr * @skb: the IPv6 packet to check 104846283Sdfr * @is_unsnoopable: stores whether the destination is snoopable 104946283Sdfr * @is_routable: stores whether the destination is routable 105046283Sdfr * 105198944Sobrien * Checks whether the given IPv6 packet has the potential to be forwarded with a 105246283Sdfr * mode more optimal than classic flooding. 105398944Sobrien * 105446283Sdfr * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory 105546283Sdfr */ 105646283Sdfrstatic int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv, 105798944Sobrien struct sk_buff *skb, 105819370Spst bool *is_unsnoopable, 105919370Spst int *is_routable) 106046283Sdfr{ 106198944Sobrien struct ipv6hdr *ip6hdr; 106246283Sdfr 106319370Spst /* We might fail due to out-of-memory -> drop it */ 106419370Spst if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr))) 106519370Spst return -ENOMEM; 106619370Spst 106798944Sobrien if (batadv_mcast_is_report_ipv6(skb)) 106846283Sdfr return -EINVAL; 106998944Sobrien 107098944Sobrien ip6hdr = ipv6_hdr(skb); 107198944Sobrien 107298944Sobrien if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) < IPV6_ADDR_SCOPE_LINKLOCAL) 107319370Spst return -EINVAL; 107498944Sobrien 107598944Sobrien /* link-local-all-nodes multicast listeners behind a bridge are 107619370Spst * not snoopable (see RFC4541, section 3, paragraph 3) 107719370Spst */ 107819370Spst if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr)) 107998944Sobrien *is_unsnoopable = true; 108046283Sdfr else if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) > IPV6_ADDR_SCOPE_LINKLOCAL) 108146283Sdfr *is_routable = ETH_P_IPV6; 108298944Sobrien 108398944Sobrien return 0; 108498944Sobrien} 108598944Sobrien 108698944Sobrien/** 108798944Sobrien * batadv_mcast_forw_mode_check() - check for optimized forwarding potential 108898944Sobrien * @bat_priv: the bat priv with all the soft interface information 108998944Sobrien * @skb: the multicast frame to check 109098944Sobrien * @is_unsnoopable: stores whether the destination is snoopable 109198944Sobrien * @is_routable: stores whether the destination is routable 109298944Sobrien * 109398944Sobrien * Checks whether the given multicast ethernet frame has the potential to be 109446283Sdfr * forwarded with a mode more optimal than classic flooding. 109546283Sdfr * 109646283Sdfr * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory 109746283Sdfr */ 109846283Sdfrstatic int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv, 109946283Sdfr struct sk_buff *skb, 110098944Sobrien bool *is_unsnoopable, 110119370Spst int *is_routable) 110219370Spst{ 110319370Spst struct ethhdr *ethhdr = eth_hdr(skb); 110419370Spst 110519370Spst if (!atomic_read(&bat_priv->multicast_mode)) 110619370Spst return -EINVAL; 110719370Spst 110819370Spst switch (ntohs(ethhdr->h_proto)) { 110919370Spst case ETH_P_IP: 111019370Spst return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb, 111119370Spst is_unsnoopable, 111219370Spst is_routable); 111319370Spst case ETH_P_IPV6: 111419370Spst if (!IS_ENABLED(CONFIG_IPV6)) 111519370Spst return -EINVAL; 111619370Spst 111719370Spst return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb, 111819370Spst is_unsnoopable, 111919370Spst is_routable); 112019370Spst default: 112119370Spst return -EINVAL; 112298944Sobrien } 112398944Sobrien} 112419370Spst 112519370Spst/** 112619370Spst * batadv_mcast_forw_want_all_ip_count() - count nodes with unspecific mcast 112719370Spst * interest 112819370Spst * @bat_priv: the bat priv with all the soft interface information 112919370Spst * @ethhdr: ethernet header of a packet 113019370Spst * 113119370Spst * Return: the number of nodes which want all IPv4 multicast traffic if the 113219370Spst * given ethhdr is from an IPv4 packet or the number of nodes which want all 113319370Spst * IPv6 traffic if it matches an IPv6 packet. 113419370Spst */ 113519370Spststatic int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv, 113619370Spst struct ethhdr *ethhdr) 113719370Spst{ 113819370Spst switch (ntohs(ethhdr->h_proto)) { 113919370Spst case ETH_P_IP: 114019370Spst return atomic_read(&bat_priv->mcast.num_want_all_ipv4); 114119370Spst case ETH_P_IPV6: 114219370Spst return atomic_read(&bat_priv->mcast.num_want_all_ipv6); 114319370Spst default: 114419370Spst /* we shouldn't be here... */ 114519370Spst return 0; 114619370Spst } 114719370Spst} 114819370Spst 114919370Spst/** 115019370Spst * batadv_mcast_forw_rtr_count() - count nodes with a multicast router 115119370Spst * @bat_priv: the bat priv with all the soft interface information 115219370Spst * @protocol: the ethernet protocol type to count multicast routers for 115319370Spst * 115446283Sdfr * Return: the number of nodes which want all routable IPv4 multicast traffic 115546283Sdfr * if the protocol is ETH_P_IP or the number of nodes which want all routable 115646283Sdfr * IPv6 traffic if the protocol is ETH_P_IPV6. Otherwise returns 0. 115798944Sobrien */ 115846283Sdfr 115946283Sdfrstatic int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv, 116098944Sobrien int protocol) 116146283Sdfr{ 116298944Sobrien switch (protocol) { 116398944Sobrien case ETH_P_IP: 116498944Sobrien return atomic_read(&bat_priv->mcast.num_want_all_rtr4); 116598944Sobrien case ETH_P_IPV6: 116698944Sobrien return atomic_read(&bat_priv->mcast.num_want_all_rtr6); 116798944Sobrien default: 116898944Sobrien return 0; 116998944Sobrien } 117046283Sdfr} 117146283Sdfr 117246283Sdfr/** 117398944Sobrien * batadv_mcast_forw_mode_by_count() - get forwarding mode by count 117498944Sobrien * @bat_priv: the bat priv with all the soft interface information 117598944Sobrien * @skb: the multicast packet to check 117698944Sobrien * @vid: the vlan identifier 117798944Sobrien * @is_routable: stores whether the destination is routable 117898944Sobrien * @count: the number of originators the multicast packet need to be sent to 117998944Sobrien * 118098944Sobrien * For a multicast packet with multiple destination originators, checks which 118198944Sobrien * mode to use. For BATADV_FORW_MCAST it also encapsulates the packet with a 118298944Sobrien * complete batman-adv multicast header. 118398944Sobrien * 118498944Sobrien * Return: 118598944Sobrien * BATADV_FORW_MCAST: If all nodes have multicast packet routing 118646283Sdfr * capabilities and an MTU >= 1280 on all hard interfaces (including us) 118798944Sobrien * and the encapsulated multicast packet with all destination addresses 1188130803Smarcel * would still fit into an 1280 bytes batman-adv multicast packet 1189130803Smarcel * (excluding the outer ethernet frame) and we could successfully push 1190130803Smarcel * the full batman-adv multicast packet header. 1191130803Smarcel * BATADV_FORW_UCASTS: If the packet cannot be sent in a batman-adv 1192130803Smarcel * multicast packet and the amount of batman-adv unicast packets needed 119319370Spst * is smaller or equal to the configured multicast fanout. 119419370Spst * BATADV_FORW_BCAST: Otherwise. 119598944Sobrien */ 119698944Sobrienstatic enum batadv_forw_mode 119798944Sobrienbatadv_mcast_forw_mode_by_count(struct batadv_priv *bat_priv, 119819370Spst struct sk_buff *skb, unsigned short vid, 119919370Spst int is_routable, int count) 120098944Sobrien{ 120119370Spst unsigned int mcast_hdrlen = batadv_mcast_forw_packet_hdrlen(count); 120219370Spst u8 own_tvlv_flags = bat_priv->mcast.mla_flags.tvlv_flags; 120319370Spst 120419370Spst if (!atomic_read(&bat_priv->mcast.num_no_mc_ptype_capa) && 120519370Spst own_tvlv_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA && 120619370Spst skb->len + mcast_hdrlen <= IPV6_MIN_MTU && 120719370Spst batadv_mcast_forw_push(bat_priv, skb, vid, is_routable, count)) 120819370Spst return BATADV_FORW_MCAST; 120919370Spst 121019370Spst if (count <= atomic_read(&bat_priv->multicast_fanout)) 121119370Spst return BATADV_FORW_UCASTS; 121219370Spst 1213 return BATADV_FORW_BCAST; 1214} 1215 1216/** 1217 * batadv_mcast_forw_mode() - check on how to forward a multicast packet 1218 * @bat_priv: the bat priv with all the soft interface information 1219 * @skb: the multicast packet to check 1220 * @vid: the vlan identifier 1221 * @is_routable: stores whether the destination is routable 1222 * 1223 * Return: The forwarding mode as enum batadv_forw_mode. 1224 */ 1225enum batadv_forw_mode 1226batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, 1227 unsigned short vid, int *is_routable) 1228{ 1229 int ret, tt_count, ip_count, unsnoop_count, total_count; 1230 bool is_unsnoopable = false; 1231 struct ethhdr *ethhdr; 1232 int rtr_count = 0; 1233 1234 ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable, 1235 is_routable); 1236 if (ret == -ENOMEM) 1237 return BATADV_FORW_NONE; 1238 else if (ret < 0) 1239 return BATADV_FORW_BCAST; 1240 1241 ethhdr = eth_hdr(skb); 1242 1243 tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest, 1244 BATADV_NO_FLAGS); 1245 ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr); 1246 unsnoop_count = !is_unsnoopable ? 0 : 1247 atomic_read(&bat_priv->mcast.num_want_all_unsnoopables); 1248 rtr_count = batadv_mcast_forw_rtr_count(bat_priv, *is_routable); 1249 1250 total_count = tt_count + ip_count + unsnoop_count + rtr_count; 1251 1252 if (!total_count) 1253 return BATADV_FORW_NONE; 1254 else if (unsnoop_count) 1255 return BATADV_FORW_BCAST; 1256 1257 return batadv_mcast_forw_mode_by_count(bat_priv, skb, vid, *is_routable, 1258 total_count); 1259} 1260 1261/** 1262 * batadv_mcast_forw_send_orig() - send a multicast packet to an originator 1263 * @bat_priv: the bat priv with all the soft interface information 1264 * @skb: the multicast packet to send 1265 * @vid: the vlan identifier 1266 * @orig_node: the originator to send the packet to 1267 * 1268 * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. 1269 */ 1270static int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, 1271 struct sk_buff *skb, 1272 unsigned short vid, 1273 struct batadv_orig_node *orig_node) 1274{ 1275 /* Avoid sending multicast-in-unicast packets to other BLA 1276 * gateways - they already got the frame from the LAN side 1277 * we share with them. 1278 * TODO: Refactor to take BLA into account earlier, to avoid 1279 * reducing the mcast_fanout count. 1280 */ 1281 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) { 1282 dev_kfree_skb(skb); 1283 return NET_XMIT_SUCCESS; 1284 } 1285 1286 return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0, 1287 orig_node, vid); 1288} 1289 1290/** 1291 * batadv_mcast_forw_tt() - forwards a packet to multicast listeners 1292 * @bat_priv: the bat priv with all the soft interface information 1293 * @skb: the multicast packet to transmit 1294 * @vid: the vlan identifier 1295 * 1296 * Sends copies of a frame with multicast destination to any multicast 1297 * listener registered in the translation table. A transmission is performed 1298 * via a batman-adv unicast packet for each such destination node. 1299 * 1300 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS 1301 * otherwise. 1302 */ 1303static int 1304batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb, 1305 unsigned short vid) 1306{ 1307 int ret = NET_XMIT_SUCCESS; 1308 struct sk_buff *newskb; 1309 1310 struct batadv_tt_orig_list_entry *orig_entry; 1311 1312 struct batadv_tt_global_entry *tt_global; 1313 const u8 *addr = eth_hdr(skb)->h_dest; 1314 1315 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid); 1316 if (!tt_global) 1317 goto out; 1318 1319 rcu_read_lock(); 1320 hlist_for_each_entry_rcu(orig_entry, &tt_global->orig_list, list) { 1321 newskb = skb_copy(skb, GFP_ATOMIC); 1322 if (!newskb) { 1323 ret = NET_XMIT_DROP; 1324 break; 1325 } 1326 1327 batadv_mcast_forw_send_orig(bat_priv, newskb, vid, 1328 orig_entry->orig_node); 1329 } 1330 rcu_read_unlock(); 1331 1332 batadv_tt_global_entry_put(tt_global); 1333 1334out: 1335 return ret; 1336} 1337 1338/** 1339 * batadv_mcast_forw_want_all_ipv4() - forward to nodes with want-all-ipv4 1340 * @bat_priv: the bat priv with all the soft interface information 1341 * @skb: the multicast packet to transmit 1342 * @vid: the vlan identifier 1343 * 1344 * Sends copies of a frame with multicast destination to any node with a 1345 * BATADV_MCAST_WANT_ALL_IPV4 flag set. A transmission is performed via a 1346 * batman-adv unicast packet for each such destination node. 1347 * 1348 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS 1349 * otherwise. 1350 */ 1351static int 1352batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv, 1353 struct sk_buff *skb, unsigned short vid) 1354{ 1355 struct batadv_orig_node *orig_node; 1356 int ret = NET_XMIT_SUCCESS; 1357 struct sk_buff *newskb; 1358 1359 rcu_read_lock(); 1360 hlist_for_each_entry_rcu(orig_node, 1361 &bat_priv->mcast.want_all_ipv4_list, 1362 mcast_want_all_ipv4_node) { 1363 newskb = skb_copy(skb, GFP_ATOMIC); 1364 if (!newskb) { 1365 ret = NET_XMIT_DROP; 1366 break; 1367 } 1368 1369 batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); 1370 } 1371 rcu_read_unlock(); 1372 return ret; 1373} 1374 1375/** 1376 * batadv_mcast_forw_want_all_ipv6() - forward to nodes with want-all-ipv6 1377 * @bat_priv: the bat priv with all the soft interface information 1378 * @skb: The multicast packet to transmit 1379 * @vid: the vlan identifier 1380 * 1381 * Sends copies of a frame with multicast destination to any node with a 1382 * BATADV_MCAST_WANT_ALL_IPV6 flag set. A transmission is performed via a 1383 * batman-adv unicast packet for each such destination node. 1384 * 1385 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS 1386 * otherwise. 1387 */ 1388static int 1389batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv, 1390 struct sk_buff *skb, unsigned short vid) 1391{ 1392 struct batadv_orig_node *orig_node; 1393 int ret = NET_XMIT_SUCCESS; 1394 struct sk_buff *newskb; 1395 1396 rcu_read_lock(); 1397 hlist_for_each_entry_rcu(orig_node, 1398 &bat_priv->mcast.want_all_ipv6_list, 1399 mcast_want_all_ipv6_node) { 1400 newskb = skb_copy(skb, GFP_ATOMIC); 1401 if (!newskb) { 1402 ret = NET_XMIT_DROP; 1403 break; 1404 } 1405 1406 batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); 1407 } 1408 rcu_read_unlock(); 1409 return ret; 1410} 1411 1412/** 1413 * batadv_mcast_forw_want_all() - forward packet to nodes in a want-all list 1414 * @bat_priv: the bat priv with all the soft interface information 1415 * @skb: the multicast packet to transmit 1416 * @vid: the vlan identifier 1417 * 1418 * Sends copies of a frame with multicast destination to any node with a 1419 * BATADV_MCAST_WANT_ALL_IPV4 or BATADV_MCAST_WANT_ALL_IPV6 flag set. A 1420 * transmission is performed via a batman-adv unicast packet for each such 1421 * destination node. 1422 * 1423 * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family 1424 * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise. 1425 */ 1426static int 1427batadv_mcast_forw_want_all(struct batadv_priv *bat_priv, 1428 struct sk_buff *skb, unsigned short vid) 1429{ 1430 switch (ntohs(eth_hdr(skb)->h_proto)) { 1431 case ETH_P_IP: 1432 return batadv_mcast_forw_want_all_ipv4(bat_priv, skb, vid); 1433 case ETH_P_IPV6: 1434 return batadv_mcast_forw_want_all_ipv6(bat_priv, skb, vid); 1435 default: 1436 /* we shouldn't be here... */ 1437 return NET_XMIT_DROP; 1438 } 1439} 1440 1441/** 1442 * batadv_mcast_forw_want_all_rtr4() - forward to nodes with want-all-rtr4 1443 * @bat_priv: the bat priv with all the soft interface information 1444 * @skb: the multicast packet to transmit 1445 * @vid: the vlan identifier 1446 * 1447 * Sends copies of a frame with multicast destination to any node with a 1448 * BATADV_MCAST_WANT_NO_RTR4 flag unset. A transmission is performed via a 1449 * batman-adv unicast packet for each such destination node. 1450 * 1451 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS 1452 * otherwise. 1453 */ 1454static int 1455batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv, 1456 struct sk_buff *skb, unsigned short vid) 1457{ 1458 struct batadv_orig_node *orig_node; 1459 int ret = NET_XMIT_SUCCESS; 1460 struct sk_buff *newskb; 1461 1462 rcu_read_lock(); 1463 hlist_for_each_entry_rcu(orig_node, 1464 &bat_priv->mcast.want_all_rtr4_list, 1465 mcast_want_all_rtr4_node) { 1466 newskb = skb_copy(skb, GFP_ATOMIC); 1467 if (!newskb) { 1468 ret = NET_XMIT_DROP; 1469 break; 1470 } 1471 1472 batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); 1473 } 1474 rcu_read_unlock(); 1475 return ret; 1476} 1477 1478/** 1479 * batadv_mcast_forw_want_all_rtr6() - forward to nodes with want-all-rtr6 1480 * @bat_priv: the bat priv with all the soft interface information 1481 * @skb: The multicast packet to transmit 1482 * @vid: the vlan identifier 1483 * 1484 * Sends copies of a frame with multicast destination to any node with a 1485 * BATADV_MCAST_WANT_NO_RTR6 flag unset. A transmission is performed via a 1486 * batman-adv unicast packet for each such destination node. 1487 * 1488 * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS 1489 * otherwise. 1490 */ 1491static int 1492batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv, 1493 struct sk_buff *skb, unsigned short vid) 1494{ 1495 struct batadv_orig_node *orig_node; 1496 int ret = NET_XMIT_SUCCESS; 1497 struct sk_buff *newskb; 1498 1499 rcu_read_lock(); 1500 hlist_for_each_entry_rcu(orig_node, 1501 &bat_priv->mcast.want_all_rtr6_list, 1502 mcast_want_all_rtr6_node) { 1503 newskb = skb_copy(skb, GFP_ATOMIC); 1504 if (!newskb) { 1505 ret = NET_XMIT_DROP; 1506 break; 1507 } 1508 1509 batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); 1510 } 1511 rcu_read_unlock(); 1512 return ret; 1513} 1514 1515/** 1516 * batadv_mcast_forw_want_rtr() - forward packet to nodes in a want-all-rtr list 1517 * @bat_priv: the bat priv with all the soft interface information 1518 * @skb: the multicast packet to transmit 1519 * @vid: the vlan identifier 1520 * 1521 * Sends copies of a frame with multicast destination to any node with a 1522 * BATADV_MCAST_WANT_NO_RTR4 or BATADV_MCAST_WANT_NO_RTR6 flag unset. A 1523 * transmission is performed via a batman-adv unicast packet for each such 1524 * destination node. 1525 * 1526 * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family 1527 * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise. 1528 */ 1529static int 1530batadv_mcast_forw_want_rtr(struct batadv_priv *bat_priv, 1531 struct sk_buff *skb, unsigned short vid) 1532{ 1533 switch (ntohs(eth_hdr(skb)->h_proto)) { 1534 case ETH_P_IP: 1535 return batadv_mcast_forw_want_all_rtr4(bat_priv, skb, vid); 1536 case ETH_P_IPV6: 1537 return batadv_mcast_forw_want_all_rtr6(bat_priv, skb, vid); 1538 default: 1539 /* we shouldn't be here... */ 1540 return NET_XMIT_DROP; 1541 } 1542} 1543 1544/** 1545 * batadv_mcast_forw_send() - send packet to any detected multicast recipient 1546 * @bat_priv: the bat priv with all the soft interface information 1547 * @skb: the multicast packet to transmit 1548 * @vid: the vlan identifier 1549 * @is_routable: stores whether the destination is routable 1550 * 1551 * Sends copies of a frame with multicast destination to any node that signaled 1552 * interest in it, that is either via the translation table or the according 1553 * want-all flags. A transmission is performed via a batman-adv unicast packet 1554 * for each such destination node. 1555 * 1556 * The given skb is consumed/freed. 1557 * 1558 * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family 1559 * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise. 1560 */ 1561int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, 1562 unsigned short vid, int is_routable) 1563{ 1564 int ret; 1565 1566 ret = batadv_mcast_forw_tt(bat_priv, skb, vid); 1567 if (ret != NET_XMIT_SUCCESS) { 1568 kfree_skb(skb); 1569 return ret; 1570 } 1571 1572 ret = batadv_mcast_forw_want_all(bat_priv, skb, vid); 1573 if (ret != NET_XMIT_SUCCESS) { 1574 kfree_skb(skb); 1575 return ret; 1576 } 1577 1578 if (!is_routable) 1579 goto skip_mc_router; 1580 1581 ret = batadv_mcast_forw_want_rtr(bat_priv, skb, vid); 1582 if (ret != NET_XMIT_SUCCESS) { 1583 kfree_skb(skb); 1584 return ret; 1585 } 1586 1587skip_mc_router: 1588 consume_skb(skb); 1589 return ret; 1590} 1591 1592/** 1593 * batadv_mcast_want_unsnoop_update() - update unsnoop counter and list 1594 * @bat_priv: the bat priv with all the soft interface information 1595 * @orig: the orig_node which multicast state might have changed of 1596 * @mcast_flags: flags indicating the new multicast state 1597 * 1598 * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator, 1599 * orig, has toggled then this method updates the counter and the list 1600 * accordingly. 1601 * 1602 * Caller needs to hold orig->mcast_handler_lock. 1603 */ 1604static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv, 1605 struct batadv_orig_node *orig, 1606 u8 mcast_flags) 1607{ 1608 struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node; 1609 struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list; 1610 1611 lockdep_assert_held(&orig->mcast_handler_lock); 1612 1613 /* switched from flag unset to set */ 1614 if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES && 1615 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) { 1616 atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables); 1617 1618 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1619 /* flag checks above + mcast_handler_lock prevents this */ 1620 WARN_ON(!hlist_unhashed(node)); 1621 1622 hlist_add_head_rcu(node, head); 1623 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1624 /* switched from flag set to unset */ 1625 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) && 1626 orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) { 1627 atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables); 1628 1629 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1630 /* flag checks above + mcast_handler_lock prevents this */ 1631 WARN_ON(hlist_unhashed(node)); 1632 1633 hlist_del_init_rcu(node); 1634 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1635 } 1636} 1637 1638/** 1639 * batadv_mcast_want_ipv4_update() - update want-all-ipv4 counter and list 1640 * @bat_priv: the bat priv with all the soft interface information 1641 * @orig: the orig_node which multicast state might have changed of 1642 * @mcast_flags: flags indicating the new multicast state 1643 * 1644 * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has 1645 * toggled then this method updates the counter and the list accordingly. 1646 * 1647 * Caller needs to hold orig->mcast_handler_lock. 1648 */ 1649static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv, 1650 struct batadv_orig_node *orig, 1651 u8 mcast_flags) 1652{ 1653 struct hlist_node *node = &orig->mcast_want_all_ipv4_node; 1654 struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list; 1655 1656 lockdep_assert_held(&orig->mcast_handler_lock); 1657 1658 /* switched from flag unset to set */ 1659 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 && 1660 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) { 1661 atomic_inc(&bat_priv->mcast.num_want_all_ipv4); 1662 1663 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1664 /* flag checks above + mcast_handler_lock prevents this */ 1665 WARN_ON(!hlist_unhashed(node)); 1666 1667 hlist_add_head_rcu(node, head); 1668 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1669 /* switched from flag set to unset */ 1670 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) && 1671 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) { 1672 atomic_dec(&bat_priv->mcast.num_want_all_ipv4); 1673 1674 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1675 /* flag checks above + mcast_handler_lock prevents this */ 1676 WARN_ON(hlist_unhashed(node)); 1677 1678 hlist_del_init_rcu(node); 1679 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1680 } 1681} 1682 1683/** 1684 * batadv_mcast_want_ipv6_update() - update want-all-ipv6 counter and list 1685 * @bat_priv: the bat priv with all the soft interface information 1686 * @orig: the orig_node which multicast state might have changed of 1687 * @mcast_flags: flags indicating the new multicast state 1688 * 1689 * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has 1690 * toggled then this method updates the counter and the list accordingly. 1691 * 1692 * Caller needs to hold orig->mcast_handler_lock. 1693 */ 1694static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv, 1695 struct batadv_orig_node *orig, 1696 u8 mcast_flags) 1697{ 1698 struct hlist_node *node = &orig->mcast_want_all_ipv6_node; 1699 struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list; 1700 1701 lockdep_assert_held(&orig->mcast_handler_lock); 1702 1703 /* switched from flag unset to set */ 1704 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 && 1705 !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) { 1706 atomic_inc(&bat_priv->mcast.num_want_all_ipv6); 1707 1708 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1709 /* flag checks above + mcast_handler_lock prevents this */ 1710 WARN_ON(!hlist_unhashed(node)); 1711 1712 hlist_add_head_rcu(node, head); 1713 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1714 /* switched from flag set to unset */ 1715 } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) && 1716 orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) { 1717 atomic_dec(&bat_priv->mcast.num_want_all_ipv6); 1718 1719 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1720 /* flag checks above + mcast_handler_lock prevents this */ 1721 WARN_ON(hlist_unhashed(node)); 1722 1723 hlist_del_init_rcu(node); 1724 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1725 } 1726} 1727 1728/** 1729 * batadv_mcast_want_rtr4_update() - update want-all-rtr4 counter and list 1730 * @bat_priv: the bat priv with all the soft interface information 1731 * @orig: the orig_node which multicast state might have changed of 1732 * @mcast_flags: flags indicating the new multicast state 1733 * 1734 * If the BATADV_MCAST_WANT_NO_RTR4 flag of this originator, orig, has 1735 * toggled then this method updates the counter and the list accordingly. 1736 * 1737 * Caller needs to hold orig->mcast_handler_lock. 1738 */ 1739static void batadv_mcast_want_rtr4_update(struct batadv_priv *bat_priv, 1740 struct batadv_orig_node *orig, 1741 u8 mcast_flags) 1742{ 1743 struct hlist_node *node = &orig->mcast_want_all_rtr4_node; 1744 struct hlist_head *head = &bat_priv->mcast.want_all_rtr4_list; 1745 1746 lockdep_assert_held(&orig->mcast_handler_lock); 1747 1748 /* switched from flag set to unset */ 1749 if (!(mcast_flags & BATADV_MCAST_WANT_NO_RTR4) && 1750 orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR4) { 1751 atomic_inc(&bat_priv->mcast.num_want_all_rtr4); 1752 1753 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1754 /* flag checks above + mcast_handler_lock prevents this */ 1755 WARN_ON(!hlist_unhashed(node)); 1756 1757 hlist_add_head_rcu(node, head); 1758 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1759 /* switched from flag unset to set */ 1760 } else if (mcast_flags & BATADV_MCAST_WANT_NO_RTR4 && 1761 !(orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR4)) { 1762 atomic_dec(&bat_priv->mcast.num_want_all_rtr4); 1763 1764 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1765 /* flag checks above + mcast_handler_lock prevents this */ 1766 WARN_ON(hlist_unhashed(node)); 1767 1768 hlist_del_init_rcu(node); 1769 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1770 } 1771} 1772 1773/** 1774 * batadv_mcast_want_rtr6_update() - update want-all-rtr6 counter and list 1775 * @bat_priv: the bat priv with all the soft interface information 1776 * @orig: the orig_node which multicast state might have changed of 1777 * @mcast_flags: flags indicating the new multicast state 1778 * 1779 * If the BATADV_MCAST_WANT_NO_RTR6 flag of this originator, orig, has 1780 * toggled then this method updates the counter and the list accordingly. 1781 * 1782 * Caller needs to hold orig->mcast_handler_lock. 1783 */ 1784static void batadv_mcast_want_rtr6_update(struct batadv_priv *bat_priv, 1785 struct batadv_orig_node *orig, 1786 u8 mcast_flags) 1787{ 1788 struct hlist_node *node = &orig->mcast_want_all_rtr6_node; 1789 struct hlist_head *head = &bat_priv->mcast.want_all_rtr6_list; 1790 1791 lockdep_assert_held(&orig->mcast_handler_lock); 1792 1793 /* switched from flag set to unset */ 1794 if (!(mcast_flags & BATADV_MCAST_WANT_NO_RTR6) && 1795 orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR6) { 1796 atomic_inc(&bat_priv->mcast.num_want_all_rtr6); 1797 1798 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1799 /* flag checks above + mcast_handler_lock prevents this */ 1800 WARN_ON(!hlist_unhashed(node)); 1801 1802 hlist_add_head_rcu(node, head); 1803 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1804 /* switched from flag unset to set */ 1805 } else if (mcast_flags & BATADV_MCAST_WANT_NO_RTR6 && 1806 !(orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR6)) { 1807 atomic_dec(&bat_priv->mcast.num_want_all_rtr6); 1808 1809 spin_lock_bh(&bat_priv->mcast.want_lists_lock); 1810 /* flag checks above + mcast_handler_lock prevents this */ 1811 WARN_ON(hlist_unhashed(node)); 1812 1813 hlist_del_init_rcu(node); 1814 spin_unlock_bh(&bat_priv->mcast.want_lists_lock); 1815 } 1816} 1817 1818/** 1819 * batadv_mcast_have_mc_ptype_update() - update multicast packet type counter 1820 * @bat_priv: the bat priv with all the soft interface information 1821 * @orig: the orig_node which multicast state might have changed of 1822 * @mcast_flags: flags indicating the new multicast state 1823 * 1824 * If the BATADV_MCAST_HAVE_MC_PTYPE_CAPA flag of this originator, orig, has 1825 * toggled then this method updates the counter accordingly. 1826 */ 1827static void batadv_mcast_have_mc_ptype_update(struct batadv_priv *bat_priv, 1828 struct batadv_orig_node *orig, 1829 u8 mcast_flags) 1830{ 1831 lockdep_assert_held(&orig->mcast_handler_lock); 1832 1833 /* switched from flag set to unset */ 1834 if (!(mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) && 1835 orig->mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) 1836 atomic_inc(&bat_priv->mcast.num_no_mc_ptype_capa); 1837 /* switched from flag unset to set */ 1838 else if (mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA && 1839 !(orig->mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA)) 1840 atomic_dec(&bat_priv->mcast.num_no_mc_ptype_capa); 1841} 1842 1843/** 1844 * batadv_mcast_tvlv_flags_get() - get multicast flags from an OGM TVLV 1845 * @enabled: whether the originator has multicast TVLV support enabled 1846 * @tvlv_value: tvlv buffer containing the multicast flags 1847 * @tvlv_value_len: tvlv buffer length 1848 * 1849 * Return: multicast flags for the given tvlv buffer 1850 */ 1851static u8 1852batadv_mcast_tvlv_flags_get(bool enabled, void *tvlv_value, u16 tvlv_value_len) 1853{ 1854 u8 mcast_flags = BATADV_NO_FLAGS; 1855 1856 if (enabled && tvlv_value && tvlv_value_len >= sizeof(mcast_flags)) 1857 mcast_flags = *(u8 *)tvlv_value; 1858 1859 if (!enabled) { 1860 mcast_flags |= BATADV_MCAST_WANT_ALL_IPV4; 1861 mcast_flags |= BATADV_MCAST_WANT_ALL_IPV6; 1862 } 1863 1864 /* remove redundant flags to avoid sending duplicate packets later */ 1865 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) 1866 mcast_flags |= BATADV_MCAST_WANT_NO_RTR4; 1867 1868 if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) 1869 mcast_flags |= BATADV_MCAST_WANT_NO_RTR6; 1870 1871 return mcast_flags; 1872} 1873 1874/** 1875 * batadv_mcast_tvlv_ogm_handler() - process incoming multicast tvlv container 1876 * @bat_priv: the bat priv with all the soft interface information 1877 * @orig: the orig_node of the ogm 1878 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) 1879 * @tvlv_value: tvlv buffer containing the multicast data 1880 * @tvlv_value_len: tvlv buffer length 1881 */ 1882static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv, 1883 struct batadv_orig_node *orig, 1884 u8 flags, 1885 void *tvlv_value, 1886 u16 tvlv_value_len) 1887{ 1888 bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 1889 u8 mcast_flags; 1890 1891 mcast_flags = batadv_mcast_tvlv_flags_get(orig_mcast_enabled, 1892 tvlv_value, tvlv_value_len); 1893 1894 spin_lock_bh(&orig->mcast_handler_lock); 1895 1896 if (orig_mcast_enabled && 1897 !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) { 1898 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities); 1899 } else if (!orig_mcast_enabled && 1900 test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) { 1901 clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities); 1902 } 1903 1904 set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized); 1905 1906 batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags); 1907 batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags); 1908 batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags); 1909 batadv_mcast_want_rtr4_update(bat_priv, orig, mcast_flags); 1910 batadv_mcast_want_rtr6_update(bat_priv, orig, mcast_flags); 1911 batadv_mcast_have_mc_ptype_update(bat_priv, orig, mcast_flags); 1912 1913 orig->mcast_flags = mcast_flags; 1914 spin_unlock_bh(&orig->mcast_handler_lock); 1915} 1916 1917/** 1918 * batadv_mcast_init() - initialize the multicast optimizations structures 1919 * @bat_priv: the bat priv with all the soft interface information 1920 */ 1921void batadv_mcast_init(struct batadv_priv *bat_priv) 1922{ 1923 batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler, 1924 NULL, NULL, BATADV_TVLV_MCAST, 2, 1925 BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 1926 batadv_tvlv_handler_register(bat_priv, NULL, NULL, 1927 batadv_mcast_forw_tracker_tvlv_handler, 1928 BATADV_TVLV_MCAST_TRACKER, 1, 1929 BATADV_TVLV_HANDLER_OGM_CIFNOTFND); 1930 1931 INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update); 1932 batadv_mcast_start_timer(bat_priv); 1933} 1934 1935/** 1936 * batadv_mcast_mesh_info_put() - put multicast info into a netlink message 1937 * @msg: buffer for the message 1938 * @bat_priv: the bat priv with all the soft interface information 1939 * 1940 * Return: 0 or error code. 1941 */ 1942int batadv_mcast_mesh_info_put(struct sk_buff *msg, 1943 struct batadv_priv *bat_priv) 1944{ 1945 u32 flags = bat_priv->mcast.mla_flags.tvlv_flags; 1946 u32 flags_priv = BATADV_NO_FLAGS; 1947 1948 if (bat_priv->mcast.mla_flags.bridged) { 1949 flags_priv |= BATADV_MCAST_FLAGS_BRIDGED; 1950 1951 if (bat_priv->mcast.mla_flags.querier_ipv4.exists) 1952 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS; 1953 if (bat_priv->mcast.mla_flags.querier_ipv6.exists) 1954 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS; 1955 if (bat_priv->mcast.mla_flags.querier_ipv4.shadowing) 1956 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING; 1957 if (bat_priv->mcast.mla_flags.querier_ipv6.shadowing) 1958 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING; 1959 } 1960 1961 if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) || 1962 nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv)) 1963 return -EMSGSIZE; 1964 1965 return 0; 1966} 1967 1968/** 1969 * batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table 1970 * to a netlink socket 1971 * @msg: buffer for the message 1972 * @portid: netlink port 1973 * @cb: Control block containing additional options 1974 * @orig_node: originator to dump the multicast flags of 1975 * 1976 * Return: 0 or error code. 1977 */ 1978static int 1979batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid, 1980 struct netlink_callback *cb, 1981 struct batadv_orig_node *orig_node) 1982{ 1983 void *hdr; 1984 1985 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, 1986 &batadv_netlink_family, NLM_F_MULTI, 1987 BATADV_CMD_GET_MCAST_FLAGS); 1988 if (!hdr) 1989 return -ENOBUFS; 1990 1991 genl_dump_check_consistent(cb, hdr); 1992 1993 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, 1994 orig_node->orig)) { 1995 genlmsg_cancel(msg, hdr); 1996 return -EMSGSIZE; 1997 } 1998 1999 if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, 2000 &orig_node->capabilities)) { 2001 if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, 2002 orig_node->mcast_flags)) { 2003 genlmsg_cancel(msg, hdr); 2004 return -EMSGSIZE; 2005 } 2006 } 2007 2008 genlmsg_end(msg, hdr); 2009 return 0; 2010} 2011 2012/** 2013 * batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags 2014 * table to a netlink socket 2015 * @msg: buffer for the message 2016 * @portid: netlink port 2017 * @cb: Control block containing additional options 2018 * @hash: hash to dump 2019 * @bucket: bucket index to dump 2020 * @idx_skip: How many entries to skip 2021 * 2022 * Return: 0 or error code. 2023 */ 2024static int 2025batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid, 2026 struct netlink_callback *cb, 2027 struct batadv_hashtable *hash, 2028 unsigned int bucket, long *idx_skip) 2029{ 2030 struct batadv_orig_node *orig_node; 2031 long idx = 0; 2032 2033 spin_lock_bh(&hash->list_locks[bucket]); 2034 cb->seq = atomic_read(&hash->generation) << 1 | 1; 2035 2036 hlist_for_each_entry(orig_node, &hash->table[bucket], hash_entry) { 2037 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, 2038 &orig_node->capa_initialized)) 2039 continue; 2040 2041 if (idx < *idx_skip) 2042 goto skip; 2043 2044 if (batadv_mcast_flags_dump_entry(msg, portid, cb, orig_node)) { 2045 spin_unlock_bh(&hash->list_locks[bucket]); 2046 *idx_skip = idx; 2047 2048 return -EMSGSIZE; 2049 } 2050 2051skip: 2052 idx++; 2053 } 2054 spin_unlock_bh(&hash->list_locks[bucket]); 2055 2056 return 0; 2057} 2058 2059/** 2060 * __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket 2061 * @msg: buffer for the message 2062 * @portid: netlink port 2063 * @cb: Control block containing additional options 2064 * @bat_priv: the bat priv with all the soft interface information 2065 * @bucket: current bucket to dump 2066 * @idx: index in current bucket to the next entry to dump 2067 * 2068 * Return: 0 or error code. 2069 */ 2070static int 2071__batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid, 2072 struct netlink_callback *cb, 2073 struct batadv_priv *bat_priv, long *bucket, long *idx) 2074{ 2075 struct batadv_hashtable *hash = bat_priv->orig_hash; 2076 long bucket_tmp = *bucket; 2077 long idx_tmp = *idx; 2078 2079 while (bucket_tmp < hash->size) { 2080 if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash, 2081 bucket_tmp, &idx_tmp)) 2082 break; 2083 2084 bucket_tmp++; 2085 idx_tmp = 0; 2086 } 2087 2088 *bucket = bucket_tmp; 2089 *idx = idx_tmp; 2090 2091 return msg->len; 2092} 2093 2094/** 2095 * batadv_mcast_netlink_get_primary() - get primary interface from netlink 2096 * callback 2097 * @cb: netlink callback structure 2098 * @primary_if: the primary interface pointer to return the result in 2099 * 2100 * Return: 0 or error code. 2101 */ 2102static int 2103batadv_mcast_netlink_get_primary(struct netlink_callback *cb, 2104 struct batadv_hard_iface **primary_if) 2105{ 2106 struct batadv_hard_iface *hard_iface = NULL; 2107 struct net *net = sock_net(cb->skb->sk); 2108 struct net_device *soft_iface; 2109 struct batadv_priv *bat_priv; 2110 int ifindex; 2111 int ret = 0; 2112 2113 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); 2114 if (!ifindex) 2115 return -EINVAL; 2116 2117 soft_iface = dev_get_by_index(net, ifindex); 2118 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { 2119 ret = -ENODEV; 2120 goto out; 2121 } 2122 2123 bat_priv = netdev_priv(soft_iface); 2124 2125 hard_iface = batadv_primary_if_get_selected(bat_priv); 2126 if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) { 2127 ret = -ENOENT; 2128 goto out; 2129 } 2130 2131out: 2132 dev_put(soft_iface); 2133 2134 if (!ret && primary_if) 2135 *primary_if = hard_iface; 2136 else 2137 batadv_hardif_put(hard_iface); 2138 2139 return ret; 2140} 2141 2142/** 2143 * batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket 2144 * @msg: buffer for the message 2145 * @cb: callback structure containing arguments 2146 * 2147 * Return: message length. 2148 */ 2149int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb) 2150{ 2151 struct batadv_hard_iface *primary_if = NULL; 2152 int portid = NETLINK_CB(cb->skb).portid; 2153 struct batadv_priv *bat_priv; 2154 long *bucket = &cb->args[0]; 2155 long *idx = &cb->args[1]; 2156 int ret; 2157 2158 ret = batadv_mcast_netlink_get_primary(cb, &primary_if); 2159 if (ret) 2160 return ret; 2161 2162 bat_priv = netdev_priv(primary_if->soft_iface); 2163 ret = __batadv_mcast_flags_dump(msg, portid, cb, bat_priv, bucket, idx); 2164 2165 batadv_hardif_put(primary_if); 2166 return ret; 2167} 2168 2169/** 2170 * batadv_mcast_free() - free the multicast optimizations structures 2171 * @bat_priv: the bat priv with all the soft interface information 2172 */ 2173void batadv_mcast_free(struct batadv_priv *bat_priv) 2174{ 2175 cancel_delayed_work_sync(&bat_priv->mcast.work); 2176 2177 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2); 2178 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST_TRACKER, 1); 2179 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2); 2180 2181 /* safely calling outside of worker, as worker was canceled above */ 2182 batadv_mcast_mla_tt_retract(bat_priv, NULL); 2183} 2184 2185/** 2186 * batadv_mcast_purge_orig() - reset originator global mcast state modifications 2187 * @orig: the originator which is going to get purged 2188 */ 2189void batadv_mcast_purge_orig(struct batadv_orig_node *orig) 2190{ 2191 struct batadv_priv *bat_priv = orig->bat_priv; 2192 2193 spin_lock_bh(&orig->mcast_handler_lock); 2194 2195 batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); 2196 batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS); 2197 batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS); 2198 batadv_mcast_want_rtr4_update(bat_priv, orig, 2199 BATADV_MCAST_WANT_NO_RTR4); 2200 batadv_mcast_want_rtr6_update(bat_priv, orig, 2201 BATADV_MCAST_WANT_NO_RTR6); 2202 batadv_mcast_have_mc_ptype_update(bat_priv, orig, 2203 BATADV_MCAST_HAVE_MC_PTYPE_CAPA); 2204 2205 spin_unlock_bh(&orig->mcast_handler_lock); 2206} 2207