* [PATCH v11 nf-next 0/3] netfilter: fastpath fixes
@ 2025-04-08 14:27 Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 1/3] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Eric Woudstra @ 2025-04-08 14:27 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Jiri Pirko, Ivan Vecera,
Nikolay Aleksandrov, Ido Schimmel, Pablo Neira Ayuso,
Jozsef Kadlecsik, Matthias Brugger, AngeloGioacchino Del Regno
Cc: netdev, bridge, netfilter-devel, linux-mediatek, Eric Woudstra
Several fixes for the existing software forward-fastpath code, also
needed for the software bridge-fastpath.
DEV_PATH_BR_VLAN_UNTAG_HW should not be applied to dsa foreign ports.
Also DEV_PATH_MTK_WDMA needs to be introduced to nft_dev_path_info().
Introduce DEV_PATH_BR_VLAN_KEEP_HW.
Changes in v11, results of testing with bridge_fastpath.sh:
- Dropped "No ingress_vlan forward info for dsa user port" patch.
- Added Introduce DEV_PATH_BR_VLAN_KEEP_HW, which changed from
applying only in the bridge-fastpath to all fastpaths. Added
a better explanation to the description.
v10 split from patch-set: bridge-fastpath and related improvements v9
Eric Woudstra (3):
netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to
nft_dev_path_info()
bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign
bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW
include/linux/netdevice.h | 1 +
include/net/switchdev.h | 1 +
net/bridge/br_device.c | 1 +
net/bridge/br_private.h | 10 ++++++++++
net/bridge/br_switchdev.c | 15 +++++++++++++++
net/bridge/br_vlan.c | 23 ++++++++++++++++-------
net/netfilter/nft_flow_offload.c | 8 ++++++++
net/switchdev/switchdev.c | 2 +-
8 files changed, 53 insertions(+), 8 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v11 nf-next 1/3] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info()
2025-04-08 14:27 [PATCH v11 nf-next 0/3] netfilter: fastpath fixes Eric Woudstra
@ 2025-04-08 14:27 ` Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 2/3] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 3/3] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW Eric Woudstra
2 siblings, 0 replies; 4+ messages in thread
From: Eric Woudstra @ 2025-04-08 14:27 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Jiri Pirko, Ivan Vecera,
Nikolay Aleksandrov, Ido Schimmel, Pablo Neira Ayuso,
Jozsef Kadlecsik, Matthias Brugger, AngeloGioacchino Del Regno
Cc: netdev, bridge, netfilter-devel, linux-mediatek, Eric Woudstra
In case of using mediatek wireless, in nft_dev_fill_forward_path(), the
forward path is filled, ending with mediatek wlan1.
Because DEV_PATH_MTK_WDMA is unknown inside nft_dev_path_info() it returns
with info.indev = NULL. Then nft_dev_forward_path() returns without
setting the direct transmit parameters.
This results in a neighbor transmit, and direct transmit not possible.
But we want to use it for flow between bridged interfaces.
So this patch adds DEV_PATH_MTK_WDMA to nft_dev_path_info() and makes
direct transmission possible.
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
net/netfilter/nft_flow_offload.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 221d50223018..d84e677384da 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -106,6 +106,7 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
switch (path->type) {
case DEV_PATH_ETHERNET:
case DEV_PATH_DSA:
+ case DEV_PATH_MTK_WDMA:
case DEV_PATH_VLAN:
case DEV_PATH_PPPOE:
info->indev = path->dev;
@@ -118,6 +119,10 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
i = stack->num_paths;
break;
}
+ if (path->type == DEV_PATH_MTK_WDMA) {
+ i = stack->num_paths;
+ break;
+ }
/* DEV_PATH_VLAN and DEV_PATH_PPPOE */
if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
--
2.47.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v11 nf-next 2/3] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign
2025-04-08 14:27 [PATCH v11 nf-next 0/3] netfilter: fastpath fixes Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 1/3] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
@ 2025-04-08 14:27 ` Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 3/3] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW Eric Woudstra
2 siblings, 0 replies; 4+ messages in thread
From: Eric Woudstra @ 2025-04-08 14:27 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Jiri Pirko, Ivan Vecera,
Nikolay Aleksandrov, Ido Schimmel, Pablo Neira Ayuso,
Jozsef Kadlecsik, Matthias Brugger, AngeloGioacchino Del Regno
Cc: netdev, bridge, netfilter-devel, linux-mediatek, Eric Woudstra
In network setup as below:
fastpath bypass
.----------------------------------------.
/ \
| IP - forwarding |
| / \ v
| / wan ...
| /
| |
| |
| brlan.1
| |
| +-------------------------------+
| | vlan 1 |
| | |
| | brlan (vlan-filtering) |
| | +---------------+
| | | DSA-SWITCH |
| | vlan 1 | |
| | to | |
| | untagged 1 vlan 1 |
| +---------------+---------------+
. / \
----->wlan1 lan0
. .
. ^
^ vlan 1 tagged packets
untagged packets
br_vlan_fill_forward_path_mode() sets DEV_PATH_BR_VLAN_UNTAG_HW when
filling in from brlan.1 towards wlan1. But it should be set to
DEV_PATH_BR_VLAN_UNTAG in this case. Using BR_VLFLAG_ADDED_BY_SWITCHDEV
is not correct. The dsa switchdev adds it as a foreign port.
The same problem for all foreignly added dsa vlans on the bridge.
First add the vlan, trying only native devices.
If this fails, we know this may be a vlan from a foreign device.
Use BR_VLFLAG_TAGGING_BY_SWITCHDEV to make sure DEV_PATH_BR_VLAN_UNTAG_HW
is set only when there if no foreign device involved.
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
include/net/switchdev.h | 1 +
net/bridge/br_private.h | 10 ++++++++++
net/bridge/br_switchdev.c | 15 +++++++++++++++
net/bridge/br_vlan.c | 7 ++++++-
net/switchdev/switchdev.c | 2 +-
5 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 8346b0d29542..ee500706496b 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -15,6 +15,7 @@
#define SWITCHDEV_F_NO_RECURSE BIT(0)
#define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1)
#define SWITCHDEV_F_DEFER BIT(2)
+#define SWITCHDEV_F_NO_FOREIGN BIT(3)
enum switchdev_attr_id {
SWITCHDEV_ATTR_ID_UNDEFINED,
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d5b3c5936a79..c3395320a4f3 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -180,6 +180,7 @@ enum {
BR_VLFLAG_MCAST_ENABLED = BIT(2),
BR_VLFLAG_GLOBAL_MCAST_ENABLED = BIT(3),
BR_VLFLAG_NEIGH_SUPPRESS_ENABLED = BIT(4),
+ BR_VLFLAG_TAGGING_BY_SWITCHDEV = BIT(5),
};
/**
@@ -2181,6 +2182,8 @@ void br_switchdev_mdb_notify(struct net_device *dev,
int type);
int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
bool changed, struct netlink_ext_ack *extack);
+int br_switchdev_port_vlan_no_foreign_add(struct net_device *dev, u16 vid, u16 flags,
+ bool changed, struct netlink_ext_ack *extack);
int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
void br_switchdev_init(struct net_bridge *br);
@@ -2264,6 +2267,13 @@ static inline int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid,
return -EOPNOTSUPP;
}
+static inline int br_switchdev_port_vlan_no_foreign_add(struct net_device *dev, u16 vid,
+ u16 flags, bool changed,
+ struct netlink_ext_ack *extack)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
{
return -EOPNOTSUPP;
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index 7b41ee8740cb..efa7a055b8f9 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -187,6 +187,21 @@ int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
return switchdev_port_obj_add(dev, &v.obj, extack);
}
+int br_switchdev_port_vlan_no_foreign_add(struct net_device *dev, u16 vid, u16 flags,
+ bool changed, struct netlink_ext_ack *extack)
+{
+ struct switchdev_obj_port_vlan v = {
+ .obj.orig_dev = dev,
+ .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
+ .obj.flags = SWITCHDEV_F_NO_FOREIGN,
+ .flags = flags,
+ .vid = vid,
+ .changed = changed,
+ };
+
+ return switchdev_port_obj_add(dev, &v.obj, extack);
+}
+
int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
{
struct switchdev_obj_port_vlan v = {
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index d9a69ec9affe..6bfc7da10865 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -109,6 +109,11 @@ static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
/* Try switchdev op first. In case it is not supported, fallback to
* 8021q add.
*/
+ err = br_switchdev_port_vlan_no_foreign_add(dev, v->vid, flags, false, extack);
+ if (err != -EOPNOTSUPP) {
+ v->priv_flags |= BR_VLFLAG_ADDED_BY_SWITCHDEV | BR_VLFLAG_TAGGING_BY_SWITCHDEV;
+ return err;
+ }
err = br_switchdev_port_vlan_add(dev, v->vid, flags, false, extack);
if (err == -EOPNOTSUPP)
return vlan_vid_add(dev, br->vlan_proto, v->vid);
@@ -1487,7 +1492,7 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
- else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
+ else if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
else
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 4d5fbacef496..bf252d116ed3 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -760,7 +760,7 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev,
/* Event is neither on a bridge nor a LAG. Check whether it is on an
* interface that is in a bridge with us.
*/
- if (!foreign_dev_check_cb)
+ if (!foreign_dev_check_cb || port_obj_info->obj->flags & SWITCHDEV_F_NO_FOREIGN)
return err;
br = netdev_master_upper_dev_get(dev);
--
2.47.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v11 nf-next 3/3] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW
2025-04-08 14:27 [PATCH v11 nf-next 0/3] netfilter: fastpath fixes Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 1/3] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 2/3] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign Eric Woudstra
@ 2025-04-08 14:27 ` Eric Woudstra
2 siblings, 0 replies; 4+ messages in thread
From: Eric Woudstra @ 2025-04-08 14:27 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Jiri Pirko, Ivan Vecera,
Nikolay Aleksandrov, Ido Schimmel, Pablo Neira Ayuso,
Jozsef Kadlecsik, Matthias Brugger, AngeloGioacchino Del Regno
Cc: netdev, bridge, netfilter-devel, linux-mediatek, Eric Woudstra
Following the path through a bridge, there are 2 situations where the
action is to keep:
1. Packets have the encap, and keep the tag at ingress and keep it at
egress. It is typical in the forward path, when a vlan-device and
bridge are combined.
2. Packets do not have the encap, are tagged at ingress and untagged
at egress. Can be found when only a bridge is in the forward path.
It is also possible in the bridged path.
For switchdev userports that support SWITCHDEV_OBJ_ID_PORT_VLAN in
sitaution 2, it is necessary to introduce DEV_PATH_BR_VLAN_KEEP_HW.
The typical situation 1 is unchanged: DEV_PATH_BR_VLAN_KEEP.
DEV_PATH_BR_VLAN_KEEP_HW is similar to DEV_PATH_BR_VLAN_TAG, with the
correcponding bit in ingress_vlans set.
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
include/linux/netdevice.h | 1 +
net/bridge/br_device.c | 1 +
net/bridge/br_vlan.c | 18 +++++++++++-------
net/netfilter/nft_flow_offload.c | 3 +++
4 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cf3b6445817b..4e8eaae8c441 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -887,6 +887,7 @@ struct net_device_path {
DEV_PATH_BR_VLAN_TAG,
DEV_PATH_BR_VLAN_UNTAG,
DEV_PATH_BR_VLAN_UNTAG_HW,
+ DEV_PATH_BR_VLAN_KEEP_HW,
} vlan_mode;
u16 vlan_id;
__be16 vlan_proto;
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index a818fdc22da9..80b75c2e229b 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -423,6 +423,7 @@ static int br_fill_forward_path(struct net_device_path_ctx *ctx,
case DEV_PATH_BR_VLAN_UNTAG:
ctx->num_vlans--;
break;
+ case DEV_PATH_BR_VLAN_KEEP_HW:
case DEV_PATH_BR_VLAN_KEEP:
break;
}
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 6bfc7da10865..0f714df92118 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1490,13 +1490,17 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED))
return 0;
- if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
- path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
- else if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
- path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
- else
- path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
-
+ if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) {
+ if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
+ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP_HW;
+ else
+ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
+ } else {
+ if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
+ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
+ else
+ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
+ }
return 0;
}
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index d84e677384da..fdf927a8252d 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -145,6 +145,9 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
case DEV_PATH_BR_VLAN_UNTAG_HW:
info->ingress_vlans |= BIT(info->num_encaps - 1);
break;
+ case DEV_PATH_BR_VLAN_KEEP_HW:
+ info->ingress_vlans |= BIT(info->num_encaps);
+ fallthrough;
case DEV_PATH_BR_VLAN_TAG:
info->encap[info->num_encaps].id = path->bridge.vlan_id;
info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
--
2.47.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-04-08 14:27 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-08 14:27 [PATCH v11 nf-next 0/3] netfilter: fastpath fixes Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 1/3] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 2/3] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign Eric Woudstra
2025-04-08 14:27 ` [PATCH v11 nf-next 3/3] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW Eric Woudstra
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).