Re: [PATCH nf-next,v2 1/3] net: pass net_device_path_ctx struct to dev_fill_forward_path()
Pablo Neira Ayuso <[email protected]>
| Newsgroups | gmane.comp.security.firewalls.netfilter.devel |
|---|---|
| Message-ID | <alPpXDQq0rOqbDUG@chamomile> |
On Sun, Jul 12, 2026 at 11:28:11AM +0200, Eric Woudstra wrote: > On 7/10/26 12:07 PM, Pablo Neira Ayuso wrote: > > Generalize dev_fill_forward_path() so it can be used by the bridge > > family to retrieve the bridge vlan filtering information from the > > bridge port when discovering the bridge flowtable path. > > > > Signed-off-by: Pablo Neira Ayuso <[email protected]> > > --- > > v2: - move nft_dev_fill_forward_path_init() call after out: goto tag > > to fix a crash otherwise in the existing flowtable ip family. > > > > include/linux/netdevice.h | 2 +- > > net/core/dev.c | 18 +++++++----------- > > net/netfilter/nf_flow_table_path.c | 14 ++++++++++++-- > > 3 files changed, 20 insertions(+), 14 deletions(-) > > > > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > > index 9981d637f8b5..db04b6d2e8d2 100644 > > --- a/include/linux/netdevice.h > > +++ b/include/linux/netdevice.h > > @@ -3420,7 +3420,7 @@ 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_forward_path(const struct net_device *dev, const u8 *daddr, > > +int dev_fill_forward_path(struct net_device_path_ctx *ctx, > > struct net_device_path_stack *stack); > > struct net_device *dev_get_by_name(struct net *net, const char *name); > > struct net_device *dev_get_by_name_rcu(struct net *net, const char *name); > > diff --git a/net/core/dev.c b/net/core/dev.c > > index 714d05283500..24c384ef9e78 100644 > > --- a/net/core/dev.c > > +++ b/net/core/dev.c > > @@ -750,41 +750,37 @@ 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, > > +int dev_fill_forward_path(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; > > } > > Calling dev_fill_forward_path() from nft_dev_fill_bridge_path() > it does not traverse the bridge. It exits at the source "indev" > already. After calling nft_dev_path_info(), the info structure > is filled in with the opposite device and the encaps of the > opposite device. Traversing the bridge is only needed for bridge vlan filtering and that is not included in this initial support. > Would need to add something like this: > > 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; > > 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(ctx, stack); > } > EXPORT_SYMBOL_GPL(dev_fill_bridge_path); > > First need to find the bridge device to call ndo_fill_forward_path() > from it. > > This also needs the patch "bridge: Add filling forward path from port to > port" > That patch still needs a change according to Nikolay. Once bridge vlan filtering is added, but that need nf_conntrack_bridge support for VLAN/PPPoE as I said.