diff options
| author | Stanislav Fomichev <[email protected]> | 2019-06-27 20:38:53 +0000 |
|---|---|---|
| committer | Alexei Starovoitov <[email protected]> | 2019-06-27 22:25:17 +0000 |
| commit | 65b4414a05ebf51966c4a28a2a1b156ab5a01b0f (patch) | |
| tree | 8f93883423a152879c420715a863227d8eb3bf39 /tools/testing/selftests/bpf/progs/sockopt_multi.c | |
| parent | selftests/bpf: add sockopt test that exercises sk helpers (diff) | |
| download | kernel-65b4414a05ebf51966c4a28a2a1b156ab5a01b0f.tar.gz kernel-65b4414a05ebf51966c4a28a2a1b156ab5a01b0f.zip | |
selftests/bpf: add sockopt test that exercises BPF_F_ALLOW_MULTI
sockopt test that verifies chaining behavior.
v9:
* setsockopt chaining example
v7:
* rework the test to verify cgroup getsockopt chaining
Cc: Andrii Nakryiko <[email protected]>
Cc: Martin Lau <[email protected]>
Signed-off-by: Stanislav Fomichev <[email protected]>
Signed-off-by: Alexei Starovoitov <[email protected]>
Diffstat (limited to 'tools/testing/selftests/bpf/progs/sockopt_multi.c')
| -rw-r--r-- | tools/testing/selftests/bpf/progs/sockopt_multi.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/sockopt_multi.c b/tools/testing/selftests/bpf/progs/sockopt_multi.c new file mode 100644 index 000000000000..4afd2595c08e --- /dev/null +++ b/tools/testing/selftests/bpf/progs/sockopt_multi.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <netinet/in.h> +#include <linux/bpf.h> +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; +__u32 _version SEC("version") = 1; + +SEC("cgroup/getsockopt/child") +int _getsockopt_child(struct bpf_sockopt *ctx) +{ + __u8 *optval_end = ctx->optval_end; + __u8 *optval = ctx->optval; + + if (ctx->level != SOL_IP || ctx->optname != IP_TOS) + return 1; + + if (optval + 1 > optval_end) + return 0; /* EPERM, bounds check */ + + if (optval[0] != 0x80) + return 0; /* EPERM, unexpected optval from the kernel */ + + ctx->retval = 0; /* Reset system call return value to zero */ + + optval[0] = 0x90; + ctx->optlen = 1; + + return 1; +} + +SEC("cgroup/getsockopt/parent") +int _getsockopt_parent(struct bpf_sockopt *ctx) +{ + __u8 *optval_end = ctx->optval_end; + __u8 *optval = ctx->optval; + + if (ctx->level != SOL_IP || ctx->optname != IP_TOS) + return 1; + + if (optval + 1 > optval_end) + return 0; /* EPERM, bounds check */ + + if (optval[0] != 0x90) + return 0; /* EPERM, unexpected optval from the kernel */ + + ctx->retval = 0; /* Reset system call return value to zero */ + + optval[0] = 0xA0; + ctx->optlen = 1; + + return 1; +} + +SEC("cgroup/setsockopt") +int _setsockopt(struct bpf_sockopt *ctx) +{ + __u8 *optval_end = ctx->optval_end; + __u8 *optval = ctx->optval; + + if (ctx->level != SOL_IP || ctx->optname != IP_TOS) + return 1; + + if (optval + 1 > optval_end) + return 0; /* EPERM, bounds check */ + + optval[0] += 0x10; + ctx->optlen = 1; + + return 1; +} |
