forked from mirrors/linux
		
	bpf: offload: report device information for offloaded programs
Report to the user ifindex and namespace information of offloaded programs. If device has disappeared return -ENODEV. Specify the namespace using dev/inode combination. CC: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
		
							parent
							
								
									cdab6ba866
								
							
						
					
					
						commit
						675fc275a3
					
				
					 5 changed files with 73 additions and 0 deletions
				
			
		|  | @ -531,6 +531,8 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, | |||
| 
 | ||||
| int bpf_prog_offload_compile(struct bpf_prog *prog); | ||||
| void bpf_prog_offload_destroy(struct bpf_prog *prog); | ||||
| int bpf_prog_offload_info_fill(struct bpf_prog_info *info, | ||||
| 			       struct bpf_prog *prog); | ||||
| 
 | ||||
| #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) | ||||
| int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); | ||||
|  |  | |||
|  | @ -921,6 +921,9 @@ struct bpf_prog_info { | |||
| 	__u32 nr_map_ids; | ||||
| 	__aligned_u64 map_ids; | ||||
| 	char name[BPF_OBJ_NAME_LEN]; | ||||
| 	__u32 ifindex; | ||||
| 	__u64 netns_dev; | ||||
| 	__u64 netns_ino; | ||||
| } __attribute__((aligned(8))); | ||||
| 
 | ||||
| struct bpf_map_info { | ||||
|  |  | |||
|  | @ -16,9 +16,11 @@ | |||
| #include <linux/bpf.h> | ||||
| #include <linux/bpf_verifier.h> | ||||
| #include <linux/bug.h> | ||||
| #include <linux/kdev_t.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/printk.h> | ||||
| #include <linux/proc_ns.h> | ||||
| #include <linux/rtnetlink.h> | ||||
| #include <linux/rwsem.h> | ||||
| 
 | ||||
|  | @ -176,6 +178,63 @@ int bpf_prog_offload_compile(struct bpf_prog *prog) | |||
| 	return bpf_prog_offload_translate(prog); | ||||
| } | ||||
| 
 | ||||
| struct ns_get_path_bpf_prog_args { | ||||
| 	struct bpf_prog *prog; | ||||
| 	struct bpf_prog_info *info; | ||||
| }; | ||||
| 
 | ||||
| static struct ns_common *bpf_prog_offload_info_fill_ns(void *private_data) | ||||
| { | ||||
| 	struct ns_get_path_bpf_prog_args *args = private_data; | ||||
| 	struct bpf_prog_aux *aux = args->prog->aux; | ||||
| 	struct ns_common *ns; | ||||
| 	struct net *net; | ||||
| 
 | ||||
| 	rtnl_lock(); | ||||
| 	down_read(&bpf_devs_lock); | ||||
| 
 | ||||
| 	if (aux->offload) { | ||||
| 		args->info->ifindex = aux->offload->netdev->ifindex; | ||||
| 		net = dev_net(aux->offload->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_prog_offload_info_fill(struct bpf_prog_info *info, | ||||
| 			       struct bpf_prog *prog) | ||||
| { | ||||
| 	struct ns_get_path_bpf_prog_args args = { | ||||
| 		.prog	= prog, | ||||
| 		.info	= info, | ||||
| 	}; | ||||
| 	struct inode *ns_inode; | ||||
| 	struct path ns_path; | ||||
| 	void *res; | ||||
| 
 | ||||
| 	res = ns_get_path_cb(&ns_path, bpf_prog_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; | ||||
| } | ||||
| 
 | ||||
| const struct bpf_prog_ops bpf_offload_prog_ops = { | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1707,6 +1707,12 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, | |||
| 			return -EFAULT; | ||||
| 	} | ||||
| 
 | ||||
| 	if (bpf_prog_is_dev_bound(prog->aux)) { | ||||
| 		err = bpf_prog_offload_info_fill(&info, prog); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 	} | ||||
| 
 | ||||
| done: | ||||
| 	if (copy_to_user(uinfo, &info, info_len) || | ||||
| 	    put_user(info_len, &uattr->info.info_len)) | ||||
|  |  | |||
|  | @ -921,6 +921,9 @@ struct bpf_prog_info { | |||
| 	__u32 nr_map_ids; | ||||
| 	__aligned_u64 map_ids; | ||||
| 	char name[BPF_OBJ_NAME_LEN]; | ||||
| 	__u32 ifindex; | ||||
| 	__u64 netns_dev; | ||||
| 	__u64 netns_ino; | ||||
| } __attribute__((aligned(8))); | ||||
| 
 | ||||
| struct bpf_map_info { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jakub Kicinski
						Jakub Kicinski