mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 12:52:29 -04:00
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>
This commit is contained in:
@@ -296,14 +296,18 @@ static int airoha_ppe_get_wdma_info(struct net_device *dev, const u8 *addr,
|
||||
return err;
|
||||
|
||||
path = &stack.path[stack.num_paths - 1];
|
||||
if (path->type != DEV_PATH_MTK_WDMA)
|
||||
return -EINVAL;
|
||||
if (path->type != DEV_PATH_MTK_WDMA) {
|
||||
err = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
info->idx = path->mtk_wdma.wdma_idx;
|
||||
info->bss = path->mtk_wdma.bss;
|
||||
info->wcid = path->mtk_wdma.wcid;
|
||||
err_out:
|
||||
dev_fill_forward_path_release(&stack);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int airoha_get_dsa_port(struct net_device **dev)
|
||||
|
||||
@@ -108,16 +108,20 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
|
||||
return err;
|
||||
|
||||
path = &stack.path[stack.num_paths - 1];
|
||||
if (path->type != DEV_PATH_MTK_WDMA)
|
||||
return -1;
|
||||
if (path->type != DEV_PATH_MTK_WDMA) {
|
||||
err = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
info->wdma_idx = path->mtk_wdma.wdma_idx;
|
||||
info->queue = path->mtk_wdma.queue;
|
||||
info->bss = path->mtk_wdma.bss;
|
||||
info->wcid = path->mtk_wdma.wcid;
|
||||
info->amsdu = path->mtk_wdma.amsdu;
|
||||
err_out:
|
||||
dev_fill_forward_path_release(&stack);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -892,6 +892,7 @@ struct net_device_path {
|
||||
u8 h_dest[ETH_ALEN];
|
||||
} encap;
|
||||
struct {
|
||||
struct dst_entry *dst;
|
||||
union {
|
||||
struct in_addr src_v4;
|
||||
struct in6_addr src_v6;
|
||||
@@ -3427,6 +3428,7 @@ 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,
|
||||
struct net_device_path_stack *stack);
|
||||
void dev_fill_forward_path_release(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);
|
||||
struct net_device *__dev_get_by_name(struct net *net, const char *name);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user