mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-05-12 02:03:55 +00: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
2 changed files with 89 additions and 0 deletions
|
@ -73,6 +73,8 @@ enum bpf_cmd {
|
||||||
BPF_PROG_LOAD,
|
BPF_PROG_LOAD,
|
||||||
BPF_OBJ_PIN,
|
BPF_OBJ_PIN,
|
||||||
BPF_OBJ_GET,
|
BPF_OBJ_GET,
|
||||||
|
BPF_PROG_ATTACH,
|
||||||
|
BPF_PROG_DETACH,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bpf_map_type {
|
enum bpf_map_type {
|
||||||
|
@ -159,6 +161,12 @@ union bpf_attr {
|
||||||
__aligned_u64 pathname;
|
__aligned_u64 pathname;
|
||||||
__u32 bpf_fd;
|
__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)));
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
/* BPF helper function descriptions:
|
/* 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));
|
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)
|
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
|
||||||
{
|
{
|
||||||
union bpf_attr attr = {};
|
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:
|
case BPF_OBJ_GET:
|
||||||
err = bpf_obj_get(&attr);
|
err = bpf_obj_get(&attr);
|
||||||
break;
|
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:
|
default:
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue