linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 nf 00/15] bridge-fastpath and related improvements
@ 2025-03-05 10:29 Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 01/15] net: pppoe: avoid zero-length arrays in struct pppoe_hdr Eric Woudstra
                   ` (15 more replies)
  0 siblings, 16 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

This patchset makes it possible to set up a software fastpath between
bridged interfaces. One patch adds the flow rule for the hardware
fastpath. This creates the possibility to have a hardware offloaded
fastpath between bridged interfaces. More patches are added to solve
issues found with the existing code.

To set up the fastpath with offloading, add this extra flowtable:

table bridge filter {
        flowtable fb {
                hook ingress priority filter
                devices = { lan0, lan1, lan2, lan3, lan4, wlan0, wlan1 }
                flags offload
        }
        chain forward {
                type filter hook forward priority filter; policy accept;
		ct state established flow add @fb
        }
}

Creating a separate fastpath for bridges.

         forward fastpath bypass
 .----------------------------------------.
/                                          \
|                        IP - forwarding    |
|                       /                \  v
|                      /                  wan ...
|                     /
|                     |
|                     |
|                   brlan.1
|                     |
|    +-------------------------------+
|    |           vlan 1              |
|    |                               |
|    |     brlan (vlan-filtering)    |
|    +---------------+               |
|    |  DSA-SWITCH   |               |
|    |               |    vlan 1     |
|    |               |      to       |
|    |   vlan 1      |   untagged    |
|    +---------------+---------------+
.         /                   \
 ------>lan0                 wlan1
        .  ^                 ^
        .  |                 |
        .  \_________________/
        .  bridge fastpath bypass
        .
        ^
     vlan 1 tagged packets

To have the ability to handle xmit direct with outgoing encaps in the
bridge fastpass bypass, we need to be able to handle them without going
through vlan/pppoe devices. So I've applied, amended and squashed wenxu's
patchset. This patch also makes it possible to egress from vlan-filtering
brlan to lan0 with vlan tagged packets, if the bridge master port is doing
the vlan tagging, instead of the vlan-device. Without this patch, this is
not possible in the bridge-fastpath and also not in the forward-fastpath,
as seen in the figure above.

There are also some more fixes for filling in the forward path. These
fixes also apply to for the forward-fastpath. They include handling
DEV_PATH_MTK_WDMA in nft_dev_path_info(). There are now 2 patches for
avoiding ingress_vlans bit set for bridged dsa user ports and foreign
(dsa) ports.

Another patch introduces DEV_PATH_BR_VLAN_KEEP_HW, needed for the
bridge-fastpath only.

Conntrack bridge only tracks untagged and 802.1q. To make the bridge
fastpath experience more similar to the forward fastpath experience,
I've added double vlan, pppoe and pppoe-in-q tagged packets to bridge
conntrack and to bridge filter chain.

Note: While testing direct transmit in the software forward-fastpath,
without the capability of setting the offload flag, it is sometimes useful
to enslave the wan interface to another bridge, brwan. This will make
sure both directions of the software forward-fastpath use direct transmit,
which also happens when the offload flag is set.

I have send RFC v2 as I previously only owned a dsa device. I now have
obtained a switchdev supporting SWITCHDEV_OBJ_ID_PORT_VLAN, and found
there was more to do to handle the ingress_vlans bit and corresponding
vlan encap.

I send v4 and above as non-RFC as the previous 2 RFC's did not get any
comment.

Changes in v9:
- No changes, resend to netfilter

Changes in v8:
- Added commit on top: Avoid zero-length arrays in struct pppoe_hdr.

Changes in v7:
- Inside br_vlan_fill_forward_path_pvid(), replaced usage of
   br_vlan_group() with br_vlan_group_rcu() and
   nbp_vlan_group() with nbp_vlan_group_rcu().

Changes in v6:
- Conntrack double vlan and pppoe patch: Set ph and vhdr after the calls
   to pskb_may_pull().

Changes in v5:
- Conntrack double vlan and pppoe patch: Moved pskb_may_pull() up to the
   first switch statement, to the start of the cases. Removed the second
   switch statement. Replaced 0xffffffff with U32_MAX.
- Added patch removing hw_outdev, out.hw_ifindex and out.hw_ifidx members.
- Fix error path returned from nft_flow_offload_bridge_init().
- Cosmetics.

Changes in v4:
- Added !CONFIG_NET_SWITCHDEV version of
   br_switchdev_port_vlan_no_foreign_add().

Changes in v3:
- Squashed the two 'port to port' patches to avoid build errors when only
   one of the two commits is applied.

Changes in v2:
- Introduce DEV_PATH_BR_VLAN_KEEP_HW for use in the bridge-fastpath only.
   It is needed for switchdevs supporting SWITCHDEV_OBJ_ID_PORT_VLAN.
- Different approach for handling BR_VLFLAG_ADDED_BY_SWITCHDEV in
   br_vlan_fill_forward_path_mode() for foreign devices. Introduce
   SWITCHDEV_F_NO_FOREIGN, BR_VLFLAG_TAGGING_BY_SWITCHDEV and
   br_switchdev_port_vlan_no_foreign_add(). The latter function can be
   used to make sure the vlan was added to a switchdev native device.
   When that fails, adding the vlan with br_switchdev_port_vlan_add()
   means it was added to a switchdev foreign device.
- Clear ingress_vlans bit and corresponding encap for dsa user ports.
- Add check for ingress_vlans bit to nft_dev_fill_bridge_path().
- Adapted cover letter description to make clear the patches apply
   to software fastpath, making hardware-offloaded fastpath possible.
- Fixed clang error for vlan_hdr * and struct ppp_hdr * by adding block.
- Updated !CONFIG_BRIDGE_VLAN_FILTERING version of
   br_vlan_fill_forward_path_pvid().
- Removed erroneous check netif_is_bridge_master(ctx->dev) from
   dev_fill_bridge_path().
- Cosmetic changes.

Eric Woudstra (15):
  net: pppoe: avoid zero-length arrays in struct pppoe_hdr
  netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit
    direct
  netfilter: flow: remove hw_outdev, out.hw_ifindex and out.hw_ifidx
  netfilter: bridge: Add conntrack double vlan and pppoe
  netfilter: nft_chain_filter: Add bridge double vlan and pppoe
  bridge: Add filling forward path from port to port
  net: core: dev: Add dev_fill_bridge_path()
  netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge()
  netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge
  netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate
  netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to
    nft_dev_path_info()
  netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user
    port
  bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign
  bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath
  netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval()

 drivers/net/ppp/pppoe.c                    |   2 +-
 include/linux/netdevice.h                  |   3 +
 include/net/netfilter/nf_flow_table.h      |   5 +-
 include/net/switchdev.h                    |   1 +
 include/uapi/linux/if_pppox.h              |   4 +
 net/bridge/br_device.c                     |  23 ++-
 net/bridge/br_private.h                    |  12 ++
 net/bridge/br_switchdev.c                  |  15 ++
 net/bridge/br_vlan.c                       |  29 +++-
 net/bridge/netfilter/nf_conntrack_bridge.c |  83 ++++++++--
 net/core/dev.c                             |  66 ++++++--
 net/netfilter/nf_flow_table_core.c         |   1 -
 net/netfilter/nf_flow_table_inet.c         |  13 ++
 net/netfilter/nf_flow_table_ip.c           |  96 +++++++++++-
 net/netfilter/nf_flow_table_offload.c      |  15 +-
 net/netfilter/nft_chain_filter.c           |  20 ++-
 net/netfilter/nft_flow_offload.c           | 168 +++++++++++++++++++--
 net/switchdev/switchdev.c                  |   2 +-
 18 files changed, 497 insertions(+), 61 deletions(-)

-- 
2.47.1



^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 01/15] net: pppoe: avoid zero-length arrays in struct pppoe_hdr
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 02/15] netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit direct Eric Woudstra
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

Jakub Kicinski suggested following patch:

W=1 C=1 GCC build gives us:

net/bridge/netfilter/nf_conntrack_bridge.c: note: in included file (through
../include/linux/if_pppox.h, ../include/uapi/linux/netfilter_bridge.h,
../include/linux/netfilter_bridge.h): include/uapi/linux/if_pppox.h:
153:29: warning: array of flexible structures

It doesn't like that hdr has a zero-length array which overlaps proto.
The kernel code doesn't currently need those arrays.

PPPoE connection is functional after applying this patch.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 drivers/net/ppp/pppoe.c       | 2 +-
 include/uapi/linux/if_pppox.h | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 68e631718ab0..17946af6a8cf 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -882,7 +882,7 @@ static int pppoe_sendmsg(struct socket *sock, struct msghdr *m,
 	skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
 
 	ph = skb_put(skb, total_len + sizeof(struct pppoe_hdr));
-	start = (char *)&ph->tag[0];
+	start = (char *)ph + sizeof(*ph);
 
 	error = memcpy_from_msg(start, m, total_len);
 	if (error < 0) {
diff --git a/include/uapi/linux/if_pppox.h b/include/uapi/linux/if_pppox.h
index 9abd80dcc46f..29b804aa7474 100644
--- a/include/uapi/linux/if_pppox.h
+++ b/include/uapi/linux/if_pppox.h
@@ -122,7 +122,9 @@ struct sockaddr_pppol2tpv3in6 {
 struct pppoe_tag {
 	__be16 tag_type;
 	__be16 tag_len;
+#ifndef __KERNEL__
 	char tag_data[];
+#endif
 } __attribute__ ((packed));
 
 /* Tag identifiers */
@@ -150,7 +152,9 @@ struct pppoe_hdr {
 	__u8 code;
 	__be16 sid;
 	__be16 length;
+#ifndef __KERNEL__
 	struct pppoe_tag tag[];
+#endif
 } __packed;
 
 /* Length of entire PPPoE + PPP header */
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 02/15] netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit direct
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 01/15] net: pppoe: avoid zero-length arrays in struct pppoe_hdr Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 03/15] netfilter: flow: remove hw_outdev, out.hw_ifindex and out.hw_ifidx Eric Woudstra
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

Loosely based on wenxu's patches:

"nf_flow_table_offload: offload the vlan/PPPoE encap in the flowtable".

Fixed double vlan and pppoe packets, almost entirely rewriting the patch.

After this patch, it is possible to transmit packets in the fastpath with
outgoing encaps, without using vlan- and/or pppoe-devices.

This makes it possible to use more different kinds of network setups.
For example, when bridge tagging is used to egress vlan tagged
packets using the forward fastpath. Another example is passing 802.1q
tagged packets through a bridge using the bridge fastpath.

This also makes the software fastpath process more similar to the
hardware offloaded fastpath process, where encaps are also pushed.

After applying this patch, always info->outdev = info->hw_outdev,
so the netfilter code can be further cleaned up by removing:
 * hw_outdev from struct nft_forward_info
 * out.hw_ifindex from struct nf_flow_route
 * out.hw_ifidx from struct flow_offload_tuple

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/netfilter/nf_flow_table_ip.c | 96 +++++++++++++++++++++++++++++++-
 net/netfilter/nft_flow_offload.c |  6 +-
 2 files changed, 96 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index 8cd4cf7ae211..d0c3c459c4d2 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -306,6 +306,92 @@ static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
 	return false;
 }
 
+static int nf_flow_vlan_inner_push(struct sk_buff *skb, __be16 proto, u16 id)
+{
+	struct vlan_hdr *vhdr;
+
+	if (skb_cow_head(skb, VLAN_HLEN))
+		return -1;
+
+	__skb_push(skb, VLAN_HLEN);
+	skb_reset_network_header(skb);
+
+	vhdr = (struct vlan_hdr *)(skb->data);
+	vhdr->h_vlan_TCI = htons(id);
+	vhdr->h_vlan_encapsulated_proto = skb->protocol;
+	skb->protocol = proto;
+
+	return 0;
+}
+
+static int nf_flow_ppoe_push(struct sk_buff *skb, u16 id)
+{
+	struct ppp_hdr {
+		struct pppoe_hdr hdr;
+		__be16 proto;
+	} *ph;
+	int data_len = skb->len + 2;
+	__be16 proto;
+
+	if (skb_cow_head(skb, PPPOE_SES_HLEN))
+		return -1;
+
+	if (skb->protocol == htons(ETH_P_IP))
+		proto = htons(PPP_IP);
+	else if (skb->protocol == htons(ETH_P_IPV6))
+		proto = htons(PPP_IPV6);
+	else
+		return -1;
+
+	__skb_push(skb, PPPOE_SES_HLEN);
+	skb_reset_network_header(skb);
+
+	ph = (struct ppp_hdr *)(skb->data);
+	ph->hdr.ver  = 1;
+	ph->hdr.type = 1;
+	ph->hdr.code = 0;
+	ph->hdr.sid  = htons(id);
+	ph->hdr.length = htons(data_len);
+	ph->proto = proto;
+	skb->protocol = htons(ETH_P_PPP_SES);
+
+	return 0;
+}
+
+static int nf_flow_encap_push(struct sk_buff *skb,
+			      struct flow_offload_tuple_rhash *tuplehash,
+			      unsigned short *type)
+{
+	int i = 0, ret = 0;
+
+	if (!tuplehash->tuple.encap_num)
+		return 0;
+
+	if (tuplehash->tuple.encap[i].proto == htons(ETH_P_8021Q) ||
+	    tuplehash->tuple.encap[i].proto == htons(ETH_P_8021AD)) {
+		__vlan_hwaccel_put_tag(skb, tuplehash->tuple.encap[i].proto,
+				       tuplehash->tuple.encap[i].id);
+		i++;
+		if (i >= tuplehash->tuple.encap_num)
+			return 0;
+	}
+
+	switch (tuplehash->tuple.encap[i].proto) {
+	case htons(ETH_P_8021Q):
+		*type = ETH_P_8021Q;
+		ret = nf_flow_vlan_inner_push(skb,
+					      tuplehash->tuple.encap[i].proto,
+					      tuplehash->tuple.encap[i].id);
+		break;
+	case htons(ETH_P_PPP_SES):
+		*type = ETH_P_PPP_SES;
+		ret = nf_flow_ppoe_push(skb,
+					tuplehash->tuple.encap[i].id);
+		break;
+	}
+	return ret;
+}
+
 static void nf_flow_encap_pop(struct sk_buff *skb,
 			      struct flow_offload_tuple_rhash *tuplehash)
 {
@@ -335,6 +421,7 @@ static void nf_flow_encap_pop(struct sk_buff *skb,
 
 static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb,
 				       const struct flow_offload_tuple_rhash *tuplehash,
+				       struct flow_offload_tuple_rhash *other_tuplehash,
 				       unsigned short type)
 {
 	struct net_device *outdev;
@@ -343,6 +430,9 @@ static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb,
 	if (!outdev)
 		return NF_DROP;
 
+	if (nf_flow_encap_push(skb, other_tuplehash, &type) < 0)
+		return NF_DROP;
+
 	skb->dev = outdev;
 	dev_hard_header(skb, skb->dev, type, tuplehash->tuple.out.h_dest,
 			tuplehash->tuple.out.h_source, skb->len);
@@ -462,7 +552,8 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 		ret = NF_STOLEN;
 		break;
 	case FLOW_OFFLOAD_XMIT_DIRECT:
-		ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IP);
+		ret = nf_flow_queue_xmit(state->net, skb, tuplehash,
+					 &flow->tuplehash[!dir], ETH_P_IP);
 		if (ret == NF_DROP)
 			flow_offload_teardown(flow);
 		break;
@@ -757,7 +848,8 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
 		ret = NF_STOLEN;
 		break;
 	case FLOW_OFFLOAD_XMIT_DIRECT:
-		ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IPV6);
+		ret = nf_flow_queue_xmit(state->net, skb, tuplehash,
+					 &flow->tuplehash[!dir], ETH_P_IPV6);
 		if (ret == NF_DROP)
 			flow_offload_teardown(flow);
 		break;
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 46a6d280b09c..b4baee519e18 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -124,13 +124,12 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 				info->indev = NULL;
 				break;
 			}
-			if (!info->outdev)
-				info->outdev = path->dev;
 			info->encap[info->num_encaps].id = path->encap.id;
 			info->encap[info->num_encaps].proto = path->encap.proto;
 			info->num_encaps++;
 			if (path->type == DEV_PATH_PPPOE)
 				memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
+			info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 			break;
 		case DEV_PATH_BRIDGE:
 			if (is_zero_ether_addr(info->h_source))
@@ -158,8 +157,7 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 			break;
 		}
 	}
-	if (!info->outdev)
-		info->outdev = info->indev;
+	info->outdev = info->indev;
 
 	info->hw_outdev = info->indev;
 
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 03/15] netfilter: flow: remove hw_outdev, out.hw_ifindex and out.hw_ifidx
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 01/15] net: pppoe: avoid zero-length arrays in struct pppoe_hdr Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 02/15] netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit direct Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 04/15] netfilter: bridge: Add conntrack double vlan and pppoe Eric Woudstra
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

Now always info->outdev == info->hw_outdev, so the netfilter code can be
further cleaned up by removing:
 * hw_outdev from struct nft_forward_info
 * out.hw_ifindex from struct nf_flow_route
 * out.hw_ifidx from struct flow_offload_tuple

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 include/net/netfilter/nf_flow_table.h | 2 --
 net/netfilter/nf_flow_table_core.c    | 1 -
 net/netfilter/nf_flow_table_offload.c | 2 +-
 net/netfilter/nft_flow_offload.c      | 4 ----
 4 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index d711642e78b5..4ab32fb61865 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -145,7 +145,6 @@ struct flow_offload_tuple {
 		};
 		struct {
 			u32		ifidx;
-			u32		hw_ifidx;
 			u8		h_source[ETH_ALEN];
 			u8		h_dest[ETH_ALEN];
 		} out;
@@ -211,7 +210,6 @@ struct nf_flow_route {
 		} in;
 		struct {
 			u32			ifindex;
-			u32			hw_ifindex;
 			u8			h_source[ETH_ALEN];
 			u8			h_dest[ETH_ALEN];
 		} out;
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index 9d8361526f82..1e5d3735c028 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -127,7 +127,6 @@ static int flow_offload_fill_route(struct flow_offload *flow,
 		memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source,
 		       ETH_ALEN);
 		flow_tuple->out.ifidx = route->tuple[dir].out.ifindex;
-		flow_tuple->out.hw_ifidx = route->tuple[dir].out.hw_ifindex;
 		dst_release(dst);
 		break;
 	case FLOW_OFFLOAD_XMIT_XFRM:
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index e06bc36f49fe..d8f7bfd60ac6 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -555,7 +555,7 @@ static void flow_offload_redirect(struct net *net,
 	switch (this_tuple->xmit_type) {
 	case FLOW_OFFLOAD_XMIT_DIRECT:
 		this_tuple = &flow->tuplehash[dir].tuple;
-		ifindex = this_tuple->out.hw_ifidx;
+		ifindex = this_tuple->out.ifidx;
 		break;
 	case FLOW_OFFLOAD_XMIT_NEIGH:
 		other_tuple = &flow->tuplehash[!dir].tuple;
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index b4baee519e18..5ef2f4ba7ab8 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -80,7 +80,6 @@ static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
 struct nft_forward_info {
 	const struct net_device *indev;
 	const struct net_device *outdev;
-	const struct net_device *hw_outdev;
 	struct id {
 		__u16	id;
 		__be16	proto;
@@ -159,8 +158,6 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 	}
 	info->outdev = info->indev;
 
-	info->hw_outdev = info->indev;
-
 	if (nf_flowtable_hw_offload(flowtable) &&
 	    nft_is_valid_ether_device(info->indev))
 		info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
@@ -212,7 +209,6 @@ static void nft_dev_forward_path(struct nf_flow_route *route,
 		memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
 		memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
 		route->tuple[dir].out.ifindex = info.outdev->ifindex;
-		route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
 		route->tuple[dir].xmit_type = info.xmit_type;
 	}
 }
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 04/15] netfilter: bridge: Add conntrack double vlan and pppoe
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (2 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 03/15] netfilter: flow: remove hw_outdev, out.hw_ifindex and out.hw_ifidx Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 05/15] netfilter: nft_chain_filter: Add bridge " Eric Woudstra
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

This adds the capability to conntrack 802.1ad, QinQ, PPPoE and PPPoE-in-Q
packets that are passing a bridge.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/bridge/netfilter/nf_conntrack_bridge.c | 83 ++++++++++++++++++----
 1 file changed, 71 insertions(+), 12 deletions(-)

diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c
index 816bb0fde718..4b4e3751fb13 100644
--- a/net/bridge/netfilter/nf_conntrack_bridge.c
+++ b/net/bridge/netfilter/nf_conntrack_bridge.c
@@ -242,53 +242,112 @@ static unsigned int nf_ct_bridge_pre(void *priv, struct sk_buff *skb,
 {
 	struct nf_hook_state bridge_state = *state;
 	enum ip_conntrack_info ctinfo;
+	int ret, offset = 0;
 	struct nf_conn *ct;
-	u32 len;
-	int ret;
+	__be16 outer_proto;
+	u32 len, data_len;
 
 	ct = nf_ct_get(skb, &ctinfo);
 	if ((ct && !nf_ct_is_template(ct)) ||
 	    ctinfo == IP_CT_UNTRACKED)
 		return NF_ACCEPT;
 
+	switch (skb->protocol) {
+	case htons(ETH_P_PPP_SES): {
+		struct ppp_hdr {
+			struct pppoe_hdr hdr;
+			__be16 proto;
+		} *ph;
+
+		offset = PPPOE_SES_HLEN;
+		if (!pskb_may_pull(skb, offset))
+			return NF_ACCEPT;
+		outer_proto = skb->protocol;
+		ph = (struct ppp_hdr *)(skb->data);
+		switch (ph->proto) {
+		case htons(PPP_IP):
+			skb->protocol = htons(ETH_P_IP);
+			break;
+		case htons(PPP_IPV6):
+			skb->protocol = htons(ETH_P_IPV6);
+			break;
+		default:
+			nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
+			return NF_ACCEPT;
+		}
+		data_len = ntohs(ph->hdr.length) - 2;
+		skb_pull_rcsum(skb, offset);
+		skb_reset_network_header(skb);
+		break;
+	}
+	case htons(ETH_P_8021Q): {
+		struct vlan_hdr *vhdr;
+
+		offset = VLAN_HLEN;
+		if (!pskb_may_pull(skb, offset))
+			return NF_ACCEPT;
+		outer_proto = skb->protocol;
+		vhdr = (struct vlan_hdr *)(skb->data);
+		skb->protocol = vhdr->h_vlan_encapsulated_proto;
+		data_len = U32_MAX;
+		skb_pull_rcsum(skb, offset);
+		skb_reset_network_header(skb);
+		break;
+	}
+	default:
+		data_len = U32_MAX;
+		break;
+	}
+
+	ret = NF_ACCEPT;
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
 		if (!pskb_may_pull(skb, sizeof(struct iphdr)))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		len = skb_ip_totlen(skb);
+		if (data_len < len)
+			len = data_len;
 		if (pskb_trim_rcsum(skb, len))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		if (nf_ct_br_ip_check(skb))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		bridge_state.pf = NFPROTO_IPV4;
 		ret = nf_ct_br_defrag4(skb, &bridge_state);
 		break;
 	case htons(ETH_P_IPV6):
 		if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len);
+		if (data_len < len)
+			len = data_len;
 		if (pskb_trim_rcsum(skb, len))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		if (nf_ct_br_ipv6_check(skb))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		bridge_state.pf = NFPROTO_IPV6;
 		ret = nf_ct_br_defrag6(skb, &bridge_state);
 		break;
 	default:
 		nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
-		return NF_ACCEPT;
+		goto do_not_track;
 	}
 
-	if (ret != NF_ACCEPT)
-		return ret;
+	if (ret == NF_ACCEPT)
+		ret = nf_conntrack_in(skb, &bridge_state);
 
-	return nf_conntrack_in(skb, &bridge_state);
+do_not_track:
+	if (offset) {
+		skb_push_rcsum(skb, offset);
+		skb_reset_network_header(skb);
+		skb->protocol = outer_proto;
+	}
+	return ret;
 }
 
 static unsigned int nf_ct_bridge_in(void *priv, struct sk_buff *skb,
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 05/15] netfilter: nft_chain_filter: Add bridge double vlan and pppoe
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (3 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 04/15] netfilter: bridge: Add conntrack double vlan and pppoe Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 06/15] bridge: Add filling forward path from port to port Eric Woudstra
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

This adds the capability to evaluate 802.1ad, QinQ, PPPoE and PPPoE-in-Q
packets in the bridge filter chain.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/netfilter/nft_chain_filter.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index 19a553550c76..7c7080c1a67d 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -232,11 +232,27 @@ nft_do_chain_bridge(void *priv,
 		    struct sk_buff *skb,
 		    const struct nf_hook_state *state)
 {
+	struct ethhdr *ethh = eth_hdr(skb);
 	struct nft_pktinfo pkt;
+	int thoff;
 
 	nft_set_pktinfo(&pkt, skb, state);
 
-	switch (eth_hdr(skb)->h_proto) {
+	switch (ethh->h_proto) {
+	case htons(ETH_P_PPP_SES):
+		thoff = PPPOE_SES_HLEN;
+		ethh += thoff;
+		break;
+	case htons(ETH_P_8021Q):
+		thoff = VLAN_HLEN;
+		ethh += thoff;
+		break;
+	default:
+		thoff = 0;
+		break;
+	}
+
+	switch (ethh->h_proto) {
 	case htons(ETH_P_IP):
 		nft_set_pktinfo_ipv4_validate(&pkt);
 		break;
@@ -248,6 +264,8 @@ nft_do_chain_bridge(void *priv,
 		break;
 	}
 
+	pkt.thoff += thoff;
+
 	return nft_do_chain(&pkt, priv);
 }
 
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 06/15] bridge: Add filling forward path from port to port
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (4 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 05/15] netfilter: nft_chain_filter: Add bridge " Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 07/15] net: core: dev: Add dev_fill_bridge_path() Eric Woudstra
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

If a port is passed as argument instead of the master, then:

At br_fill_forward_path(): find the master and use it to fill the
forward path.

At br_vlan_fill_forward_path_pvid(): lookup vlan group from port
instead.

Changed call to br_vlan_group() into br_vlan_group_rcu() while at it.

Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/bridge/br_device.c  | 19 ++++++++++++++-----
 net/bridge/br_private.h |  2 ++
 net/bridge/br_vlan.c    |  6 +++++-
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 9d8c72ed01ab..02eb23e8aab8 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -383,16 +383,25 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
 static int br_fill_forward_path(struct net_device_path_ctx *ctx,
 				struct net_device_path *path)
 {
+	struct net_bridge_port *src, *dst;
 	struct net_bridge_fdb_entry *f;
-	struct net_bridge_port *dst;
 	struct net_bridge *br;
 
-	if (netif_is_bridge_port(ctx->dev))
-		return -1;
+	if (netif_is_bridge_port(ctx->dev)) {
+		struct net_device *br_dev;
+
+		br_dev = netdev_master_upper_dev_get_rcu((struct net_device *)ctx->dev);
+		if (!br_dev)
+			return -1;
 
-	br = netdev_priv(ctx->dev);
+		src = br_port_get_rcu(ctx->dev);
+		br = netdev_priv(br_dev);
+	} else {
+		src = NULL;
+		br = netdev_priv(ctx->dev);
+	}
 
-	br_vlan_fill_forward_path_pvid(br, ctx, path);
+	br_vlan_fill_forward_path_pvid(br, src, ctx, path);
 
 	f = br_fdb_find_rcu(br, ctx->daddr, path->bridge.vlan_id);
 	if (!f)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1054b8a88edc..a0b950390a16 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1584,6 +1584,7 @@ bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
 			     const struct net_bridge_vlan *range_end);
 
 void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
+				    struct net_bridge_port *p,
 				    struct net_device_path_ctx *ctx,
 				    struct net_device_path *path);
 int br_vlan_fill_forward_path_mode(struct net_bridge *br,
@@ -1753,6 +1754,7 @@ static inline int nbp_get_num_vlan_infos(struct net_bridge_port *p,
 }
 
 static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
+						  struct net_bridge_port *p,
 						  struct net_device_path_ctx *ctx,
 						  struct net_device_path *path)
 {
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index d9a69ec9affe..a18c7da12ebd 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1441,6 +1441,7 @@ int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid)
 EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu);
 
 void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
+				    struct net_bridge_port *p,
 				    struct net_device_path_ctx *ctx,
 				    struct net_device_path *path)
 {
@@ -1453,7 +1454,10 @@ void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
 	if (!br_opt_get(br, BROPT_VLAN_ENABLED))
 		return;
 
-	vg = br_vlan_group(br);
+	if (p)
+		vg = nbp_vlan_group_rcu(p);
+	else
+		vg = br_vlan_group_rcu(br);
 
 	if (idx >= 0 &&
 	    ctx->vlan[idx].proto == br->vlan_proto) {
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 07/15] net: core: dev: Add dev_fill_bridge_path()
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (5 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 06/15] bridge: Add filling forward path from port to port Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 08/15] netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge() Eric Woudstra
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

New function dev_fill_bridge_path(), similar to dev_fill_forward_path().
It handles starting from a bridge port instead of the bridge master.
The structures ctx and nft_forward_info need to be already filled in with
the (vlan) encaps.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 include/linux/netdevice.h |  2 ++
 net/core/dev.c            | 66 +++++++++++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7ab86ec228b7..81cdad85d9f1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3318,6 +3318,8 @@ void dev_remove_offload(struct packet_offload *po);
 
 int dev_get_iflink(const struct net_device *dev);
 int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
+int dev_fill_bridge_path(struct net_device_path_ctx *ctx,
+			 struct net_device_path_stack *stack);
 int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
 			  struct net_device_path_stack *stack);
 struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags,
diff --git a/net/core/dev.c b/net/core/dev.c
index 2dc705604509..d0810f052d3a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -714,44 +714,84 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
 	return &stack->path[k];
 }
 
-int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
-			  struct net_device_path_stack *stack)
+static int dev_fill_forward_path_common(struct net_device_path_ctx *ctx,
+					struct net_device_path_stack *stack)
 {
 	const struct net_device *last_dev;
-	struct net_device_path_ctx ctx = {
-		.dev	= dev,
-	};
 	struct net_device_path *path;
 	int ret = 0;
 
-	memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
-	stack->num_paths = 0;
-	while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) {
-		last_dev = ctx.dev;
+	while (ctx->dev && ctx->dev->netdev_ops->ndo_fill_forward_path) {
+		last_dev = ctx->dev;
 		path = dev_fwd_path(stack);
 		if (!path)
 			return -1;
 
 		memset(path, 0, sizeof(struct net_device_path));
-		ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path);
+		ret = ctx->dev->netdev_ops->ndo_fill_forward_path(ctx, path);
 		if (ret < 0)
 			return -1;
 
-		if (WARN_ON_ONCE(last_dev == ctx.dev))
+		if (WARN_ON_ONCE(last_dev == ctx->dev))
 			return -1;
 	}
 
-	if (!ctx.dev)
+	if (!ctx->dev)
 		return ret;
 
 	path = dev_fwd_path(stack);
 	if (!path)
 		return -1;
 	path->type = DEV_PATH_ETHERNET;
-	path->dev = ctx.dev;
+	path->dev = ctx->dev;
 
 	return ret;
 }
+
+int dev_fill_bridge_path(struct net_device_path_ctx *ctx,
+			 struct net_device_path_stack *stack)
+{
+	const struct net_device *last_dev, *br_dev;
+	struct net_device_path *path;
+
+	stack->num_paths = 0;
+
+	if (!ctx->dev || !netif_is_bridge_port(ctx->dev))
+		return -1;
+
+	br_dev = netdev_master_upper_dev_get_rcu((struct net_device *)ctx->dev);
+	if (!br_dev || !br_dev->netdev_ops->ndo_fill_forward_path)
+		return -1;
+
+	last_dev = ctx->dev;
+	path = dev_fwd_path(stack);
+	if (!path)
+		return -1;
+
+	memset(path, 0, sizeof(struct net_device_path));
+	if (br_dev->netdev_ops->ndo_fill_forward_path(ctx, path) < 0)
+		return -1;
+
+	if (!ctx->dev || WARN_ON_ONCE(last_dev == ctx->dev))
+		return -1;
+
+	return dev_fill_forward_path_common(ctx, stack);
+}
+EXPORT_SYMBOL_GPL(dev_fill_bridge_path);
+
+int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
+			  struct net_device_path_stack *stack)
+{
+	struct net_device_path_ctx ctx = {
+		.dev	= dev,
+	};
+
+	memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
+
+	stack->num_paths = 0;
+
+	return dev_fill_forward_path_common(&ctx, stack);
+}
 EXPORT_SYMBOL_GPL(dev_fill_forward_path);
 
 /* must be called under rcu_read_lock(), as we dont take a reference */
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 08/15] netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge()
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (6 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 07/15] net: core: dev: Add dev_fill_bridge_path() Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 09/15] netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge Eric Woudstra
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

Add nf_flow_rule_bridge().

It only calls the common rule and adds the redirect.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 include/net/netfilter/nf_flow_table.h |  3 +++
 net/netfilter/nf_flow_table_offload.c | 13 +++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index 4ab32fb61865..a7f5d6166088 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -340,6 +340,9 @@ void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable);
 int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
 				struct net_device *dev,
 				enum flow_block_command cmd);
+int nf_flow_rule_bridge(struct net *net, struct flow_offload *flow,
+			enum flow_offload_tuple_dir dir,
+			struct nf_flow_rule *flow_rule);
 int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow,
 			    enum flow_offload_tuple_dir dir,
 			    struct nf_flow_rule *flow_rule);
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index d8f7bfd60ac6..3cc30ebfa6ff 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -679,6 +679,19 @@ nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow,
 	return 0;
 }
 
+int nf_flow_rule_bridge(struct net *net, struct flow_offload *flow,
+			enum flow_offload_tuple_dir dir,
+			struct nf_flow_rule *flow_rule)
+{
+	if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0)
+		return -1;
+
+	flow_offload_redirect(net, flow, dir, flow_rule);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nf_flow_rule_bridge);
+
 int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow,
 			    enum flow_offload_tuple_dir dir,
 			    struct nf_flow_rule *flow_rule)
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 09/15] netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (7 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 08/15] netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge() Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 10/15] netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate Eric Woudstra
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

This will allow a flowtable to be added to the nft bridge family.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/netfilter/nf_flow_table_inet.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/net/netfilter/nf_flow_table_inet.c b/net/netfilter/nf_flow_table_inet.c
index b0f199171932..80b238196f29 100644
--- a/net/netfilter/nf_flow_table_inet.c
+++ b/net/netfilter/nf_flow_table_inet.c
@@ -65,6 +65,16 @@ static int nf_flow_rule_route_inet(struct net *net,
 	return err;
 }
 
+static struct nf_flowtable_type flowtable_bridge = {
+	.family		= NFPROTO_BRIDGE,
+	.init		= nf_flow_table_init,
+	.setup		= nf_flow_table_offload_setup,
+	.action		= nf_flow_rule_bridge,
+	.free		= nf_flow_table_free,
+	.hook		= nf_flow_offload_inet_hook,
+	.owner		= THIS_MODULE,
+};
+
 static struct nf_flowtable_type flowtable_inet = {
 	.family		= NFPROTO_INET,
 	.init		= nf_flow_table_init,
@@ -97,6 +107,7 @@ static struct nf_flowtable_type flowtable_ipv6 = {
 
 static int __init nf_flow_inet_module_init(void)
 {
+	nft_register_flowtable_type(&flowtable_bridge);
 	nft_register_flowtable_type(&flowtable_ipv4);
 	nft_register_flowtable_type(&flowtable_ipv6);
 	nft_register_flowtable_type(&flowtable_inet);
@@ -109,6 +120,7 @@ static void __exit nf_flow_inet_module_exit(void)
 	nft_unregister_flowtable_type(&flowtable_inet);
 	nft_unregister_flowtable_type(&flowtable_ipv6);
 	nft_unregister_flowtable_type(&flowtable_ipv4);
+	nft_unregister_flowtable_type(&flowtable_bridge);
 }
 
 module_init(nf_flow_inet_module_init);
@@ -118,5 +130,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
 MODULE_ALIAS_NF_FLOWTABLE(AF_INET);
 MODULE_ALIAS_NF_FLOWTABLE(AF_INET6);
+MODULE_ALIAS_NF_FLOWTABLE(AF_BRIDGE);
 MODULE_ALIAS_NF_FLOWTABLE(1); /* NFPROTO_INET */
 MODULE_DESCRIPTION("Netfilter flow table mixed IPv4/IPv6 module");
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 10/15] netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (8 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 09/15] netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 11/15] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

Need to add NFPROTO_BRIDGE to nft_flow_offload_validate() to support
the bridge-fastpath.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/netfilter/nft_flow_offload.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 5ef2f4ba7ab8..323c531c7046 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -421,7 +421,8 @@ static int nft_flow_offload_validate(const struct nft_ctx *ctx,
 
 	if (ctx->family != NFPROTO_IPV4 &&
 	    ctx->family != NFPROTO_IPV6 &&
-	    ctx->family != NFPROTO_INET)
+	    ctx->family != NFPROTO_INET &&
+	    ctx->family != NFPROTO_BRIDGE)
 		return -EOPNOTSUPP;
 
 	return nft_chain_validate_hooks(ctx->chain, hook_mask);
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 11/15] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info()
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (9 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 10/15] netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 12/15] netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user port Eric Woudstra
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, 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 323c531c7046..b9e6d9e6df66 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -105,6 +105,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;
@@ -117,6 +118,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] 22+ messages in thread

* [PATCH v9 nf 12/15] netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user port
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (10 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 11/15] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 13/15] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign Eric Woudstra
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

The bitfield info->ingress_vlans and corresponding vlan encap are used for
a switchdev user port. However, they should not be set for a dsa user port.

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 b9e6d9e6df66..c95fad495460 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -116,6 +116,11 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 				break;
 			if (path->type == DEV_PATH_DSA) {
 				i = stack->num_paths;
+				if (!info->num_encaps ||
+				    !(info->ingress_vlans & BIT(info->num_encaps - 1)))
+					break;
+				info->num_encaps--;
+				info->ingress_vlans &= ~BIT(info->num_encaps - 1);
 				break;
 			}
 			if (path->type == DEV_PATH_MTK_WDMA) {
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v9 nf 13/15] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (11 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 12/15] netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user port Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 14/15] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath Eric Woudstra
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, 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 a0b950390a16..b950db453d8d 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),
 };
 
 /**
@@ -2184,6 +2185,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);
 
@@ -2267,6 +2270,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 a18c7da12ebd..aea94d401a30 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);
@@ -1491,7 +1496,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 6488ead9e464..c48f66643e99 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -749,7 +749,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] 22+ messages in thread

* [PATCH v9 nf 14/15] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (12 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 13/15] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-05 10:29 ` [PATCH v9 nf 15/15] netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval() Eric Woudstra
  2025-03-11  8:22 ` [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

This patch introduces DEV_PATH_BR_VLAN_KEEP_HW. It is needed in the
bridge fastpath for switchdevs supporting SWITCHDEV_OBJ_ID_PORT_VLAN.

It is similar to DEV_PATH_BR_VLAN_TAG, with the correcponding bit in
ingress_vlans set.

In the forward fastpath it is not needed.

Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 include/linux/netdevice.h        |  1 +
 net/bridge/br_device.c           |  4 ++++
 net/bridge/br_vlan.c             | 18 +++++++++++-------
 net/netfilter/nft_flow_offload.c |  3 +++
 4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 81cdad85d9f1..1e2f519e8802 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 02eb23e8aab8..55c64a1d2758 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -430,6 +430,10 @@ 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:
+		if (!src)
+			path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
+		break;
 	case DEV_PATH_BR_VLAN_KEEP:
 		break;
 	}
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index aea94d401a30..114d47d5f90f 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1494,13 +1494,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 c95fad495460..c0c310c569cd 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -148,6 +148,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] 22+ messages in thread

* [PATCH v9 nf 15/15] netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval()
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (13 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 14/15] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath Eric Woudstra
@ 2025-03-05 10:29 ` Eric Woudstra
  2025-03-11  8:22 ` [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
  15 siblings, 0 replies; 22+ messages in thread
From: Eric Woudstra @ 2025-03-05 10:29 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Jiri Pirko, Ivan Vecera, Roopa Prabhu, Nikolay Aleksandrov,
	Matthias Brugger, AngeloGioacchino Del Regno, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Ahmed Zaki, Alexander Lobakin,
	Vladimir Oltean, Frank Wunderlich, Daniel Golle
  Cc: netdev, linux-kernel, netfilter-devel, coreteam, bridge,
	linux-arm-kernel, linux-mediatek, linux-hardening, Kees Cook,
	Gustavo A. R. Silva, Eric Woudstra

Edit nft_flow_offload_eval() to make it possible to handle a flowtable of
the nft bridge family.

Use nft_flow_offload_bridge_init() to fill the flow tuples. It uses
nft_dev_fill_bridge_path() in each direction.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
 net/netfilter/nft_flow_offload.c | 142 +++++++++++++++++++++++++++++--
 1 file changed, 137 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index c0c310c569cd..03a0b5f7e8d2 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -193,6 +193,128 @@ static bool nft_flowtable_find_dev(const struct net_device *dev,
 	return found;
 }
 
+static int nft_dev_fill_bridge_path(struct flow_offload *flow,
+				    struct nft_flowtable *ft,
+				    enum ip_conntrack_dir dir,
+				    const struct net_device *src_dev,
+				    const struct net_device *dst_dev,
+				    unsigned char *src_ha,
+				    unsigned char *dst_ha)
+{
+	struct flow_offload_tuple_rhash *th = flow->tuplehash;
+	struct net_device_path_ctx ctx = {};
+	struct net_device_path_stack stack;
+	struct nft_forward_info info = {};
+	int i, j = 0;
+
+	for (i = th[dir].tuple.encap_num - 1; i >= 0 ; i--) {
+		if (info.num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
+			return -1;
+
+		if (th[dir].tuple.in_vlan_ingress & BIT(i))
+			continue;
+
+		info.encap[info.num_encaps].id = th[dir].tuple.encap[i].id;
+		info.encap[info.num_encaps].proto = th[dir].tuple.encap[i].proto;
+		info.num_encaps++;
+
+		if (th[dir].tuple.encap[i].proto == htons(ETH_P_PPP_SES))
+			continue;
+
+		if (ctx.num_vlans >= NET_DEVICE_PATH_VLAN_MAX)
+			return -1;
+		ctx.vlan[ctx.num_vlans].id = th[dir].tuple.encap[i].id;
+		ctx.vlan[ctx.num_vlans].proto = th[dir].tuple.encap[i].proto;
+		ctx.num_vlans++;
+	}
+	ctx.dev = src_dev;
+	ether_addr_copy(ctx.daddr, dst_ha);
+
+	if (dev_fill_bridge_path(&ctx, &stack) < 0)
+		return -1;
+
+	nft_dev_path_info(&stack, &info, dst_ha, &ft->data);
+
+	if (!info.indev || info.indev != dst_dev)
+		return -1;
+
+	th[!dir].tuple.iifidx = info.indev->ifindex;
+	for (i = info.num_encaps - 1; i >= 0; i--) {
+		th[!dir].tuple.encap[j].id = info.encap[i].id;
+		th[!dir].tuple.encap[j].proto = info.encap[i].proto;
+		if (info.ingress_vlans & BIT(i))
+			th[!dir].tuple.in_vlan_ingress |= BIT(j);
+		j++;
+	}
+	th[!dir].tuple.encap_num = info.num_encaps;
+
+	th[dir].tuple.mtu = dst_dev->mtu;
+	ether_addr_copy(th[dir].tuple.out.h_source, src_ha);
+	ether_addr_copy(th[dir].tuple.out.h_dest, dst_ha);
+	th[dir].tuple.out.ifidx = info.outdev->ifindex;
+	th[dir].tuple.xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
+
+	return 0;
+}
+
+static int nft_flow_offload_bridge_init(struct flow_offload *flow,
+					const struct nft_pktinfo *pkt,
+					enum ip_conntrack_dir dir,
+					struct nft_flowtable *ft)
+{
+	const struct net_device *in_dev, *out_dev;
+	struct ethhdr *eth = eth_hdr(pkt->skb);
+	struct flow_offload_tuple *tuple;
+	struct pppoe_hdr *phdr;
+	struct vlan_hdr *vhdr;
+	int err, i = 0;
+
+	in_dev = nft_in(pkt);
+	if (!in_dev || !nft_flowtable_find_dev(in_dev, ft))
+		return -1;
+
+	out_dev = nft_out(pkt);
+	if (!out_dev || !nft_flowtable_find_dev(out_dev, ft))
+		return -1;
+
+	tuple =  &flow->tuplehash[!dir].tuple;
+
+	if (skb_vlan_tag_present(pkt->skb)) {
+		tuple->encap[i].id = skb_vlan_tag_get(pkt->skb);
+		tuple->encap[i].proto = pkt->skb->vlan_proto;
+		i++;
+	}
+	switch (pkt->skb->protocol) {
+	case htons(ETH_P_8021Q):
+		vhdr = (struct vlan_hdr *)skb_network_header(pkt->skb);
+		tuple->encap[i].id = ntohs(vhdr->h_vlan_TCI);
+		tuple->encap[i].proto = pkt->skb->protocol;
+		i++;
+		break;
+	case htons(ETH_P_PPP_SES):
+		phdr = (struct pppoe_hdr *)skb_network_header(pkt->skb);
+		tuple->encap[i].id = ntohs(phdr->sid);
+		tuple->encap[i].proto = pkt->skb->protocol;
+		i++;
+		break;
+	}
+	tuple->encap_num = i;
+
+	err = nft_dev_fill_bridge_path(flow, ft, !dir, out_dev, in_dev,
+				       eth->h_dest, eth->h_source);
+	if (err < 0)
+		return err;
+
+	memset(tuple->encap, 0, sizeof(tuple->encap));
+
+	err = nft_dev_fill_bridge_path(flow, ft, dir, in_dev, out_dev,
+				       eth->h_source, eth->h_dest);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static void nft_dev_forward_path(struct nf_flow_route *route,
 				 const struct nf_conn *ct,
 				 enum ip_conntrack_dir dir,
@@ -311,6 +433,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 {
 	struct nft_flow_offload *priv = nft_expr_priv(expr);
 	struct nf_flowtable *flowtable = &priv->flowtable->data;
+	bool routing = flowtable->type->family != NFPROTO_BRIDGE;
 	struct tcphdr _tcph, *tcph = NULL;
 	struct nf_flow_route route = {};
 	enum ip_conntrack_info ctinfo;
@@ -364,14 +487,21 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 		goto out;
 
 	dir = CTINFO2DIR(ctinfo);
-	if (nft_flow_route(pkt, ct, &route, dir, priv->flowtable) < 0)
-		goto err_flow_route;
+	if (routing) {
+		if (nft_flow_route(pkt, ct, &route, dir, priv->flowtable) < 0)
+			goto err_flow_route;
+	}
 
 	flow = flow_offload_alloc(ct);
 	if (!flow)
 		goto err_flow_alloc;
 
-	flow_offload_route_init(flow, &route);
+	if (routing)
+		flow_offload_route_init(flow, &route);
+	else
+		if (nft_flow_offload_bridge_init(flow, pkt, dir, priv->flowtable) < 0)
+			goto err_flow_add;
+
 	if (tcph)
 		flow_offload_ct_tcp(ct);
 
@@ -419,8 +549,10 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 err_flow_add:
 	flow_offload_free(flow);
 err_flow_alloc:
-	dst_release(route.tuple[dir].dst);
-	dst_release(route.tuple[!dir].dst);
+	if (routing) {
+		dst_release(route.tuple[dir].dst);
+		dst_release(route.tuple[!dir].dst);
+	}
 err_flow_route:
 	clear_bit(IPS_OFFLOAD_BIT, &ct->status);
 out:
-- 
2.47.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v9 nf 00/15] bridge-fastpath and related improvements
  2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
                   ` (14 preceding siblings ...)
  2025-03-05 10:29 ` [PATCH v9 nf 15/15] netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval() Eric Woudstra
@ 2025-03-11  8:22 ` Eric Woudstra
  2025-03-11 23:44   ` Pablo Neira Ayuso
  15 siblings, 1 reply; 22+ messages in thread
From: Eric Woudstra @ 2025-03-11  8:22 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Sebastian Andrzej Siewior, Kuniyuki Iwashima,
	AngeloGioacchino Del Regno, Matthias Brugger, Nikolay Aleksandrov,
	Roopa Prabhu, Ivan Vecera, Jiri Pirko, Jozsef Kadlecsik,
	Simon Horman, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Andrew Lunn, netdev, linux-kernel,
	netfilter-devel, coreteam, bridge, linux-arm-kernel,
	linux-mediatek, linux-hardening, Kees Cook, Gustavo A. R. Silva,
	Alexander Lobakin, Ahmed Zaki, Vladimir Oltean, Frank Wunderlich,
	Daniel Golle



On 3/5/25 11:29 AM, Eric Woudstra wrote:
> This patchset makes it possible to set up a software fastpath between
> bridged interfaces. One patch adds the flow rule for the hardware
> fastpath. This creates the possibility to have a hardware offloaded
> fastpath between bridged interfaces. More patches are added to solve
> issues found with the existing code.


> Changes in v9:
> - No changes, resend to netfilter

Hi Pablo,

I've changed tag [net-next] to [nf], hopefully you can have a look at
this patch-set. But, after some days, I was in doubt if this way I have
brought it to your attention. Perhaps I need to do something different
to ask the netfilter maintainer have a look at it?

Best regards,

Eric



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v9 nf 00/15] bridge-fastpath and related improvements
  2025-03-11  8:22 ` [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
@ 2025-03-11 23:44   ` Pablo Neira Ayuso
  2025-03-12 16:21     ` Eric Woudstra
  0 siblings, 1 reply; 22+ messages in thread
From: Pablo Neira Ayuso @ 2025-03-11 23:44 UTC (permalink / raw)
  To: Eric Woudstra
  Cc: Sebastian Andrzej Siewior, Kuniyuki Iwashima,
	AngeloGioacchino Del Regno, Matthias Brugger, Nikolay Aleksandrov,
	Roopa Prabhu, Ivan Vecera, Jiri Pirko, Jozsef Kadlecsik,
	Simon Horman, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Andrew Lunn, netdev, linux-kernel,
	netfilter-devel, coreteam, bridge, linux-arm-kernel,
	linux-mediatek, linux-hardening, Kees Cook, Gustavo A. R. Silva,
	Alexander Lobakin, Ahmed Zaki, Vladimir Oltean, Frank Wunderlich,
	Daniel Golle

Hi,

On Tue, Mar 11, 2025 at 09:22:35AM +0100, Eric Woudstra wrote:
> 
> 
> On 3/5/25 11:29 AM, Eric Woudstra wrote:
> > This patchset makes it possible to set up a software fastpath between
> > bridged interfaces. One patch adds the flow rule for the hardware
> > fastpath. This creates the possibility to have a hardware offloaded
> > fastpath between bridged interfaces. More patches are added to solve
> > issues found with the existing code.
> 
> 
> > Changes in v9:
> > - No changes, resend to netfilter
> 
> Hi Pablo,
> 
> I've changed tag [net-next] to [nf], hopefully you can have a look at
> this patch-set. But, after some days, I was in doubt if this way I have
> brought it to your attention. Perhaps I need to do something different
> to ask the netfilter maintainer have a look at it?

Apologies, this maintainance service is best effort.

I am also going to be very busy until April to complete a few more
deliverables, I cannot afford more cancelled projects. I will try to
collect what is left for net-next and wait for the next merge window.

Therefore, I suggest you start with a much smaller series with a
carefully selected subset including preparatory patches. I suggest you
start with the software enhancements only. Please, add datapath tests.

As for the hardware offload part, I have a board that I received 4.5
ago years as a engineering sample that maybe I can use to test this,
but no idea, really.

You are a passer-by (ahem, "contributor"), this will get merged
upstream at some point and we will have to maintain all this new code
without your help maybe ... (people change bussiness units...), I have
to understand what is going on here. The throughput available is
limited, I am afraid we can only go _slow and careful_.

Thanks.

P.S: You work is important, very important, but maybe there is no need
to Cc so many mailing lists and people, maybe netdev@,
netfilter-devel@ and bridge@ is sufficient.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v9 nf 00/15] bridge-fastpath and related improvements
  2025-03-11 23:44   ` Pablo Neira Ayuso
@ 2025-03-12 16:21     ` Eric Woudstra
  2025-03-12 23:11       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 22+ messages in thread
From: Eric Woudstra @ 2025-03-12 16:21 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Sebastian Andrzej Siewior, Kuniyuki Iwashima,
	AngeloGioacchino Del Regno, Matthias Brugger, Nikolay Aleksandrov,
	Roopa Prabhu, Ivan Vecera, Jiri Pirko, Jozsef Kadlecsik,
	Simon Horman, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Andrew Lunn, netdev, linux-kernel,
	netfilter-devel, coreteam, bridge, linux-arm-kernel,
	linux-mediatek, linux-hardening, Kees Cook, Gustavo A. R. Silva,
	Alexander Lobakin, Ahmed Zaki, Vladimir Oltean, Frank Wunderlich,
	Daniel Golle



On 3/12/25 12:44 AM, Pablo Neira Ayuso wrote:
> Therefore, I suggest you start with a much smaller series with a
> carefully selected subset including preparatory patches. I suggest you
> start with the software enhancements only. Please, add datapath tests.

Then I will split it in:
1. Separate preparatory patches and small patch-sets that apply
     to the forward-fastpath already.
2. One patch-set that brings the bridge-fastpath with datapath tests.

> P.S: You work is important, very important, but maybe there is no need
> to Cc so many mailing lists and people, maybe netdev@,
> netfilter-devel@ and bridge@ is sufficient.

Ok, but my main question then is which tree should I work in, and
therefore which tag should I give my patches, [nf] or [net-next].
I think it will get more complicated if I split my patch-set and half of
the patches go to [nf] and another half to [net-next].

What do you suggest?



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v9 nf 00/15] bridge-fastpath and related improvements
  2025-03-12 16:21     ` Eric Woudstra
@ 2025-03-12 23:11       ` Pablo Neira Ayuso
  2025-03-13 18:01         ` Eric Woudstra
  0 siblings, 1 reply; 22+ messages in thread
From: Pablo Neira Ayuso @ 2025-03-12 23:11 UTC (permalink / raw)
  To: Eric Woudstra
  Cc: Sebastian Andrzej Siewior, Kuniyuki Iwashima,
	AngeloGioacchino Del Regno, Matthias Brugger, Nikolay Aleksandrov,
	Roopa Prabhu, Ivan Vecera, Jiri Pirko, Jozsef Kadlecsik,
	Simon Horman, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Andrew Lunn, netdev, linux-kernel,
	netfilter-devel, coreteam, bridge, linux-arm-kernel,
	linux-mediatek, linux-hardening, Kees Cook, Gustavo A. R. Silva,
	Alexander Lobakin, Ahmed Zaki, Vladimir Oltean, Frank Wunderlich,
	Daniel Golle

On Wed, Mar 12, 2025 at 05:21:29PM +0100, Eric Woudstra wrote:
> 
> 
> On 3/12/25 12:44 AM, Pablo Neira Ayuso wrote:
> > Therefore, I suggest you start with a much smaller series with a
> > carefully selected subset including preparatory patches. I suggest you
> > start with the software enhancements only. Please, add datapath tests.
> 
> Then I will split it in:
> 1. Separate preparatory patches and small patch-sets that apply
>      to the forward-fastpath already.
> 2. One patch-set that brings the bridge-fastpath with datapath tests.
> 
> > P.S: You work is important, very important, but maybe there is no need
> > to Cc so many mailing lists and people, maybe netdev@,
> > netfilter-devel@ and bridge@ is sufficient.
> 
> Ok, but my main question then is which tree should I work in, and
> therefore which tag should I give my patches, [nf] or [net-next].
> I think it will get more complicated if I split my patch-set and half of
> the patches go to [nf] and another half to [net-next].

Use [nf-next].

> What do you suggest?

Probably I can collect 4/15 and 5/15 from this series to be included
in the next pull request, let me take a look. But it would be good to
have tests for these two patches.

I would suggest you continue by making a series to add bridge support
for the flowtable, software only, including tests.

Once this gets merged, then follow up with the hardware offload code.

Thanks.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v9 nf 00/15] bridge-fastpath and related improvements
  2025-03-12 23:11       ` Pablo Neira Ayuso
@ 2025-03-13 18:01         ` Eric Woudstra
  2025-03-14 12:37           ` Pablo Neira Ayuso
  0 siblings, 1 reply; 22+ messages in thread
From: Eric Woudstra @ 2025-03-13 18:01 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Sebastian Andrzej Siewior, Kuniyuki Iwashima,
	AngeloGioacchino Del Regno, Matthias Brugger, Nikolay Aleksandrov,
	Roopa Prabhu, Ivan Vecera, Jiri Pirko, Jozsef Kadlecsik,
	Simon Horman, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Andrew Lunn, netdev, linux-kernel,
	netfilter-devel, coreteam, bridge, linux-arm-kernel,
	linux-mediatek, linux-hardening, Kees Cook, Gustavo A. R. Silva,
	Alexander Lobakin, Ahmed Zaki, Vladimir Oltean, Frank Wunderlich,
	Daniel Golle



On 3/13/25 12:11 AM, Pablo Neira Ayuso wrote:

>> What do you suggest?
> 
> Probably I can collect 4/15 and 5/15 from this series to be included
> in the next pull request, let me take a look. But it would be good to
> have tests for these two patches.
> 

These are not most important to bridge-fastpath, but it gives extra
possibilities. How about concentrating first on patch 2/15 (with 1/15
removing a warning and 3/15 cleaning up), adding nf_flow_encap_push()
for xmit direct? It is a vital patch for the bridge-fastpath.

Anyway, I will look into writing selftests for conntrack-bridge setup,
including various vlan setups. This will take me some time, which I
do not have in abundance, so for that I do not know if I get it done
before the merge window.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v9 nf 00/15] bridge-fastpath and related improvements
  2025-03-13 18:01         ` Eric Woudstra
@ 2025-03-14 12:37           ` Pablo Neira Ayuso
  0 siblings, 0 replies; 22+ messages in thread
From: Pablo Neira Ayuso @ 2025-03-14 12:37 UTC (permalink / raw)
  To: Eric Woudstra
  Cc: Sebastian Andrzej Siewior, Kuniyuki Iwashima,
	AngeloGioacchino Del Regno, Matthias Brugger, Nikolay Aleksandrov,
	Roopa Prabhu, Ivan Vecera, Jiri Pirko, Jozsef Kadlecsik,
	Simon Horman, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Andrew Lunn, netdev, linux-kernel,
	netfilter-devel, coreteam, bridge, linux-arm-kernel,
	linux-mediatek, linux-hardening, Kees Cook, Gustavo A. R. Silva,
	Alexander Lobakin, Ahmed Zaki, Vladimir Oltean, Frank Wunderlich,
	Daniel Golle

On Thu, Mar 13, 2025 at 07:01:38PM +0100, Eric Woudstra wrote:
> 
> 
> On 3/13/25 12:11 AM, Pablo Neira Ayuso wrote:
> 
> >> What do you suggest?
> > 
> > Probably I can collect 4/15 and 5/15 from this series to be included
> > in the next pull request, let me take a look. But it would be good to
> > have tests for these two patches.
> > 
> 
> These are not most important to bridge-fastpath, but it gives extra
> possibilities. How about concentrating first on patch 2/15 (with 1/15
> removing a warning and 3/15 cleaning up), adding nf_flow_encap_push()
> for xmit direct? It is a vital patch for the bridge-fastpath.

I see cleanup patch 3/15 is a consequence of 2/15, let me take a look.

> Anyway, I will look into writing selftests for conntrack-bridge setup,
> including various vlan setups. This will take me some time, which I
> do not have in abundance, so for that I do not know if I get it done
> before the merge window.

There is tools/testing/selftests/net/netfilter/nft_flowtable.sh that
can possibly be extended to improve coverage.

Thanks.


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2025-03-14 12:41 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-05 10:29 [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 01/15] net: pppoe: avoid zero-length arrays in struct pppoe_hdr Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 02/15] netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit direct Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 03/15] netfilter: flow: remove hw_outdev, out.hw_ifindex and out.hw_ifidx Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 04/15] netfilter: bridge: Add conntrack double vlan and pppoe Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 05/15] netfilter: nft_chain_filter: Add bridge " Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 06/15] bridge: Add filling forward path from port to port Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 07/15] net: core: dev: Add dev_fill_bridge_path() Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 08/15] netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge() Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 09/15] netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 10/15] netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 11/15] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 12/15] netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user port Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 13/15] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 14/15] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath Eric Woudstra
2025-03-05 10:29 ` [PATCH v9 nf 15/15] netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval() Eric Woudstra
2025-03-11  8:22 ` [PATCH v9 nf 00/15] bridge-fastpath and related improvements Eric Woudstra
2025-03-11 23:44   ` Pablo Neira Ayuso
2025-03-12 16:21     ` Eric Woudstra
2025-03-12 23:11       ` Pablo Neira Ayuso
2025-03-13 18:01         ` Eric Woudstra
2025-03-14 12:37           ` Pablo Neira Ayuso

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).