Commit 4d5b4e84 authored by Nikolay Aleksandrov's avatar Nikolay Aleksandrov Committed by David S. Miller

net: bridge: mcast: move querier state to the multicast context

We need to have the querier state per multicast context in order to have
per-vlan control, so remove the internal option bit and move it to the
multicast context. Also annotate the lockless reads of the new variable.
Signed-off-by: default avatarNikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 941121ee
...@@ -1668,7 +1668,7 @@ static void br_multicast_send_query(struct net_bridge_mcast *brmctx, ...@@ -1668,7 +1668,7 @@ static void br_multicast_send_query(struct net_bridge_mcast *brmctx,
if (!br_multicast_ctx_should_use(brmctx, pmctx) || if (!br_multicast_ctx_should_use(brmctx, pmctx) ||
!br_opt_get(brmctx->br, BROPT_MULTICAST_ENABLED) || !br_opt_get(brmctx->br, BROPT_MULTICAST_ENABLED) ||
!br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER)) !brmctx->multicast_querier)
return; return;
memset(&br_group.dst, 0, sizeof(br_group.dst)); memset(&br_group.dst, 0, sizeof(br_group.dst));
...@@ -1747,14 +1747,16 @@ static void br_multicast_port_group_rexmit(struct timer_list *t) ...@@ -1747,14 +1747,16 @@ static void br_multicast_port_group_rexmit(struct timer_list *t)
spin_lock(&br->multicast_lock); spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) || if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
!br_opt_get(br, BROPT_MULTICAST_ENABLED) || !br_opt_get(br, BROPT_MULTICAST_ENABLED))
!br_opt_get(br, BROPT_MULTICAST_QUERIER))
goto out; goto out;
pmctx = br_multicast_pg_to_port_ctx(pg); pmctx = br_multicast_pg_to_port_ctx(pg);
if (!pmctx) if (!pmctx)
goto out; goto out;
brmctx = br_multicast_port_ctx_get_global(pmctx); brmctx = br_multicast_port_ctx_get_global(pmctx);
if (!brmctx->multicast_querier)
goto out;
if (pg->key.addr.proto == htons(ETH_P_IP)) if (pg->key.addr.proto == htons(ETH_P_IP))
other_query = &brmctx->ip4_other_query; other_query = &brmctx->ip4_other_query;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
...@@ -1974,8 +1976,7 @@ static void __grp_src_query_marked_and_rexmit(struct net_bridge_mcast *brmctx, ...@@ -1974,8 +1976,7 @@ static void __grp_src_query_marked_and_rexmit(struct net_bridge_mcast *brmctx,
if (ent->flags & BR_SGRP_F_SEND) { if (ent->flags & BR_SGRP_F_SEND) {
ent->flags &= ~BR_SGRP_F_SEND; ent->flags &= ~BR_SGRP_F_SEND;
if (ent->timer.expires > lmqt) { if (ent->timer.expires > lmqt) {
if (br_opt_get(brmctx->br, if (brmctx->multicast_querier &&
BROPT_MULTICAST_QUERIER) &&
other_query && other_query &&
!timer_pending(&other_query->timer)) !timer_pending(&other_query->timer))
ent->src_query_rexmit_cnt = lmqc; ent->src_query_rexmit_cnt = lmqc;
...@@ -1984,7 +1985,7 @@ static void __grp_src_query_marked_and_rexmit(struct net_bridge_mcast *brmctx, ...@@ -1984,7 +1985,7 @@ static void __grp_src_query_marked_and_rexmit(struct net_bridge_mcast *brmctx,
} }
} }
if (!br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER) || if (!brmctx->multicast_querier ||
!other_query || timer_pending(&other_query->timer)) !other_query || timer_pending(&other_query->timer))
return; return;
...@@ -2015,7 +2016,7 @@ static void __grp_send_query_and_rexmit(struct net_bridge_mcast *brmctx, ...@@ -2015,7 +2016,7 @@ static void __grp_send_query_and_rexmit(struct net_bridge_mcast *brmctx,
other_query = &brmctx->ip6_other_query; other_query = &brmctx->ip6_other_query;
#endif #endif
if (br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER) && if (brmctx->multicast_querier &&
other_query && !timer_pending(&other_query->timer)) { other_query && !timer_pending(&other_query->timer)) {
lmi = now + brmctx->multicast_last_member_interval; lmi = now + brmctx->multicast_last_member_interval;
pg->grp_query_rexmit_cnt = brmctx->multicast_last_member_count - 1; pg->grp_query_rexmit_cnt = brmctx->multicast_last_member_count - 1;
...@@ -3316,7 +3317,7 @@ br_multicast_leave_group(struct net_bridge_mcast *brmctx, ...@@ -3316,7 +3317,7 @@ br_multicast_leave_group(struct net_bridge_mcast *brmctx,
if (timer_pending(&other_query->timer)) if (timer_pending(&other_query->timer))
goto out; goto out;
if (br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER)) { if (brmctx->multicast_querier) {
__br_multicast_send_query(brmctx, pmctx, NULL, NULL, &mp->addr, __br_multicast_send_query(brmctx, pmctx, NULL, NULL, &mp->addr,
false, 0, NULL); false, 0, NULL);
...@@ -4300,10 +4301,10 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val) ...@@ -4300,10 +4301,10 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
val = !!val; val = !!val;
spin_lock_bh(&br->multicast_lock); spin_lock_bh(&br->multicast_lock);
if (br_opt_get(br, BROPT_MULTICAST_QUERIER) == val) if (brmctx->multicast_querier == val)
goto unlock; goto unlock;
br_opt_toggle(br, BROPT_MULTICAST_QUERIER, !!val); WRITE_ONCE(brmctx->multicast_querier, val);
if (!val) if (!val)
goto unlock; goto unlock;
......
...@@ -1575,7 +1575,7 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev) ...@@ -1575,7 +1575,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, nla_put_u8(skb, IFLA_BR_MCAST_QUERY_USE_IFADDR,
br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)) || br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)) ||
nla_put_u8(skb, IFLA_BR_MCAST_QUERIER, nla_put_u8(skb, IFLA_BR_MCAST_QUERIER,
br_opt_get(br, BROPT_MULTICAST_QUERIER)) || READ_ONCE(br->multicast_ctx.multicast_querier)) ||
nla_put_u8(skb, IFLA_BR_MCAST_STATS_ENABLED, nla_put_u8(skb, IFLA_BR_MCAST_STATS_ENABLED,
br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)) || br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)) ||
nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY, RHT_ELASTICITY) || nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY, RHT_ELASTICITY) ||
......
...@@ -118,6 +118,7 @@ struct net_bridge_mcast { ...@@ -118,6 +118,7 @@ struct net_bridge_mcast {
u32 multicast_last_member_count; u32 multicast_last_member_count;
u32 multicast_startup_query_count; u32 multicast_startup_query_count;
u8 multicast_querier;
u8 multicast_igmp_version; u8 multicast_igmp_version;
u8 multicast_router; u8 multicast_router;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
...@@ -431,7 +432,6 @@ enum net_bridge_opts { ...@@ -431,7 +432,6 @@ enum net_bridge_opts {
BROPT_NF_CALL_ARPTABLES, BROPT_NF_CALL_ARPTABLES,
BROPT_GROUP_ADDR_SET, BROPT_GROUP_ADDR_SET,
BROPT_MULTICAST_ENABLED, BROPT_MULTICAST_ENABLED,
BROPT_MULTICAST_QUERIER,
BROPT_MULTICAST_QUERY_USE_IFADDR, BROPT_MULTICAST_QUERY_USE_IFADDR,
BROPT_MULTICAST_STATS_ENABLED, BROPT_MULTICAST_STATS_ENABLED,
BROPT_HAS_IPV6_ADDR, BROPT_HAS_IPV6_ADDR,
...@@ -1028,7 +1028,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx, ...@@ -1028,7 +1028,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
{ {
bool own_querier_enabled; bool own_querier_enabled;
if (br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER)) { if (READ_ONCE(brmctx->multicast_querier)) {
if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR)) if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR))
own_querier_enabled = false; own_querier_enabled = false;
else else
......
...@@ -447,7 +447,7 @@ static ssize_t multicast_querier_show(struct device *d, ...@@ -447,7 +447,7 @@ static ssize_t multicast_querier_show(struct device *d,
char *buf) char *buf)
{ {
struct net_bridge *br = to_bridge(d); struct net_bridge *br = to_bridge(d);
return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_QUERIER)); return sprintf(buf, "%d\n", READ_ONCE(br->multicast_ctx.multicast_querier));
} }
static int set_multicast_querier(struct net_bridge *br, unsigned long val, static int set_multicast_querier(struct net_bridge *br, unsigned long val,
......
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