Functionality is the same, but the ndo_xdp_xmit call is now
simply invoked from inside the devmap.c code.

V2: Fix compile issue reported by kbuild test robot <l...@intel.com>

Signed-off-by: Jesper Dangaard Brouer <bro...@redhat.com>
---
 include/linux/bpf.h        |   14 +++++++++++---
 include/trace/events/xdp.h |    9 ++++++++-
 kernel/bpf/devmap.c        |   37 +++++++++++++++++++++++++++++++------
 net/core/filter.c          |   15 ++-------------
 4 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index a38e474bf7ee..8527964da402 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -485,14 +485,15 @@ int bpf_check(struct bpf_prog **fp, union bpf_attr *attr);
 void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth);
 
 /* Map specifics */
-struct net_device  *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
+struct xdp_buff;
+struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
 void __dev_map_insert_ctx(struct bpf_map *map, u32 index);
 void __dev_map_flush(struct bpf_map *map);
+int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp);
 
 struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key);
 void __cpu_map_insert_ctx(struct bpf_map *map, u32 index);
 void __cpu_map_flush(struct bpf_map *map);
-struct xdp_buff;
 int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
                    struct net_device *dev_rx);
 
@@ -571,6 +572,14 @@ static inline void __dev_map_flush(struct bpf_map *map)
 {
 }
 
+struct xdp_buff;
+struct bpf_dtab_netdev;
+static inline
+int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp)
+{
+       return 0;
+}
+
 static inline
 struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
 {
@@ -585,7 +594,6 @@ static inline void __cpu_map_flush(struct bpf_map *map)
 {
 }
 
-struct xdp_buff;
 static inline int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu,
                                  struct xdp_buff *xdp,
                                  struct net_device *dev_rx)
diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h
index 8989a92c571a..96104610d40e 100644
--- a/include/trace/events/xdp.h
+++ b/include/trace/events/xdp.h
@@ -138,11 +138,18 @@ DEFINE_EVENT_PRINT(xdp_redirect_template, 
xdp_redirect_map_err,
                  __entry->map_id, __entry->map_index)
 );
 
+#ifndef __DEVMAP_OBJ_TYPE
+#define __DEVMAP_OBJ_TYPE
+struct _bpf_dtab_netdev {
+       struct net_device *dev;
+};
+#endif /* __DEVMAP_OBJ_TYPE */
+
 #define devmap_ifindex(fwd, map)                               \
        (!fwd ? 0 :                                             \
         (!map ? 0 :                                            \
          ((map->map_type == BPF_MAP_TYPE_DEVMAP) ?             \
-          ((struct net_device *)fwd)->ifindex : 0)))
+          ((struct _bpf_dtab_netdev *)fwd)->dev->ifindex : 0)))
 
 #define _trace_xdp_redirect_map(dev, xdp, fwd, map, idx)               \
         trace_xdp_redirect_map(dev, xdp, devmap_ifindex(fwd, map),     \
diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index 565f9ece9115..808808bf2bf2 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -48,18 +48,21 @@
  * calls will fail at this point.
  */
 #include <linux/bpf.h>
+#include <net/xdp.h>
 #include <linux/filter.h>
 
 #define DEV_CREATE_FLAG_MASK \
        (BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY)
 
+/* objects in the map */
 struct bpf_dtab_netdev {
-       struct net_device *dev;
+       struct net_device *dev; /* must be first member, due to tracepoint */
        struct bpf_dtab *dtab;
        unsigned int bit;
        struct rcu_head rcu;
 };
 
+/* bpf map container */
 struct bpf_dtab {
        struct bpf_map map;
        struct bpf_dtab_netdev **netdev_map;
@@ -240,21 +243,43 @@ void __dev_map_flush(struct bpf_map *map)
  * update happens in parallel here a dev_put wont happen until after reading 
the
  * ifindex.
  */
-struct net_device  *__dev_map_lookup_elem(struct bpf_map *map, u32 key)
+struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key)
 {
        struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
-       struct bpf_dtab_netdev *dev;
+       struct bpf_dtab_netdev *obj;
 
        if (key >= map->max_entries)
                return NULL;
 
-       dev = READ_ONCE(dtab->netdev_map[key]);
-       return dev ? dev->dev : NULL;
+       obj = READ_ONCE(dtab->netdev_map[key]);
+       return obj;
+}
+
+int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp)
+{
+       struct net_device *dev = dst->dev;
+       struct xdp_frame *xdpf;
+       int err;
+
+       if (!dev->netdev_ops->ndo_xdp_xmit)
+               return -EOPNOTSUPP;
+
+       xdpf = convert_to_xdp_frame(xdp);
+       if (unlikely(!xdpf))
+               return -EOVERFLOW;
+
+       /* TODO: implement a bulking/enqueue step later */
+       err = dev->netdev_ops->ndo_xdp_xmit(dev, xdpf);
+       if (err)
+               return err;
+
+       return 0;
 }
 
 static void *dev_map_lookup_elem(struct bpf_map *map, void *key)
 {
-       struct net_device *dev = __dev_map_lookup_elem(map, *(u32 *)key);
+       struct bpf_dtab_netdev *obj = __dev_map_lookup_elem(map, *(u32 *)key);
+       struct net_device *dev = dev = obj ? obj->dev : NULL;
 
        return dev ? &dev->ifindex : NULL;
 }
diff --git a/net/core/filter.c b/net/core/filter.c
index ca60d2872da4..284b9ec3d50f 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3024,20 +3024,9 @@ static int __bpf_tx_xdp_map(struct net_device *dev_rx, 
void *fwd,
 
        switch (map->map_type) {
        case BPF_MAP_TYPE_DEVMAP: {
-               struct net_device *dev = fwd;
-               struct xdp_frame *xdpf;
+               struct bpf_dtab_netdev *dst = fwd;
 
-               if (!dev->netdev_ops->ndo_xdp_xmit)
-                       return -EOPNOTSUPP;
-
-               xdpf = convert_to_xdp_frame(xdp);
-               if (unlikely(!xdpf))
-                       return -EOVERFLOW;
-
-               /* TODO: move to inside map code instead, for bulk support
-                * err = dev_map_enqueue(dev, xdp);
-                */
-               err = dev->netdev_ops->ndo_xdp_xmit(dev, xdpf);
+               err = dev_map_enqueue(dst, xdp);
                if (err)
                        return err;
                __dev_map_insert_ctx(map, index);

Reply via email to