^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Bridge multicast support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/igmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/netfilter_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/timer.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/mroute.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/switchdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/icmpv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <net/mld.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <net/ip6_checksum.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/addrconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "br_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static const struct rhashtable_params br_mdb_rht_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .head_offset = offsetof(struct net_bridge_mdb_entry, rhnode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .key_offset = offsetof(struct net_bridge_mdb_entry, addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .key_len = sizeof(struct br_ip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .automatic_shrinking = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static const struct rhashtable_params br_sg_port_rht_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .head_offset = offsetof(struct net_bridge_port_group, rhnode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .key_offset = offsetof(struct net_bridge_port_group, key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .key_len = sizeof(struct net_bridge_port_group_sg_key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .automatic_shrinking = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void br_multicast_start_querier(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct bridge_mcast_own_query *query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void br_multicast_add_router(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct net_bridge_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static void br_ip4_multicast_leave_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __be32 group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) __u16 vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) const unsigned char *src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void br_multicast_port_group_rexmit(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void __del_port_router(struct net_bridge_port *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static void br_ip6_multicast_leave_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const struct in6_addr *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __u16 vid, const unsigned char *src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static struct net_bridge_port_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) __br_multicast_add_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) const unsigned char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) bool igmpv2_mldv1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bool blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void br_multicast_find_del_pg(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct net_bridge_port_group *pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct net_bridge_port_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) br_sg_port_find(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct net_bridge_port_group_sg_key *sg_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) lockdep_assert_held_once(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return rhashtable_lookup_fast(&br->sg_port_tbl, sg_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) br_sg_port_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static struct net_bridge_mdb_entry *br_mdb_ip_get_rcu(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct br_ip *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return rhashtable_lookup(&br->mdb_hash_tbl, dst, br_mdb_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct br_ip *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct net_bridge_mdb_entry *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) lockdep_assert_held_once(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ent = rhashtable_lookup(&br->mdb_hash_tbl, dst, br_mdb_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static struct net_bridge_mdb_entry *br_mdb_ip4_get(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) __be32 dst, __u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct br_ip br_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) memset(&br_dst, 0, sizeof(br_dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) br_dst.dst.ip4 = dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) br_dst.proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) br_dst.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return br_mdb_ip_get(br, &br_dst);
^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) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static struct net_bridge_mdb_entry *br_mdb_ip6_get(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) const struct in6_addr *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) __u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct br_ip br_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) memset(&br_dst, 0, sizeof(br_dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) br_dst.dst.ip6 = *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) br_dst.proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) br_dst.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return br_mdb_ip_get(br, &br_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct sk_buff *skb, u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct br_ip ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (BR_INPUT_SKB_CB(skb)->igmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) memset(&ip, 0, sizeof(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ip.proto = skb->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ip.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) switch (skb->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ip.dst.ip4 = ip_hdr(skb)->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (br->multicast_igmp_version == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct net_bridge_mdb_entry *mdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ip.src.ip4 = ip_hdr(skb)->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mdb = br_mdb_ip_get_rcu(br, &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (mdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return mdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ip.src.ip4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ip.dst.ip6 = ipv6_hdr(skb)->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (br->multicast_mld_version == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct net_bridge_mdb_entry *mdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ip.src.ip6 = ipv6_hdr(skb)->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mdb = br_mdb_ip_get_rcu(br, &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (mdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return mdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) memset(&ip.src.ip6, 0, sizeof(ip.src.ip6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return br_mdb_ip_get_rcu(br, &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static bool br_port_group_equal(struct net_bridge_port_group *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) const unsigned char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (p->key.port != port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!(port->flags & BR_MULTICAST_TO_UNICAST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return ether_addr_equal(src, p->eth_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void __fwd_add_star_excl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct br_ip *sg_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct net_bridge_port_group_sg_key sg_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct net_bridge_port_group *src_pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) memset(&sg_key, 0, sizeof(sg_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) sg_key.port = pg->key.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) sg_key.addr = *sg_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (br_sg_port_find(br, &sg_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) src_pg = __br_multicast_add_group(br, pg->key.port, sg_ip, pg->eth_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) MCAST_INCLUDE, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (IS_ERR_OR_NULL(src_pg) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) src_pg->rt_protocol != RTPROT_KERNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) src_pg->flags |= MDB_PG_FLAGS_STAR_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static void __fwd_del_star_excl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct br_ip *sg_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct net_bridge_port_group_sg_key sg_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct net_bridge_port_group *src_pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) memset(&sg_key, 0, sizeof(sg_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) sg_key.port = pg->key.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) sg_key.addr = *sg_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) src_pg = br_sg_port_find(br, &sg_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (!src_pg || !(src_pg->flags & MDB_PG_FLAGS_STAR_EXCL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) src_pg->rt_protocol != RTPROT_KERNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) br_multicast_find_del_pg(br, src_pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* When a port group transitions to (or is added as) EXCLUDE we need to add it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * to all other ports' S,G entries which are not blocked by the current group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * for proper replication, the assumption is that any S,G blocked entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * are already added so the S,G,port lookup should skip them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * When a port group transitions from EXCLUDE -> INCLUDE mode or is being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * deleted we need to remove it from all ports' S,G entries where it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * automatically installed before (i.e. where it's MDB_PG_FLAGS_STAR_EXCL).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) void br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) u8 filter_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct net_bridge_port_group *pg_lst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct br_ip sg_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (WARN_ON(!br_multicast_is_star_g(&pg->key.addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mp = br_mdb_ip_get(br, &pg->key.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) memset(&sg_ip, 0, sizeof(sg_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) sg_ip = pg->key.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) for (pg_lst = mlock_dereference(mp->ports, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pg_lst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pg_lst = mlock_dereference(pg_lst->next, br)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct net_bridge_group_src *src_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (pg_lst == pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) hlist_for_each_entry(src_ent, &pg_lst->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (!(src_ent->flags & BR_SGRP_F_INSTALLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sg_ip.src = src_ent->addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) switch (filter_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case MCAST_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) __fwd_del_star_excl(pg, &sg_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case MCAST_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __fwd_add_star_excl(pg, &sg_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* called when adding a new S,G with host_joined == false by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void br_multicast_sg_host_state(struct net_bridge_mdb_entry *star_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct net_bridge_port_group *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct net_bridge_mdb_entry *sg_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (WARN_ON(!br_multicast_is_star_g(&star_mp->addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!star_mp->host_joined)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sg_mp = br_mdb_ip_get(star_mp->br, &sg->key.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!sg_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) sg_mp->host_joined = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* set the host_joined state of all of *,G's S,G entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void br_multicast_star_g_host_state(struct net_bridge_mdb_entry *star_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct net_bridge *br = star_mp->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct net_bridge_mdb_entry *sg_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct br_ip sg_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (WARN_ON(!br_multicast_is_star_g(&star_mp->addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) memset(&sg_ip, 0, sizeof(sg_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sg_ip = star_mp->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) for (pg = mlock_dereference(star_mp->ports, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pg = mlock_dereference(pg->next, br)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct net_bridge_group_src *src_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) hlist_for_each_entry(src_ent, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!(src_ent->flags & BR_SGRP_F_INSTALLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sg_ip.src = src_ent->addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sg_mp = br_mdb_ip_get(br, &sg_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!sg_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sg_mp->host_joined = star_mp->host_joined;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^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) static void br_multicast_sg_del_exclude_ports(struct net_bridge_mdb_entry *sgmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* *,G exclude ports are only added to S,G entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (WARN_ON(br_multicast_is_star_g(&sgmp->addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* we need the STAR_EXCLUDE ports if there are non-STAR_EXCLUDE ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * we should ignore perm entries since they're managed by user-space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) for (pp = &sgmp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) (p = mlock_dereference(*pp, sgmp->br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pp = &p->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (!(p->flags & (MDB_PG_FLAGS_STAR_EXCL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) MDB_PG_FLAGS_PERMANENT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* currently the host can only have joined the *,G which means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * we treat it as EXCLUDE {}, so for an S,G it's considered a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * STAR_EXCLUDE entry and we can safely leave it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) sgmp->host_joined = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) for (pp = &sgmp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) (p = mlock_dereference(*pp, sgmp->br)) != NULL;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!(p->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) br_multicast_del_pg(sgmp, p, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pp = &p->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct net_bridge_port_group *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct net_bridge_port_group_sg_key sg_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct net_bridge *br = star_mp->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (WARN_ON(br_multicast_is_star_g(&sg->key.addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (WARN_ON(!br_multicast_is_star_g(&star_mp->addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) br_multicast_sg_host_state(star_mp, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) memset(&sg_key, 0, sizeof(sg_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) sg_key.addr = sg->key.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* we need to add all exclude ports to the S,G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) for (pg = mlock_dereference(star_mp->ports, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pg = mlock_dereference(pg->next, br)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct net_bridge_port_group *src_pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (pg == sg || pg->filter_mode == MCAST_INCLUDE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) sg_key.port = pg->key.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (br_sg_port_find(br, &sg_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) src_pg = __br_multicast_add_group(br, pg->key.port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) &sg->key.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sg->eth_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) MCAST_INCLUDE, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (IS_ERR_OR_NULL(src_pg) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) src_pg->rt_protocol != RTPROT_KERNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) src_pg->flags |= MDB_PG_FLAGS_STAR_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static void br_multicast_fwd_src_add(struct net_bridge_group_src *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct net_bridge_mdb_entry *star_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct net_bridge_port_group *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct br_ip sg_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (src->flags & BR_SGRP_F_INSTALLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) memset(&sg_ip, 0, sizeof(sg_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) sg_ip = src->pg->key.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) sg_ip.src = src->addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) sg = __br_multicast_add_group(src->br, src->pg->key.port, &sg_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) src->pg->eth_addr, MCAST_INCLUDE, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) !timer_pending(&src->timer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (IS_ERR_OR_NULL(sg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) src->flags |= BR_SGRP_F_INSTALLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) sg->flags &= ~MDB_PG_FLAGS_STAR_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* if it was added by user-space as perm we can skip next steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (sg->rt_protocol != RTPROT_KERNEL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) (sg->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* the kernel is now responsible for removing this S,G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) del_timer(&sg->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) star_mp = br_mdb_ip_get(src->br, &src->pg->key.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (!star_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) br_multicast_sg_add_exclude_ports(star_mp, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static void br_multicast_fwd_src_remove(struct net_bridge_group_src *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct net_bridge_port_group *p, *pg = src->pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct br_ip sg_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) memset(&sg_ip, 0, sizeof(sg_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) sg_ip = pg->key.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) sg_ip.src = src->addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) mp = br_mdb_ip_get(src->br, &sg_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (!mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) for (pp = &mp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) (p = mlock_dereference(*pp, src->br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) pp = &p->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (!br_port_group_equal(p, pg->key.port, pg->eth_addr))
^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 (p->rt_protocol != RTPROT_KERNEL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) (p->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) br_multicast_del_pg(mp, p, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) src->flags &= ~BR_SGRP_F_INSTALLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* install S,G and based on src's timer enable or disable forwarding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static void br_multicast_fwd_src_handle(struct net_bridge_group_src *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct net_bridge_port_group_sg_key sg_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct net_bridge_port_group *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) u8 old_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) br_multicast_fwd_src_add(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) memset(&sg_key, 0, sizeof(sg_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) sg_key.addr = src->pg->key.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) sg_key.addr.src = src->addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) sg_key.port = src->pg->key.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sg = br_sg_port_find(src->br, &sg_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!sg || (sg->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) old_flags = sg->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (timer_pending(&src->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) sg->flags &= ~MDB_PG_FLAGS_BLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) sg->flags |= MDB_PG_FLAGS_BLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (old_flags != sg->flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct net_bridge_mdb_entry *sg_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) sg_mp = br_mdb_ip_get(src->br, &sg_key.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!sg_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) br_mdb_notify(src->br->dev, sg_mp, sg, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static void br_multicast_destroy_mdb_entry(struct net_bridge_mcast_gc *gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mp = container_of(gc, struct net_bridge_mdb_entry, mcast_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) WARN_ON(!hlist_unhashed(&mp->mdb_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) WARN_ON(mp->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) del_timer_sync(&mp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) kfree_rcu(mp, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static void br_multicast_del_mdb_entry(struct net_bridge_mdb_entry *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct net_bridge *br = mp->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rhashtable_remove_fast(&br->mdb_hash_tbl, &mp->rhnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) br_mdb_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) hlist_del_init_rcu(&mp->mdb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) hlist_add_head(&mp->mcast_gc.gc_node, &br->mcast_gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) queue_work(system_long_wq, &br->mcast_gc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static void br_multicast_group_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct net_bridge_mdb_entry *mp = from_timer(mp, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct net_bridge *br = mp->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (hlist_unhashed(&mp->mdb_node) || !netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) timer_pending(&mp->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) br_multicast_host_leave(mp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (mp->ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) br_multicast_del_mdb_entry(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) spin_unlock(&br->multicast_lock);
^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) static void br_multicast_destroy_group_src(struct net_bridge_mcast_gc *gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct net_bridge_group_src *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) src = container_of(gc, struct net_bridge_group_src, mcast_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) WARN_ON(!hlist_unhashed(&src->node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) del_timer_sync(&src->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) kfree_rcu(src, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static void br_multicast_del_group_src(struct net_bridge_group_src *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct net_bridge *br = src->pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) br_multicast_fwd_src_remove(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) hlist_del_init_rcu(&src->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) src->pg->src_ents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) hlist_add_head(&src->mcast_gc.gc_node, &br->mcast_gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) queue_work(system_long_wq, &br->mcast_gc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pg = container_of(gc, struct net_bridge_port_group, mcast_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) WARN_ON(!hlist_unhashed(&pg->mglist));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) WARN_ON(!hlist_empty(&pg->src_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) del_timer_sync(&pg->rexmit_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) del_timer_sync(&pg->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) kfree_rcu(pg, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct net_bridge_port_group __rcu **pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) rcu_assign_pointer(*pp, pg->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) hlist_del_init(&pg->mglist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) br_multicast_del_group_src(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) br_mdb_notify(br->dev, mp, pg, RTM_DELMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!br_multicast_is_star_g(&mp->addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) rhashtable_remove_fast(&br->sg_port_tbl, &pg->rhnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) br_sg_port_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) br_multicast_sg_del_exclude_ports(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) br_multicast_star_g_handle_mode(pg, MCAST_INCLUDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) hlist_add_head(&pg->mcast_gc.gc_node, &br->mcast_gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) queue_work(system_long_wq, &br->mcast_gc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (!mp->ports && !mp->host_joined && netif_running(br->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) mod_timer(&mp->timer, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static void br_multicast_find_del_pg(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct net_bridge_port_group *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) mp = br_mdb_ip_get(br, &pg->key.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (WARN_ON(!mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) for (pp = &mp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) (p = mlock_dereference(*pp, br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) pp = &p->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (p != pg)
^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) br_multicast_del_pg(mp, pg, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static void br_multicast_port_group_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct net_bridge_port_group *pg = from_timer(pg, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct net_bridge_group_src *src_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) bool changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) hlist_unhashed(&pg->mglist) || pg->flags & MDB_PG_FLAGS_PERMANENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) changed = !!(pg->filter_mode == MCAST_EXCLUDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) pg->filter_mode = MCAST_INCLUDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) hlist_for_each_entry_safe(src_ent, tmp, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (!timer_pending(&src_ent->timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) br_multicast_del_group_src(src_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (hlist_empty(&pg->src_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) br_multicast_find_del_pg(br, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) } else if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct net_bridge_mdb_entry *mp = br_mdb_ip_get(br, &pg->key.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (changed && br_multicast_is_star_g(&pg->key.addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) br_multicast_star_g_handle_mode(pg, MCAST_INCLUDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (WARN_ON(!mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) br_mdb_notify(br->dev, mp, pg, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static void br_multicast_gc(struct hlist_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct net_bridge_mcast_gc *gcent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) hlist_for_each_entry_safe(gcent, tmp, head, gc_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) hlist_del_init(&gcent->gc_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) gcent->destroy(gcent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) __be32 ip_dst, __be32 group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) bool with_srcs, bool over_lmqt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) u8 sflag, u8 *igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) bool *need_rexmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct net_bridge_port *p = pg ? pg->key.port : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) size_t pkt_size, igmp_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct igmpv3_query *ihv3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) void *csum_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) __sum16 *csum = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct igmphdr *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct ethhdr *eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned long lmqt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct iphdr *iph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u16 lmqt_srcs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) igmp_hdr_size = sizeof(*ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (br->multicast_igmp_version == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) igmp_hdr_size = sizeof(*ihv3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (pg && with_srcs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) lmqt = now + (br->multicast_last_member_interval *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) br->multicast_last_member_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) hlist_for_each_entry(ent, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (over_lmqt == time_after(ent->timer.expires,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) lmqt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ent->src_query_rexmit_cnt > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) lmqt_srcs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (!lmqt_srcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) igmp_hdr_size += lmqt_srcs * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pkt_size = sizeof(*eth) + sizeof(*iph) + 4 + igmp_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if ((p && pkt_size > p->dev->mtu) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) pkt_size > br->dev->mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) skb = netdev_alloc_skb_ip_align(br->dev, pkt_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) skb->protocol = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) eth = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ether_addr_copy(eth->h_source, br->dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ip_eth_mc_map(ip_dst, eth->h_dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) eth->h_proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) skb_put(skb, sizeof(*eth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) skb_set_network_header(skb, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) iph = ip_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) iph->tot_len = htons(pkt_size - sizeof(*eth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) iph->version = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) iph->ihl = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) iph->tos = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) iph->id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) iph->frag_off = htons(IP_DF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) iph->ttl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) iph->protocol = IPPROTO_IGMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) iph->saddr = br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) inet_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) iph->daddr = ip_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ((u8 *)&iph[1])[0] = IPOPT_RA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ((u8 *)&iph[1])[1] = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ((u8 *)&iph[1])[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ((u8 *)&iph[1])[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ip_send_check(iph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) skb_put(skb, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) skb_set_transport_header(skb, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) *igmp_type = IGMP_HOST_MEMBERSHIP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) switch (br->multicast_igmp_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ih = igmp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ih->type = IGMP_HOST_MEMBERSHIP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ih->code = (group ? br->multicast_last_member_interval :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) br->multicast_query_response_interval) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) (HZ / IGMP_TIMER_SCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ih->group = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ih->csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) csum = &ih->csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) csum_start = (void *)ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ihv3 = igmpv3_query_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ihv3->type = IGMP_HOST_MEMBERSHIP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ihv3->code = (group ? br->multicast_last_member_interval :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) br->multicast_query_response_interval) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) (HZ / IGMP_TIMER_SCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ihv3->group = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ihv3->qqic = br->multicast_query_interval / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ihv3->nsrcs = htons(lmqt_srcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ihv3->resv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ihv3->suppress = sflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ihv3->qrv = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ihv3->csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) csum = &ihv3->csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) csum_start = (void *)ihv3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (!pg || !with_srcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) lmqt_srcs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) hlist_for_each_entry(ent, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (over_lmqt == time_after(ent->timer.expires,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) lmqt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ent->src_query_rexmit_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ihv3->srcs[lmqt_srcs++] = ent->addr.src.ip4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ent->src_query_rexmit_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (need_rexmit && ent->src_query_rexmit_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *need_rexmit = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (WARN_ON(lmqt_srcs != ntohs(ihv3->nsrcs))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (WARN_ON(!csum || !csum_start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) *csum = ip_compute_csum(csum_start, igmp_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) skb_put(skb, igmp_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) __skb_pull(skb, sizeof(*eth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) const struct in6_addr *ip6_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) const struct in6_addr *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) bool with_srcs, bool over_llqt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) u8 sflag, u8 *igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) bool *need_rexmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct net_bridge_port *p = pg ? pg->key.port : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) size_t pkt_size, mld_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct mld2_query *mld2q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) void *csum_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) unsigned long interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) __sum16 *csum = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct ipv6hdr *ip6h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct mld_msg *mldq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) unsigned long llqt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct ethhdr *eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) u16 llqt_srcs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u8 *hopopt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) mld_hdr_size = sizeof(*mldq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (br->multicast_mld_version == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) mld_hdr_size = sizeof(*mld2q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (pg && with_srcs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) llqt = now + (br->multicast_last_member_interval *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) br->multicast_last_member_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) hlist_for_each_entry(ent, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (over_llqt == time_after(ent->timer.expires,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) llqt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ent->src_query_rexmit_cnt > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) llqt_srcs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (!llqt_srcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) mld_hdr_size += llqt_srcs * sizeof(struct in6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) pkt_size = sizeof(*eth) + sizeof(*ip6h) + 8 + mld_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if ((p && pkt_size > p->dev->mtu) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) pkt_size > br->dev->mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) skb = netdev_alloc_skb_ip_align(br->dev, pkt_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) skb->protocol = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* Ethernet header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) eth = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ether_addr_copy(eth->h_source, br->dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) eth->h_proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) skb_put(skb, sizeof(*eth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* IPv6 header + HbH option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) skb_set_network_header(skb, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ip6h = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) *(__force __be32 *)ip6h = htonl(0x60000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ip6h->payload_len = htons(8 + mld_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ip6h->nexthdr = IPPROTO_HOPOPTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ip6h->hop_limit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) ip6h->daddr = *ip6_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) &ip6h->saddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) hopopt = (u8 *)(ip6h + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) hopopt[0] = IPPROTO_ICMPV6; /* next hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) hopopt[1] = 0; /* length of HbH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) hopopt[2] = IPV6_TLV_ROUTERALERT; /* Router Alert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) hopopt[3] = 2; /* Length of RA Option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) hopopt[4] = 0; /* Type = 0x0000 (MLD) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) hopopt[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) hopopt[6] = IPV6_TLV_PAD1; /* Pad1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) hopopt[7] = IPV6_TLV_PAD1; /* Pad1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) skb_put(skb, sizeof(*ip6h) + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* ICMPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) skb_set_transport_header(skb, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) interval = ipv6_addr_any(group) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) br->multicast_query_response_interval :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) br->multicast_last_member_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) *igmp_type = ICMPV6_MGM_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) switch (br->multicast_mld_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) mldq = (struct mld_msg *)icmp6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) mldq->mld_type = ICMPV6_MGM_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) mldq->mld_code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) mldq->mld_cksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) mldq->mld_maxdelay = htons((u16)jiffies_to_msecs(interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) mldq->mld_reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) mldq->mld_mca = *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) csum = &mldq->mld_cksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) csum_start = (void *)mldq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) mld2q = (struct mld2_query *)icmp6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) mld2q->mld2q_mrc = htons((u16)jiffies_to_msecs(interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) mld2q->mld2q_type = ICMPV6_MGM_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) mld2q->mld2q_code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) mld2q->mld2q_cksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) mld2q->mld2q_resv1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) mld2q->mld2q_resv2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) mld2q->mld2q_suppress = sflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) mld2q->mld2q_qrv = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) mld2q->mld2q_nsrcs = htons(llqt_srcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) mld2q->mld2q_qqic = br->multicast_query_interval / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) mld2q->mld2q_mca = *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) csum = &mld2q->mld2q_cksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) csum_start = (void *)mld2q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (!pg || !with_srcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) llqt_srcs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) hlist_for_each_entry(ent, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (over_llqt == time_after(ent->timer.expires,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) llqt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ent->src_query_rexmit_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) mld2q->mld2q_srcs[llqt_srcs++] = ent->addr.src.ip6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ent->src_query_rexmit_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (need_rexmit && ent->src_query_rexmit_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) *need_rexmit = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (WARN_ON(llqt_srcs != ntohs(mld2q->mld2q_nsrcs))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (WARN_ON(!csum || !csum_start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) *csum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, mld_hdr_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) IPPROTO_ICMPV6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) csum_partial(csum_start, mld_hdr_size, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) skb_put(skb, mld_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) __skb_pull(skb, sizeof(*eth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct br_ip *ip_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) bool with_srcs, bool over_lmqt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) u8 sflag, u8 *igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) bool *need_rexmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) __be32 ip4_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) switch (group->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ip4_dst = ip_dst ? ip_dst->dst.ip4 : htonl(INADDR_ALLHOSTS_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return br_ip4_multicast_alloc_query(br, pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ip4_dst, group->dst.ip4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) with_srcs, over_lmqt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) sflag, igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) need_rexmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) case htons(ETH_P_IPV6): {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct in6_addr ip6_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (ip_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ip6_dst = ip_dst->dst.ip6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) ipv6_addr_set(&ip6_dst, htonl(0xff020000), 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) htonl(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return br_ip6_multicast_alloc_query(br, pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) &ip6_dst, &group->dst.ip6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) with_srcs, over_lmqt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) sflag, igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) need_rexmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct br_ip *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) mp = br_mdb_ip_get(br, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (atomic_read(&br->mdb_hash_tbl.nelems) >= br->hash_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) br_opt_toggle(br, BROPT_MULTICAST_ENABLED, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return ERR_PTR(-E2BIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) mp = kzalloc(sizeof(*mp), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (unlikely(!mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) mp->br = br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mp->addr = *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) mp->mcast_gc.destroy = br_multicast_destroy_mdb_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) timer_setup(&mp->timer, br_multicast_group_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) err = rhashtable_lookup_insert_fast(&br->mdb_hash_tbl, &mp->rhnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) br_mdb_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) mp = ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) hlist_add_head_rcu(&mp->mdb_node, &br->mdb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static void br_multicast_group_src_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct net_bridge_group_src *src = from_timer(src, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct net_bridge *br = src->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (hlist_unhashed(&src->node) || !netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) timer_pending(&src->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) pg = src->pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (pg->filter_mode == MCAST_INCLUDE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) br_multicast_del_group_src(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!hlist_empty(&pg->src_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) br_multicast_find_del_pg(br, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) br_multicast_fwd_src_handle(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static struct net_bridge_group_src *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) br_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) switch (ip->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (ip->src.ip4 == ent->addr.src.ip4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (!ipv6_addr_cmp(&ent->addr.src.ip6, &ip->src.ip6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) static struct net_bridge_group_src *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) br_multicast_new_group_src(struct net_bridge_port_group *pg, struct br_ip *src_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct net_bridge_group_src *grp_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (unlikely(pg->src_ents >= PG_SRC_ENT_LIMIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) switch (src_ip->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (ipv4_is_zeronet(src_ip->src.ip4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ipv4_is_multicast(src_ip->src.ip4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (ipv6_addr_any(&src_ip->src.ip6) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) ipv6_addr_is_multicast(&src_ip->src.ip6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) grp_src = kzalloc(sizeof(*grp_src), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (unlikely(!grp_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) grp_src->pg = pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) grp_src->br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) grp_src->addr = *src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) grp_src->mcast_gc.destroy = br_multicast_destroy_group_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) timer_setup(&grp_src->timer, br_multicast_group_src_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) hlist_add_head_rcu(&grp_src->node, &pg->src_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) pg->src_ents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return grp_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct net_bridge_port_group *br_multicast_new_port_group(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct net_bridge_port_group __rcu *next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) unsigned char flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) const unsigned char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) u8 filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) u8 rt_protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) p = kzalloc(sizeof(*p), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (unlikely(!p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) p->key.addr = *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) p->key.port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) p->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) p->filter_mode = filter_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) p->rt_protocol = rt_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) p->mcast_gc.destroy = br_multicast_destroy_port_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) INIT_HLIST_HEAD(&p->src_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (!br_multicast_is_star_g(group) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) rhashtable_lookup_insert_fast(&port->br->sg_port_tbl, &p->rhnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) br_sg_port_rht_params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) rcu_assign_pointer(p->next, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) timer_setup(&p->timer, br_multicast_port_group_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) hlist_add_head(&p->mglist, &port->mglist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) memcpy(p->eth_addr, src, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) eth_broadcast_addr(p->eth_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) void br_multicast_host_join(struct net_bridge_mdb_entry *mp, bool notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (!mp->host_joined) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) mp->host_joined = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (br_multicast_is_star_g(&mp->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) br_multicast_star_g_host_state(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) br_mdb_notify(mp->br->dev, mp, NULL, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) mod_timer(&mp->timer, jiffies + mp->br->multicast_membership_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) void br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (!mp->host_joined)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) mp->host_joined = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (br_multicast_is_star_g(&mp->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) br_multicast_star_g_host_state(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) br_mdb_notify(mp->br->dev, mp, NULL, RTM_DELMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static struct net_bridge_port_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) __br_multicast_add_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) const unsigned char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) u8 filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) bool igmpv2_mldv1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) bool blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct net_bridge_port_group *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) (port && port->state == BR_STATE_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) mp = br_multicast_new_group(br, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (IS_ERR(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return ERR_PTR(PTR_ERR(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) br_multicast_host_join(mp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) for (pp = &mp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) (p = mlock_dereference(*pp, br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) pp = &p->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (br_port_group_equal(p, port, src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if ((unsigned long)p->key.port < (unsigned long)port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) RTPROT_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (unlikely(!p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) p = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) rcu_assign_pointer(*pp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) p->flags |= MDB_PG_FLAGS_BLOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) br_mdb_notify(br->dev, mp, p, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (igmpv2_mldv1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) mod_timer(&p->timer, now + br->multicast_membership_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static int br_multicast_add_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) const unsigned char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) u8 filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) bool igmpv2_mldv1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) pg = __br_multicast_add_group(br, port, group, src, filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) igmpv2_mldv1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* NULL is considered valid for host joined groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) err = IS_ERR(pg) ? PTR_ERR(pg) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) static int br_ip4_multicast_add_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) __be32 group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) __u16 vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) const unsigned char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) bool igmpv2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) struct br_ip br_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) u8 filter_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (ipv4_is_local_multicast(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) memset(&br_group, 0, sizeof(br_group));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) br_group.dst.ip4 = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) br_group.proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) br_group.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) filter_mode = igmpv2 ? MCAST_EXCLUDE : MCAST_INCLUDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) return br_multicast_add_group(br, port, &br_group, src, filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) igmpv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static int br_ip6_multicast_add_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) const struct in6_addr *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) __u16 vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) const unsigned char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) bool mldv1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct br_ip br_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) u8 filter_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (ipv6_addr_is_ll_all_nodes(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) memset(&br_group, 0, sizeof(br_group));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) br_group.dst.ip6 = *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) br_group.proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) br_group.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) filter_mode = mldv1 ? MCAST_EXCLUDE : MCAST_INCLUDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return br_multicast_add_group(br, port, &br_group, src, filter_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) mldv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) static void br_multicast_router_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) struct net_bridge_port *port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) from_timer(port, t, multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct net_bridge *br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (port->multicast_router == MDB_RTR_TYPE_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) port->multicast_router == MDB_RTR_TYPE_PERM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) timer_pending(&port->multicast_router_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) __del_port_router(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) static void br_mc_router_state_change(struct net_bridge *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) bool is_mc_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct switchdev_attr attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) .orig_dev = p->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .id = SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) .flags = SWITCHDEV_F_DEFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) .u.mrouter = is_mc_router,
^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) switchdev_port_attr_set(p->dev, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static void br_multicast_local_router_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct net_bridge *br = from_timer(br, t, multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (br->multicast_router == MDB_RTR_TYPE_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) br->multicast_router == MDB_RTR_TYPE_PERM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) timer_pending(&br->multicast_router_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) br_mc_router_state_change(br, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static void br_multicast_querier_expired(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct bridge_mcast_own_query *query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) br_multicast_start_querier(br, query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) static void br_ip4_multicast_querier_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct net_bridge *br = from_timer(br, t, ip4_other_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) br_multicast_querier_expired(br, &br->ip4_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) static void br_ip6_multicast_querier_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) struct net_bridge *br = from_timer(br, t, ip6_other_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) br_multicast_querier_expired(br, &br->ip6_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static void br_multicast_select_own_querier(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct br_ip *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (ip->proto == htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) br->ip4_querier.addr.src.ip4 = ip_hdr(skb)->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) br->ip6_querier.addr.src.ip6 = ipv6_hdr(skb)->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static void __br_multicast_send_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct br_ip *ip_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) bool with_srcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) u8 sflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) bool *need_rexmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) bool over_lmqt = !!sflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) u8 igmp_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) again_under_lmqt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) skb = br_multicast_alloc_query(br, pg, ip_dst, group, with_srcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) over_lmqt, sflag, &igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) need_rexmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) skb->dev = port->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) br_multicast_count(br, port, skb, igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) BR_MCAST_DIR_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dev_net(port->dev), NULL, skb, NULL, skb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) br_dev_queue_push_xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (over_lmqt && with_srcs && sflag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) over_lmqt = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) goto again_under_lmqt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) br_multicast_select_own_querier(br, group, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) br_multicast_count(br, port, skb, igmp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) BR_MCAST_DIR_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) static void br_multicast_send_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) struct bridge_mcast_own_query *own_query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) struct bridge_mcast_other_query *other_query = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) struct br_ip br_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) unsigned long time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) !br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) !br_opt_get(br, BROPT_MULTICAST_QUERIER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) memset(&br_group.dst, 0, sizeof(br_group.dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) if (port ? (own_query == &port->ip4_own_query) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) (own_query == &br->ip4_own_query)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) other_query = &br->ip4_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) br_group.proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) other_query = &br->ip6_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) br_group.proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (!other_query || timer_pending(&other_query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) __br_multicast_send_query(br, port, NULL, NULL, &br_group, false, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) time += own_query->startup_sent < br->multicast_startup_query_count ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) br->multicast_startup_query_interval :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) br->multicast_query_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) mod_timer(&own_query->timer, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) br_multicast_port_query_expired(struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) struct bridge_mcast_own_query *query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct net_bridge *br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (port->state == BR_STATE_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) port->state == BR_STATE_BLOCKING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (query->startup_sent < br->multicast_startup_query_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) query->startup_sent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) br_multicast_send_query(port->br, port, query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static void br_ip4_multicast_port_query_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct net_bridge_port *port = from_timer(port, t, ip4_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) br_multicast_port_query_expired(port, &port->ip4_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) static void br_ip6_multicast_port_query_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) struct net_bridge_port *port = from_timer(port, t, ip6_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) br_multicast_port_query_expired(port, &port->ip6_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) static void br_multicast_port_group_rexmit(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct bridge_mcast_other_query *other_query = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) bool need_rexmit = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) !br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) !br_opt_get(br, BROPT_MULTICAST_QUERIER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (pg->key.addr.proto == htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) other_query = &br->ip4_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) other_query = &br->ip6_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (!other_query || timer_pending(&other_query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (pg->grp_query_rexmit_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) pg->grp_query_rexmit_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) &pg->key.addr, false, 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) &pg->key.addr, true, 0, &need_rexmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (pg->grp_query_rexmit_cnt || need_rexmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) mod_timer(&pg->rexmit_timer, jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) br->multicast_last_member_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) spin_unlock(&br->multicast_lock);
^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) static void br_mc_disabled_update(struct net_device *dev, bool value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) struct switchdev_attr attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .orig_dev = dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .id = SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .flags = SWITCHDEV_F_DEFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .u.mc_disabled = !value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) switchdev_port_attr_set(dev, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) int br_multicast_add_port(struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) timer_setup(&port->multicast_router_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) br_multicast_router_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) timer_setup(&port->ip4_own_query.timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) br_ip4_multicast_port_query_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) timer_setup(&port->ip6_own_query.timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) br_ip6_multicast_port_query_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) br_mc_disabled_update(port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) br_opt_get(port->br, BROPT_MULTICAST_ENABLED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) port->mcast_stats = netdev_alloc_pcpu_stats(struct bridge_mcast_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (!port->mcast_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return 0;
^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) void br_multicast_del_port(struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) struct net_bridge *br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) HLIST_HEAD(deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) struct hlist_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) /* Take care of the remaining groups, only perm ones should be left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) hlist_for_each_entry_safe(pg, n, &port->mglist, mglist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) br_multicast_find_del_pg(br, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) hlist_move_list(&br->mcast_gc_list, &deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) br_multicast_gc(&deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) del_timer_sync(&port->multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) free_percpu(port->mcast_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) static void br_multicast_enable(struct bridge_mcast_own_query *query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) query->startup_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (try_to_del_timer_sync(&query->timer) >= 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) del_timer(&query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) mod_timer(&query->timer, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) static void __br_multicast_enable_port(struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct net_bridge *br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (!br_opt_get(br, BROPT_MULTICAST_ENABLED) || !netif_running(br->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) br_multicast_enable(&port->ip4_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) br_multicast_enable(&port->ip6_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (port->multicast_router == MDB_RTR_TYPE_PERM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) hlist_unhashed(&port->rlist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) br_multicast_add_router(br, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) void br_multicast_enable_port(struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) struct net_bridge *br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) __br_multicast_enable_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) void br_multicast_disable_port(struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct net_bridge *br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct hlist_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) hlist_for_each_entry_safe(pg, n, &port->mglist, mglist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (!(pg->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) br_multicast_find_del_pg(br, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) __del_port_router(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) del_timer(&port->multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) del_timer(&port->ip4_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) del_timer(&port->ip6_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) static int __grp_src_delete_marked(struct net_bridge_port_group *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) int deleted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (ent->flags & BR_SGRP_F_DELETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) br_multicast_del_group_src(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) deleted++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) return deleted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) static void __grp_src_mod_timer(struct net_bridge_group_src *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) unsigned long expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) mod_timer(&src->timer, expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) br_multicast_fwd_src_handle(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) static void __grp_src_query_marked_and_rexmit(struct net_bridge_port_group *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) struct bridge_mcast_other_query *other_query = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) u32 lmqc = br->multicast_last_member_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) unsigned long lmqt, lmi, now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) !br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (pg->key.addr.proto == htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) other_query = &br->ip4_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) other_query = &br->ip6_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) lmqt = now + br_multicast_lmqt(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) hlist_for_each_entry(ent, &pg->src_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (ent->flags & BR_SGRP_F_SEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) ent->flags &= ~BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (ent->timer.expires > lmqt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (br_opt_get(br, BROPT_MULTICAST_QUERIER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) other_query &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) !timer_pending(&other_query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) ent->src_query_rexmit_cnt = lmqc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) __grp_src_mod_timer(ent, lmqt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (!br_opt_get(br, BROPT_MULTICAST_QUERIER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) !other_query || timer_pending(&other_query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) &pg->key.addr, true, 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) lmi = now + br->multicast_last_member_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (!timer_pending(&pg->rexmit_timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) time_after(pg->rexmit_timer.expires, lmi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) mod_timer(&pg->rexmit_timer, lmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) static void __grp_send_query_and_rexmit(struct net_bridge_port_group *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) struct bridge_mcast_other_query *other_query = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) unsigned long now = jiffies, lmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) !br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) if (pg->key.addr.proto == htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) other_query = &br->ip4_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) other_query = &br->ip6_other_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) if (br_opt_get(br, BROPT_MULTICAST_QUERIER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) other_query && !timer_pending(&other_query->timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) lmi = now + br->multicast_last_member_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) pg->grp_query_rexmit_cnt = br->multicast_last_member_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) &pg->key.addr, false, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (!timer_pending(&pg->rexmit_timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) time_after(pg->rexmit_timer.expires, lmi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) mod_timer(&pg->rexmit_timer, lmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (pg->filter_mode == MCAST_EXCLUDE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) (!timer_pending(&pg->timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) time_after(pg->timer.expires, now + br_multicast_lmqt(br))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) mod_timer(&pg->timer, now + br_multicast_lmqt(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) * INCLUDE (A) IS_IN (B) INCLUDE (A+B) (B)=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) * INCLUDE (A) ALLOW (B) INCLUDE (A+B) (B)=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) * EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) u32 src_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) if (!ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) __grp_src_mod_timer(ent, now + br_multicast_gmi(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * INCLUDE (A) IS_EX (B) EXCLUDE (A*B,B-A) (B-A)=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) * Delete (A-B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * Group Timer=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static void __grp_src_isexc_incl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) u32 src_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) ent->flags |= BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) ent->flags &= ~BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) br_multicast_fwd_src_handle(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) __grp_src_delete_marked(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) * EXCLUDE (X,Y) IS_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) * Delete (X-A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) * Delete (Y-A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) * Group Timer=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) static bool __grp_src_isexc_excl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) u32 src_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) ent->flags |= BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) ent->flags &= ~BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) __grp_src_mod_timer(ent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) now + br_multicast_gmi(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (__grp_src_delete_marked(pg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) static bool br_multicast_isexc(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) switch (pg->filter_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) case MCAST_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) __grp_src_isexc_incl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) br_multicast_star_g_handle_mode(pg, MCAST_EXCLUDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) case MCAST_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) changed = __grp_src_isexc_excl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) pg->filter_mode = MCAST_EXCLUDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) mod_timer(&pg->timer, jiffies + br_multicast_gmi(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * INCLUDE (A) TO_IN (B) INCLUDE (A+B) (B)=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) * Send Q(G,A-B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) static bool __grp_src_toin_incl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) u32 src_idx, to_send = pg->src_ents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) ent->flags |= BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) ent->flags &= ~BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) to_send--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) __grp_src_mod_timer(ent, now + br_multicast_gmi(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) __grp_src_query_marked_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) * EXCLUDE (X,Y) TO_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) * Send Q(G,X-A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) * Send Q(G)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) static bool __grp_src_toin_excl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) u32 src_idx, to_send = pg->src_ents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (timer_pending(&ent->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) ent->flags |= BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) if (timer_pending(&ent->timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) ent->flags &= ~BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) to_send--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) __grp_src_mod_timer(ent, now + br_multicast_gmi(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) __grp_src_query_marked_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) __grp_send_query_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) static bool br_multicast_toin(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) switch (pg->filter_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) case MCAST_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) changed = __grp_src_toin_incl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) case MCAST_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) changed = __grp_src_toin_excl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) break;
^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) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) * INCLUDE (A) TO_EX (B) EXCLUDE (A*B,B-A) (B-A)=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) * Delete (A-B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) * Send Q(G,A*B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) * Group Timer=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) static void __grp_src_toex_incl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) u32 src_idx, to_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) ent->flags = (ent->flags & ~BR_SGRP_F_DELETE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) to_send++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) br_multicast_fwd_src_handle(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) __grp_src_delete_marked(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) if (to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) __grp_src_query_marked_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) * EXCLUDE (X,Y) TO_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=Group Timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) * Delete (X-A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) * Delete (Y-A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) * Send Q(G,A-Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) * Group Timer=GMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) static bool __grp_src_toex_excl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) u32 src_idx, to_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) ent->flags &= ~BR_SGRP_F_DELETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) __grp_src_mod_timer(ent, pg->timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) if (ent && timer_pending(&ent->timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) ent->flags |= BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) to_send++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) if (__grp_src_delete_marked(pg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) if (to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) __grp_src_query_marked_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) static bool br_multicast_toex(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) struct net_bridge *br = pg->key.port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) switch (pg->filter_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) case MCAST_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) __grp_src_toex_incl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) br_multicast_star_g_handle_mode(pg, MCAST_EXCLUDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) case MCAST_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) changed = __grp_src_toex_excl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) pg->filter_mode = MCAST_EXCLUDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) mod_timer(&pg->timer, jiffies + br_multicast_gmi(br));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) * INCLUDE (A) BLOCK (B) INCLUDE (A) Send Q(G,A*B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) static void __grp_src_block_incl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) u32 src_idx, to_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ent->flags &= ~BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) ent->flags |= BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) to_send++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) if (to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) __grp_src_query_marked_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if (pg->filter_mode == MCAST_INCLUDE && hlist_empty(&pg->src_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) br_multicast_find_del_pg(pg->key.port->br, pg);
^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) /* State Msg type New state Actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) * EXCLUDE (X,Y) BLOCK (A) EXCLUDE (X+(A-Y),Y) (A-X-Y)=Group Timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) * Send Q(G,A-Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) static bool __grp_src_block_excl(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) struct net_bridge_group_src *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) u32 src_idx, to_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) struct br_ip src_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) hlist_for_each_entry(ent, &pg->src_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) ent->flags &= ~BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) memset(&src_ip, 0, sizeof(src_ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) src_ip.proto = pg->key.addr.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) for (src_idx = 0; src_idx < nsrcs; src_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) memcpy(&src_ip.src, srcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) ent = br_multicast_find_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (!ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) ent = br_multicast_new_group_src(pg, &src_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) __grp_src_mod_timer(ent, pg->timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) if (ent && timer_pending(&ent->timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) ent->flags |= BR_SGRP_F_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) to_send++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) srcs += src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) __grp_src_query_marked_and_rexmit(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) static bool br_multicast_block(struct net_bridge_port_group *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) void *srcs, u32 nsrcs, size_t src_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) switch (pg->filter_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) case MCAST_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) __grp_src_block_incl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) case MCAST_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) changed = __grp_src_block_excl(pg, srcs, nsrcs, src_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) return changed;
^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) static struct net_bridge_port_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) br_multicast_find_port(struct net_bridge_mdb_entry *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) const unsigned char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) struct net_bridge *br __maybe_unused = mp->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) for (pg = mlock_dereference(mp->ports, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) pg = mlock_dereference(pg->next, br))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (br_port_group_equal(pg, p, src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) bool igmpv2 = br->multicast_igmp_version == 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) struct net_bridge_mdb_entry *mdst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) const unsigned char *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) struct igmpv3_report *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) struct igmpv3_grec *grec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) int i, len, num, type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) __be32 group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) u16 nsrcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) ih = igmpv3_report_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) num = ntohs(ih->ngrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) len = skb_transport_offset(skb) + sizeof(*ih);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) len += sizeof(*grec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) if (!ip_mc_may_pull(skb, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) grec = (void *)(skb->data + len - sizeof(*grec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) group = grec->grec_mca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) type = grec->grec_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) nsrcs = ntohs(grec->grec_nsrcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) len += nsrcs * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (!ip_mc_may_pull(skb, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) case IGMPV3_MODE_IS_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) case IGMPV3_MODE_IS_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) case IGMPV3_CHANGE_TO_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) case IGMPV3_CHANGE_TO_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) case IGMPV3_ALLOW_NEW_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) case IGMPV3_BLOCK_OLD_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) src = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (nsrcs == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) (type == IGMPV3_CHANGE_TO_INCLUDE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) type == IGMPV3_MODE_IS_INCLUDE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) if (!port || igmpv2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) br_ip4_multicast_leave_group(br, port, group, vid, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) err = br_ip4_multicast_add_group(br, port, group, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) src, igmpv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) if (!port || igmpv2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) mdst = br_mdb_ip4_get(br, group, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) if (!mdst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) goto unlock_continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) pg = br_multicast_find_port(mdst, port, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (!pg || (pg->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) goto unlock_continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) /* reload grec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) grec = (void *)(skb->data + len - sizeof(*grec) - (nsrcs * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) case IGMPV3_ALLOW_NEW_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) changed = br_multicast_isinc_allow(pg, grec->grec_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) nsrcs, sizeof(__be32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) case IGMPV3_MODE_IS_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) changed = br_multicast_isinc_allow(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) sizeof(__be32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) case IGMPV3_MODE_IS_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) changed = br_multicast_isexc(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) sizeof(__be32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) case IGMPV3_CHANGE_TO_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) changed = br_multicast_toin(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) sizeof(__be32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) case IGMPV3_CHANGE_TO_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) changed = br_multicast_toex(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) sizeof(__be32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) case IGMPV3_BLOCK_OLD_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) changed = br_multicast_block(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) sizeof(__be32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) br_mdb_notify(br->dev, mdst, pg, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) unlock_continue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static int br_ip6_multicast_mld2_report(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) bool mldv1 = br->multicast_mld_version == 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) struct net_bridge_mdb_entry *mdst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) struct net_bridge_port_group *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) unsigned int nsrcs_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) const unsigned char *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) struct icmp6hdr *icmp6h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) struct mld2_grec *grec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) unsigned int grec_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) int i, len, num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (!ipv6_mc_may_pull(skb, sizeof(*icmp6h)))
^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) icmp6h = icmp6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) len = skb_transport_offset(skb) + sizeof(*icmp6h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) __be16 *_nsrcs, __nsrcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) u16 nsrcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) nsrcs_offset = len + offsetof(struct mld2_grec, grec_nsrcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (skb_transport_offset(skb) + ipv6_transport_len(skb) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) nsrcs_offset + sizeof(__nsrcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) _nsrcs = skb_header_pointer(skb, nsrcs_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) sizeof(__nsrcs), &__nsrcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) if (!_nsrcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) nsrcs = ntohs(*_nsrcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) grec_len = struct_size(grec, grec_src, nsrcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) if (!ipv6_mc_may_pull(skb, len + grec_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) grec = (struct mld2_grec *)(skb->data + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) len += grec_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) switch (grec->grec_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) case MLD2_MODE_IS_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) case MLD2_MODE_IS_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) case MLD2_CHANGE_TO_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) case MLD2_CHANGE_TO_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) case MLD2_ALLOW_NEW_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) case MLD2_BLOCK_OLD_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) src = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) if ((grec->grec_type == MLD2_CHANGE_TO_INCLUDE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) grec->grec_type == MLD2_MODE_IS_INCLUDE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) nsrcs == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) if (!port || mldv1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) br_ip6_multicast_leave_group(br, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) &grec->grec_mca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) vid, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) err = br_ip6_multicast_add_group(br, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) &grec->grec_mca, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) src, mldv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) if (!port || mldv1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) mdst = br_mdb_ip6_get(br, &grec->grec_mca, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) if (!mdst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) goto unlock_continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) pg = br_multicast_find_port(mdst, port, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) if (!pg || (pg->flags & MDB_PG_FLAGS_PERMANENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) goto unlock_continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) switch (grec->grec_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) case MLD2_ALLOW_NEW_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) changed = br_multicast_isinc_allow(pg, grec->grec_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) case MLD2_MODE_IS_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) changed = br_multicast_isinc_allow(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) case MLD2_MODE_IS_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) changed = br_multicast_isexc(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) case MLD2_CHANGE_TO_INCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) changed = br_multicast_toin(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) case MLD2_CHANGE_TO_EXCLUDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) changed = br_multicast_toex(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) case MLD2_BLOCK_OLD_SOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) changed = br_multicast_block(pg, grec->grec_src, nsrcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) br_mdb_notify(br->dev, mdst, pg, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) unlock_continue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static bool br_ip4_multicast_select_querier(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) __be32 saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) if (!timer_pending(&br->ip4_own_query.timer) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) !timer_pending(&br->ip4_other_query.timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) if (!br->ip4_querier.addr.src.ip4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) if (ntohl(saddr) <= ntohl(br->ip4_querier.addr.src.ip4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) update:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) br->ip4_querier.addr.src.ip4 = saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) /* update protected by general multicast_lock by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) rcu_assign_pointer(br->ip4_querier.port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) static bool br_ip6_multicast_select_querier(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) struct in6_addr *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!timer_pending(&br->ip6_own_query.timer) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) !timer_pending(&br->ip6_other_query.timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) if (ipv6_addr_cmp(saddr, &br->ip6_querier.addr.src.ip6) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) update:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) br->ip6_querier.addr.src.ip6 = *saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) /* update protected by general multicast_lock by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) rcu_assign_pointer(br->ip6_querier.port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) static bool br_multicast_select_querier(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) struct br_ip *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) switch (saddr->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) return br_ip4_multicast_select_querier(br, port, saddr->src.ip4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) return br_ip6_multicast_select_querier(br, port, &saddr->src.ip6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) br_multicast_update_query_timer(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) struct bridge_mcast_other_query *query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) unsigned long max_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (!timer_pending(&query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) query->delay_time = jiffies + max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) mod_timer(&query->timer, jiffies + br->multicast_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) static void br_port_mc_router_state_change(struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) bool is_mc_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) struct switchdev_attr attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) .orig_dev = p->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) .id = SWITCHDEV_ATTR_ID_PORT_MROUTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) .flags = SWITCHDEV_F_DEFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) .u.mrouter = is_mc_router,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) switchdev_port_attr_set(p->dev, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) * Add port to router_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) * list is maintained ordered by pointer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) * and locked by br->multicast_lock and RCU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) static void br_multicast_add_router(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) struct hlist_node *slot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) if (!hlist_unhashed(&port->rlist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) hlist_for_each_entry(p, &br->router_list, rlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) if ((unsigned long) port >= (unsigned long) p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) slot = &p->rlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) if (slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) hlist_add_behind_rcu(&port->rlist, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) hlist_add_head_rcu(&port->rlist, &br->router_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) br_rtr_notify(br->dev, port, RTM_NEWMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) br_port_mc_router_state_change(port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) static void br_multicast_mark_router(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (br->multicast_router == MDB_RTR_TYPE_TEMP_QUERY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) if (!timer_pending(&br->multicast_router_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) br_mc_router_state_change(br, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) mod_timer(&br->multicast_router_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) now + br->multicast_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) if (port->multicast_router == MDB_RTR_TYPE_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) port->multicast_router == MDB_RTR_TYPE_PERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) br_multicast_add_router(br, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) mod_timer(&port->multicast_router_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) now + br->multicast_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) static void br_multicast_query_received(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) struct bridge_mcast_other_query *query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) struct br_ip *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) unsigned long max_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) if (!br_multicast_select_querier(br, port, saddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) br_multicast_update_query_timer(br, query, max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) br_multicast_mark_router(br, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) static void br_ip4_multicast_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) unsigned int transport_len = ip_transport_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) const struct iphdr *iph = ip_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) struct igmphdr *ih = igmp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) struct igmpv3_query *ih3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) struct br_ip saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) unsigned long max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) __be32 group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) (port && port->state == BR_STATE_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) group = ih->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) if (transport_len == sizeof(*ih)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) max_delay = ih->code * (HZ / IGMP_TIMER_SCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (!max_delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) max_delay = 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) group = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) } else if (transport_len >= sizeof(*ih3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) ih3 = igmpv3_query_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) if (ih3->nsrcs ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) (br->multicast_igmp_version == 3 && group && ih3->suppress))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) max_delay = ih3->code ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) if (!group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) saddr.proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) saddr.src.ip4 = iph->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) br_multicast_query_received(br, port, &br->ip4_other_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) &saddr, max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) mp = br_mdb_ip4_get(br, group, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) if (!mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) max_delay *= br->multicast_last_member_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) if (mp->host_joined &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) (timer_pending(&mp->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) time_after(mp->timer.expires, now + max_delay) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) try_to_del_timer_sync(&mp->timer) >= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) mod_timer(&mp->timer, now + max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) for (pp = &mp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) (p = mlock_dereference(*pp, br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) pp = &p->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) if (timer_pending(&p->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) time_after(p->timer.expires, now + max_delay) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) try_to_del_timer_sync(&p->timer) >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) (br->multicast_igmp_version == 2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) p->filter_mode == MCAST_EXCLUDE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) mod_timer(&p->timer, now + max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) static int br_ip6_multicast_query(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) unsigned int transport_len = ipv6_transport_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) struct mld_msg *mld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) struct mld2_query *mld2q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) struct br_ip saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) unsigned long max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) unsigned int offset = skb_transport_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) const struct in6_addr *group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) bool is_general_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) (port && port->state == BR_STATE_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) if (transport_len == sizeof(*mld)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) if (!pskb_may_pull(skb, offset + sizeof(*mld))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) mld = (struct mld_msg *) icmp6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) if (max_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) group = &mld->mld_mca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) if (!pskb_may_pull(skb, offset + sizeof(*mld2q))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) mld2q = (struct mld2_query *)icmp6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) if (!mld2q->mld2q_nsrcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) group = &mld2q->mld2q_mca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) if (br->multicast_mld_version == 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) !ipv6_addr_any(&mld2q->mld2q_mca) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) mld2q->mld2q_suppress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) is_general_query = group && ipv6_addr_any(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) if (is_general_query) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) saddr.proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) saddr.src.ip6 = ipv6_hdr(skb)->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) br_multicast_query_received(br, port, &br->ip6_other_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) &saddr, max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) } else if (!group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) mp = br_mdb_ip6_get(br, group, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) if (!mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) max_delay *= br->multicast_last_member_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) if (mp->host_joined &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) (timer_pending(&mp->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) time_after(mp->timer.expires, now + max_delay) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) try_to_del_timer_sync(&mp->timer) >= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) mod_timer(&mp->timer, now + max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) for (pp = &mp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) (p = mlock_dereference(*pp, br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) pp = &p->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) if (timer_pending(&p->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) time_after(p->timer.expires, now + max_delay) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) try_to_del_timer_sync(&p->timer) >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) (br->multicast_mld_version == 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) p->filter_mode == MCAST_EXCLUDE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) mod_timer(&p->timer, now + max_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) br_multicast_leave_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) struct br_ip *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) struct bridge_mcast_other_query *other_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) struct bridge_mcast_own_query *own_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) const unsigned char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) unsigned long now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) unsigned long time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (!netif_running(br->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) (port && port->state == BR_STATE_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) mp = br_mdb_ip_get(br, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) if (!mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) struct net_bridge_port_group __rcu **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) for (pp = &mp->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) (p = mlock_dereference(*pp, br)) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) pp = &p->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) if (!br_port_group_equal(p, port, src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) if (p->flags & MDB_PG_FLAGS_PERMANENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) p->flags |= MDB_PG_FLAGS_FAST_LEAVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) br_multicast_del_pg(mp, p, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) if (timer_pending(&other_query->timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) if (br_opt_get(br, BROPT_MULTICAST_QUERIER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) __br_multicast_send_query(br, port, NULL, NULL, &mp->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) false, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) time = jiffies + br->multicast_last_member_count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) br->multicast_last_member_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) mod_timer(&own_query->timer, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) for (p = mlock_dereference(mp->ports, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) p != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) p = mlock_dereference(p->next, br)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) if (!br_port_group_equal(p, port, src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) if (!hlist_unhashed(&p->mglist) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) (timer_pending(&p->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) time_after(p->timer.expires, time) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) try_to_del_timer_sync(&p->timer) >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) mod_timer(&p->timer, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) time = now + br->multicast_last_member_count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) br->multicast_last_member_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) if (mp->host_joined &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) (timer_pending(&mp->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) time_after(mp->timer.expires, time) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) try_to_del_timer_sync(&mp->timer) >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) mod_timer(&mp->timer, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) for (p = mlock_dereference(mp->ports, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) p != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) p = mlock_dereference(p->next, br)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) if (p->key.port != port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) if (!hlist_unhashed(&p->mglist) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) (timer_pending(&p->timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) time_after(p->timer.expires, time) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) try_to_del_timer_sync(&p->timer) >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) mod_timer(&p->timer, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) static void br_ip4_multicast_leave_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) __be32 group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) __u16 vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) const unsigned char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) struct br_ip br_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) struct bridge_mcast_own_query *own_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) if (ipv4_is_local_multicast(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) own_query = port ? &port->ip4_own_query : &br->ip4_own_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) memset(&br_group, 0, sizeof(br_group));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) br_group.dst.ip4 = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) br_group.proto = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) br_group.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) own_query, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) static void br_ip6_multicast_leave_group(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) const struct in6_addr *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) __u16 vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) const unsigned char *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) struct br_ip br_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) struct bridge_mcast_own_query *own_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) if (ipv6_addr_is_ll_all_nodes(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) own_query = port ? &port->ip6_own_query : &br->ip6_own_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) memset(&br_group, 0, sizeof(br_group));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) br_group.dst.ip6 = *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) br_group.proto = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) br_group.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) own_query, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) static void br_multicast_err_count(const struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) const struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) __be16 proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) struct bridge_mcast_stats __percpu *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) struct bridge_mcast_stats *pstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) if (!br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) stats = p->mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) stats = br->mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) if (WARN_ON(!stats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) pstats = this_cpu_ptr(stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) u64_stats_update_begin(&pstats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) switch (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) pstats->mstats.igmp_parse_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) pstats->mstats.mld_parse_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) u64_stats_update_end(&pstats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) static void br_multicast_pim(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) const struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) unsigned int offset = skb_transport_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) struct pimhdr *pimhdr, _pimhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) pimhdr = skb_header_pointer(skb, offset, sizeof(_pimhdr), &_pimhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) if (!pimhdr || pim_hdr_version(pimhdr) != PIM_VERSION ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) pim_hdr_type(pimhdr) != PIM_TYPE_HELLO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) br_multicast_mark_router(br, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) static int br_ip4_multicast_mrd_rcv(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) if (ip_hdr(skb)->protocol != IPPROTO_IGMP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) igmp_hdr(skb)->type != IGMP_MRDISC_ADV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) return -ENOMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) br_multicast_mark_router(br, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) static int br_multicast_ipv4_rcv(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) const unsigned char *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) struct igmphdr *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) err = ip_mc_check_igmp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) if (err == -ENOMSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) if (!ipv4_is_local_multicast(ip_hdr(skb)->daddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) } else if (pim_ipv4_all_pim_routers(ip_hdr(skb)->daddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) if (ip_hdr(skb)->protocol == IPPROTO_PIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) br_multicast_pim(br, port, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) } else if (ipv4_is_all_snoopers(ip_hdr(skb)->daddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) br_ip4_multicast_mrd_rcv(br, port, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) } else if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) br_multicast_err_count(br, port, skb->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) ih = igmp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) src = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) BR_INPUT_SKB_CB(skb)->igmp = ih->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) switch (ih->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) case IGMP_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) case IGMPV2_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) err = br_ip4_multicast_add_group(br, port, ih->group, vid, src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) case IGMPV3_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) err = br_ip4_multicast_igmp3_report(br, port, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) case IGMP_HOST_MEMBERSHIP_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) br_ip4_multicast_query(br, port, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) case IGMP_HOST_LEAVE_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) br_ip4_multicast_leave_group(br, port, ih->group, vid, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) br_multicast_count(br, port, skb, BR_INPUT_SKB_CB(skb)->igmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) BR_MCAST_DIR_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) static void br_ip6_multicast_mrd_rcv(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) if (icmp6_hdr(skb)->icmp6_type != ICMPV6_MRDISC_ADV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) br_multicast_mark_router(br, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) static int br_multicast_ipv6_rcv(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) const unsigned char *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) struct mld_msg *mld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) err = ipv6_mc_check_mld(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) if (err == -ENOMSG || err == -ENODATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) if (!ipv6_addr_is_ll_all_nodes(&ipv6_hdr(skb)->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) if (err == -ENODATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) ipv6_addr_is_all_snoopers(&ipv6_hdr(skb)->daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) br_ip6_multicast_mrd_rcv(br, port, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) } else if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) br_multicast_err_count(br, port, skb->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) mld = (struct mld_msg *)skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) BR_INPUT_SKB_CB(skb)->igmp = mld->mld_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) switch (mld->mld_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) case ICMPV6_MGM_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) src = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) src, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) case ICMPV6_MLD2_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) err = br_ip6_multicast_mld2_report(br, port, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) case ICMPV6_MGM_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) err = br_ip6_multicast_query(br, port, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) case ICMPV6_MGM_REDUCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) src = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) br_multicast_count(br, port, skb, BR_INPUT_SKB_CB(skb)->igmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) BR_MCAST_DIR_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) struct sk_buff *skb, u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) BR_INPUT_SKB_CB(skb)->igmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) switch (skb->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) ret = br_multicast_ipv4_rcv(br, port, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) ret = br_multicast_ipv6_rcv(br, port, skb, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) static void br_multicast_query_expired(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) struct bridge_mcast_own_query *query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) struct bridge_mcast_querier *querier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) if (query->startup_sent < br->multicast_startup_query_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) query->startup_sent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) RCU_INIT_POINTER(querier->port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) br_multicast_send_query(br, NULL, query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) static void br_ip4_multicast_query_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) struct net_bridge *br = from_timer(br, t, ip4_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) br_multicast_query_expired(br, &br->ip4_own_query, &br->ip4_querier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) static void br_ip6_multicast_query_expired(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) struct net_bridge *br = from_timer(br, t, ip6_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) br_multicast_query_expired(br, &br->ip6_own_query, &br->ip6_querier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) static void br_multicast_gc_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) struct net_bridge *br = container_of(work, struct net_bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) mcast_gc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) HLIST_HEAD(deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) hlist_move_list(&br->mcast_gc_list, &deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) br_multicast_gc(&deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) void br_multicast_init(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) br->hash_max = BR_MULTICAST_DEFAULT_HASH_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) br->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) br->multicast_last_member_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) br->multicast_startup_query_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) br->multicast_last_member_interval = HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) br->multicast_query_response_interval = 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) br->multicast_startup_query_interval = 125 * HZ / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) br->multicast_query_interval = 125 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) br->multicast_querier_interval = 255 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) br->multicast_membership_interval = 260 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) br->ip4_other_query.delay_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) br->ip4_querier.port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) br->multicast_igmp_version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) br->multicast_mld_version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) br->ip6_other_query.delay_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) br->ip6_querier.port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) br_opt_toggle(br, BROPT_MULTICAST_ENABLED, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) spin_lock_init(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) timer_setup(&br->multicast_router_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) br_multicast_local_router_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) timer_setup(&br->ip4_other_query.timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) br_ip4_multicast_querier_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) timer_setup(&br->ip4_own_query.timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) br_ip4_multicast_query_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) timer_setup(&br->ip6_other_query.timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) br_ip6_multicast_querier_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) timer_setup(&br->ip6_own_query.timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) br_ip6_multicast_query_expired, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) INIT_HLIST_HEAD(&br->mdb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) INIT_HLIST_HEAD(&br->mcast_gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) INIT_WORK(&br->mcast_gc_work, br_multicast_gc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) static void br_ip4_multicast_join_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) struct in_device *in_dev = in_dev_get(br->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) if (!in_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) __ip_mc_inc_group(in_dev, htonl(INADDR_ALLSNOOPERS_GROUP), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) in_dev_put(in_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) static void br_ip6_multicast_join_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) struct in6_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) ipv6_addr_set(&addr, htonl(0xff020000), 0, 0, htonl(0x6a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) ipv6_dev_mc_inc(br->dev, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) static inline void br_ip6_multicast_join_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) void br_multicast_join_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) br_ip4_multicast_join_snoopers(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) br_ip6_multicast_join_snoopers(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) static void br_ip4_multicast_leave_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) struct in_device *in_dev = in_dev_get(br->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) if (WARN_ON(!in_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) __ip_mc_dec_group(in_dev, htonl(INADDR_ALLSNOOPERS_GROUP), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) in_dev_put(in_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) static void br_ip6_multicast_leave_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) struct in6_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) ipv6_addr_set(&addr, htonl(0xff020000), 0, 0, htonl(0x6a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) ipv6_dev_mc_dec(br->dev, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) static inline void br_ip6_multicast_leave_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) void br_multicast_leave_snoopers(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) br_ip4_multicast_leave_snoopers(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) br_ip6_multicast_leave_snoopers(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) static void __br_multicast_open(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) struct bridge_mcast_own_query *query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) query->startup_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) mod_timer(&query->timer, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) void br_multicast_open(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) __br_multicast_open(br, &br->ip4_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) __br_multicast_open(br, &br->ip6_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) void br_multicast_stop(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) del_timer_sync(&br->multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) del_timer_sync(&br->ip4_other_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) del_timer_sync(&br->ip4_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) del_timer_sync(&br->ip6_other_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) del_timer_sync(&br->ip6_own_query.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) void br_multicast_dev_del(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) struct net_bridge_mdb_entry *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) HLIST_HEAD(deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) hlist_for_each_entry_safe(mp, tmp, &br->mdb_list, mdb_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) br_multicast_del_mdb_entry(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) hlist_move_list(&br->mcast_gc_list, &deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) br_multicast_gc(&deleted_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) cancel_work_sync(&br->mcast_gc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) rcu_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) int br_multicast_set_router(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) case MDB_RTR_TYPE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) case MDB_RTR_TYPE_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) br_mc_router_state_change(br, val == MDB_RTR_TYPE_PERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) del_timer(&br->multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) br->multicast_router = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) case MDB_RTR_TYPE_TEMP_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) if (br->multicast_router != MDB_RTR_TYPE_TEMP_QUERY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) br_mc_router_state_change(br, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) br->multicast_router = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) static void __del_port_router(struct net_bridge_port *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) if (hlist_unhashed(&p->rlist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) hlist_del_init_rcu(&p->rlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) br_rtr_notify(p->br->dev, p, RTM_DELMDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) br_port_mc_router_state_change(p, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) /* don't allow timer refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) if (p->multicast_router == MDB_RTR_TYPE_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) p->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) struct net_bridge *br = p->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) spin_lock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) if (p->multicast_router == val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) /* Refresh the temp router port timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) if (p->multicast_router == MDB_RTR_TYPE_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) mod_timer(&p->multicast_router_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) now + br->multicast_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) case MDB_RTR_TYPE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) p->multicast_router = MDB_RTR_TYPE_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) __del_port_router(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) del_timer(&p->multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) case MDB_RTR_TYPE_TEMP_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) p->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) __del_port_router(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) case MDB_RTR_TYPE_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) p->multicast_router = MDB_RTR_TYPE_PERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) del_timer(&p->multicast_router_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) br_multicast_add_router(br, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) case MDB_RTR_TYPE_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) p->multicast_router = MDB_RTR_TYPE_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) br_multicast_mark_router(br, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) spin_unlock(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) static void br_multicast_start_querier(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) struct bridge_mcast_own_query *query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) struct net_bridge_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) __br_multicast_open(br, query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) list_for_each_entry_rcu(port, &br->port_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) if (port->state == BR_STATE_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) port->state == BR_STATE_BLOCKING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) if (query == &br->ip4_own_query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) br_multicast_enable(&port->ip4_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) br_multicast_enable(&port->ip6_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) int br_multicast_toggle(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) struct net_bridge_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) bool change_snoopers = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) if (!!br_opt_get(br, BROPT_MULTICAST_ENABLED) == !!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) br_mc_disabled_update(br->dev, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) br_opt_toggle(br, BROPT_MULTICAST_ENABLED, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) if (!br_opt_get(br, BROPT_MULTICAST_ENABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) change_snoopers = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) if (!netif_running(br->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) br_multicast_open(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) list_for_each_entry(port, &br->port_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) __br_multicast_enable_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) change_snoopers = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) /* br_multicast_join_snoopers has the potential to cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) * an MLD Report/Leave to be delivered to br_multicast_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) * which would in turn call br_multicast_add_group, which would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) * attempt to acquire multicast_lock. This function should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) * called after the lock has been released to avoid deadlocks on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) * multicast_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) * br_multicast_leave_snoopers does not have the problem since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) * br_multicast_rcv first checks BROPT_MULTICAST_ENABLED, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) * returns without calling br_multicast_ipv4/6_rcv if it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) * enabled. Moved both functions out just for symmetry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) if (change_snoopers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) if (br_opt_get(br, BROPT_MULTICAST_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) br_multicast_join_snoopers(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) br_multicast_leave_snoopers(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) bool br_multicast_enabled(const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) struct net_bridge *br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) return !!br_opt_get(br, BROPT_MULTICAST_ENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) EXPORT_SYMBOL_GPL(br_multicast_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) bool br_multicast_router(const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) struct net_bridge *br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) bool is_router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) is_router = br_multicast_is_router(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) return is_router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) EXPORT_SYMBOL_GPL(br_multicast_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) unsigned long max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) val = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) if (br_opt_get(br, BROPT_MULTICAST_QUERIER) == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) br_opt_toggle(br, BROPT_MULTICAST_QUERIER, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) max_delay = br->multicast_query_response_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) if (!timer_pending(&br->ip4_other_query.timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) br->ip4_other_query.delay_time = jiffies + max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) br_multicast_start_querier(br, &br->ip4_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) if (!timer_pending(&br->ip6_other_query.timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) br->ip6_other_query.delay_time = jiffies + max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) br_multicast_start_querier(br, &br->ip6_own_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) int br_multicast_set_igmp_version(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) /* Currently we support only version 2 and 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) br->multicast_igmp_version = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) int br_multicast_set_mld_version(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) /* Currently we support version 1 and 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) spin_lock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) br->multicast_mld_version = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) spin_unlock_bh(&br->multicast_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) * br_multicast_list_adjacent - Returns snooped multicast addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) * @dev: The bridge port adjacent to which to retrieve addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) * @br_ip_list: The list to store found, snooped multicast IP addresses in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) * Creates a list of IP addresses (struct br_ip_list) sensed by the multicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) * snooping feature on all bridge ports of dev's bridge device, excluding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) * the addresses from dev itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) * Returns the number of items added to br_ip_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) * - br_ip_list needs to be initialized by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) * - br_ip_list might contain duplicates in the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) * (needs to be taken care of by caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) * - br_ip_list needs to be freed by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) int br_multicast_list_adjacent(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) struct list_head *br_ip_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) struct net_bridge_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) struct net_bridge_port_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) struct br_ip_list *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) if (!br_ip_list || !netif_is_bridge_port(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) port = br_port_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) if (!port || !port->br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) list_for_each_entry_rcu(port, &br->port_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) if (!port->dev || port->dev == dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) hlist_for_each_entry_rcu(group, &port->mglist, mglist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) entry->addr = group->key.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) list_add(&entry->list, br_ip_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) EXPORT_SYMBOL_GPL(br_multicast_list_adjacent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) * br_multicast_has_querier_anywhere - Checks for a querier on a bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) * @dev: The bridge port providing the bridge on which to check for a querier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) * @proto: The protocol family to check for: IGMP -> ETH_P_IP, MLD -> ETH_P_IPV6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) * Checks whether the given interface has a bridge on top and if so returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) * true if a valid querier exists anywhere on the bridged link layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) * Otherwise returns false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) bool br_multicast_has_querier_anywhere(struct net_device *dev, int proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) struct net_bridge_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) if (!netif_is_bridge_port(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) port = br_port_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) if (!port || !port->br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) memset(ð, 0, sizeof(eth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) eth.h_proto = htons(proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) ret = br_multicast_querier_exists(br, ð);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) EXPORT_SYMBOL_GPL(br_multicast_has_querier_anywhere);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) * br_multicast_has_querier_adjacent - Checks for a querier behind a bridge port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) * @dev: The bridge port adjacent to which to check for a querier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) * @proto: The protocol family to check for: IGMP -> ETH_P_IP, MLD -> ETH_P_IPV6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) * Checks whether the given interface has a bridge on top and if so returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) * true if a selected querier is behind one of the other ports of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) * bridge. Otherwise returns false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) bool br_multicast_has_querier_adjacent(struct net_device *dev, int proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) struct net_bridge_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) if (!netif_is_bridge_port(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) port = br_port_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) if (!port || !port->br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) switch (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) if (!timer_pending(&br->ip4_other_query.timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) rcu_dereference(br->ip4_querier.port) == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) if (!timer_pending(&br->ip6_other_query.timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) rcu_dereference(br->ip6_querier.port) == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) EXPORT_SYMBOL_GPL(br_multicast_has_querier_adjacent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) static void br_mcast_stats_add(struct bridge_mcast_stats __percpu *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) const struct sk_buff *skb, u8 type, u8 dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) struct bridge_mcast_stats *pstats = this_cpu_ptr(stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) __be16 proto = skb->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) unsigned int t_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) u64_stats_update_begin(&pstats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) switch (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) t_len = ntohs(ip_hdr(skb)->tot_len) - ip_hdrlen(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) case IGMP_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) pstats->mstats.igmp_v1reports[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) case IGMPV2_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) pstats->mstats.igmp_v2reports[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) case IGMPV3_HOST_MEMBERSHIP_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) pstats->mstats.igmp_v3reports[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) case IGMP_HOST_MEMBERSHIP_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) if (t_len != sizeof(struct igmphdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) pstats->mstats.igmp_v3queries[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) unsigned int offset = skb_transport_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) struct igmphdr *ih, _ihdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) ih = skb_header_pointer(skb, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) sizeof(_ihdr), &_ihdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) if (!ih)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) if (!ih->code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) pstats->mstats.igmp_v1queries[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) pstats->mstats.igmp_v2queries[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) case IGMP_HOST_LEAVE_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) pstats->mstats.igmp_leaves[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) t_len = ntohs(ipv6_hdr(skb)->payload_len) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) sizeof(struct ipv6hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) t_len -= skb_network_header_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) case ICMPV6_MGM_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) pstats->mstats.mld_v1reports[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) case ICMPV6_MLD2_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) pstats->mstats.mld_v2reports[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) case ICMPV6_MGM_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) if (t_len != sizeof(struct mld_msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) pstats->mstats.mld_v2queries[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) pstats->mstats.mld_v1queries[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) case ICMPV6_MGM_REDUCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) pstats->mstats.mld_leaves[dir]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) #endif /* CONFIG_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) u64_stats_update_end(&pstats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) const struct sk_buff *skb, u8 type, u8 dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) struct bridge_mcast_stats __percpu *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) /* if multicast_disabled is true then igmp type can't be set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) if (!type || !br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) stats = p->mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) stats = br->mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) if (WARN_ON(!stats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) br_mcast_stats_add(stats, skb, type, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) int br_multicast_init_stats(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) br->mcast_stats = netdev_alloc_pcpu_stats(struct bridge_mcast_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) if (!br->mcast_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) void br_multicast_uninit_stats(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) free_percpu(br->mcast_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) /* noinline for https://bugs.llvm.org/show_bug.cgi?id=45802#c9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) static noinline_for_stack void mcast_stats_add_dir(u64 *dst, u64 *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) dst[BR_MCAST_DIR_RX] += src[BR_MCAST_DIR_RX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) dst[BR_MCAST_DIR_TX] += src[BR_MCAST_DIR_TX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) void br_multicast_get_stats(const struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) const struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) struct br_mcast_stats *dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) struct bridge_mcast_stats __percpu *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) struct br_mcast_stats tdst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) memset(dest, 0, sizeof(*dest));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) stats = p->mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) stats = br->mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) if (WARN_ON(!stats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) memset(&tdst, 0, sizeof(tdst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) struct bridge_mcast_stats *cpu_stats = per_cpu_ptr(stats, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) struct br_mcast_stats temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) unsigned int start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) memcpy(&temp, &cpu_stats->mstats, sizeof(temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) mcast_stats_add_dir(tdst.igmp_v1queries, temp.igmp_v1queries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) mcast_stats_add_dir(tdst.igmp_v2queries, temp.igmp_v2queries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) mcast_stats_add_dir(tdst.igmp_v3queries, temp.igmp_v3queries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) mcast_stats_add_dir(tdst.igmp_leaves, temp.igmp_leaves);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) mcast_stats_add_dir(tdst.igmp_v1reports, temp.igmp_v1reports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) mcast_stats_add_dir(tdst.igmp_v2reports, temp.igmp_v2reports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) mcast_stats_add_dir(tdst.igmp_v3reports, temp.igmp_v3reports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) tdst.igmp_parse_errors += temp.igmp_parse_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) mcast_stats_add_dir(tdst.mld_v1queries, temp.mld_v1queries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) mcast_stats_add_dir(tdst.mld_v2queries, temp.mld_v2queries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) mcast_stats_add_dir(tdst.mld_leaves, temp.mld_leaves);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) mcast_stats_add_dir(tdst.mld_v1reports, temp.mld_v1reports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) mcast_stats_add_dir(tdst.mld_v2reports, temp.mld_v2reports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) tdst.mld_parse_errors += temp.mld_parse_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) memcpy(dest, &tdst, sizeof(*dest));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) int br_mdb_hash_init(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) err = rhashtable_init(&br->sg_port_tbl, &br_sg_port_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) err = rhashtable_init(&br->mdb_hash_tbl, &br_mdb_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) rhashtable_destroy(&br->sg_port_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) void br_mdb_hash_fini(struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) rhashtable_destroy(&br->sg_port_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) rhashtable_destroy(&br->mdb_hash_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) }