From: Daniel Borkmann <dborkman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>,
Ingo Molnar <mingo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Linus Torvalds
<torvalds-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>,
Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org>,
Hannes Frederic Sowa
<hannes-tFNcAqjVMyqKXQKiL6tip0B+6BGkLq7r@public.gmane.org>,
Chema Gonzalez <chema-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>,
Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>,
Peter Zijlstra
<a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw@public.gmane.org>,
Pablo Neira Ayuso <pablo-Cap9r6Oaw4JrovVCs/uTlw@public.gmane.org>,
"H. Peter Anvin" <hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>,
Andrew Morton
<akpm-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v11 net-next 04/12] bpf: expand BPF syscall with program load/unload
Date: Wed, 10 Sep 2014 10:04:58 +0200 [thread overview]
Message-ID: <5410062A.4090003@redhat.com> (raw)
In-Reply-To: <1410325808-3657-5-git-send-email-ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
On 09/10/2014 07:10 AM, Alexei Starovoitov wrote:
> eBPF programs are similar to kernel modules. They are loaded by the user
> process and automatically unloaded when process exits. Each eBPF program is
> a safe run-to-completion set of instructions. eBPF verifier statically
> determines that the program terminates and is safe to execute.
>
> The following syscall wrapper can be used to load the program:
> int bpf_prog_load(enum bpf_prog_type prog_type,
> const struct bpf_insn *insns, int insn_cnt,
> const char *license)
> {
> union bpf_attr attr = {
> .prog_type = prog_type,
> .insns = insns,
> .insn_cnt = insn_cnt,
> .license = license,
> };
>
> return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
> }
> where 'insns' is an array of eBPF instructions and 'license' is a string
> that must be GPL compatible to call helper functions marked gpl_only
>
> Upon succesful load the syscall returns prog_fd.
> Use close(prog_fd) to unload the program.
>
> User space tests and examples follow in the later patches
>
> Signed-off-by: Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
...
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index 4b59edead908..9727616693e5 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -15,6 +15,7 @@
> struct sk_buff;
> struct sock;
> struct seccomp_data;
> +struct bpf_prog_info;
>
> /* ArgX, context and stack frame pointer register positions. Note,
> * Arg1, Arg2, Arg3, etc are used as argument mappings of function
> @@ -302,8 +303,12 @@ struct bpf_work_struct {
> struct bpf_prog {
> u16 pages; /* Number of allocated pages */
> bool jited; /* Is our filter JIT'ed? */
> + bool has_info; /* whether 'info' is valid */
> u32 len; /* Number of filter blocks */
> - struct sock_fprog_kern *orig_prog; /* Original BPF program */
> + union {
> + struct sock_fprog_kern *orig_prog; /* Original BPF program */
> + struct bpf_prog_info *info;
> + };
All members of this bpf_prog_info should go into bpf_work_struct,
as I have intended this to be a ancillary structure here. Since
we already allocate this anyway, you can reduce complexity by doing
the additional allocation plus remove the has_info member.
> struct bpf_work_struct *work; /* Deferred free work struct */
> unsigned int (*bpf_func)(const struct sk_buff *skb,
> const struct bpf_insn *filter);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 3a03fdf4db0e..1d0411965576 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -99,12 +99,23 @@ enum bpf_cmd {
...
> +/* called by sockets/tracing/seccomp before attaching program to an event
> + * pairs with bpf_prog_put()
> + */
But seccomp already does refcounting on each BPF filter. Or, is the
intention to remove this from seccomp?
> +struct bpf_prog *bpf_prog_get(u32 ufd)
> +{
> + struct fd f = fdget(ufd);
> + struct bpf_prog *prog;
> +
> + prog = get_prog(f);
> +
> + if (IS_ERR(prog))
> + return prog;
> +
> + atomic_inc(&prog->info->refcnt);
> + fdput(f);
> + return prog;
> +}
...
> diff --git a/net/core/filter.c b/net/core/filter.c
> index dfc716ffa44b..d771e4f03745 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -835,6 +835,7 @@ static void bpf_release_orig_filter(struct bpf_prog *fp)
> {
> struct sock_fprog_kern *fprog = fp->orig_prog;
>
> + BUG_ON(fp->has_info);
Why BUG_ON() (also in so many other places)?
> if (fprog) {
> kfree(fprog->filter);
> kfree(fprog);
> @@ -973,6 +974,7 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
>
> fp->bpf_func = NULL;
> fp->jited = false;
> + fp->has_info = false;
>
> err = bpf_check_classic(fp->insns, fp->len);
> if (err) {
>
WARNING: multiple messages have this Message-ID (diff)
From: Daniel Borkmann <dborkman@redhat.com>
To: Alexei Starovoitov <ast@plumgrid.com>
Cc: "David S. Miller" <davem@davemloft.net>,
Ingo Molnar <mingo@kernel.org>,
Linus Torvalds <torvalds@linuxfoundation.org>,
Andy Lutomirski <luto@amacapital.net>,
Steven Rostedt <rostedt@goodmis.org>,
Hannes Frederic Sowa <hannes@stressinduktion.org>,
Chema Gonzalez <chema@google.com>,
Eric Dumazet <edumazet@google.com>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Pablo Neira Ayuso <pablo@netfilter.org>,
"H. Peter Anvin" <hpa@zytor.com>,
Andrew Morton <akpm@linuxfoundation.org>,
Kees Cook <keescook@chromium.org>,
linux-api@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v11 net-next 04/12] bpf: expand BPF syscall with program load/unload
Date: Wed, 10 Sep 2014 10:04:58 +0200 [thread overview]
Message-ID: <5410062A.4090003@redhat.com> (raw)
In-Reply-To: <1410325808-3657-5-git-send-email-ast@plumgrid.com>
On 09/10/2014 07:10 AM, Alexei Starovoitov wrote:
> eBPF programs are similar to kernel modules. They are loaded by the user
> process and automatically unloaded when process exits. Each eBPF program is
> a safe run-to-completion set of instructions. eBPF verifier statically
> determines that the program terminates and is safe to execute.
>
> The following syscall wrapper can be used to load the program:
> int bpf_prog_load(enum bpf_prog_type prog_type,
> const struct bpf_insn *insns, int insn_cnt,
> const char *license)
> {
> union bpf_attr attr = {
> .prog_type = prog_type,
> .insns = insns,
> .insn_cnt = insn_cnt,
> .license = license,
> };
>
> return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
> }
> where 'insns' is an array of eBPF instructions and 'license' is a string
> that must be GPL compatible to call helper functions marked gpl_only
>
> Upon succesful load the syscall returns prog_fd.
> Use close(prog_fd) to unload the program.
>
> User space tests and examples follow in the later patches
>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
...
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index 4b59edead908..9727616693e5 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -15,6 +15,7 @@
> struct sk_buff;
> struct sock;
> struct seccomp_data;
> +struct bpf_prog_info;
>
> /* ArgX, context and stack frame pointer register positions. Note,
> * Arg1, Arg2, Arg3, etc are used as argument mappings of function
> @@ -302,8 +303,12 @@ struct bpf_work_struct {
> struct bpf_prog {
> u16 pages; /* Number of allocated pages */
> bool jited; /* Is our filter JIT'ed? */
> + bool has_info; /* whether 'info' is valid */
> u32 len; /* Number of filter blocks */
> - struct sock_fprog_kern *orig_prog; /* Original BPF program */
> + union {
> + struct sock_fprog_kern *orig_prog; /* Original BPF program */
> + struct bpf_prog_info *info;
> + };
All members of this bpf_prog_info should go into bpf_work_struct,
as I have intended this to be a ancillary structure here. Since
we already allocate this anyway, you can reduce complexity by doing
the additional allocation plus remove the has_info member.
> struct bpf_work_struct *work; /* Deferred free work struct */
> unsigned int (*bpf_func)(const struct sk_buff *skb,
> const struct bpf_insn *filter);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 3a03fdf4db0e..1d0411965576 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -99,12 +99,23 @@ enum bpf_cmd {
...
> +/* called by sockets/tracing/seccomp before attaching program to an event
> + * pairs with bpf_prog_put()
> + */
But seccomp already does refcounting on each BPF filter. Or, is the
intention to remove this from seccomp?
> +struct bpf_prog *bpf_prog_get(u32 ufd)
> +{
> + struct fd f = fdget(ufd);
> + struct bpf_prog *prog;
> +
> + prog = get_prog(f);
> +
> + if (IS_ERR(prog))
> + return prog;
> +
> + atomic_inc(&prog->info->refcnt);
> + fdput(f);
> + return prog;
> +}
...
> diff --git a/net/core/filter.c b/net/core/filter.c
> index dfc716ffa44b..d771e4f03745 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -835,6 +835,7 @@ static void bpf_release_orig_filter(struct bpf_prog *fp)
> {
> struct sock_fprog_kern *fprog = fp->orig_prog;
>
> + BUG_ON(fp->has_info);
Why BUG_ON() (also in so many other places)?
> if (fprog) {
> kfree(fprog->filter);
> kfree(fprog);
> @@ -973,6 +974,7 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
>
> fp->bpf_func = NULL;
> fp->jited = false;
> + fp->has_info = false;
>
> err = bpf_check_classic(fp->insns, fp->len);
> if (err) {
>
next prev parent reply other threads:[~2014-09-10 8:04 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-10 5:09 [PATCH v11 net-next 00/12] eBPF syscall, verifier, testsuite Alexei Starovoitov
2014-09-10 5:09 ` Alexei Starovoitov
2014-09-10 5:09 ` [PATCH v11 net-next 01/12] bpf: introduce BPF syscall and maps Alexei Starovoitov
2014-09-10 5:09 ` [PATCH v11 net-next 02/12] bpf: enable bpf syscall on x64 and i386 Alexei Starovoitov
2014-09-10 5:09 ` [PATCH v11 net-next 03/12] bpf: add lookup/update/delete/iterate methods to BPF maps Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 04/12] bpf: expand BPF syscall with program load/unload Alexei Starovoitov
[not found] ` <1410325808-3657-5-git-send-email-ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
2014-09-10 8:04 ` Daniel Borkmann [this message]
2014-09-10 8:04 ` Daniel Borkmann
2014-09-10 17:19 ` Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 05/12] bpf: handle pseudo BPF_CALL insn Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 06/12] bpf: verifier (add docs) Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 07/12] bpf: verifier (add ability to receive verification log) Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 08/12] bpf: handle pseudo BPF_LD_IMM64 insn Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 09/12] bpf: verifier (add branch/goto checks) Alexei Starovoitov
[not found] ` <1410325808-3657-1-git-send-email-ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
2014-09-10 5:10 ` [PATCH v11 net-next 10/12] bpf: verifier (add verifier core) Alexei Starovoitov
2014-09-10 5:10 ` Alexei Starovoitov
2014-09-10 8:19 ` [PATCH v11 net-next 00/12] eBPF syscall, verifier, testsuite Daniel Borkmann
2014-09-10 8:19 ` Daniel Borkmann
2014-09-10 17:28 ` Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 11/12] net: filter: move eBPF instruction macros Alexei Starovoitov
[not found] ` <1410325808-3657-12-git-send-email-ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
2014-09-10 11:24 ` Daniel Borkmann
2014-09-10 11:24 ` Daniel Borkmann
[not found] ` <54103506.1030501-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-09-10 18:16 ` Alexei Starovoitov
2014-09-10 18:16 ` Alexei Starovoitov
2014-09-11 6:29 ` Daniel Borkmann
2014-09-11 6:45 ` Alexei Starovoitov
2014-09-10 5:10 ` [PATCH v11 net-next 12/12] bpf: mini eBPF library, test stubs and verifier testsuite Alexei Starovoitov
[not found] ` <1410325808-3657-13-git-send-email-ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
2014-09-10 11:35 ` Daniel Borkmann
2014-09-10 11:35 ` Daniel Borkmann
[not found] ` <54103776.3080706-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-09-10 18:08 ` Alexei Starovoitov
2014-09-10 18:08 ` Alexei Starovoitov
[not found] ` <CAMEtUuzEQu30WiYprRcDBogJxxrDeNhvn=kF+z8cVvhR-vjTQg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-17 7:16 ` Daniel Borkmann
2014-09-17 7:16 ` Daniel Borkmann
2014-09-17 16:17 ` Alexei Starovoitov
[not found] ` <CAMEtUuzaCEX9RKDBMnQBZSHdTjjidp81myfSVVi4qQqtSGgtmw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-17 21:59 ` Daniel Borkmann
2014-09-17 21:59 ` Daniel Borkmann
2014-09-17 22:16 ` Alexei Starovoitov
2014-09-10 9:03 ` [PATCH v11 net-next 00/12] eBPF syscall, verifier, testsuite Daniel Borkmann
[not found] ` <541013CE.6020307-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-09-10 17:32 ` Alexei Starovoitov
2014-09-10 17:32 ` Alexei Starovoitov
[not found] ` <CAMEtUuwrHX4ENK9cZ0C+XVB=wkMz1=wLphX_GVLvd8pyJKMXeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-11 19:47 ` Daniel Borkmann
2014-09-11 19:47 ` Daniel Borkmann
[not found] ` <5411FC42.3070505-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-09-11 20:33 ` Alexei Starovoitov
2014-09-11 20:33 ` Alexei Starovoitov
[not found] ` <CAMEtUuziPptHxtw_7fkOdR-paB+8BatNmRPoo3txP8wOp9D6Tw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-11 21:54 ` Andy Lutomirski
2014-09-11 21:54 ` Andy Lutomirski
[not found] ` <CALCETrWCEwscbbfX7wAW-A+VQ5Y92igD36BmTXqFra04Qdwk0Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-11 22:29 ` Alexei Starovoitov
2014-09-11 22:29 ` Alexei Starovoitov
2014-09-12 1:17 ` Andy Lutomirski
2014-09-12 1:29 ` Alexei Starovoitov
2014-09-12 22:40 ` Alexei Starovoitov
2014-09-10 9:21 ` Daniel Borkmann
2014-09-10 17:48 ` Alexei Starovoitov
2014-09-10 18:22 ` Andy Lutomirski
[not found] ` <CALCETrVBb_uQZpodv67XSTGVU40y6+9Ktw=3zAJgGV2mNJ=_0A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-10 20:21 ` Alexei Starovoitov
2014-09-10 20:21 ` Alexei Starovoitov
2014-09-11 19:54 ` Daniel Borkmann
[not found] ` <5411FDE1.3060302-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-09-11 20:35 ` Alexei Starovoitov
2014-09-11 20:35 ` Alexei Starovoitov
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=5410062A.4090003@redhat.com \
--to=dborkman-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw@public.gmane.org \
--cc=akpm-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
--cc=ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org \
--cc=chema-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
--cc=davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org \
--cc=edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
--cc=hannes-tFNcAqjVMyqKXQKiL6tip0B+6BGkLq7r@public.gmane.org \
--cc=hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org \
--cc=keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
--cc=linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org \
--cc=mingo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=pablo-Cap9r6Oaw4JrovVCs/uTlw@public.gmane.org \
--cc=rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org \
--cc=torvalds-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
/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.