Message ID | 20190724170018.96659-4-sdf@google.com |
---|---|
State | Changes Requested |
Delegated to: | BPF Maintainers |
Headers | show |
Series | bpf/flow_dissector: support input flags | expand |
On Wed, Jul 24, 2019 at 10:11 AM Stanislav Fomichev <sdf@google.com> wrote: > > This will allow us to write tests for those flags. > > Cc: Willem de Bruijn <willemb@google.com> > Cc: Petar Penkov <ppenkov@google.com> > Signed-off-by: Stanislav Fomichev <sdf@google.com> Acked-by: Song Liu <songliubraving@fb.com> > --- > net/bpf/test_run.c | 39 +++++++++++++++++++++++++++++++++++---- > 1 file changed, 35 insertions(+), 4 deletions(-) > > diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c > index 4e41d15a1098..444a7baed791 100644 > --- a/net/bpf/test_run.c > +++ b/net/bpf/test_run.c > @@ -377,6 +377,22 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, > return ret; > } > > +static int verify_user_bpf_flow_keys(struct bpf_flow_keys *ctx) > +{ > + /* make sure the fields we don't use are zeroed */ > + if (!range_is_zero(ctx, 0, offsetof(struct bpf_flow_keys, flags))) > + return -EINVAL; > + > + /* flags is allowed */ > + > + if (!range_is_zero(ctx, offsetof(struct bpf_flow_keys, flags) + > + FIELD_SIZEOF(struct bpf_flow_keys, flags), > + sizeof(struct bpf_flow_keys))) > + return -EINVAL; > + > + return 0; > +} > + > int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, > const union bpf_attr *kattr, > union bpf_attr __user *uattr) > @@ -384,9 +400,11 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, > u32 size = kattr->test.data_size_in; > struct bpf_flow_dissector ctx = {}; > u32 repeat = kattr->test.repeat; > + struct bpf_flow_keys *user_ctx; > struct bpf_flow_keys flow_keys; > u64 time_start, time_spent = 0; > const struct ethhdr *eth; > + unsigned int flags = 0; > u32 retval, duration; > void *data; > int ret; > @@ -395,9 +413,6 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, > if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR) > return -EINVAL; > > - if (kattr->test.ctx_in || kattr->test.ctx_out) > - return -EINVAL; > - > if (size < ETH_HLEN) > return -EINVAL; > > @@ -410,6 +425,18 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, > if (!repeat) > repeat = 1; > > + user_ctx = bpf_ctx_init(kattr, sizeof(struct bpf_flow_keys)); > + if (IS_ERR(user_ctx)) { > + kfree(data); > + return PTR_ERR(user_ctx); > + } > + if (user_ctx) { > + ret = verify_user_bpf_flow_keys(user_ctx); > + if (ret) > + goto out; > + flags = user_ctx->flags; > + } > + > ctx.flow_keys = &flow_keys; > ctx.data = data; > ctx.data_end = (__u8 *)data + size; > @@ -419,7 +446,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, > time_start = ktime_get_ns(); > for (i = 0; i < repeat; i++) { > retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN, > - size, 0); > + size, flags); > > if (signal_pending(current)) { > preempt_enable(); > @@ -450,8 +477,12 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, > > ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys), > retval, duration); > + if (!ret) > + ret = bpf_ctx_finish(kattr, uattr, user_ctx, > + sizeof(struct bpf_flow_keys)); > > out: > kfree(data); > + kfree(user_ctx); nit: it is not really necessary now, but maybe put kfree(user_ctx) before kfree(data). > return ret; > } > -- > 2.22.0.657.g960e92d24f-goog >
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 4e41d15a1098..444a7baed791 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -377,6 +377,22 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, return ret; } +static int verify_user_bpf_flow_keys(struct bpf_flow_keys *ctx) +{ + /* make sure the fields we don't use are zeroed */ + if (!range_is_zero(ctx, 0, offsetof(struct bpf_flow_keys, flags))) + return -EINVAL; + + /* flags is allowed */ + + if (!range_is_zero(ctx, offsetof(struct bpf_flow_keys, flags) + + FIELD_SIZEOF(struct bpf_flow_keys, flags), + sizeof(struct bpf_flow_keys))) + return -EINVAL; + + return 0; +} + int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr) @@ -384,9 +400,11 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, u32 size = kattr->test.data_size_in; struct bpf_flow_dissector ctx = {}; u32 repeat = kattr->test.repeat; + struct bpf_flow_keys *user_ctx; struct bpf_flow_keys flow_keys; u64 time_start, time_spent = 0; const struct ethhdr *eth; + unsigned int flags = 0; u32 retval, duration; void *data; int ret; @@ -395,9 +413,6 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR) return -EINVAL; - if (kattr->test.ctx_in || kattr->test.ctx_out) - return -EINVAL; - if (size < ETH_HLEN) return -EINVAL; @@ -410,6 +425,18 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (!repeat) repeat = 1; + user_ctx = bpf_ctx_init(kattr, sizeof(struct bpf_flow_keys)); + if (IS_ERR(user_ctx)) { + kfree(data); + return PTR_ERR(user_ctx); + } + if (user_ctx) { + ret = verify_user_bpf_flow_keys(user_ctx); + if (ret) + goto out; + flags = user_ctx->flags; + } + ctx.flow_keys = &flow_keys; ctx.data = data; ctx.data_end = (__u8 *)data + size; @@ -419,7 +446,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, time_start = ktime_get_ns(); for (i = 0; i < repeat; i++) { retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN, - size, 0); + size, flags); if (signal_pending(current)) { preempt_enable(); @@ -450,8 +477,12 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys), retval, duration); + if (!ret) + ret = bpf_ctx_finish(kattr, uattr, user_ctx, + sizeof(struct bpf_flow_keys)); out: kfree(data); + kfree(user_ctx); return ret; }
This will allow us to write tests for those flags. Cc: Willem de Bruijn <willemb@google.com> Cc: Petar Penkov <ppenkov@google.com> Signed-off-by: Stanislav Fomichev <sdf@google.com> --- net/bpf/test_run.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-)