History

bpf: offload: report device information about offloaded maps

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.

Jakub Kicinski committed 8 years ago

Commit 52775b31 parent 7a0ef695 files · +69 −0Browse files

Unified · Split

5 files
  1. include/linux/bpf.h +2 −0
  2. include/uapi/linux/bpf.h +3 −0
  3. kernel/bpf/offload.c +55 −0
  4. kernel/bpf/syscall.c +6 −0
  5. tools/include/uapi/linux/bpf.h +3 −0
include/linux/bpf.h+2−0
@@ -586,6 +586,8 @@ void bpf_prog_offload_destroy(struct bpf_prog *prog); · 585 unmodified lines
586586 int bpf_prog_offload_info_fill(struct bpf_prog_info *info,
587587 struct bpf_prog *prog);
588588
589+int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map);
590+
589591 int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value);
590592 int bpf_map_offload_update_elem(struct bpf_map *map,
591593 void *key, void *value, u64 flags);
include/uapi/linux/bpf.h+3−0
@@ -938,6 +938,9 @@ struct bpf_map_info { · 937 unmodified lines
938938 __u32 max_entries;
939939 __u32 map_flags;
940940 char name[BPF_OBJ_NAME_LEN];
941+ __u32 ifindex;
942+ __u64 netns_dev;
943+ __u64 netns_ino;
941944 } __attribute__((aligned(8)));
942945
943946 /* User bpf_sock_ops struct to access socket values and specify request ops
kernel/bpf/offload.c+55−0
@@ -413,6 +413,61 @@ int bpf_map_offload_get_next_key(struct bpf_map *map, void *key, void *next_key) · 412 unmodified lines
413413 return ret;
414414 }
415415
416+struct ns_get_path_bpf_map_args {
417+ struct bpf_offloaded_map *offmap;
418+ struct bpf_map_info *info;
419+};
420+
421+static struct ns_common *bpf_map_offload_info_fill_ns(void *private_data)
422+{
423+ struct ns_get_path_bpf_map_args *args = private_data;
424+ struct ns_common *ns;
425+ struct net *net;
426+
427+ rtnl_lock();
428+ down_read(&bpf_devs_lock);
429+
430+ if (args->offmap->netdev) {
431+ args->info->ifindex = args->offmap->netdev->ifindex;
432+ net = dev_net(args->offmap->netdev);
433+ get_net(net);
434+ ns = &net->ns;
435+ } else {
436+ args->info->ifindex = 0;
437+ ns = NULL;
438+ }
439+
440+ up_read(&bpf_devs_lock);
441+ rtnl_unlock();
442+
443+ return ns;
444+}
445+
446+int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map)
447+{
448+ struct ns_get_path_bpf_map_args args = {
449+ .offmap = map_to_offmap(map),
450+ .info = info,
451+ };
452+ struct inode *ns_inode;
453+ struct path ns_path;
454+ void *res;
455+
456+ res = ns_get_path_cb(&ns_path, bpf_map_offload_info_fill_ns, &args);
457+ if (IS_ERR(res)) {
458+ if (!info->ifindex)
459+ return -ENODEV;
460+ return PTR_ERR(res);
461+ }
462+
463+ ns_inode = ns_path.dentry->d_inode;
464+ info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev);
465+ info->netns_ino = ns_inode->i_ino;
466+ path_put(&ns_path);
467+
468+ return 0;
469+}
470+
416471 bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map)
417472 {
418473 struct bpf_offloaded_map *offmap;
kernel/bpf/syscall.c+6−0
@@ -1801,6 +1801,12 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map, · 1800 unmodified lines
18011801 info.map_flags = map->map_flags;
18021802 memcpy(info.name, map->name, sizeof(map->name));
18031803
1804+ if (bpf_map_is_dev_bound(map)) {
1805+ err = bpf_map_offload_info_fill(&info, map);
1806+ if (err)
1807+ return err;
1808+ }
1809+
18041810 if (copy_to_user(uinfo, &info, info_len) ||
18051811 put_user(info_len, &uattr->info.info_len))
18061812 return -EFAULT;
tools/include/uapi/linux/bpf.h+3−0
@@ -938,6 +938,9 @@ struct bpf_map_info { · 937 unmodified lines
938938 __u32 max_entries;
939939 __u32 map_flags;
940940 char name[BPF_OBJ_NAME_LEN];
941+ __u32 ifindex;
942+ __u64 netns_dev;
943+ __u64 netns_ino;
941944 } __attribute__((aligned(8)));
942945
943946 /* User bpf_sock_ops struct to access socket values and specify request ops