Skip to content

Commit 675fc27

Browse files
Jakub Kicinskiborkmann
authored andcommitted
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 <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent cdab6ba commit 675fc27

File tree

5 files changed

+73
-0
lines changed

5 files changed

+73
-0
lines changed

include/linux/bpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,8 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd,
531531

532532
int bpf_prog_offload_compile(struct bpf_prog *prog);
533533
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);
534536

535537
#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
536538
int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr);

include/uapi/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,9 @@ struct bpf_prog_info {
921921
__u32 nr_map_ids;
922922
__aligned_u64 map_ids;
923923
char name[BPF_OBJ_NAME_LEN];
924+
__u32 ifindex;
925+
__u64 netns_dev;
926+
__u64 netns_ino;
924927
} __attribute__((aligned(8)));
925928

926929
struct bpf_map_info {

kernel/bpf/offload.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include <linux/bpf.h>
1717
#include <linux/bpf_verifier.h>
1818
#include <linux/bug.h>
19+
#include <linux/kdev_t.h>
1920
#include <linux/list.h>
2021
#include <linux/netdevice.h>
2122
#include <linux/printk.h>
23+
#include <linux/proc_ns.h>
2224
#include <linux/rtnetlink.h>
2325
#include <linux/rwsem.h>
2426

@@ -176,6 +178,63 @@ int bpf_prog_offload_compile(struct bpf_prog *prog)
176178
return bpf_prog_offload_translate(prog);
177179
}
178180

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+
179238
const struct bpf_prog_ops bpf_offload_prog_ops = {
180239
};
181240

kernel/bpf/syscall.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,12 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
17071707
return -EFAULT;
17081708
}
17091709

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+
17101716
done:
17111717
if (copy_to_user(uinfo, &info, info_len) ||
17121718
put_user(info_len, &uattr->info.info_len))

tools/include/uapi/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,9 @@ struct bpf_prog_info {
921921
__u32 nr_map_ids;
922922
__aligned_u64 map_ids;
923923
char name[BPF_OBJ_NAME_LEN];
924+
__u32 ifindex;
925+
__u64 netns_dev;
926+
__u64 netns_ino;
924927
} __attribute__((aligned(8)));
925928

926929
struct bpf_map_info {

0 commit comments

Comments
 (0)