Skip to content

Commit

Permalink
bpf: offload: report device information for offloaded programs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jakub Kicinski authored and borkmann committed Dec 31, 2017
1 parent cdab6ba commit 675fc27
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/linux/bpf.h
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions include/uapi/linux/bpf.h
Expand Up @@ -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 {
Expand Down
59 changes: 59 additions & 0 deletions kernel/bpf/offload.c
Expand Up @@ -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>

Expand Down Expand Up @@ -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 = {
};

Expand Down
6 changes: 6 additions & 0 deletions kernel/bpf/syscall.c
Expand Up @@ -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))
Expand Down
3 changes: 3 additions & 0 deletions tools/include/uapi/linux/bpf.h
Expand Up @@ -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 {
Expand Down

0 comments on commit 675fc27

Please sign in to comment.