Linux Netfilter development
 help / color / mirror / Atom feed
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.

  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