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
|
@ -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 New Issue