mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-21 11:44:01 +08:00
bpf: add BPF_PROG_ATTACH and BPF_PROG_DETACH commands
Extend the bpf(2) syscall by two new commands, BPF_PROG_ATTACH and BPF_PROG_DETACH which allow attaching and detaching eBPF programs to a target. On the API level, the target could be anything that has an fd in userspace, hence the name of the field in union bpf_attr is called 'target_fd'. When called with BPF_ATTACH_TYPE_CGROUP_INET_{E,IN}GRESS, the target is expected to be a valid file descriptor of a cgroup v2 directory which has the bpf controller enabled. These are the only use-cases implemented by this patch at this point, but more can be added. If a program of the given type already exists in the given cgroup, the program is swapped automically, so userspace does not have to drop an existing program first before installing a new one, which would otherwise leave a gap in which no program is attached. For more information on the propagation logic to subcgroups, please refer to the bpf cgroup controller implementation. The API is guarded by CAP_NET_ADMIN. Signed-off-by: Daniel Mack <daniel@zonque.org> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3007098494
commit
f432455148
@ -73,6 +73,8 @@ enum bpf_cmd {
|
||||
BPF_PROG_LOAD,
|
||||
BPF_OBJ_PIN,
|
||||
BPF_OBJ_GET,
|
||||
BPF_PROG_ATTACH,
|
||||
BPF_PROG_DETACH,
|
||||
};
|
||||
|
||||
enum bpf_map_type {
|
||||
@ -159,6 +161,12 @@ union bpf_attr {
|
||||
__aligned_u64 pathname;
|
||||
__u32 bpf_fd;
|
||||
};
|
||||
|
||||
struct { /* anonymous struct used by BPF_PROG_ATTACH/DETACH commands */
|
||||
__u32 target_fd; /* container object to attach to */
|
||||
__u32 attach_bpf_fd; /* eBPF program to attach */
|
||||
__u32 attach_type;
|
||||
};
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* BPF helper function descriptions:
|
||||
|
@ -835,6 +835,77 @@ static int bpf_obj_get(const union bpf_attr *attr)
|
||||
return bpf_obj_get_user(u64_to_user_ptr(attr->pathname));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CGROUP_BPF
|
||||
|
||||
#define BPF_PROG_ATTACH_LAST_FIELD attach_type
|
||||
|
||||
static int bpf_prog_attach(const union bpf_attr *attr)
|
||||
{
|
||||
struct bpf_prog *prog;
|
||||
struct cgroup *cgrp;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (CHECK_ATTR(BPF_PROG_ATTACH))
|
||||
return -EINVAL;
|
||||
|
||||
switch (attr->attach_type) {
|
||||
case BPF_CGROUP_INET_INGRESS:
|
||||
case BPF_CGROUP_INET_EGRESS:
|
||||
prog = bpf_prog_get_type(attr->attach_bpf_fd,
|
||||
BPF_PROG_TYPE_CGROUP_SKB);
|
||||
if (IS_ERR(prog))
|
||||
return PTR_ERR(prog);
|
||||
|
||||
cgrp = cgroup_get_from_fd(attr->target_fd);
|
||||
if (IS_ERR(cgrp)) {
|
||||
bpf_prog_put(prog);
|
||||
return PTR_ERR(cgrp);
|
||||
}
|
||||
|
||||
cgroup_bpf_update(cgrp, prog, attr->attach_type);
|
||||
cgroup_put(cgrp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BPF_PROG_DETACH_LAST_FIELD attach_type
|
||||
|
||||
static int bpf_prog_detach(const union bpf_attr *attr)
|
||||
{
|
||||
struct cgroup *cgrp;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (CHECK_ATTR(BPF_PROG_DETACH))
|
||||
return -EINVAL;
|
||||
|
||||
switch (attr->attach_type) {
|
||||
case BPF_CGROUP_INET_INGRESS:
|
||||
case BPF_CGROUP_INET_EGRESS:
|
||||
cgrp = cgroup_get_from_fd(attr->target_fd);
|
||||
if (IS_ERR(cgrp))
|
||||
return PTR_ERR(cgrp);
|
||||
|
||||
cgroup_bpf_update(cgrp, NULL, attr->attach_type);
|
||||
cgroup_put(cgrp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CGROUP_BPF */
|
||||
|
||||
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
@ -901,6 +972,16 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
|
||||
case BPF_OBJ_GET:
|
||||
err = bpf_obj_get(&attr);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_CGROUP_BPF
|
||||
case BPF_PROG_ATTACH:
|
||||
err = bpf_prog_attach(&attr);
|
||||
break;
|
||||
case BPF_PROG_DETACH:
|
||||
err = bpf_prog_detach(&attr);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user