Commit 7b0dcbd8 authored by David S. Miller's avatar David S. Miller

Merge branch 'bridge_multicast_exports'

Linus Lüssing says:

====================
bridge: multicast snooping patches / exports

The first patch is simply a cosmetic patch. So far I (and maybe others
too?) have been regularly confusing these two structs, therefore I'd
suggest renaming them and therefore making the follow-up patches easier
to understand and nicer to fit in.

The second patch fixes a minor issue, but probably not worth for stable.

On the other hand the first two patches are also preparations for the
third and fourth patch:

These two patches are exporting functionality needed to marry the bridge
multicast snooping with the batman-adv multicast optimizations recently
added for the 3.15 kernel, allowing to use these optimzations in common
setups having a bridge on top of e.g. bat0, too. So far these bridged
setups would fall back to simple flooding through the batman-adv mesh
network for any multicast packet entering bat0.

More information about the batman-adv multicast optimizations currently
implemented can be found here:

http://www.open-mesh.org/projects/batman-adv/wiki/Basic-multicast-optimizations

The integration on the batman-adv side could afterwards look like this,
for instance:

http://git.open-mesh.org/batman-adv.git/commitdiff/576b59dd3e34737c702e548b21fa72059262f796?hp=f95ce7131746c65fbcdffcf2089cab59e2c2f7ac
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c4d4c255 2cd41431
...@@ -16,9 +16,28 @@ ...@@ -16,9 +16,28 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <uapi/linux/if_bridge.h> #include <uapi/linux/if_bridge.h>
struct br_ip {
union {
__be32 ip4;
#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr ip6;
#endif
} u;
__be16 proto;
__u16 vid;
};
struct br_ip_list {
struct list_head list;
struct br_ip addr;
};
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
typedef int br_should_route_hook_t(struct sk_buff *skb); typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook; extern br_should_route_hook_t __rcu *br_should_route_hook;
int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list);
bool br_multicast_has_querier_adjacent(struct net_device *dev, int proto);
#endif #endif
...@@ -418,13 +418,13 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) ...@@ -418,13 +418,13 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
ip.proto = entry->addr.proto; ip.proto = entry->addr.proto;
if (ip.proto == htons(ETH_P_IP)) { if (ip.proto == htons(ETH_P_IP)) {
if (timer_pending(&br->ip4_querier.timer)) if (timer_pending(&br->ip4_other_query.timer))
return -EBUSY; return -EBUSY;
ip.u.ip4 = entry->addr.u.ip4; ip.u.ip4 = entry->addr.u.ip4;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
} else { } else {
if (timer_pending(&br->ip6_querier.timer)) if (timer_pending(&br->ip6_other_query.timer))
return -EBUSY; return -EBUSY;
ip.u.ip6 = entry->addr.u.ip6; ip.u.ip6 = entry->addr.u.ip6;
......
This diff is collapsed.
...@@ -54,30 +54,24 @@ struct mac_addr ...@@ -54,30 +54,24 @@ struct mac_addr
unsigned char addr[ETH_ALEN]; unsigned char addr[ETH_ALEN];
}; };
struct br_ip
{
union {
__be32 ip4;
#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr ip6;
#endif
} u;
__be16 proto;
__u16 vid;
};
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
/* our own querier */ /* our own querier */
struct bridge_mcast_query { struct bridge_mcast_own_query {
struct timer_list timer; struct timer_list timer;
u32 startup_sent; u32 startup_sent;
}; };
/* other querier */ /* other querier */
struct bridge_mcast_querier { struct bridge_mcast_other_query {
struct timer_list timer; struct timer_list timer;
unsigned long delay_time; unsigned long delay_time;
}; };
/* selected querier */
struct bridge_mcast_querier {
struct br_ip addr;
struct net_bridge_port __rcu *port;
};
#endif #endif
struct net_port_vlans { struct net_port_vlans {
...@@ -178,9 +172,9 @@ struct net_bridge_port ...@@ -178,9 +172,9 @@ struct net_bridge_port
#define BR_PROMISC 0x00000080 #define BR_PROMISC 0x00000080
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
struct bridge_mcast_query ip4_query; struct bridge_mcast_own_query ip4_own_query;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
struct bridge_mcast_query ip6_query; struct bridge_mcast_own_query ip6_own_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */ #endif /* IS_ENABLED(CONFIG_IPV6) */
unsigned char multicast_router; unsigned char multicast_router;
struct timer_list multicast_router_timer; struct timer_list multicast_router_timer;
...@@ -282,11 +276,13 @@ struct net_bridge ...@@ -282,11 +276,13 @@ struct net_bridge
struct hlist_head router_list; struct hlist_head router_list;
struct timer_list multicast_router_timer; struct timer_list multicast_router_timer;
struct bridge_mcast_other_query ip4_other_query;
struct bridge_mcast_own_query ip4_own_query;
struct bridge_mcast_querier ip4_querier; struct bridge_mcast_querier ip4_querier;
struct bridge_mcast_query ip4_query;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
struct bridge_mcast_other_query ip6_other_query;
struct bridge_mcast_own_query ip6_own_query;
struct bridge_mcast_querier ip6_querier; struct bridge_mcast_querier ip6_querier;
struct bridge_mcast_query ip6_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */ #endif /* IS_ENABLED(CONFIG_IPV6) */
#endif #endif
...@@ -493,7 +489,7 @@ static inline bool br_multicast_is_router(struct net_bridge *br) ...@@ -493,7 +489,7 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
static inline bool static inline bool
__br_multicast_querier_exists(struct net_bridge *br, __br_multicast_querier_exists(struct net_bridge *br,
struct bridge_mcast_querier *querier) struct bridge_mcast_other_query *querier)
{ {
return time_is_before_jiffies(querier->delay_time) && return time_is_before_jiffies(querier->delay_time) &&
(br->multicast_querier || timer_pending(&querier->timer)); (br->multicast_querier || timer_pending(&querier->timer));
...@@ -504,10 +500,10 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br, ...@@ -504,10 +500,10 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br,
{ {
switch (eth->h_proto) { switch (eth->h_proto) {
case (htons(ETH_P_IP)): case (htons(ETH_P_IP)):
return __br_multicast_querier_exists(br, &br->ip4_querier); return __br_multicast_querier_exists(br, &br->ip4_other_query);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
case (htons(ETH_P_IPV6)): case (htons(ETH_P_IPV6)):
return __br_multicast_querier_exists(br, &br->ip6_querier); return __br_multicast_querier_exists(br, &br->ip6_other_query);
#endif #endif
default: default:
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment