From: Ryan Chen <[email protected]>

Export __dev_fill_forward_path() which accepts a caller-supplied
net_device_path_ctx, allowing callers to pre-populate context (e.g.
VLAN state) before the forward path walk. The existing
dev_fill_forward_path() is refactored to call it.

This is a prerequisite for nft_flow_offload bridge offload, which needs
to supply a pre-populated ctx for bridge port devices.

Signed-off-by: Ryan Chen <[email protected]>
Signed-off-by: Daniel Pawlik <[email protected]>
---
 include/linux/netdevice.h |  2 ++
 net/core/dev.c            | 32 ++++++++++++++++++++------------
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9981d637f8b5..c1d0b897de95 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3422,6 +3422,8 @@ 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);
+int __dev_fill_forward_path(struct net_device_path_ctx *ctx, const u8 *daddr,
+                           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);
diff --git a/net/core/dev.c b/net/core/dev.c
index 4b3d5cfdf6e0..62f1d0b64c76 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -750,44 +750,52 @@ 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,
-                         struct net_device_path_stack *stack)
+int __dev_fill_forward_path(struct net_device_path_ctx *ctx, const u8 *daddr,
+                           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));
+       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;
 }
+EXPORT_SYMBOL_GPL(__dev_fill_forward_path);
+
+int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
+                         struct net_device_path_stack *stack)
+{
+       struct net_device_path_ctx ctx = {
+               .dev    = dev,
+       };
+
+       return __dev_fill_forward_path(&ctx, daddr, stack);
+}
 EXPORT_SYMBOL_GPL(dev_fill_forward_path);
 
 /* must be called under rcu_read_lock(), as we dont take a reference */
-- 
2.54.0


Reply via email to