diff options
author | Linus Lüssing <linus.luessing@web.de> | 2014-06-07 12:26:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-11 02:50:47 -0400 |
commit | 07f8ac4a1e26e8283542cdaf658a6e2a12fd6980 (patch) | |
tree | 767bc394b56374b576feb4da5ff38808428c0857 /net | |
parent | dc4eb53a996a78bfb8ea07b47423ff5a3aadc362 (diff) |
bridge: add export of multicast database adjacent to net_dev
With this new, exported function br_multicast_list_adjacent(net_dev) a
list of IPv4/6 addresses is returned. This list contains all multicast
addresses sensed by the bridge multicast snooping feature on all bridge
ports of the bridge interface of net_dev, excluding addresses from the
specified net_device itself.
Adding bridge support to the batman-adv multicast optimization requires
batman-adv knowing about the existence of bridged-in multicast
listeners to be able to reliably serve them with multicast packets.
Signed-off-by: Linus Lüssing <linus.luessing@web.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_multicast.c | 58 | ||||
-rw-r--r-- | net/bridge/br_private.h | 12 |
2 files changed, 58 insertions, 12 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index b3f17c9b4d06..772476b7c4b7 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/export.h> | ||
14 | #include <linux/if_ether.h> | 15 | #include <linux/if_ether.h> |
15 | #include <linux/igmp.h> | 16 | #include <linux/igmp.h> |
16 | #include <linux/jhash.h> | 17 | #include <linux/jhash.h> |
@@ -2141,3 +2142,60 @@ unlock: | |||
2141 | 2142 | ||
2142 | return err; | 2143 | return err; |
2143 | } | 2144 | } |
2145 | |||
2146 | /** | ||
2147 | * br_multicast_list_adjacent - Returns snooped multicast addresses | ||
2148 | * @dev: The bridge port adjacent to which to retrieve addresses | ||
2149 | * @br_ip_list: The list to store found, snooped multicast IP addresses in | ||
2150 | * | ||
2151 | * Creates a list of IP addresses (struct br_ip_list) sensed by the multicast | ||
2152 | * snooping feature on all bridge ports of dev's bridge device, excluding | ||
2153 | * the addresses from dev itself. | ||
2154 | * | ||
2155 | * Returns the number of items added to br_ip_list. | ||
2156 | * | ||
2157 | * Notes: | ||
2158 | * - br_ip_list needs to be initialized by caller | ||
2159 | * - br_ip_list might contain duplicates in the end | ||
2160 | * (needs to be taken care of by caller) | ||
2161 | * - br_ip_list needs to be freed by caller | ||
2162 | */ | ||
2163 | int br_multicast_list_adjacent(struct net_device *dev, | ||
2164 | struct list_head *br_ip_list) | ||
2165 | { | ||
2166 | struct net_bridge *br; | ||
2167 | struct net_bridge_port *port; | ||
2168 | struct net_bridge_port_group *group; | ||
2169 | struct br_ip_list *entry; | ||
2170 | int count = 0; | ||
2171 | |||
2172 | rcu_read_lock(); | ||
2173 | if (!br_ip_list || !br_port_exists(dev)) | ||
2174 | goto unlock; | ||
2175 | |||
2176 | port = br_port_get_rcu(dev); | ||
2177 | if (!port || !port->br) | ||
2178 | goto unlock; | ||
2179 | |||
2180 | br = port->br; | ||
2181 | |||
2182 | list_for_each_entry_rcu(port, &br->port_list, list) { | ||
2183 | if (!port->dev || port->dev == dev) | ||
2184 | continue; | ||
2185 | |||
2186 | hlist_for_each_entry_rcu(group, &port->mglist, mglist) { | ||
2187 | entry = kmalloc(sizeof(*entry), GFP_ATOMIC); | ||
2188 | if (!entry) | ||
2189 | goto unlock; | ||
2190 | |||
2191 | entry->addr = group->addr; | ||
2192 | list_add(&entry->list, br_ip_list); | ||
2193 | count++; | ||
2194 | } | ||
2195 | } | ||
2196 | |||
2197 | unlock: | ||
2198 | rcu_read_unlock(); | ||
2199 | return count; | ||
2200 | } | ||
2201 | EXPORT_SYMBOL_GPL(br_multicast_list_adjacent); | ||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 97c5e46dde72..50e2ab021484 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -54,18 +54,6 @@ struct mac_addr | |||
54 | unsigned char addr[ETH_ALEN]; | 54 | unsigned char addr[ETH_ALEN]; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct br_ip | ||
58 | { | ||
59 | union { | ||
60 | __be32 ip4; | ||
61 | #if IS_ENABLED(CONFIG_IPV6) | ||
62 | struct in6_addr ip6; | ||
63 | #endif | ||
64 | } u; | ||
65 | __be16 proto; | ||
66 | __u16 vid; | ||
67 | }; | ||
68 | |||
69 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 57 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
70 | /* our own querier */ | 58 | /* our own querier */ |
71 | struct bridge_mcast_own_query { | 59 | struct bridge_mcast_own_query { |