aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/bpf.h2
-rw-r--r--include/uapi/linux/bpf.h3
-rw-r--r--kernel/bpf/offload.c59
-rw-r--r--kernel/bpf/syscall.c6
-rw-r--r--tools/include/uapi/linux/bpf.h3
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
532int bpf_prog_offload_compile(struct bpf_prog *prog); 532int bpf_prog_offload_compile(struct bpf_prog *prog);
533void bpf_prog_offload_destroy(struct bpf_prog *prog); 533void bpf_prog_offload_destroy(struct bpf_prog *prog);
534int 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)
536int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); 538int 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
926struct bpf_map_info { 929struct 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
181struct ns_get_path_bpf_prog_args {
182 struct bpf_prog *prog;
183 struct bpf_prog_info *info;
184};
185
186static 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
212int 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
179const struct bpf_prog_ops bpf_offload_prog_ops = { 238const 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
1710done: 1716done:
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
926struct bpf_map_info { 929struct bpf_map_info {