mirror of https://gitee.com/openkylin/linux.git
selftests/bpf: Add test for freplace program with expected_attach_type
This adds a new selftest that tests the ability to attach an freplace program to a program type that relies on the expected_attach_type of the target program to pass verification. Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/158773526831.293902.16011743438619684815.stgit@toke.dk
This commit is contained in:
parent
03f87c0b45
commit
1d8a0af5ee
|
@ -5,7 +5,8 @@
|
|||
static void test_fexit_bpf2bpf_common(const char *obj_file,
|
||||
const char *target_obj_file,
|
||||
int prog_cnt,
|
||||
const char **prog_name)
|
||||
const char **prog_name,
|
||||
bool run_prog)
|
||||
{
|
||||
struct bpf_object *obj = NULL, *pkt_obj;
|
||||
int err, pkt_fd, i;
|
||||
|
@ -18,7 +19,8 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
|
|||
|
||||
err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
|
||||
&pkt_obj, &pkt_fd);
|
||||
if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
|
||||
if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n",
|
||||
target_obj_file, err, errno))
|
||||
return;
|
||||
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
|
||||
.attach_prog_fd = pkt_fd,
|
||||
|
@ -33,7 +35,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
|
|||
|
||||
obj = bpf_object__open_file(obj_file, &opts);
|
||||
if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
|
||||
"failed to open fexit_bpf2bpf: %ld\n",
|
||||
"failed to open %s: %ld\n", obj_file,
|
||||
PTR_ERR(obj)))
|
||||
goto close_prog;
|
||||
|
||||
|
@ -49,6 +51,10 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
|
|||
if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n"))
|
||||
goto close_prog;
|
||||
}
|
||||
|
||||
if (!run_prog)
|
||||
goto close_prog;
|
||||
|
||||
data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss");
|
||||
if (CHECK(!data_map, "find_data_map", "data map not found\n"))
|
||||
goto close_prog;
|
||||
|
@ -89,7 +95,7 @@ static void test_target_no_callees(void)
|
|||
test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o",
|
||||
"./test_pkt_md_access.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name);
|
||||
prog_name, true);
|
||||
}
|
||||
|
||||
static void test_target_yes_callees(void)
|
||||
|
@ -103,7 +109,7 @@ static void test_target_yes_callees(void)
|
|||
test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
|
||||
"./test_pkt_access.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name);
|
||||
prog_name, true);
|
||||
}
|
||||
|
||||
static void test_func_replace(void)
|
||||
|
@ -120,7 +126,18 @@ static void test_func_replace(void)
|
|||
test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
|
||||
"./test_pkt_access.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name);
|
||||
prog_name, true);
|
||||
}
|
||||
|
||||
static void test_func_replace_verify(void)
|
||||
{
|
||||
const char *prog_name[] = {
|
||||
"freplace/do_bind",
|
||||
};
|
||||
test_fexit_bpf2bpf_common("./freplace_connect4.o",
|
||||
"./connect4_prog.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name, false);
|
||||
}
|
||||
|
||||
void test_fexit_bpf2bpf(void)
|
||||
|
@ -128,4 +145,5 @@ void test_fexit_bpf2bpf(void)
|
|||
test_target_no_callees();
|
||||
test_target_yes_callees();
|
||||
test_func_replace();
|
||||
test_func_replace_verify();
|
||||
}
|
||||
|
|
|
@ -18,11 +18,25 @@
|
|||
|
||||
int _version SEC("version") = 1;
|
||||
|
||||
__attribute__ ((noinline))
|
||||
int do_bind(struct bpf_sock_addr *ctx)
|
||||
{
|
||||
struct sockaddr_in sa = {};
|
||||
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = bpf_htons(0);
|
||||
sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4);
|
||||
|
||||
if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SEC("cgroup/connect4")
|
||||
int connect_v4_prog(struct bpf_sock_addr *ctx)
|
||||
{
|
||||
struct bpf_sock_tuple tuple = {};
|
||||
struct sockaddr_in sa;
|
||||
struct bpf_sock *sk;
|
||||
|
||||
/* Verify that new destination is available. */
|
||||
|
@ -56,17 +70,7 @@ int connect_v4_prog(struct bpf_sock_addr *ctx)
|
|||
ctx->user_ip4 = bpf_htonl(DST_REWRITE_IP4);
|
||||
ctx->user_port = bpf_htons(DST_REWRITE_PORT4);
|
||||
|
||||
/* Rewrite source. */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = bpf_htons(0);
|
||||
sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4);
|
||||
|
||||
if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return do_bind(ctx) ? 1 : 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include <linux/stddef.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_endian.h>
|
||||
|
||||
SEC("freplace/do_bind")
|
||||
int new_do_bind(struct bpf_sock_addr *ctx)
|
||||
{
|
||||
struct sockaddr_in sa = {};
|
||||
|
||||
bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
Loading…
Reference in New Issue