diff options
| -rw-r--r-- | include/linux/bpf.h | 2 | ||||
| -rw-r--r-- | include/uapi/linux/bpf.h | 3 | ||||
| -rw-r--r-- | kernel/bpf/offload.c | 59 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 6 | ||||
| -rw-r--r-- | tools/include/uapi/linux/bpf.h | 3 |
5 files changed, 73 insertions, 0 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9a916ab34299..7810ae57b357 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -531,6 +531,8 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, | |||
| 531 | 531 | ||
| 532 | int bpf_prog_offload_compile(struct bpf_prog *prog); | 532 | int bpf_prog_offload_compile(struct bpf_prog *prog); |
| 533 | void bpf_prog_offload_destroy(struct bpf_prog *prog); | 533 | void bpf_prog_offload_destroy(struct bpf_prog *prog); |
| 534 | int bpf_prog_offload_info_fill(struct bpf_prog_info *info, | ||
| 535 | struct bpf_prog *prog); | ||
| 534 | 536 | ||
| 535 | #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) | 537 | #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) |
| 536 | int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); | 538 | int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); |
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 69eabfcb9bdb..f2f8b36e2ad4 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h | |||
| @@ -921,6 +921,9 @@ struct bpf_prog_info { | |||
| 921 | __u32 nr_map_ids; | 921 | __u32 nr_map_ids; |
| 922 | __aligned_u64 map_ids; | 922 | __aligned_u64 map_ids; |
| 923 | char name[BPF_OBJ_NAME_LEN]; | 923 | char name[BPF_OBJ_NAME_LEN]; |
| 924 | __u32 ifindex; | ||
| 925 | __u64 netns_dev; | ||
| 926 | __u64 netns_ino; | ||
| 924 | } __attribute__((aligned(8))); | 927 | } __attribute__((aligned(8))); |
| 925 | 928 | ||
| 926 | struct bpf_map_info { | 929 | struct bpf_map_info { |
diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index e4f1668a021c..040d4e0edf3f 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c | |||
| @@ -16,9 +16,11 @@ | |||
| 16 | #include <linux/bpf.h> | 16 | #include <linux/bpf.h> |
| 17 | #include <linux/bpf_verifier.h> | 17 | #include <linux/bpf_verifier.h> |
| 18 | #include <linux/bug.h> | 18 | #include <linux/bug.h> |
| 19 | #include <linux/kdev_t.h> | ||
| 19 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 20 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
| 21 | #include <linux/printk.h> | 22 | #include <linux/printk.h> |
| 23 | #include <linux/proc_ns.h> | ||
| 22 | #include <linux/rtnetlink.h> | 24 | #include <linux/rtnetlink.h> |
| 23 | #include <linux/rwsem.h> | 25 | #include <linux/rwsem.h> |
| 24 | 26 | ||
| @@ -176,6 +178,63 @@ int bpf_prog_offload_compile(struct bpf_prog *prog) | |||
| 176 | return bpf_prog_offload_translate(prog); | 178 | return bpf_prog_offload_translate(prog); |
| 177 | } | 179 | } |
| 178 | 180 | ||
| 181 | struct ns_get_path_bpf_prog_args { | ||
| 182 | struct bpf_prog *prog; | ||
| 183 | struct bpf_prog_info *info; | ||
| 184 | }; | ||
| 185 | |||
| 186 | static struct ns_common *bpf_prog_offload_info_fill_ns(void *private_data) | ||
| 187 | { | ||
| 188 | struct ns_get_path_bpf_prog_args *args = private_data; | ||
| 189 | struct bpf_prog_aux *aux = args->prog->aux; | ||
| 190 | struct ns_common *ns; | ||
| 191 | struct net *net; | ||
| 192 | |||
| 193 | rtnl_lock(); | ||
| 194 | down_read(&bpf_devs_lock); | ||
| 195 | |||
| 196 | if (aux->offload) { | ||
| 197 | args->info->ifindex = aux->offload->netdev->ifindex; | ||
| 198 | net = dev_net(aux->offload->netdev); | ||
| 199 | get_net(net); | ||
| 200 | ns = &net->ns; | ||
| 201 | } else { | ||
| 202 | args->info->ifindex = 0; | ||
| 203 | ns = NULL; | ||
| 204 | } | ||
| 205 | |||
| 206 | up_read(&bpf_devs_lock); | ||
| 207 | rtnl_unlock(); | ||
| 208 | |||
| 209 | return ns; | ||
| 210 | } | ||
| 211 | |||
| 212 | int bpf_prog_offload_info_fill(struct bpf_prog_info *info, | ||
| 213 | struct bpf_prog *prog) | ||
| 214 | { | ||
| 215 | struct ns_get_path_bpf_prog_args args = { | ||
| 216 | .prog = prog, | ||
| 217 | .info = info, | ||
| 218 | }; | ||
| 219 | struct inode *ns_inode; | ||
| 220 | struct path ns_path; | ||
| 221 | void *res; | ||
| 222 | |||
| 223 | res = ns_get_path_cb(&ns_path, bpf_prog_offload_info_fill_ns, &args); | ||
| 224 | if (IS_ERR(res)) { | ||
| 225 | if (!info->ifindex) | ||
| 226 | return -ENODEV; | ||
| 227 | return PTR_ERR(res); | ||
| 228 | } | ||
| 229 | |||
| 230 | ns_inode = ns_path.dentry->d_inode; | ||
| 231 | info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev); | ||
| 232 | info->netns_ino = ns_inode->i_ino; | ||
| 233 | path_put(&ns_path); | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 179 | const struct bpf_prog_ops bpf_offload_prog_ops = { | 238 | const struct bpf_prog_ops bpf_offload_prog_ops = { |
| 180 | }; | 239 | }; |
| 181 | 240 | ||
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index e02dafa6f402..ebf0fb23e237 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -1707,6 +1707,12 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, | |||
| 1707 | return -EFAULT; | 1707 | return -EFAULT; |
| 1708 | } | 1708 | } |
| 1709 | 1709 | ||
| 1710 | if (bpf_prog_is_dev_bound(prog->aux)) { | ||
| 1711 | err = bpf_prog_offload_info_fill(&info, prog); | ||
| 1712 | if (err) | ||
| 1713 | return err; | ||
| 1714 | } | ||
| 1715 | |||
| 1710 | done: | 1716 | done: |
| 1711 | if (copy_to_user(uinfo, &info, info_len) || | 1717 | if (copy_to_user(uinfo, &info, info_len) || |
| 1712 | put_user(info_len, &uattr->info.info_len)) | 1718 | put_user(info_len, &uattr->info.info_len)) |
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index db1b0923a308..4e8c60acfa32 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
| @@ -921,6 +921,9 @@ struct bpf_prog_info { | |||
| 921 | __u32 nr_map_ids; | 921 | __u32 nr_map_ids; |
| 922 | __aligned_u64 map_ids; | 922 | __aligned_u64 map_ids; |
| 923 | char name[BPF_OBJ_NAME_LEN]; | 923 | char name[BPF_OBJ_NAME_LEN]; |
| 924 | __u32 ifindex; | ||
| 925 | __u64 netns_dev; | ||
| 926 | __u64 netns_ino; | ||
| 924 | } __attribute__((aligned(8))); | 927 | } __attribute__((aligned(8))); |
| 925 | 928 | ||
| 926 | struct bpf_map_info { | 929 | struct bpf_map_info { |
