bpf/flow_dissector: support flags in BPF_PROG_TEST_RUN
This will allow us to write tests for those flags. v2: * Swap kfree(data) and kfree(user_ctx) (Song Liu) Acked-by: Petar Penkov <ppenkov@google.com> Acked-by: Willem de Bruijn <willemb@google.com> Acked-by: Song Liu <songliubraving@fb.com> Cc: Song Liu <songliubraving@fb.com> Cc: Willem de Bruijn <willemb@google.com> Cc: Petar Penkov <ppenkov@google.com> Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
1ac6b126db
commit
b2ca4e1cfa
|
@ -377,6 +377,22 @@ out:
|
|||
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(user_ctx);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue