[PATCH nf-next] net: pass net_device_path_ctx to dev_fill_forward_path()
Lorenzo Bianconi
lorenzo.bianconi at oss.qualcomm.com
Wed Aug 5 01:53:09 PDT 2026
Refactor dev_fill_forward_path() to take a struct net_device_path_ctx
pointer instead of a (dev, daddr) pair, so the caller can build and
populate the context up front and keep it after the forward path walk.
This allows additional fields (e.g. vlan and ether_type) to be carried
in the context and shared with ndo_fill_forward_path implementations,
instead of being reconstructed on the stack inside the core helper.
Update the mtk_ppe_offload, airoha_ppe and nf_flow_table_path callers to
allocate and fill the context before invoking dev_fill_forward_path().
The network topology resolution behaviour is unchanged.
This is a preliminary patch to enable HW flowtable offload for IPv4
over IPv6 tunnels.
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>
---
drivers/net/ethernet/airoha/airoha_ppe.c | 7 ++++++-
drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 7 ++++++-
include/linux/netdevice.h | 2 +-
net/core/dev.c | 18 +++++++-----------
net/netfilter/nf_flow_table_path.c | 7 ++++++-
5 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 33ddf0d07855..53183a132100 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -283,14 +283,19 @@ static int airoha_ppe_get_wdma_info(struct net_device *dev, const u8 *addr,
struct airoha_wdma_info *info)
{
struct net_device_path_stack stack;
+ struct net_device_path_ctx ctx = {
+ .dev = dev,
+ };
struct net_device_path *path;
int err;
if (!dev)
return -ENODEV;
+ ether_addr_copy(ctx.daddr, addr);
+
rcu_read_lock();
- err = dev_fill_forward_path(dev, addr, &stack);
+ err = dev_fill_forward_path(&ctx, &stack);
rcu_read_unlock();
if (err)
return err;
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
index cc8c4ef8038f..1ec46784f018 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -92,6 +92,9 @@ static int
mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info)
{
struct net_device_path_stack stack;
+ struct net_device_path_ctx ctx = {
+ .dev = dev,
+ };
struct net_device_path *path;
int err;
@@ -101,8 +104,10 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED))
return -1;
+ ether_addr_copy(ctx.daddr, addr);
+
rcu_read_lock();
- err = dev_fill_forward_path(dev, addr, &stack);
+ err = dev_fill_forward_path(&ctx, &stack);
rcu_read_unlock();
if (err)
return err;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8db25b79573e..d2f545016f7f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3425,7 +3425,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 c1c1be1a6962..e2c9fe3f7a7b 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;
}
diff --git a/net/netfilter/nf_flow_table_path.c b/net/netfilter/nf_flow_table_path.c
index 98c03b487f52..b9df7453f762 100644
--- a/net/netfilter/nf_flow_table_path.c
+++ b/net/netfilter/nf_flow_table_path.c
@@ -50,6 +50,9 @@ static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
{
const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
struct net_device *dev = dst_cache->dev;
+ struct net_device_path_ctx ctx = {
+ .dev = dev,
+ };
struct neighbour *n;
u8 nud_state;
@@ -72,7 +75,9 @@ static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
return -1;
out:
- return dev_fill_forward_path(dev, ha, stack);
+ ether_addr_copy(ctx.daddr, ha);
+
+ return dev_fill_forward_path(&ctx, stack);
}
struct nft_forward_info {
---
base-commit: a23b36233d4103def55dc8cf65698106d0bd1e62
change-id: 20260805-dev_fill_forward_path-ctx-arg-73366345e3b8
Best regards,
--
Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>
More information about the linux-arm-kernel
mailing list