diff options
| author | Pablo Neira Ayuso <pablo@netfilter.org> | 2026-07-28 18:30:48 +0200 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2026-07-31 14:47:03 +0200 |
| commit | 0ad8404e776698de4dac5cc0df3be68d344e741c (patch) | |
| tree | 71f6b42bf1633e76efc10c976e156fb2b596cb6f /net/core | |
| parent | 5deda60c56eeeab25beb10cf4d48e07587076b11 (diff) | |
net: pass dst via net_device_path in dev_fill_forward_path()
Add dst_entry to tunnel device path, this will allow us to remove
a duplicated route lookup.
This is a preparation patch to retrieve the tunnel route directly
from the .fill_forward_path. This new dst_entry in the tunnel will be
used by a follow up patch.
Since dst_release() works fine on NULL interface, this is still
noop until the flowtable starts using this.
Add a new dev_fill_forward_path_release() function to drop the refcount
on the tunnel device route and use it in case of error out. Export it so
to drop the refcount on the tunnel route at a later stage.
Adjust existing drivers that recycle dev_fill_forward_path() to call
dev_fill_forward_path_release() for safety reasons.
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dev.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 429a55fff667..e50ed677de72 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -748,6 +748,27 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) return &stack->path[stack->num_paths]; } +void dev_fill_forward_path_release(struct net_device_path_stack *stack) +{ + struct net_device_path *path; + int k; + + if (stack->num_paths == 0) + return; + + for (k = stack->num_paths - 1; k >= 0; k--) { + path = &stack->path[k]; + switch (path->type) { + case DEV_PATH_TUN: + dst_release(path->tun.dst); + break; + default: + break; + } + } +} +EXPORT_SYMBOL_GPL(dev_fill_forward_path_release); + int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, struct net_device_path_stack *stack) { @@ -764,16 +785,16 @@ int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, last_dev = ctx.dev; path = dev_fwd_path(stack); if (!path) - return -1; + goto err_out; memset(path, 0, sizeof(struct net_device_path)); ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path); if (ret < 0) - return -1; + goto err_out; stack->num_paths++; if (WARN_ON_ONCE(last_dev == ctx.dev)) - return -1; + goto err_out; } if (!ctx.dev) @@ -781,12 +802,17 @@ int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, path = dev_fwd_path(stack); if (!path) - return -1; + goto err_out; + path->type = DEV_PATH_ETHERNET; path->dev = ctx.dev; stack->num_paths++; - return ret; + return 0; +err_out: + dev_fill_forward_path_release(stack); + + return -1; } EXPORT_SYMBOL_GPL(dev_fill_forward_path); |
