From: Eric Woudstra <ericwouds@gmail.com>
To: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Pablo Neira Ayuso <pablo@netfilter.org>,
Jozsef Kadlecsik <kadlec@netfilter.org>,
Roopa Prabhu <roopa@nvidia.com>,
Nikolay Aleksandrov <razor@blackwall.org>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Jiri Pirko <jiri@resnulli.us>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Lorenzo Bianconi <lorenzo@kernel.org>,
"Frank Wunderlich" <frank-w@public-files.de>,
Daniel Golle <daniel@makrotopia.org>,
Eric Woudstra <ericwouds@gmail.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
netfilter-devel@vger.kernel.org, coreteam@netfilter.org,
bridge@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org
Subject: [PATCH RFC v1 net-next 12/12] netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval()
Date: Sun, 13 Oct 2024 20:55:08 +0200 [thread overview]
Message-ID: <20241013185509.4430-13-ericwouds@gmail.com> (raw)
In-Reply-To: <20241013185509.4430-1-ericwouds@gmail.com>
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.
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 2923286d475e..bd4850691baa 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -184,6 +184,129 @@ 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,
+ const struct nft_pktinfo *pkt,
+ 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_stack stack;
+ struct net_device_path_ctx ctx = {};
+ 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;
+ 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.out.hw_ifidx = info.hw_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)
+{
+ struct ethhdr *eth = eth_hdr(pkt->skb);
+ struct flow_offload_tuple *tuple;
+ const struct net_device *out_dev;
+ const struct net_device *in_dev;
+ 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):
+ struct vlan_hdr *vhdr;
+
+ 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):
+ struct pppoe_hdr *phdr;
+
+ 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, pkt, !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, pkt, 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,
@@ -294,6 +417,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;
@@ -347,14 +471,20 @@ 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_route;
if (tcph) {
ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
@@ -407,8 +537,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.45.2
next prev parent reply other threads:[~2024-10-13 19:12 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-13 18:54 [PATCH RFC v1 net-next 00/12] bridge-fastpath and related improvements Eric Woudstra
2024-10-13 18:54 ` [PATCH RFC v1 net-next 01/12] netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit direct Eric Woudstra
2024-10-13 18:54 ` [PATCH RFC v1 net-next 02/12] netfilter: bridge: Add conntrack double vlan and pppoe Eric Woudstra
2024-10-18 13:17 ` Vladimir Oltean
2024-10-18 18:53 ` Eric Woudstra
2024-10-13 18:54 ` [PATCH RFC v1 net-next 03/12] netfilter: nft_chain_filter: Add bridge " Eric Woudstra
2024-10-13 18:55 ` [PATCH RFC v1 net-next 04/12] bridge: br_vlan_fill_forward_path_pvid: Add port to port Eric Woudstra
2024-10-14 6:36 ` Nikolay Aleksandrov
2024-10-13 18:55 ` [PATCH RFC v1 net-next 05/12] bridge: br_fill_forward_path add " Eric Woudstra
2024-10-14 6:30 ` Nikolay Aleksandrov
2024-10-13 18:55 ` [PATCH RFC v1 net-next 06/12] net: core: dev: Add dev_fill_bridge_path() Eric Woudstra
2024-10-14 6:59 ` Nikolay Aleksandrov
2024-10-14 18:34 ` Eric Woudstra
2024-10-16 7:43 ` Nikolay Aleksandrov
2024-10-16 15:57 ` Eric Woudstra
2024-10-13 18:55 ` [PATCH RFC v1 net-next 07/12] netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge() Eric Woudstra
2024-10-13 18:55 ` [PATCH RFC v1 net-next 08/12] netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge Eric Woudstra
2024-10-13 18:55 ` [PATCH RFC v1 net-next 09/12] netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate Eric Woudstra
2024-10-13 18:55 ` [PATCH RFC v1 net-next 10/12] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info() Eric Woudstra
2024-10-13 18:55 ` [PATCH RFC v1 net-next 11/12] bridge: br_vlan_fill_forward_path_mode no _UNTAG_HW for dsa Eric Woudstra
2024-10-14 6:18 ` Nikolay Aleksandrov
2024-10-14 6:22 ` Nikolay Aleksandrov
2024-10-14 14:46 ` Vladimir Oltean
2024-10-15 10:26 ` Eric Woudstra
2024-10-20 9:23 ` Eric Woudstra
2024-10-21 13:47 ` Vladimir Oltean
2024-10-22 7:25 ` Eric Woudstra
2024-10-13 18:55 ` Eric Woudstra [this message]
2024-10-14 6:35 ` [PATCH RFC v1 net-next 00/12] bridge-fastpath and related improvements Nikolay Aleksandrov
2024-10-14 18:29 ` Eric Woudstra
2024-10-15 12:16 ` Felix Fietkau
2024-10-15 13:32 ` Eric Woudstra
2024-10-15 19:44 ` Felix Fietkau
2024-10-16 15:59 ` Eric Woudstra
2024-10-17 9:17 ` Felix Fietkau
2024-10-17 12:39 ` Pablo Neira Ayuso
2024-10-17 17:06 ` Felix Fietkau
2024-10-17 18:09 ` Pablo Neira Ayuso
2024-10-17 18:39 ` Felix Fietkau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241013185509.4430-13-ericwouds@gmail.com \
--to=ericwouds@gmail.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=bigeasy@linutronix.de \
--cc=bridge@lists.linux.dev \
--cc=coreteam@netfilter.org \
--cc=daniel@makrotopia.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=frank-w@public-files.de \
--cc=jiri@resnulli.us \
--cc=kadlec@netfilter.org \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=lorenzo@kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pablo@netfilter.org \
--cc=razor@blackwall.org \
--cc=roopa@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).