Skip to content

Commit

Permalink
net: bridge: vlan: add support for mcast querier global option
Browse files Browse the repository at this point in the history
Add support to change and retrieve global vlan multicast querier state.
We just need to pass multicast context to br_multicast_set_querier
instead of bridge device and the rest of the logic remains the same.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nikolay Aleksandrov authored and David S. Miller committed Aug 11, 2021
1 parent cb486ce commit 6293818
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 11 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/if_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ enum {
BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
__BRIDGE_VLANDB_GOPTS_MAX
};
#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1)
Expand Down
7 changes: 3 additions & 4 deletions net/bridge/br_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -4297,14 +4297,13 @@ bool br_multicast_router(const struct net_device *dev)
}
EXPORT_SYMBOL_GPL(br_multicast_router);

int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val)
{
struct net_bridge_mcast *brmctx = &br->multicast_ctx;
unsigned long max_delay;

val = !!val;

spin_lock_bh(&br->multicast_lock);
spin_lock_bh(&brmctx->br->multicast_lock);
if (brmctx->multicast_querier == val)
goto unlock;

Expand All @@ -4327,7 +4326,7 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
#endif

unlock:
spin_unlock_bh(&br->multicast_lock);
spin_unlock_bh(&brmctx->br->multicast_lock);

return 0;
}
Expand Down
5 changes: 3 additions & 2 deletions net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,8 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
if (data[IFLA_BR_MCAST_QUERIER]) {
u8 mcast_querier = nla_get_u8(data[IFLA_BR_MCAST_QUERIER]);

err = br_multicast_set_querier(br, mcast_querier);
err = br_multicast_set_querier(&br->multicast_ctx,
mcast_querier);
if (err)
return err;
}
Expand Down Expand Up @@ -1575,7 +1576,7 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
nla_put_u8(skb, IFLA_BR_MCAST_QUERY_USE_IFADDR,
br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)) ||
nla_put_u8(skb, IFLA_BR_MCAST_QUERIER,
READ_ONCE(br->multicast_ctx.multicast_querier)) ||
br->multicast_ctx.multicast_querier) ||
nla_put_u8(skb, IFLA_BR_MCAST_STATS_ENABLED,
br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)) ||
nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY, RHT_ELASTICITY) ||
Expand Down
5 changes: 3 additions & 2 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ int br_multicast_set_router(struct net_bridge *br, unsigned long val);
int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val);
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_querier(struct net_bridge_mcast *brmctx, 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_mcast *brmctx,
unsigned long val);
Expand Down Expand Up @@ -1028,7 +1028,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
{
bool own_querier_enabled;

if (READ_ONCE(brmctx->multicast_querier)) {
if (brmctx->multicast_querier) {
if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR))
own_querier_enabled = false;
else
Expand Down Expand Up @@ -1190,6 +1190,7 @@ br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
brmctx2->multicast_query_response_interval &&
brmctx1->multicast_startup_query_interval ==
brmctx2->multicast_startup_query_interval &&
brmctx1->multicast_querier == brmctx2->multicast_querier &&
#if IS_ENABLED(CONFIG_IPV6)
brmctx1->multicast_mld_version ==
brmctx2->multicast_mld_version &&
Expand Down
4 changes: 2 additions & 2 deletions net/bridge/br_sysfs_br.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,13 @@ static ssize_t multicast_querier_show(struct device *d,
char *buf)
{
struct net_bridge *br = to_bridge(d);
return sprintf(buf, "%d\n", READ_ONCE(br->multicast_ctx.multicast_querier));
return sprintf(buf, "%d\n", br->multicast_ctx.multicast_querier);
}

static int set_multicast_querier(struct net_bridge *br, unsigned long val,
struct netlink_ext_ack *extack)
{
return br_multicast_set_querier(br, val);
return br_multicast_set_querier(&br->multicast_ctx, val);
}

static ssize_t multicast_querier_store(struct device *d,
Expand Down
15 changes: 14 additions & 1 deletion net/bridge/br_vlan_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,9 @@ bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
v_opts->br_mcast_ctx.multicast_last_member_count) ||
nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
v_opts->br_mcast_ctx.multicast_startup_query_count))
v_opts->br_mcast_ctx.multicast_startup_query_count) ||
nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
v_opts->br_mcast_ctx.multicast_querier))
goto out_err;

clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval);
Expand Down Expand Up @@ -355,6 +357,7 @@ static size_t rtnl_vlan_global_opts_nlmsg_size(void)
+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL */
+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */
+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */
+ nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */
#endif
+ nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */
}
Expand Down Expand Up @@ -485,6 +488,15 @@ static int br_vlan_process_global_one_opts(const struct net_bridge *br,
v->br_mcast_ctx.multicast_startup_query_interval = clock_t_to_jiffies(val);
*changed = true;
}
if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
u8 val;

val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]);
err = br_multicast_set_querier(&v->br_mcast_ctx, val);
if (err)
return err;
*changed = true;
}
#if IS_ENABLED(CONFIG_IPV6)
if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
u8 ver;
Expand All @@ -507,6 +519,7 @@ static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = {
[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING] = { .type = NLA_U8 },
[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 },
[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 },
[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER] = { .type = NLA_U8 },
[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION] = { .type = NLA_U8 },
[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 },
[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 },
Expand Down

0 comments on commit 6293818

Please sign in to comment.