From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
To: bridge@lists.linux-foundation.org, netdev@vger.kernel.org
Cc: ivecera@redhat.com, igor.mitsyanko.os@quantenna.com,
jiri@resnulli.us, sergey.matyukevich.os@quantenna.com,
ashevchenko@quantenna.com, smaksimenko@quantenna.com,
dlebed@quantenna.com
Subject: [RFC PATCH net-next 3/5] bridge: allow switchdev port to handle flooding by itself
Date: Fri, 9 Mar 2018 19:03:06 -0800 [thread overview]
Message-ID: <20180310030308.12947-4-igor.mitsyanko.os@quantenna.com> (raw)
In-Reply-To: <20180310030308.12947-1-igor.mitsyanko.os@quantenna.com>
Introduce BR_FLOOD_OFFLOAD bridge port flag that can be used by
switchdev-capable hardware to advertize that it wants to handle all
flooding by itself.
In that case there is no need for a driver to set skb::offload_fwd_mark
on each offloaded packet as it is implied by BR_FLOOD_OFFLOAD bridge
port flag.
BR_FLOOD_OFFLOAD port flags helps in two scenarios:
1. Mixed bridge configuration with SW ports and switchdev-capable ports.
In case a data frame that needs to be flooded is ingressed on a SW port,
it needs to be flooded to a single HW port of any given
switchdev-capable hardware only. Switchdev hardware will than take care
about flooding to the rest of the ports that it manages.
2. Switch driver does not have to identify frames that were flooded by
hardware and explicitly mark them with skb::offload_fwd_mark. Assuming
it knows that hardware will always handle flooding by itself, it can
simply advertise BR_FLOOD_OFFLOAD port flag.
Note: current implementation can only handle a single switchdev-capable
device in a single port. Frame will be flooded as usual to all ports of
any additional switchdev present in a given bridge.
Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
---
include/linux/if_bridge.h | 1 +
net/bridge/br_forward.c | 2 ++
net/bridge/br_private.h | 8 ++++++++
net/bridge/br_switchdev.c | 14 +++++++++++++-
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 02639eb..5d0e277 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -50,6 +50,7 @@ struct br_ip_list {
#define BR_VLAN_TUNNEL BIT(13)
#define BR_BCAST_FLOOD BIT(14)
#define BR_NEIGH_SUPPRESS BIT(15)
+#define BR_FLOOD_OFFLOAD BIT(16)
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index b4eed11..ac761a9 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -163,6 +163,8 @@ static struct net_bridge_port *maybe_deliver(
if (!should_deliver(p, skb))
return prev;
+ nbp_switchdev_offload_fwd_track(p, skb);
+
if (!prev)
goto out;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 8e13a64..a6d2f2b 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1111,6 +1111,8 @@ void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
struct sk_buff *skb);
bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
const struct sk_buff *skb);
+void nbp_switchdev_offload_fwd_track(const struct net_bridge_port *p,
+ struct sk_buff *skb);
int br_switchdev_set_port_flag(struct net_bridge_port *p,
unsigned long flags,
unsigned long mask);
@@ -1138,6 +1140,12 @@ static inline bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
return true;
}
+static inline void
+nbp_switchdev_offload_fwd_track(const struct net_bridge_port *p,
+ struct sk_buff *skb)
+{
+}
+
static inline int br_switchdev_set_port_flag(struct net_bridge_port *p,
unsigned long flags,
unsigned long mask)
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index ee775f4..aee3c01 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -46,6 +46,9 @@ int nbp_switchdev_mark_set(struct net_bridge_port *p)
void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
struct sk_buff *skb)
{
+ if (p->flags & BR_FLOOD_OFFLOAD)
+ skb->offload_fwd_mark = 1;
+
if (skb->offload_fwd_mark && !WARN_ON_ONCE(!p->offload_fwd_mark))
BR_INPUT_SKB_CB(skb)->offload_fwd_mark = p->offload_fwd_mark;
}
@@ -57,8 +60,17 @@ bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
BR_INPUT_SKB_CB(skb)->offload_fwd_mark != p->offload_fwd_mark;
}
+void nbp_switchdev_offload_fwd_track(const struct net_bridge_port *p,
+ struct sk_buff *skb)
+{
+ if (skb->offload_fwd_mark || !(p->flags & BR_FLOOD_OFFLOAD))
+ return;
+
+ nbp_switchdev_frame_mark(p, skb);
+}
+
/* Flags that can be offloaded to hardware */
-#define BR_PORT_FLAGS_HW_OFFLOAD (BR_LEARNING | BR_FLOOD | \
+#define BR_PORT_FLAGS_HW_OFFLOAD (BR_LEARNING | BR_FLOOD | BR_FLOOD_OFFLOAD | \
BR_MCAST_FLOOD | BR_BCAST_FLOOD)
int br_switchdev_set_port_flag(struct net_bridge_port *p,
--
2.9.5
next prev parent reply other threads:[~2018-03-10 3:03 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-10 3:03 [PATCH net-next 0/5] Switchdev: flooding offload option Igor Mitsyanko
2018-03-10 3:03 ` [PATCH net-next 1/5] bridge: initialize port flags with switchdev defaults Igor Mitsyanko
2018-03-10 16:30 ` Andrew Lunn
2018-03-12 18:44 ` Igor Mitsyanko
2018-03-10 16:32 ` Stephen Hemminger
2018-03-12 19:03 ` Igor Mitsyanko
2018-03-10 3:03 ` [PATCH net-next 2/5] bridge: propagate BR_ flags updates through sysfs to switchdev Igor Mitsyanko
2018-03-10 16:38 ` Andrew Lunn
2018-03-12 20:07 ` Igor Mitsyanko
2018-03-10 3:03 ` Igor Mitsyanko [this message]
2018-03-10 16:55 ` [RFC PATCH net-next 3/5] bridge: allow switchdev port to handle flooding by itself Andrew Lunn
2018-03-12 23:00 ` Igor Mitsyanko
2018-03-13 1:11 ` Andrew Lunn
2018-03-13 14:41 ` Roopa Prabhu
2018-03-10 3:03 ` [RFC PATCH net-next 4/5] bridge: provide sysfs and netlink interface to set BR_FLOOD_OFFLOAD Igor Mitsyanko
2018-03-10 3:03 ` [RFC PATCH net-next 5/5] bridge: verify "HW only" flags can't be set without HW support Igor Mitsyanko
2018-03-10 22:08 ` [PATCH net-next 0/5] Switchdev: flooding offload option Andrew Lunn
2018-03-12 23:08 ` Igor Mitsyanko
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=20180310030308.12947-4-igor.mitsyanko.os@quantenna.com \
--to=igor.mitsyanko.os@quantenna.com \
--cc=ashevchenko@quantenna.com \
--cc=bridge@lists.linux-foundation.org \
--cc=dlebed@quantenna.com \
--cc=ivecera@redhat.com \
--cc=jiri@resnulli.us \
--cc=netdev@vger.kernel.org \
--cc=sergey.matyukevich.os@quantenna.com \
--cc=smaksimenko@quantenna.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;
as well as URLs for NNTP newsgroup(s).