^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 2014-2020 B.A.T.M.A.N. contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linus Lüssing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "multicast.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/byteorder/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/icmpv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/if_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/igmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/lockdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <net/addrconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <net/if_inet6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <uapi/linux/batman_adv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "bridge_loop_avoidance.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include "hash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "send.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include "soft-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include "translation-table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include "tvlv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static void batadv_mcast_mla_update(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * batadv_mcast_start_timer() - schedule the multicast periodic worker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void batadv_mcast_start_timer(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) queue_delayed_work(batadv_event_workqueue, &bat_priv->mcast.work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) msecs_to_jiffies(BATADV_MCAST_WORK_PERIOD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * batadv_mcast_get_bridge() - get the bridge on top of the softif if it exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @soft_iface: netdev struct of the mesh interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * If the given soft interface has a bridge on top then the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * of the according net device is increased.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Return: NULL if no such bridge exists. Otherwise the net device of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct net_device *upper = soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) upper = netdev_master_upper_dev_get_rcu(upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) } while (upper && !(upper->priv_flags & IFF_EBRIDGE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dev_hold(upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * batadv_mcast_mla_rtr_flags_softif_get_ipv4() - get mcast router flags from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * node for IPv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @dev: the interface to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Checks the presence of an IPv4 multicast router on this node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Caller needs to hold rcu read lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Return: BATADV_NO_FLAGS if present, BATADV_MCAST_WANT_NO_RTR4 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static u8 batadv_mcast_mla_rtr_flags_softif_get_ipv4(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct in_device *in_dev = __in_dev_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (in_dev && IN_DEV_MFORWARD(in_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return BATADV_MCAST_WANT_NO_RTR4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * batadv_mcast_mla_rtr_flags_softif_get_ipv6() - get mcast router flags from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * node for IPv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @dev: the interface to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Checks the presence of an IPv6 multicast router on this node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Caller needs to hold rcu read lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * Return: BATADV_NO_FLAGS if present, BATADV_MCAST_WANT_NO_RTR6 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #if IS_ENABLED(CONFIG_IPV6_MROUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static u8 batadv_mcast_mla_rtr_flags_softif_get_ipv6(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct inet6_dev *in6_dev = __in6_dev_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (in6_dev && in6_dev->cnf.mc_forwarding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) batadv_mcast_mla_rtr_flags_softif_get_ipv6(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * batadv_mcast_mla_rtr_flags_softif_get() - get mcast router flags from node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @bridge: bridge interface on top of the soft_iface if present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * otherwise pass NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * Checks the presence of IPv4 and IPv6 multicast routers on this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * The former two OR'd: no multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static u8 batadv_mcast_mla_rtr_flags_softif_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct net_device *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct net_device *dev = bridge ? bridge : bat_priv->soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u8 flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) flags |= batadv_mcast_mla_rtr_flags_softif_get_ipv4(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) flags |= batadv_mcast_mla_rtr_flags_softif_get_ipv6(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * batadv_mcast_mla_rtr_flags_bridge_get() - get mcast router flags from bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * @bridge: bridge interface on top of the soft_iface if present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * otherwise pass NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Checks the presence of IPv4 and IPv6 multicast routers behind a bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * The former two OR'd: no multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static u8 batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct net_device *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct net_device *dev = bat_priv->soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct br_ip_list *br_ip_entry, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u8 flags = BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (!bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* TODO: ask the bridge if a multicast router is present (the bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * is capable of performing proper RFC4286 multicast router
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * discovery) instead of searching for a ff02::2 listener here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* the bridge snooping does not maintain IPv4 link-local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * addresses - therefore we won't find any IPv4 multicast router
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * address here, only IPv6 ones
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (br_ip_entry->addr.proto == htons(ETH_P_IPV6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ipv6_addr_is_ll_all_routers(&br_ip_entry->addr.dst.ip6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) flags &= ~BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) list_del(&br_ip_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) kfree(br_ip_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static inline u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct net_device *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * batadv_mcast_mla_rtr_flags_get() - get multicast router flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @bridge: bridge interface on top of the soft_iface if present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * otherwise pass NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Checks the presence of IPv4 and IPv6 multicast routers on this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * node or behind its bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * BATADV_NO_FLAGS: Both an IPv4 and IPv6 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * BATADV_MCAST_WANT_NO_RTR4: No IPv4 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * The former two OR'd: no multicast router is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static u8 batadv_mcast_mla_rtr_flags_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct net_device *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u8 flags = BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) flags &= batadv_mcast_mla_rtr_flags_softif_get(bat_priv, bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) flags &= batadv_mcast_mla_rtr_flags_bridge_get(bat_priv, bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * batadv_mcast_mla_flags_get() - get the new multicast flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * Return: A set of flags for the current/next TVLV, querier and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * bridge state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static struct batadv_mcast_mla_flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) batadv_mcast_mla_flags_get(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct net_device *dev = bat_priv->soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct batadv_mcast_querier_state *qr4, *qr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct batadv_mcast_mla_flags mla_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct net_device *bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) bridge = batadv_mcast_get_bridge(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) memset(&mla_flags, 0, sizeof(mla_flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mla_flags.enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) mla_flags.tvlv_flags |= batadv_mcast_mla_rtr_flags_get(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return mla_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dev_put(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) mla_flags.bridged = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) qr4 = &mla_flags.querier_ipv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) qr6 = &mla_flags.querier_ipv6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pr_warn_once("No bridge IGMP snooping compiled - multicast optimizations disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) qr4->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) qr4->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) qr6->exists = br_multicast_has_querier_anywhere(dev, ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) qr6->shadowing = br_multicast_has_querier_adjacent(dev, ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* 1) If no querier exists at all, then multicast listeners on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * our local TT clients behind the bridge will keep silent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * 2) If the selected querier is on one of our local TT clients,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * behind the bridge, then this querier might shadow multicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * listeners on our local TT clients, behind this bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * In both cases, we will signalize other batman nodes that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * we need all multicast traffic of the according protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!qr4->exists || qr4->shadowing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) mla_flags.tvlv_flags &= ~BATADV_MCAST_WANT_NO_RTR4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!qr6->exists || qr6->shadowing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mla_flags.tvlv_flags |= BATADV_MCAST_WANT_ALL_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mla_flags.tvlv_flags &= ~BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return mla_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * batadv_mcast_mla_is_duplicate() - check whether an address is in a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * @mcast_addr: the multicast address to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * @mcast_list: the list with multicast addresses to search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * Return: true if the given address is already in the given list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * Otherwise returns false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static bool batadv_mcast_mla_is_duplicate(u8 *mcast_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct hlist_head *mcast_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct batadv_hw_addr *mcast_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) hlist_for_each_entry(mcast_entry, mcast_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * batadv_mcast_mla_softif_get_ipv4() - get softif IPv4 multicast listeners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @dev: the device to collect multicast addresses from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @mcast_list: a list to put found addresses into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Collects multicast addresses of IPv4 multicast listeners residing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * on this kernel on the given soft interface, dev, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * the given mcast_list. In general, multicast listeners provided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * your multicast receiving applications run directly on this node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * Return: -ENOMEM on memory allocation error or the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * items added to the mcast_list otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) batadv_mcast_mla_softif_get_ipv4(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct hlist_head *mcast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct batadv_mcast_mla_flags *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct batadv_hw_addr *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct in_device *in_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u8 mcast_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct ip_mc_list *pmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) in_dev = __in_dev_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (!in_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (pmc = rcu_dereference(in_dev->mc_list); pmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) pmc = rcu_dereference(pmc->next_rcu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ipv4_is_local_multicast(pmc->multiaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!(flags->tvlv_flags & BATADV_MCAST_WANT_NO_RTR4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) !ipv4_is_local_multicast(pmc->multiaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ip_eth_mc_map(pmc->multiaddr, mcast_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) new = kmalloc(sizeof(*new), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ether_addr_copy(new->addr, mcast_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) hlist_add_head(&new->list, mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * batadv_mcast_mla_softif_get_ipv6() - get softif IPv6 multicast listeners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * @dev: the device to collect multicast addresses from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * @mcast_list: a list to put found addresses into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * @flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * Collects multicast addresses of IPv6 multicast listeners residing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * on this kernel on the given soft interface, dev, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * the given mcast_list. In general, multicast listeners provided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * your multicast receiving applications run directly on this node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * Return: -ENOMEM on memory allocation error or the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * items added to the mcast_list otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) batadv_mcast_mla_softif_get_ipv6(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct hlist_head *mcast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct batadv_mcast_mla_flags *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct batadv_hw_addr *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct inet6_dev *in6_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u8 mcast_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct ifmcaddr6 *pmc6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) in6_dev = __in6_dev_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!in6_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) read_lock_bh(&in6_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) for (pmc6 = in6_dev->mc_list; pmc6; pmc6 = pmc6->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) IPV6_ADDR_SCOPE_LINKLOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (flags->tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ipv6_addr_is_ll_all_nodes(&pmc6->mca_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!(flags->tvlv_flags & BATADV_MCAST_WANT_NO_RTR6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) IPV6_ADDR_MC_SCOPE(&pmc6->mca_addr) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) IPV6_ADDR_SCOPE_LINKLOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ipv6_eth_mc_map(&pmc6->mca_addr, mcast_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) new = kmalloc(sizeof(*new), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ether_addr_copy(new->addr, mcast_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) hlist_add_head(&new->list, mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) read_unlock_bh(&in6_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) batadv_mcast_mla_softif_get_ipv6(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct hlist_head *mcast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct batadv_mcast_mla_flags *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * batadv_mcast_mla_softif_get() - get softif multicast listeners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * @dev: the device to collect multicast addresses from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * @mcast_list: a list to put found addresses into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * Collects multicast addresses of multicast listeners residing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * on this kernel on the given soft interface, dev, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * the given mcast_list. In general, multicast listeners provided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * your multicast receiving applications run directly on this node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * If there is a bridge interface on top of dev, collect from that one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * instead. Just like with IP addresses and routes, multicast listeners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * will(/should) register to the bridge interface instead of an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * enslaved bat0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * Return: -ENOMEM on memory allocation error or the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * items added to the mcast_list otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) batadv_mcast_mla_softif_get(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct hlist_head *mcast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct batadv_mcast_mla_flags *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct net_device *bridge = batadv_mcast_get_bridge(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int ret4, ret6 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev = bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ret4 = batadv_mcast_mla_softif_get_ipv4(dev, mcast_list, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (ret4 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ret6 = batadv_mcast_mla_softif_get_ipv6(dev, mcast_list, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (ret6 < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dev_put(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return ret4 + ret6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * batadv_mcast_mla_br_addr_cpy() - copy a bridge multicast address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * @dst: destination to write to - a multicast MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * @src: source to read from - a multicast IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Converts a given multicast IPv4/IPv6 address from a bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * to its matching multicast MAC address and copies it into the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * destination buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * Caller needs to make sure the destination buffer can hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * at least ETH_ALEN bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (src->proto == htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ip_eth_mc_map(src->dst.ip4, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) else if (src->proto == htons(ETH_P_IPV6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ipv6_eth_mc_map(&src->dst.ip6, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) eth_zero_addr(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * @dev: a bridge slave whose bridge to collect multicast addresses from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * @mcast_list: a list to put found addresses into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * @flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * Collects multicast addresses of multicast listeners residing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * on foreign, non-mesh devices which we gave access to our mesh via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * a bridge on top of the given soft interface, dev, in the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * mcast_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * Return: -ENOMEM on memory allocation error or the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * items added to the mcast_list otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int batadv_mcast_mla_bridge_get(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct hlist_head *mcast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct batadv_mcast_mla_flags *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct br_ip_list *br_ip_entry, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) u8 tvlv_flags = flags->tvlv_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct batadv_hw_addr *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) u8 mcast_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* we don't need to detect these devices/listeners, the IGMP/MLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * snooping code of the Linux bridge already does that for us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (br_ip_entry->addr.proto == htons(ETH_P_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ipv4_is_local_multicast(br_ip_entry->addr.dst.ip4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!(tvlv_flags & BATADV_MCAST_WANT_NO_RTR4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) !ipv4_is_local_multicast(br_ip_entry->addr.dst.ip4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (br_ip_entry->addr.proto == htons(ETH_P_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (tvlv_flags & BATADV_MCAST_WANT_ALL_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (tvlv_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ipv6_addr_is_ll_all_nodes(&br_ip_entry->addr.dst.ip6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (!(tvlv_flags & BATADV_MCAST_WANT_NO_RTR6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) IPV6_ADDR_MC_SCOPE(&br_ip_entry->addr.dst.ip6) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) IPV6_ADDR_SCOPE_LINKLOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) new = kmalloc(sizeof(*new), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ether_addr_copy(new->addr, mcast_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) hlist_add_head(&new->list, mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) list_del(&br_ip_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) kfree(br_ip_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * batadv_mcast_mla_list_free() - free a list of multicast addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * @mcast_list: the list to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * Removes and frees all items in the given mcast_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct batadv_hw_addr *mcast_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) hlist_del(&mcast_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) kfree(mcast_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * batadv_mcast_mla_tt_retract() - clean up multicast listener announcements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * @mcast_list: a list of addresses which should _not_ be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * Retracts the announcement of any multicast listener from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * translation table except the ones listed in the given mcast_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * If mcast_list is NULL then all are retracted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct hlist_head *mcast_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct batadv_hw_addr *mcast_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (mcast_list &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) batadv_mcast_mla_is_duplicate(mcast_entry->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) mcast_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) batadv_tt_local_remove(bat_priv, mcast_entry->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) BATADV_NO_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) "mcast TT outdated", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) hlist_del(&mcast_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) kfree(mcast_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * batadv_mcast_mla_tt_add() - add multicast listener announcements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * @mcast_list: a list of addresses which are going to get added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * Adds multicast listener announcements from the given mcast_list to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * translation table if they have not been added yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct hlist_head *mcast_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct batadv_hw_addr *mcast_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (!mcast_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) &bat_priv->mcast.mla_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (!batadv_tt_local_add(bat_priv->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mcast_entry->addr, BATADV_NO_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) BATADV_NULL_IFINDEX, BATADV_NO_MARK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) hlist_del(&mcast_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * batadv_mcast_querier_log() - debug output regarding the querier status on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * @str_proto: a string for the querier protocol (e.g. "IGMP" or "MLD")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * @old_state: the previous querier state on our link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * @new_state: the new querier state on our link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * Outputs debug messages to the logging facility with log level 'mcast'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * regarding changes to the querier status on the link which are relevant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * to our multicast optimizations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * Usually this is about whether a querier appeared or vanished in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * our mesh or whether the querier is in the suboptimal position of being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * behind our local bridge segment: Snooping switches will directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * forward listener reports to the querier, therefore batman-adv and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * the bridge will potentially not see these listeners - the querier is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * potentially shadowing listeners from us then.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * This is only interesting for nodes with a bridge on top of their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * soft interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) batadv_mcast_querier_log(struct batadv_priv *bat_priv, char *str_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct batadv_mcast_querier_state *old_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct batadv_mcast_querier_state *new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (!old_state->exists && new_state->exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) batadv_info(bat_priv->soft_iface, "%s Querier appeared\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) str_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) else if (old_state->exists && !new_state->exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) batadv_info(bat_priv->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) "%s Querier disappeared - multicast optimizations disabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) str_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) else if (!bat_priv->mcast.mla_flags.bridged && !new_state->exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) batadv_info(bat_priv->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) "No %s Querier present - multicast optimizations disabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) str_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (new_state->exists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if ((!old_state->shadowing && new_state->shadowing) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) (!old_state->exists && new_state->shadowing))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) batadv_dbg(BATADV_DBG_MCAST, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) "%s Querier is behind our bridged segment: Might shadow listeners\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) str_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) else if (old_state->shadowing && !new_state->shadowing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) batadv_dbg(BATADV_DBG_MCAST, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) "%s Querier is not behind our bridged segment\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) str_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * batadv_mcast_bridge_log() - debug output for topology changes in bridged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * setups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * @new_flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * If no bridges are ever used on this node, then this function does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * Otherwise this function outputs debug information to the 'mcast' log level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * which might be relevant to our multicast optimizations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * More precisely, it outputs information when a bridge interface is added or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * removed from a soft interface. And when a bridge is present, it further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * outputs information about the querier state which is relevant for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * multicast flags this node is going to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) batadv_mcast_bridge_log(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct batadv_mcast_mla_flags *new_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct batadv_mcast_mla_flags *old_flags = &bat_priv->mcast.mla_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (!old_flags->bridged && new_flags->bridged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) batadv_dbg(BATADV_DBG_MCAST, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) "Bridge added: Setting Unsnoopables(U)-flag\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) else if (old_flags->bridged && !new_flags->bridged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) batadv_dbg(BATADV_DBG_MCAST, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) "Bridge removed: Unsetting Unsnoopables(U)-flag\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (new_flags->bridged) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) batadv_mcast_querier_log(bat_priv, "IGMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) &old_flags->querier_ipv4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) &new_flags->querier_ipv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) batadv_mcast_querier_log(bat_priv, "MLD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) &old_flags->querier_ipv6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) &new_flags->querier_ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * batadv_mcast_flags_logs() - output debug information about mcast flag changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * @flags: TVLV flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * Whenever the multicast TVLV flags this node announces change, this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * should be used to notify userspace about the change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) bool old_enabled = bat_priv->mcast.mla_flags.enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) u8 old_flags = bat_priv->mcast.mla_flags.tvlv_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) char str_old_flags[] = "[.... . ]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) sprintf(str_old_flags, "[%c%c%c%s%s]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) (old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) (old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) (old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) !(old_flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) !(old_flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) batadv_dbg(BATADV_DBG_MCAST, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) "Changing multicast flags from '%s' to '[%c%c%c%s%s]'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) old_enabled ? str_old_flags : "<undefined>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) !(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * batadv_mcast_mla_flags_update() - update multicast flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * @flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * Updates the own multicast tvlv with our current multicast related settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * capabilities and inabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) batadv_mcast_mla_flags_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct batadv_mcast_mla_flags *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct batadv_tvlv_mcast_data mcast_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (!memcmp(flags, &bat_priv->mcast.mla_flags, sizeof(*flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) batadv_mcast_bridge_log(bat_priv, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) batadv_mcast_flags_log(bat_priv, flags->tvlv_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) mcast_data.flags = flags->tvlv_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) &mcast_data, sizeof(mcast_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) bat_priv->mcast.mla_flags = *flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * __batadv_mcast_mla_update() - update the own MLAs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * Updates the own multicast listener announcements in the translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * table as well as the own, announced multicast tvlv container.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * Note that non-conflicting reads and writes to bat_priv->mcast.mla_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * in batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add() are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * ensured by the non-parallel execution of the worker this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * belongs to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct net_device *soft_iface = bat_priv->soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct hlist_head mcast_list = HLIST_HEAD_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct batadv_mcast_mla_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) flags = batadv_mcast_mla_flags_get(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spin_lock(&bat_priv->mcast.mla_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) batadv_mcast_mla_flags_update(bat_priv, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) spin_unlock(&bat_priv->mcast.mla_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) batadv_mcast_mla_list_free(&mcast_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * batadv_mcast_mla_update() - update the own MLAs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * @work: kernel work struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * Updates the own multicast listener announcements in the translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * table as well as the own, announced multicast tvlv container.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * In the end, reschedules the work timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static void batadv_mcast_mla_update(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct delayed_work *delayed_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct batadv_priv_mcast *priv_mcast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) delayed_work = to_delayed_work(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) bat_priv = container_of(priv_mcast, struct batadv_priv, mcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) __batadv_mcast_mla_update(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) batadv_mcast_start_timer(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * batadv_mcast_is_report_ipv4() - check for IGMP reports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * @skb: the ethernet frame destined for the mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * This call might reallocate skb data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * Checks whether the given frame is a valid IGMP report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * Return: If so then true, otherwise false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static bool batadv_mcast_is_report_ipv4(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (ip_mc_check_igmp(skb) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) switch (igmp_hdr(skb)->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) case IGMP_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) case IGMPV2_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) case IGMPV3_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * batadv_mcast_forw_mode_check_ipv4() - check for optimized forwarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * potential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * @skb: the IPv4 packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * @is_unsnoopable: stores whether the destination is snoopable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * @is_routable: stores whether the destination is routable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * Checks whether the given IPv4 packet has the potential to be forwarded with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * mode more optimal than classic flooding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * Return: If so then 0. Otherwise -EINVAL or -ENOMEM in case of memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * allocation failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) bool *is_unsnoopable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) int *is_routable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct iphdr *iphdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* We might fail due to out-of-memory -> drop it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (batadv_mcast_is_report_ipv4(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) iphdr = ip_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* link-local multicast listeners behind a bridge are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * not snoopable (see RFC4541, section 2.1.2.2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (ipv4_is_local_multicast(iphdr->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) *is_unsnoopable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) *is_routable = ETH_P_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * batadv_mcast_is_report_ipv6() - check for MLD reports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * @skb: the ethernet frame destined for the mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * This call might reallocate skb data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * Checks whether the given frame is a valid MLD report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * Return: If so then true, otherwise false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static bool batadv_mcast_is_report_ipv6(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (ipv6_mc_check_mld(skb) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) switch (icmp6_hdr(skb)->icmp6_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) case ICMPV6_MGM_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) case ICMPV6_MLD2_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * batadv_mcast_forw_mode_check_ipv6() - check for optimized forwarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * potential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * @skb: the IPv6 packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * @is_unsnoopable: stores whether the destination is snoopable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * @is_routable: stores whether the destination is routable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * Checks whether the given IPv6 packet has the potential to be forwarded with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * mode more optimal than classic flooding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) bool *is_unsnoopable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) int *is_routable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct ipv6hdr *ip6hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* We might fail due to out-of-memory -> drop it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (batadv_mcast_is_report_ipv6(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) ip6hdr = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) < IPV6_ADDR_SCOPE_LINKLOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* link-local-all-nodes multicast listeners behind a bridge are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * not snoopable (see RFC4541, section 3, paragraph 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) *is_unsnoopable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) else if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) > IPV6_ADDR_SCOPE_LINKLOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) *is_routable = ETH_P_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * batadv_mcast_forw_mode_check() - check for optimized forwarding potential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * @skb: the multicast frame to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * @is_unsnoopable: stores whether the destination is snoopable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * @is_routable: stores whether the destination is routable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * Checks whether the given multicast ethernet frame has the potential to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * forwarded with a mode more optimal than classic flooding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * Return: If so then 0. Otherwise -EINVAL is or -ENOMEM if we are out of memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) bool *is_unsnoopable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) int *is_routable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct ethhdr *ethhdr = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (!atomic_read(&bat_priv->multicast_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) switch (ntohs(ethhdr->h_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return batadv_mcast_forw_mode_check_ipv4(bat_priv, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) is_unsnoopable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) is_routable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (!IS_ENABLED(CONFIG_IPV6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return batadv_mcast_forw_mode_check_ipv6(bat_priv, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) is_unsnoopable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) is_routable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * batadv_mcast_forw_want_all_ip_count() - count nodes with unspecific mcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * @ethhdr: ethernet header of a packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * Return: the number of nodes which want all IPv4 multicast traffic if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * given ethhdr is from an IPv4 packet or the number of nodes which want all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * IPv6 traffic if it matches an IPv6 packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct ethhdr *ethhdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) switch (ntohs(ethhdr->h_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return atomic_read(&bat_priv->mcast.num_want_all_ipv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return atomic_read(&bat_priv->mcast.num_want_all_ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /* we shouldn't be here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * batadv_mcast_forw_rtr_count() - count nodes with a multicast router
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * @protocol: the ethernet protocol type to count multicast routers for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * Return: the number of nodes which want all routable IPv4 multicast traffic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * if the protocol is ETH_P_IP or the number of nodes which want all routable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * IPv6 traffic if the protocol is ETH_P_IPV6. Otherwise returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return atomic_read(&bat_priv->mcast.num_want_all_rtr4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return atomic_read(&bat_priv->mcast.num_want_all_rtr6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * batadv_mcast_forw_tt_node_get() - get a multicast tt node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * @ethhdr: the ether header containing the multicast destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * Return: an orig_node matching the multicast address provided by ethhdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * via a translation table lookup. This increases the returned nodes refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct ethhdr *ethhdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * batadv_mcast_forw_ipv4_node_get() - get a node with an ipv4 flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) hlist_for_each_entry_rcu(tmp_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) &bat_priv->mcast.want_all_ipv4_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) mcast_want_all_ipv4_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (!kref_get_unless_zero(&tmp_orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) orig_node = tmp_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * batadv_mcast_forw_ipv6_node_get() - get a node with an ipv6 flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * and increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) hlist_for_each_entry_rcu(tmp_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) &bat_priv->mcast.want_all_ipv6_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) mcast_want_all_ipv6_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (!kref_get_unless_zero(&tmp_orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) orig_node = tmp_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * batadv_mcast_forw_ip_node_get() - get a node with an ipv4/ipv6 flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * @ethhdr: an ethernet header to determine the protocol family from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, sets and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) * increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct ethhdr *ethhdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) switch (ntohs(ethhdr->h_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return batadv_mcast_forw_ipv4_node_get(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return batadv_mcast_forw_ipv6_node_get(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /* we shouldn't be here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * batadv_mcast_forw_unsnoop_node_get() - get a node with an unsnoopable flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * set and increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) hlist_for_each_entry_rcu(tmp_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) &bat_priv->mcast.want_all_unsnoopables_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) mcast_want_all_unsnoopables_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (!kref_get_unless_zero(&tmp_orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) orig_node = tmp_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * batadv_mcast_forw_rtr4_node_get() - get a node with an ipv4 mcast router flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * Return: an orig_node which has the BATADV_MCAST_WANT_NO_RTR4 flag unset and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) batadv_mcast_forw_rtr4_node_get(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) hlist_for_each_entry_rcu(tmp_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) &bat_priv->mcast.want_all_rtr4_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) mcast_want_all_rtr4_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (!kref_get_unless_zero(&tmp_orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) orig_node = tmp_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * batadv_mcast_forw_rtr6_node_get() - get a node with an ipv6 mcast router flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * Return: an orig_node which has the BATADV_MCAST_WANT_NO_RTR6 flag unset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * and increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) batadv_mcast_forw_rtr6_node_get(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) hlist_for_each_entry_rcu(tmp_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) &bat_priv->mcast.want_all_rtr6_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) mcast_want_all_rtr6_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (!kref_get_unless_zero(&tmp_orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) orig_node = tmp_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * batadv_mcast_forw_rtr_node_get() - get a node with an ipv4/ipv6 router flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * @ethhdr: an ethernet header to determine the protocol family from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * Return: an orig_node which has no BATADV_MCAST_WANT_NO_RTR4 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * BATADV_MCAST_WANT_NO_RTR6 flag, depending on the provided ethhdr, set and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * increases its refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static struct batadv_orig_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) batadv_mcast_forw_rtr_node_get(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct ethhdr *ethhdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) switch (ntohs(ethhdr->h_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) return batadv_mcast_forw_rtr4_node_get(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return batadv_mcast_forw_rtr6_node_get(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) /* we shouldn't be here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * batadv_mcast_forw_mode() - check on how to forward a multicast packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * @skb: The multicast packet to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) * @orig: an originator to be set to forward the skb to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * @is_routable: stores whether the destination is routable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) * Return: the forwarding mode as enum batadv_forw_mode and in case of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * BATADV_FORW_SINGLE set the orig to the single originator the skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * should be forwarded to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) enum batadv_forw_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct batadv_orig_node **orig, int *is_routable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) int ret, tt_count, ip_count, unsnoop_count, total_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) bool is_unsnoopable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) unsigned int mcast_fanout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct ethhdr *ethhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) int rtr_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) is_routable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (ret == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) return BATADV_FORW_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return BATADV_FORW_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) ethhdr = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) unsnoop_count = !is_unsnoopable ? 0 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) atomic_read(&bat_priv->mcast.num_want_all_unsnoopables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) rtr_count = batadv_mcast_forw_rtr_count(bat_priv, *is_routable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) total_count = tt_count + ip_count + unsnoop_count + rtr_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) switch (total_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (tt_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) else if (ip_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) else if (unsnoop_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) else if (rtr_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) *orig = batadv_mcast_forw_rtr_node_get(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) ethhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (*orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return BATADV_FORW_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) return BATADV_FORW_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) mcast_fanout = atomic_read(&bat_priv->multicast_fanout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (!unsnoop_count && total_count <= mcast_fanout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return BATADV_FORW_SOME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return BATADV_FORW_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * batadv_mcast_forw_send_orig() - send a multicast packet to an originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * @skb: the multicast packet to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) * @orig_node: the originator to send the packet to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) unsigned short vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /* Avoid sending multicast-in-unicast packets to other BLA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * gateways - they already got the frame from the LAN side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * we share with them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) * TODO: Refactor to take BLA into account earlier, to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * reducing the mcast_fanout count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) orig_node, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * batadv_mcast_forw_tt() - forwards a packet to multicast listeners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * @skb: the multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * Sends copies of a frame with multicast destination to any multicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * listener registered in the translation table. A transmission is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * via a batman-adv unicast packet for each such destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) int ret = NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct sk_buff *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) struct batadv_tt_global_entry *tt_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) const u8 *addr = eth_hdr(skb)->h_dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (!tt_global)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) hlist_for_each_entry_rcu(orig_entry, &tt_global->orig_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) newskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (!newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) ret = NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) batadv_mcast_forw_send_orig(bat_priv, newskb, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) orig_entry->orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) batadv_tt_global_entry_put(tt_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * batadv_mcast_forw_want_all_ipv4() - forward to nodes with want-all-ipv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * @skb: the multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * Sends copies of a frame with multicast destination to any node with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) * BATADV_MCAST_WANT_ALL_IPV4 flag set. A transmission is performed via a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * batman-adv unicast packet for each such destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) struct sk_buff *skb, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) int ret = NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) struct sk_buff *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) hlist_for_each_entry_rcu(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) &bat_priv->mcast.want_all_ipv4_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) mcast_want_all_ipv4_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) newskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (!newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ret = NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) * batadv_mcast_forw_want_all_ipv6() - forward to nodes with want-all-ipv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) * @skb: The multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) * Sends copies of a frame with multicast destination to any node with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) * BATADV_MCAST_WANT_ALL_IPV6 flag set. A transmission is performed via a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) * batman-adv unicast packet for each such destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct sk_buff *skb, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) int ret = NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) struct sk_buff *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) hlist_for_each_entry_rcu(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) &bat_priv->mcast.want_all_ipv6_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) mcast_want_all_ipv6_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) newskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (!newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) ret = NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) * batadv_mcast_forw_want_all() - forward packet to nodes in a want-all list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * @skb: the multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) * Sends copies of a frame with multicast destination to any node with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * BATADV_MCAST_WANT_ALL_IPV4 or BATADV_MCAST_WANT_ALL_IPV6 flag set. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * transmission is performed via a batman-adv unicast packet for each such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) * destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) batadv_mcast_forw_want_all(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct sk_buff *skb, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) switch (ntohs(eth_hdr(skb)->h_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return batadv_mcast_forw_want_all_ipv4(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return batadv_mcast_forw_want_all_ipv6(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /* we shouldn't be here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) * batadv_mcast_forw_want_all_rtr4() - forward to nodes with want-all-rtr4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) * @skb: the multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) * Sends copies of a frame with multicast destination to any node with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) * BATADV_MCAST_WANT_NO_RTR4 flag unset. A transmission is performed via a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) * batman-adv unicast packet for each such destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct sk_buff *skb, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) int ret = NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct sk_buff *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) hlist_for_each_entry_rcu(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) &bat_priv->mcast.want_all_rtr4_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) mcast_want_all_rtr4_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) newskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (!newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) ret = NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) * batadv_mcast_forw_want_all_rtr6() - forward to nodes with want-all-rtr6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) * @skb: The multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) * Sends copies of a frame with multicast destination to any node with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * BATADV_MCAST_WANT_NO_RTR6 flag unset. A transmission is performed via a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) * batman-adv unicast packet for each such destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * Return: NET_XMIT_DROP on memory allocation failure, NET_XMIT_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct sk_buff *skb, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) int ret = NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct sk_buff *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) hlist_for_each_entry_rcu(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) &bat_priv->mcast.want_all_rtr6_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) mcast_want_all_rtr6_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) newskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (!newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) ret = NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) * batadv_mcast_forw_want_rtr() - forward packet to nodes in a want-all-rtr list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) * @skb: the multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * Sends copies of a frame with multicast destination to any node with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * BATADV_MCAST_WANT_NO_RTR4 or BATADV_MCAST_WANT_NO_RTR6 flag unset. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * transmission is performed via a batman-adv unicast packet for each such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) * destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) batadv_mcast_forw_want_rtr(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) struct sk_buff *skb, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) switch (ntohs(eth_hdr(skb)->h_proto)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) return batadv_mcast_forw_want_all_rtr4(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) return batadv_mcast_forw_want_all_rtr6(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /* we shouldn't be here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) return NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * batadv_mcast_forw_send() - send packet to any detected multicast recipient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * @skb: the multicast packet to transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) * @is_routable: stores whether the destination is routable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) * Sends copies of a frame with multicast destination to any node that signaled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * interest in it, that is either via the translation table or the according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * want-all flags. A transmission is performed via a batman-adv unicast packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) * for each such destination node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) * The given skb is consumed/freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) * Return: NET_XMIT_DROP on memory allocation failure or if the protocol family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) * is neither IPv4 nor IPv6. NET_XMIT_SUCCESS otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) unsigned short vid, int is_routable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) ret = batadv_mcast_forw_tt(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (ret != NET_XMIT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ret = batadv_mcast_forw_want_all(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (ret != NET_XMIT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (!is_routable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) goto skip_mc_router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) ret = batadv_mcast_forw_want_rtr(bat_priv, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (ret != NET_XMIT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) skip_mc_router:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) * batadv_mcast_want_unsnoop_update() - update unsnoop counter and list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * @orig: the orig_node which multicast state might have changed of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) * @mcast_flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) * orig, has toggled then this method updates the counter and the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) * Caller needs to hold orig->mcast_handler_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) u8 mcast_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) lockdep_assert_held(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) /* switched from flag unset to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) WARN_ON(!hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) hlist_add_head_rcu(node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) /* switched from flag set to unset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) WARN_ON(hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) hlist_del_init_rcu(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * batadv_mcast_want_ipv4_update() - update want-all-ipv4 counter and list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) * @orig: the orig_node which multicast state might have changed of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) * @mcast_flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) * toggled then this method updates the counter and the list accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) * Caller needs to hold orig->mcast_handler_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) u8 mcast_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) lockdep_assert_held(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) /* switched from flag unset to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) WARN_ON(!hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) hlist_add_head_rcu(node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) /* switched from flag set to unset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) WARN_ON(hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) hlist_del_init_rcu(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) * batadv_mcast_want_ipv6_update() - update want-all-ipv6 counter and list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) * @orig: the orig_node which multicast state might have changed of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) * @mcast_flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * toggled then this method updates the counter and the list accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) * Caller needs to hold orig->mcast_handler_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) u8 mcast_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) lockdep_assert_held(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) /* switched from flag unset to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) WARN_ON(!hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) hlist_add_head_rcu(node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) /* switched from flag set to unset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) WARN_ON(hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) hlist_del_init_rcu(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) * batadv_mcast_want_rtr4_update() - update want-all-rtr4 counter and list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) * @orig: the orig_node which multicast state might have changed of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) * @mcast_flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * If the BATADV_MCAST_WANT_NO_RTR4 flag of this originator, orig, has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * toggled then this method updates the counter and the list accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) * Caller needs to hold orig->mcast_handler_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) static void batadv_mcast_want_rtr4_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) u8 mcast_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) struct hlist_node *node = &orig->mcast_want_all_rtr4_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) struct hlist_head *head = &bat_priv->mcast.want_all_rtr4_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) lockdep_assert_held(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) /* switched from flag set to unset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (!(mcast_flags & BATADV_MCAST_WANT_NO_RTR4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) atomic_inc(&bat_priv->mcast.num_want_all_rtr4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) WARN_ON(!hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) hlist_add_head_rcu(node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) /* switched from flag unset to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) } else if (mcast_flags & BATADV_MCAST_WANT_NO_RTR4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) !(orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) atomic_dec(&bat_priv->mcast.num_want_all_rtr4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) WARN_ON(hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) hlist_del_init_rcu(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * batadv_mcast_want_rtr6_update() - update want-all-rtr6 counter and list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) * @orig: the orig_node which multicast state might have changed of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * @mcast_flags: flags indicating the new multicast state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * If the BATADV_MCAST_WANT_NO_RTR6 flag of this originator, orig, has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) * toggled then this method updates the counter and the list accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) * Caller needs to hold orig->mcast_handler_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) static void batadv_mcast_want_rtr6_update(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) u8 mcast_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) struct hlist_node *node = &orig->mcast_want_all_rtr6_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) struct hlist_head *head = &bat_priv->mcast.want_all_rtr6_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) lockdep_assert_held(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) /* switched from flag set to unset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (!(mcast_flags & BATADV_MCAST_WANT_NO_RTR6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) atomic_inc(&bat_priv->mcast.num_want_all_rtr6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) WARN_ON(!hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) hlist_add_head_rcu(node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) /* switched from flag unset to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) } else if (mcast_flags & BATADV_MCAST_WANT_NO_RTR6 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) !(orig->mcast_flags & BATADV_MCAST_WANT_NO_RTR6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) atomic_dec(&bat_priv->mcast.num_want_all_rtr6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) spin_lock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) /* flag checks above + mcast_handler_lock prevents this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) WARN_ON(hlist_unhashed(node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) hlist_del_init_rcu(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) * batadv_mcast_tvlv_flags_get() - get multicast flags from an OGM TVLV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) * @enabled: whether the originator has multicast TVLV support enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) * @tvlv_value: tvlv buffer containing the multicast flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) * @tvlv_value_len: tvlv buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * Return: multicast flags for the given tvlv buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) static u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) batadv_mcast_tvlv_flags_get(bool enabled, void *tvlv_value, u16 tvlv_value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) u8 mcast_flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if (enabled && tvlv_value && tvlv_value_len >= sizeof(mcast_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) mcast_flags = *(u8 *)tvlv_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (!enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) mcast_flags |= BATADV_MCAST_WANT_ALL_IPV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) mcast_flags |= BATADV_MCAST_WANT_ALL_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /* remove redundant flags to avoid sending duplicate packets later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) mcast_flags |= BATADV_MCAST_WANT_NO_RTR4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) mcast_flags |= BATADV_MCAST_WANT_NO_RTR6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return mcast_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) * batadv_mcast_tvlv_ogm_handler() - process incoming multicast tvlv container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) * @orig: the orig_node of the ogm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) * @tvlv_value: tvlv buffer containing the multicast data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) * @tvlv_value_len: tvlv buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) u8 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) void *tvlv_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) u16 tvlv_value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) bool orig_mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) u8 mcast_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) mcast_flags = batadv_mcast_tvlv_flags_get(orig_mcast_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) tvlv_value, tvlv_value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) spin_lock_bh(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (orig_mcast_enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) } else if (!orig_mcast_enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) batadv_mcast_want_rtr4_update(bat_priv, orig, mcast_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) batadv_mcast_want_rtr6_update(bat_priv, orig, mcast_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) orig->mcast_flags = mcast_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) spin_unlock_bh(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) * batadv_mcast_init() - initialize the multicast optimizations structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) void batadv_mcast_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) NULL, BATADV_TVLV_MCAST, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) batadv_mcast_start_timer(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) * batadv_mcast_flags_print_header() - print own mcast flags to debugfs table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * @seq: debugfs table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) * Prints our own multicast flags including a more specific reason why
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) * they are set, that is prints the bridge and querier state too, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) * the debugfs table specified via @seq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) static void batadv_mcast_flags_print_header(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) struct batadv_mcast_mla_flags *mla_flags = &bat_priv->mcast.mla_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) char querier4, querier6, shadowing4, shadowing6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) bool bridged = mla_flags->bridged;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) u8 flags = mla_flags->tvlv_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (bridged) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) querier4 = mla_flags->querier_ipv4.exists ? '.' : '4';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) querier6 = mla_flags->querier_ipv6.exists ? '.' : '6';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) shadowing4 = mla_flags->querier_ipv4.shadowing ? '4' : '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) shadowing6 = mla_flags->querier_ipv6.shadowing ? '6' : '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) querier4 = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) querier6 = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) shadowing4 = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) shadowing6 = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) seq_printf(seq, "Multicast flags (own flags: [%c%c%c%s%s])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) (flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) (flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) !(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) !(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) seq_printf(seq, "* Bridged [U]\t\t\t\t%c\n", bridged ? 'U' : '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) seq_printf(seq, "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) querier4, querier6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) seq_printf(seq, "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) shadowing4, shadowing6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) seq_puts(seq, "-------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) seq_printf(seq, " %-10s %s\n", "Originator", "Flags");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) * batadv_mcast_flags_seq_print_text() - print the mcast flags of other nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) * @seq: seq file to print on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) * @offset: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) * This prints a table of (primary) originators and their according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) * multicast flags, including (in the header) our own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) * Return: always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) struct net_device *net_dev = (struct net_device *)seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) struct batadv_priv *bat_priv = netdev_priv(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) primary_if = batadv_seq_print_text_primary_if_get(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) batadv_mcast_flags_print_header(bat_priv, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) &orig_node->capa_initialized))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) &orig_node->capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) seq_printf(seq, "%pM -\n", orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) flags = orig_node->mcast_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) seq_printf(seq, "%pM [%c%c%c%s%s]\n", orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) (flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) ? 'U' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) (flags & BATADV_MCAST_WANT_ALL_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) ? '4' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) (flags & BATADV_MCAST_WANT_ALL_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) ? '6' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) !(flags & BATADV_MCAST_WANT_NO_RTR4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) ? "R4" : ". ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) !(flags & BATADV_MCAST_WANT_NO_RTR6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) ? "R6" : ". ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) * batadv_mcast_mesh_info_put() - put multicast info into a netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) int batadv_mcast_mesh_info_put(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) u32 flags = bat_priv->mcast.mla_flags.tvlv_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) u32 flags_priv = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if (bat_priv->mcast.mla_flags.bridged) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) flags_priv |= BATADV_MCAST_FLAGS_BRIDGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (bat_priv->mcast.mla_flags.querier_ipv4.exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (bat_priv->mcast.mla_flags.querier_ipv6.exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (bat_priv->mcast.mla_flags.querier_ipv4.shadowing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (bat_priv->mcast.mla_flags.querier_ipv6.shadowing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) * batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * to a netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) * @portid: netlink port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) * @orig_node: originator to dump the multicast flags of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) &batadv_netlink_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) BATADV_CMD_GET_MCAST_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) orig_node->orig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) &orig_node->capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) orig_node->mcast_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) * batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * table to a netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) * @portid: netlink port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) * @hash: hash to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) * @bucket: bucket index to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) * @idx_skip: How many entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) struct batadv_hashtable *hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) unsigned int bucket, long *idx_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) long idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) spin_lock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) cb->seq = atomic_read(&hash->generation) << 1 | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) hlist_for_each_entry(orig_node, &hash->table[bucket], hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) &orig_node->capa_initialized))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) if (idx < *idx_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if (batadv_mcast_flags_dump_entry(msg, portid, cb, orig_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) spin_unlock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) *idx_skip = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) skip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) spin_unlock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) * __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) * @portid: netlink port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) * @bucket: current bucket to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) * @idx: index in current bucket to the next entry to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) __batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) struct batadv_priv *bat_priv, long *bucket, long *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) struct batadv_hashtable *hash = bat_priv->orig_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) long bucket_tmp = *bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) long idx_tmp = *idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) while (bucket_tmp < hash->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) bucket_tmp, &idx_tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) bucket_tmp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) idx_tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) *bucket = bucket_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) *idx = idx_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) return msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) * batadv_mcast_netlink_get_primary() - get primary interface from netlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) * callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) * @cb: netlink callback structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) * @primary_if: the primary interface pointer to return the result in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) * Return: 0 or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) batadv_mcast_netlink_get_primary(struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) struct batadv_hard_iface **primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) struct batadv_hard_iface *hard_iface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) struct net *net = sock_net(cb->skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) struct net_device *soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) int ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (!ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) soft_iface = dev_get_by_index(net, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) hard_iface = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) if (soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) dev_put(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) if (!ret && primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) *primary_if = hard_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) else if (hard_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) batadv_hardif_put(hard_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) * batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) * @msg: buffer for the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) * @cb: callback structure containing arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) * Return: message length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) long *bucket = &cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) long *idx = &cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) ret = batadv_mcast_netlink_get_primary(cb, &primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) bat_priv = netdev_priv(primary_if->soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) ret = __batadv_mcast_flags_dump(msg, portid, cb, bat_priv, bucket, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) * batadv_mcast_free() - free the multicast optimizations structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) void batadv_mcast_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) cancel_delayed_work_sync(&bat_priv->mcast.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) /* safely calling outside of worker, as worker was canceled above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) batadv_mcast_mla_tt_retract(bat_priv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) * batadv_mcast_purge_orig() - reset originator global mcast state modifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) * @orig: the originator which is going to get purged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) struct batadv_priv *bat_priv = orig->bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) spin_lock_bh(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) batadv_mcast_want_rtr4_update(bat_priv, orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) BATADV_MCAST_WANT_NO_RTR4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) batadv_mcast_want_rtr6_update(bat_priv, orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) BATADV_MCAST_WANT_NO_RTR6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) spin_unlock_bh(&orig->mcast_handler_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) }