From: Daniel Mack <daniel@zonque.org>
To: htejun@fb.com, daniel@iogearbox.net, ast@fb.com
Cc: davem@davemloft.net, kafai@fb.com, fw@strlen.de,
pablo@netfilter.org, harald@redhat.com, netdev@vger.kernel.org,
sargun@sargun.me, cgroups@vger.kernel.org,
Daniel Mack <daniel@zonque.org>
Subject: [PATCH v5 3/6] bpf: add BPF_PROG_ATTACH and BPF_PROG_DETACH commands
Date: Mon, 12 Sep 2016 18:12:12 +0200 [thread overview]
Message-ID: <1473696735-11269-4-git-send-email-daniel@zonque.org> (raw)
In-Reply-To: <1473696735-11269-1-git-send-email-daniel@zonque.org>
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>
---
include/uapi/linux/bpf.h | 8 +++++
kernel/bpf/syscall.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 55f815e..7cd3616 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -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 {
@@ -150,6 +152,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)));
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 228f962..1a8592a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -822,6 +822,77 @@ static int bpf_obj_get(const union bpf_attr *attr)
return bpf_obj_get_user(u64_to_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_SOCKET);
+ 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 = {};
@@ -888,6 +959,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;
--
2.5.5
next prev parent reply other threads:[~2016-09-12 16:12 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-12 16:12 [PATCH v5 0/6] Add eBPF hooks for cgroups Daniel Mack
2016-09-12 16:12 ` [PATCH v5 1/6] bpf: add new prog type for cgroup socket filtering Daniel Mack
2016-09-12 16:12 ` [PATCH v5 2/6] cgroup: add support for eBPF programs Daniel Mack
2016-09-12 16:12 ` Daniel Mack [this message]
[not found] ` <1473696735-11269-1-git-send-email-daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>
2016-09-12 16:12 ` [PATCH v5 4/6] net: filter: run cgroup eBPF ingress programs Daniel Mack
2016-09-12 16:12 ` [PATCH v5 5/6] net: core: run cgroup eBPF egress programs Daniel Mack
2016-09-12 16:12 ` [PATCH v5 6/6] samples: bpf: add userspace example for attaching eBPF programs to cgroups Daniel Mack
2016-09-13 11:56 ` [PATCH v5 0/6] Add eBPF hooks for cgroups Pablo Neira Ayuso
2016-09-13 13:31 ` Daniel Mack
[not found] ` <da300784-284c-0d1f-a82e-aa0a0f8ae116-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>
2016-09-13 14:14 ` Daniel Borkmann
2016-09-13 17:24 ` Pablo Neira Ayuso
2016-09-14 4:42 ` Alexei Starovoitov
2016-09-14 9:03 ` Thomas Graf
[not found] ` <20160914044217.GA44742-+o4/htvd0TDFYCXBM6kdu7fOX0fSgVTm@public.gmane.org>
2016-09-14 10:30 ` Pablo Neira Ayuso
2016-09-14 11:06 ` Thomas Graf
2016-09-14 11:36 ` Daniel Borkmann
2016-09-14 11:13 ` Daniel Mack
[not found] ` <6de6809a-13f5-4000-5639-c760dde30223-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>
2016-09-14 11:42 ` Daniel Borkmann
[not found] ` <57D937B9.2090100-FeC+5ew28dpmcu3hnIyYJQ@public.gmane.org>
2016-09-14 15:55 ` Alexei Starovoitov
2016-09-16 19:57 ` Sargun Dhillon
[not found] ` <20160916195728.GA14736-I4sfFR6g6EicJoAdRrHjTrzMkBWIpU9tytq7g7fCXyjEk0E+pv7Png@public.gmane.org>
2016-09-18 23:34 ` Sargun Dhillon
2016-09-19 16:34 ` Daniel Mack
2016-09-19 21:53 ` Sargun Dhillon
[not found] ` <20160919215311.GA9723-I4sfFR6g6EicJoAdRrHjTrzMkBWIpU9tytq7g7fCXyjEk0E+pv7Png@public.gmane.org>
2016-09-20 14:25 ` Daniel Mack
2016-09-15 6:36 ` Vincent Bernat
[not found] ` <m3y42tlldz.fsf-PiWSfznZvZU/eRriIvX0kg@public.gmane.org>
2016-09-15 8:11 ` Daniel Mack
2016-09-15 8:11 ` Daniel Mack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1473696735-11269-4-git-send-email-daniel@zonque.org \
--to=daniel@zonque.org \
--cc=ast@fb.com \
--cc=cgroups@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=fw@strlen.de \
--cc=harald@redhat.com \
--cc=htejun@fb.com \
--cc=kafai@fb.com \
--cc=netdev@vger.kernel.org \
--cc=pablo@netfilter.org \
--cc=sargun@sargun.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.