bpf: offload: report device information about offloaded maps
authorJakub Kicinski <jakub.kicinski@netronome.com>
Thu, 18 Jan 2018 03:13:28 +0000 (19:13 -0800)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 18 Jan 2018 21:54:25 +0000 (22:54 +0100)
Tell user space about device on which the map was created.
Unfortunate reality of user ABI makes sharing this code
with program offload difficult but the information is the
same.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/linux/bpf.h
include/uapi/linux/bpf.h
kernel/bpf/offload.c
kernel/bpf/syscall.c
tools/include/uapi/linux/bpf.h

index 025b1c2f80532e32c5c12c53c55dfab0f07c8cb4..66df387106de4bcb62547b9698cd8872269e7f37 100644 (file)
@@ -586,6 +586,8 @@ void bpf_prog_offload_destroy(struct bpf_prog *prog);
 int bpf_prog_offload_info_fill(struct bpf_prog_info *info,
                               struct bpf_prog *prog);
 
+int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map);
+
 int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value);
 int bpf_map_offload_update_elem(struct bpf_map *map,
                                void *key, void *value, u64 flags);
index 74dc4dc98681ac6fdb308f7a2715c85bf004ab1b..406c19d6016b209fb1988680c7fe958c2a7e9c2c 100644 (file)
@@ -938,6 +938,9 @@ struct bpf_map_info {
        __u32 max_entries;
        __u32 map_flags;
        char  name[BPF_OBJ_NAME_LEN];
+       __u32 ifindex;
+       __u64 netns_dev;
+       __u64 netns_ino;
 } __attribute__((aligned(8)));
 
 /* User bpf_sock_ops struct to access socket values and specify request ops
index 2657976aec2a8aff3873b938d07a23019d8f3ce6..c9401075b58c842d7a6e239d51a25283d1f53b3f 100644 (file)
@@ -413,6 +413,61 @@ int bpf_map_offload_get_next_key(struct bpf_map *map, void *key, void *next_key)
        return ret;
 }
 
+struct ns_get_path_bpf_map_args {
+       struct bpf_offloaded_map *offmap;
+       struct bpf_map_info *info;
+};
+
+static struct ns_common *bpf_map_offload_info_fill_ns(void *private_data)
+{
+       struct ns_get_path_bpf_map_args *args = private_data;
+       struct ns_common *ns;
+       struct net *net;
+
+       rtnl_lock();
+       down_read(&bpf_devs_lock);
+
+       if (args->offmap->netdev) {
+               args->info->ifindex = args->offmap->netdev->ifindex;
+               net = dev_net(args->offmap->netdev);
+               get_net(net);
+               ns = &net->ns;
+       } else {
+               args->info->ifindex = 0;
+               ns = NULL;
+       }
+
+       up_read(&bpf_devs_lock);
+       rtnl_unlock();
+
+       return ns;
+}
+
+int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map)
+{
+       struct ns_get_path_bpf_map_args args = {
+               .offmap = map_to_offmap(map),
+               .info   = info,
+       };
+       struct inode *ns_inode;
+       struct path ns_path;
+       void *res;
+
+       res = ns_get_path_cb(&ns_path, bpf_map_offload_info_fill_ns, &args);
+       if (IS_ERR(res)) {
+               if (!info->ifindex)
+                       return -ENODEV;
+               return PTR_ERR(res);
+       }
+
+       ns_inode = ns_path.dentry->d_inode;
+       info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev);
+       info->netns_ino = ns_inode->i_ino;
+       path_put(&ns_path);
+
+       return 0;
+}
+
 bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map)
 {
        struct bpf_offloaded_map *offmap;
index 97a825ffc7639526b163b936d9eae0862f9758c9..5bdb0cc84ad24c1596506d1bb68f2e1cb05ed791 100644 (file)
@@ -1801,6 +1801,12 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
        info.map_flags = map->map_flags;
        memcpy(info.name, map->name, sizeof(map->name));
 
+       if (bpf_map_is_dev_bound(map)) {
+               err = bpf_map_offload_info_fill(&info, map);
+               if (err)
+                       return err;
+       }
+
        if (copy_to_user(uinfo, &info, info_len) ||
            put_user(info_len, &uattr->info.info_len))
                return -EFAULT;
index 7c2259e8bc545998cc4d88a0ed3b18cabbde202d..af1f49ad8b88d5eea71040a1743bb0271c0c2180 100644 (file)
@@ -938,6 +938,9 @@ struct bpf_map_info {
        __u32 max_entries;
        __u32 map_flags;
        char  name[BPF_OBJ_NAME_LEN];
+       __u32 ifindex;
+       __u64 netns_dev;
+       __u64 netns_ino;
 } __attribute__((aligned(8)));
 
 /* User bpf_sock_ops struct to access socket values and specify request ops