From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Eric Woudstra <ericwouds@gmail.com>
Cc: netfilter-devel@vger.kernel.org, razor@blackwall.org, fw@strlen.de
Subject: Re: [PATCH nf-next,v2 3/3] netfilter: flowtable: initial bridge support
Date: Sun, 12 Jul 2026 21:19:31 +0200 [thread overview]
Message-ID: <alPowzheMt-_N-Z6@chamomile> (raw)
In-Reply-To: <9b423fa5-88cb-4197-9849-91e40901dd5b@gmail.com>
On Sun, Jul 12, 2026 at 11:27:50AM +0200, Eric Woudstra wrote:
[...]
> On 7/10/26 12:07 PM, Pablo Neira Ayuso wrote:
> > diff --git a/net/netfilter/nf_flow_table_path.c b/net/netfilter/nf_flow_table_path.c
> > index 5455149e5d9a..a3aa9a9ce673 100644
> > --- a/net/netfilter/nf_flow_table_path.c
> > +++ b/net/netfilter/nf_flow_table_path.c
> > @@ -8,6 +8,7 @@
> > #include <linux/spinlock.h>
> > #include <linux/netfilter/nf_conntrack_common.h>
> > #include <linux/netfilter/nf_tables.h>
> > +#include <linux/if_vlan.h>
> > #include <net/ip.h>
> > #include <net/inet_dscp.h>
> > #include <net/netfilter/nf_tables.h>
> > @@ -360,3 +361,67 @@ int nft_flow_route(const struct nft_pktinfo *pkt, const struct nf_conn *ct,
> > return -ENOENT;
> > }
> > EXPORT_SYMBOL_GPL(nft_flow_route);
> > +
> > +static int nft_dev_fill_bridge_path(struct flow_offload *flow,
> > + struct nft_flowtable *ft,
> > + enum ip_conntrack_dir dir,
> > + const struct net_device *dev,
> > + unsigned char *src_ha,
> > + unsigned char *dst_ha)
> > +{
> > + struct flow_offload_tuple *this_tuple = &flow->tuplehash[dir].tuple;
>
> Add:
>
> struct flow_offload_tuple *other_tuple = &flow->tuplehash[!dir].tuple;
>
> See below.
>
> > + struct net_device_path_stack stack;
> > + struct nft_forward_info info = {};
> > + struct net_device_path_ctx ctx;
> > + int i, j = 0;
> > +
> > + nft_dev_fill_forward_path_init(&ctx, dev, dst_ha);
> > +
>
> Here you could add the following to handle the encaps on this_tuple.
Why?
> for (i = this_tuple->encap_num - 1; i >= 0 ; i--) {
> if (info.num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
> return -1;
>
> if (this_tuple->in_vlan_ingress & BIT(i))
> continue;
I don't do bridge vlan filtering at this stage. I have to teach
nf_conntrack_bridge to track PPPoE/VLAN tagged packets, this is not
included in this series.
> info.encap[info.num_encaps].id = this_tuple->encap[i].id;
> info.encap[info.num_encaps].proto = this_tuple->encap[i].proto;
> info.num_encaps++;
>
> if (this_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 = this_tuple->encap[i].id;
> ctx.vlan[ctx.num_vlans].proto = this_tuple->encap[i].proto;
> ctx.num_vlans++;
> }
>
> > + if (dev_fill_forward_path(&ctx, &stack) < 0 ||
> > + nft_dev_path_info(&stack, &info, dst_ha, &ft->data) < 0)
> > + return -1;
> > +
> > + if (!nft_flowtable_find_dev(info.indev, ft))
> > + return -1;
> > +
>
> After replacing dev_fill_forward_path() with dev_fill_bridge_path(),
> from here...
>
> > + this_tuple->iifidx = info.indev->ifindex;
> > + for (i = info.num_encaps - 1; i >= 0; i--) {
> > + this_tuple->encap[j].id = info.encap[i].id;
> > + this_tuple->encap[j].proto = info.encap[i].proto;
> > + j++;
> > + }
> > + this_tuple->encap_num = info.num_encaps;
>
> Until here, this_tuple needs to be the other_tuple.
> dev_fill_forward_path() does not traverse the bridge.
As I said, this series does not included bridge vlan filtering support.
> See other comment in other patch. Also, need to copy
> the in_vlan_ingress bit.
>
> So it becomes:
>
> other_tuple->iifidx = info.indev->ifindex;
> for (i = info.num_encaps - 1; i >= 0; i--) {
> other_tuple->encap[j].id = info.encap[i].id;
> other_tuple->encap[j].proto = info.encap[i].proto;
> if (info.ingress_vlans & BIT(i))
> other_tuple->in_vlan_ingress |= BIT(j);
> j++;
> }
> other_tuple->encap_num = info.num_encaps;
>
> > +
> > + ether_addr_copy(this_tuple->out.h_source, src_ha);
> > + ether_addr_copy(this_tuple->out.h_dest, dst_ha);
> > + this_tuple->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
> > +
> > + return 0;
> > +}
> > +
> > +int nft_flow_bridge(struct flow_offload *flow, const struct nft_pktinfo *pkt,
> > + enum ip_conntrack_dir dir, struct nft_flowtable *ft)
> > +{
> > + struct flow_offload_tuple *other_tuple = &flow->tuplehash[!dir].tuple;
> > + struct flow_offload_tuple *this_tuple = &flow->tuplehash[dir].tuple;
> > + const struct net_device *outdev = nft_out(pkt);
> > + const struct net_device *indev = nft_in(pkt);
> > + struct ethhdr *eth = eth_hdr(pkt->skb);
> > + int err;
> > +
>
> Here I use the skb to fill other_tuple->encaps. I understand you want to
> do this differently.
Using skb to populate tuples will not work, the skb comes with no tags
when VLAN/PPPoE devices are used in the bridge ports.
> Then I call nft_dev_fill_bridge_path() with !dir first, then dir.
>
> > + err = nft_dev_fill_bridge_path(flow, ft, dir, indev,
> > + eth->h_source, eth->h_dest);
> > + if (err < 0)
> > + return err;
> > +
> > + err = nft_dev_fill_bridge_path(flow, ft, !dir, outdev,
> > + eth->h_dest, eth->h_source);
> > + if (err < 0)
> > + return err;
> > +
> > + this_tuple->out.ifidx = other_tuple->iifidx;
> > + other_tuple->out.ifidx = this_tuple->iifidx;
>
> This could move to nft_dev_fill_bridge_path() (only 1 line) as both
> tuples are also known there.
No, because other_tuple is unset when the first nft_dev_fill_bridge_path()
call is done.
next prev parent reply other threads:[~2026-07-12 19:19 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 10:07 [PATCH nf-next,v2 0/3] initial flowtable bridge support Pablo Neira Ayuso
2026-07-10 10:07 ` [PATCH nf-next,v2 1/3] net: pass net_device_path_ctx struct to dev_fill_forward_path() Pablo Neira Ayuso
2026-07-11 9:30 ` Eric Woudstra
2026-07-12 9:28 ` Eric Woudstra
2026-07-12 19:22 ` Pablo Neira Ayuso
2026-07-10 10:07 ` [PATCH nf-next,v2 2/3] net: expose dev_fwd_path() helper via static inline Pablo Neira Ayuso
2026-07-10 10:07 ` [PATCH nf-next,v2 3/3] netfilter: flowtable: initial bridge support Pablo Neira Ayuso
2026-07-12 9:27 ` Eric Woudstra
2026-07-12 13:46 ` Eric Woudstra
2026-07-12 19:13 ` Pablo Neira Ayuso
2026-07-12 19:19 ` Pablo Neira Ayuso [this message]
2026-07-13 8:24 ` Pablo Neira Ayuso
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=alPowzheMt-_N-Z6@chamomile \
--to=pablo@netfilter.org \
--cc=ericwouds@gmail.com \
--cc=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
--cc=razor@blackwall.org \
/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