Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -16,9 +16,28 @@
#include <linux/netdevice.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 *));

typedef int br_should_route_hook_t(struct sk_buff *skb);
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
+2 −2
Original line number Diff line number Diff line
@@ -418,13 +418,13 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)

	ip.proto = entry->addr.proto;
	if (ip.proto == htons(ETH_P_IP)) {
		if (timer_pending(&br->ip4_querier.timer))
		if (timer_pending(&br->ip4_other_query.timer))
			return -EBUSY;

		ip.u.ip4 = entry->addr.u.ip4;
#if IS_ENABLED(CONFIG_IPV6)
	} else {
		if (timer_pending(&br->ip6_querier.timer))
		if (timer_pending(&br->ip6_other_query.timer))
			return -EBUSY;

		ip.u.ip6 = entry->addr.u.ip6;
+288 −90

File changed.

Preview size limit exceeded, changes collapsed.

+17 −21
Original line number Diff line number Diff line
@@ -54,30 +54,24 @@ struct mac_addr
	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
/* our own querier */
struct bridge_mcast_query {
struct bridge_mcast_own_query {
	struct timer_list	timer;
	u32			startup_sent;
};

/* other querier */
struct bridge_mcast_querier {
struct bridge_mcast_other_query {
	struct timer_list		timer;
	unsigned long			delay_time;
};

/* selected querier */
struct bridge_mcast_querier {
	struct br_ip addr;
	struct net_bridge_port __rcu	*port;
};
#endif

struct net_port_vlans {
@@ -178,9 +172,9 @@ struct net_bridge_port
#define BR_PROMISC		0x00000080

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	struct bridge_mcast_query	ip4_query;
	struct bridge_mcast_own_query	ip4_own_query;
#if IS_ENABLED(CONFIG_IPV6)
	struct bridge_mcast_query	ip6_query;
	struct bridge_mcast_own_query	ip6_own_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */
	unsigned char			multicast_router;
	struct timer_list		multicast_router_timer;
@@ -282,11 +276,13 @@ struct net_bridge
	struct hlist_head		router_list;

	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_query	ip4_query;
#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_query	ip6_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */
#endif

@@ -493,7 +489,7 @@ static inline bool br_multicast_is_router(struct net_bridge *br)

static inline bool
__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) &&
	       (br->multicast_querier || timer_pending(&querier->timer));
@@ -504,10 +500,10 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br,
{
	switch (eth->h_proto) {
	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)
	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
	default:
		return false;