From: Nikolay Aleksandrov <razor@blackwall.org>
To: netdev@vger.kernel.org
Cc: bridge@lists.linux-foundation.org,
Nikolay Aleksandrov <nikolay@nvidia.com>,
roopa@nvidia.com
Subject: [Bridge] [PATCH net-next 09/15] net: bridge: multicast: check if should use vlan mcast ctx
Date: Mon, 19 Jul 2021 20:06:31 +0300 [thread overview]
Message-ID: <20210719170637.435541-10-razor@blackwall.org> (raw)
In-Reply-To: <20210719170637.435541-1-razor@blackwall.org>
From: Nikolay Aleksandrov <nikolay@nvidia.com>
Add helpers which check if the current bridge/port multicast context
should be used (i.e. they're not disabled) and use them for Rx IGMP/MLD
processing, timers and new group addition. It is important for vlans to
disable processing of timer/packet after the multicast_lock is obtained
if the vlan context doesn't have BR_VLFLAG_MCAST_ENABLED. There are two
cases when that flag is missing:
- if the vlan is getting destroyed it will be removed and timers will
be stopped
- if the vlan mcast snooping is being disabled
Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
net/bridge/br_multicast.c | 59 +++++++++++++++++++++++++++++----------
net/bridge/br_private.h | 18 ++++++++++++
2 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index e61e23c0ce17..4620946ec7d7 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -147,7 +147,8 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
struct net_bridge *br = brmctx->br;
struct br_ip ip;
- if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
+ br_multicast_ctx_vlan_global_disabled(brmctx))
return NULL;
if (BR_INPUT_SKB_CB(skb)->igmp)
@@ -230,6 +231,24 @@ br_multicast_pg_to_port_ctx(const struct net_bridge_port_group *pg)
return pmctx;
}
+/* when snooping we need to check if the contexts should be used
+ * in the following order:
+ * - if pmctx is non-NULL (port), check if it should be used
+ * - if pmctx is NULL (bridge), check if brmctx should be used
+ */
+static bool
+br_multicast_ctx_should_use(const struct net_bridge_mcast *brmctx,
+ const struct net_bridge_mcast_port *pmctx)
+{
+ if (!netif_running(brmctx->br->dev))
+ return false;
+
+ if (pmctx)
+ return !br_multicast_port_ctx_state_disabled(pmctx);
+ else
+ return !br_multicast_ctx_vlan_disabled(brmctx);
+}
+
static bool br_port_group_equal(struct net_bridge_port_group *p,
struct net_bridge_port *port,
const unsigned char *src)
@@ -1311,8 +1330,7 @@ __br_multicast_add_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mdb_entry *mp;
unsigned long now = jiffies;
- if (!netif_running(brmctx->br->dev) ||
- (pmctx && pmctx->port->state == BR_STATE_DISABLED))
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
goto out;
mp = br_multicast_new_group(brmctx->br, group);
@@ -1532,6 +1550,7 @@ static void br_multicast_querier_expired(struct net_bridge_mcast *brmctx,
{
spin_lock(&brmctx->br->multicast_lock);
if (!netif_running(brmctx->br->dev) ||
+ br_multicast_ctx_vlan_global_disabled(brmctx) ||
!br_opt_get(brmctx->br, BROPT_MULTICAST_ENABLED))
goto out;
@@ -1619,7 +1638,7 @@ static void br_multicast_send_query(struct net_bridge_mcast *brmctx,
struct br_ip br_group;
unsigned long time;
- if (!netif_running(brmctx->br->dev) ||
+ if (!br_multicast_ctx_should_use(brmctx, pmctx) ||
!br_opt_get(brmctx->br, BROPT_MULTICAST_ENABLED) ||
!br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER))
return;
@@ -1655,16 +1674,16 @@ br_multicast_port_query_expired(struct net_bridge_mcast_port *pmctx,
struct bridge_mcast_own_query *query)
{
struct net_bridge *br = pmctx->port->br;
+ struct net_bridge_mcast *brmctx;
spin_lock(&br->multicast_lock);
- if (pmctx->port->state == BR_STATE_DISABLED ||
- pmctx->port->state == BR_STATE_BLOCKING)
+ if (br_multicast_port_ctx_state_stopped(pmctx))
goto out;
-
- if (query->startup_sent < br->multicast_ctx.multicast_startup_query_count)
+ brmctx = br_multicast_port_ctx_get_global(pmctx);
+ if (query->startup_sent < brmctx->multicast_startup_query_count)
query->startup_sent++;
- br_multicast_send_query(&br->multicast_ctx, pmctx, query);
+ br_multicast_send_query(brmctx, pmctx, query);
out:
spin_unlock(&br->multicast_lock);
@@ -2582,6 +2601,9 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge_mcast *brmctx,
continue;
spin_lock_bh(&brmctx->br->multicast_lock);
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
+ goto unlock_continue;
+
mdst = br_mdb_ip4_get(brmctx->br, group, vid);
if (!mdst)
goto unlock_continue;
@@ -2717,6 +2739,9 @@ static int br_ip6_multicast_mld2_report(struct net_bridge_mcast *brmctx,
continue;
spin_lock_bh(&brmctx->br->multicast_lock);
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
+ goto unlock_continue;
+
mdst = br_mdb_ip6_get(brmctx->br, &grec->grec_mca, vid);
if (!mdst)
goto unlock_continue;
@@ -2962,6 +2987,9 @@ static void br_multicast_mark_router(struct net_bridge_mcast *brmctx,
{
unsigned long now = jiffies;
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
+ return;
+
if (!pmctx) {
if (brmctx->multicast_router == MDB_RTR_TYPE_TEMP_QUERY) {
if (!br_ip4_multicast_is_router(brmctx) &&
@@ -3060,8 +3088,7 @@ static void br_ip4_multicast_query(struct net_bridge_mcast *brmctx,
__be32 group;
spin_lock(&brmctx->br->multicast_lock);
- if (!netif_running(brmctx->br->dev) ||
- (pmctx && pmctx->port->state == BR_STATE_DISABLED))
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
goto out;
group = ih->group;
@@ -3144,8 +3171,7 @@ static int br_ip6_multicast_query(struct net_bridge_mcast *brmctx,
int err = 0;
spin_lock(&brmctx->br->multicast_lock);
- if (!netif_running(brmctx->br->dev) ||
- (pmctx && pmctx->port->state == BR_STATE_DISABLED))
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
goto out;
if (transport_len == sizeof(*mld)) {
@@ -3229,8 +3255,7 @@ br_multicast_leave_group(struct net_bridge_mcast *brmctx,
unsigned long time;
spin_lock(&brmctx->br->multicast_lock);
- if (!netif_running(brmctx->br->dev) ||
- (pmctx && pmctx->port->state == BR_STATE_DISABLED))
+ if (!br_multicast_ctx_should_use(brmctx, pmctx))
goto out;
mp = br_mdb_ip_get(brmctx->br, group);
@@ -3609,11 +3634,15 @@ static void br_multicast_query_expired(struct net_bridge_mcast *brmctx,
struct bridge_mcast_querier *querier)
{
spin_lock(&brmctx->br->multicast_lock);
+ if (br_multicast_ctx_vlan_disabled(brmctx))
+ goto out;
+
if (query->startup_sent < brmctx->multicast_startup_query_count)
query->startup_sent++;
RCU_INIT_POINTER(querier->port, NULL);
br_multicast_send_query(brmctx, NULL, query);
+out:
spin_unlock(&brmctx->br->multicast_lock);
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index a643f6bf759f..00b93fcc7870 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1126,6 +1126,24 @@ br_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx)
return br_multicast_port_ctx_is_vlan(pmctx) &&
!(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
}
+
+static inline bool
+br_multicast_port_ctx_state_disabled(const struct net_bridge_mcast_port *pmctx)
+{
+ return pmctx->port->state == BR_STATE_DISABLED ||
+ (br_multicast_port_ctx_is_vlan(pmctx) &&
+ (br_multicast_port_ctx_vlan_disabled(pmctx) ||
+ pmctx->vlan->state == BR_STATE_DISABLED));
+}
+
+static inline bool
+br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx)
+{
+ return br_multicast_port_ctx_state_disabled(pmctx) ||
+ pmctx->port->state == BR_STATE_BLOCKING ||
+ (br_multicast_port_ctx_is_vlan(pmctx) &&
+ pmctx->vlan->state == BR_STATE_BLOCKING);
+}
#else
static inline int br_multicast_rcv(struct net_bridge_mcast **brmctx,
struct net_bridge_mcast_port **pmctx,
--
2.31.1
next prev parent reply other threads:[~2021-07-19 17:06 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-19 17:06 [Bridge] [PATCH net-next 00/15] net: bridge: multicast: add vlan support Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 01/15] net: bridge: multicast: factor out port multicast context Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 02/15] net: bridge: multicast: factor out bridge " Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 03/15] net: bridge: multicast: use multicast contexts instead of bridge or port Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 04/15] net: bridge: vlan: add global and per-port multicast context Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 05/15] net: bridge: multicast: add vlan state initialization and control Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 06/15] net: bridge: add vlan mcast snooping knob Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 07/15] net: bridge: multicast: add helper to get port mcast context from port group Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 08/15] net: bridge: multicast: use the port group to port context helper Nikolay Aleksandrov
2021-07-19 17:06 ` Nikolay Aleksandrov [this message]
2021-07-19 17:06 ` [Bridge] [PATCH net-next 10/15] net: bridge: multicast: add vlan querier and query support Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 11/15] net: bridge: multicast: include router port vlan id in notifications Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 12/15] net: bridge: vlan: add support for global options Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 13/15] net: bridge: vlan: add support for dumping global vlan options Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 14/15] net: bridge: vlan: notify when global options change Nikolay Aleksandrov
2021-07-19 17:06 ` [Bridge] [PATCH net-next 15/15] net: bridge: vlan: add mcast snooping control Nikolay Aleksandrov
2021-07-20 13:30 ` [Bridge] [PATCH net-next 00/15] net: bridge: multicast: add vlan support patchwork-bot+netdevbpf
2021-08-19 16:01 ` Joachim Wiberg
2021-08-19 16:22 ` Nikolay Aleksandrov
2021-08-20 6:26 ` Joachim Wiberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210719170637.435541-10-razor@blackwall.org \
--to=razor@blackwall.org \
--cc=bridge@lists.linux-foundation.org \
--cc=netdev@vger.kernel.org \
--cc=nikolay@nvidia.com \
--cc=roopa@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox