Commit df271cd6 authored by Nikolay Aleksandrov's avatar Nikolay Aleksandrov Committed by David S. Miller
Browse files

net: bridge: vlan: add support for mcast igmp/mld version global options



Add support to change and retrieve global vlan IGMP/MLD versions.

Signed-off-by: default avatarNikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6899192f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -549,6 +549,8 @@ enum {
	BRIDGE_VLANDB_GOPTS_ID,
	BRIDGE_VLANDB_GOPTS_RANGE,
	BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING,
	BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION,
	BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
	__BRIDGE_VLANDB_GOPTS_MAX
};
#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1)
+10 −8
Original line number Diff line number Diff line
@@ -4327,7 +4327,8 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
	return 0;
}

int br_multicast_set_igmp_version(struct net_bridge *br, unsigned long val)
int br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx,
				  unsigned long val)
{
	/* Currently we support only version 2 and 3 */
	switch (val) {
@@ -4338,15 +4339,16 @@ int br_multicast_set_igmp_version(struct net_bridge *br, unsigned long val)
		return -EINVAL;
	}

	spin_lock_bh(&br->multicast_lock);
	br->multicast_ctx.multicast_igmp_version = val;
	spin_unlock_bh(&br->multicast_lock);
	spin_lock_bh(&brmctx->br->multicast_lock);
	brmctx->multicast_igmp_version = val;
	spin_unlock_bh(&brmctx->br->multicast_lock);

	return 0;
}

#if IS_ENABLED(CONFIG_IPV6)
int br_multicast_set_mld_version(struct net_bridge *br, unsigned long val)
int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
				 unsigned long val)
{
	/* Currently we support version 1 and 2 */
	switch (val) {
@@ -4357,9 +4359,9 @@ int br_multicast_set_mld_version(struct net_bridge *br, unsigned long val)
		return -EINVAL;
	}

	spin_lock_bh(&br->multicast_lock);
	br->multicast_ctx.multicast_mld_version = val;
	spin_unlock_bh(&br->multicast_lock);
	spin_lock_bh(&brmctx->br->multicast_lock);
	brmctx->multicast_mld_version = val;
	spin_unlock_bh(&brmctx->br->multicast_lock);

	return 0;
}
+4 −2
Original line number Diff line number Diff line
@@ -1380,7 +1380,8 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
		__u8 igmp_version;

		igmp_version = nla_get_u8(data[IFLA_BR_MCAST_IGMP_VERSION]);
		err = br_multicast_set_igmp_version(br, igmp_version);
		err = br_multicast_set_igmp_version(&br->multicast_ctx,
						    igmp_version);
		if (err)
			return err;
	}
@@ -1390,7 +1391,8 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
		__u8 mld_version;

		mld_version = nla_get_u8(data[IFLA_BR_MCAST_MLD_VERSION]);
		err = br_multicast_set_mld_version(br, mld_version);
		err = br_multicast_set_mld_version(&br->multicast_ctx,
						   mld_version);
		if (err)
			return err;
	}
+24 −2
Original line number Diff line number Diff line
@@ -883,9 +883,11 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val,
			struct netlink_ext_ack *extack);
int br_multicast_set_querier(struct net_bridge *br, unsigned long val);
int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
int br_multicast_set_igmp_version(struct net_bridge *br, unsigned long val);
int br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx,
				  unsigned long val);
#if IS_ENABLED(CONFIG_IPV6)
int br_multicast_set_mld_version(struct net_bridge *br, unsigned long val);
int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
				 unsigned long val);
#endif
struct net_bridge_mdb_entry *
br_mdb_ip_get(struct net_bridge *br, struct br_ip *dst);
@@ -1165,6 +1167,19 @@ br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx)
	       (br_multicast_port_ctx_is_vlan(pmctx) &&
		pmctx->vlan->state == BR_STATE_BLOCKING);
}

static inline bool
br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
			       const struct net_bridge_mcast *brmctx2)
{
	return brmctx1->multicast_igmp_version ==
	       brmctx2->multicast_igmp_version &&
#if IS_ENABLED(CONFIG_IPV6)
	       brmctx1->multicast_mld_version ==
	       brmctx2->multicast_mld_version &&
#endif
	       true;
}
#else
static inline int br_multicast_rcv(struct net_bridge_mcast **brmctx,
				   struct net_bridge_mcast_port **pmctx,
@@ -1330,6 +1345,13 @@ static inline int br_mdb_replay(struct net_device *br_dev,
{
	return -EOPNOTSUPP;
}

static inline bool
br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
			       const struct net_bridge_mcast *brmctx2)
{
	return true;
}
#endif

/* br_vlan.c */
+2 −2
Original line number Diff line number Diff line
@@ -520,7 +520,7 @@ static ssize_t multicast_igmp_version_show(struct device *d,
static int set_multicast_igmp_version(struct net_bridge *br, unsigned long val,
				      struct netlink_ext_ack *extack)
{
	return br_multicast_set_igmp_version(br, val);
	return br_multicast_set_igmp_version(&br->multicast_ctx, val);
}

static ssize_t multicast_igmp_version_store(struct device *d,
@@ -757,7 +757,7 @@ static ssize_t multicast_mld_version_show(struct device *d,
static int set_multicast_mld_version(struct net_bridge *br, unsigned long val,
				     struct netlink_ext_ack *extack)
{
	return br_multicast_set_mld_version(br, val);
	return br_multicast_set_mld_version(&br->multicast_ctx, val);
}

static ssize_t multicast_mld_version_store(struct device *d,
Loading