mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
The test itself is not particularly useful but it encodes a common pattern we have. Namely do a sk storage lookup then depending on data here decide if we need to do more work or alternatively allow packet to PASS. Then if we need to do more work consult task_struct for more information about the running task. Finally based on this additional information drop or pass the data. In this case the suspicious check is not so realisitic but it encodes the general pattern and uses the helpers so we test the workflow. This is a load test to ensure verifier correctly handles this case. Signed-off-by: John Fastabend <john.fastabend@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Andrii Nakryiko <andriin@fb.com> Link: https://lore.kernel.org/bpf/159033909665.12355.6166415847337547879.stgit@john-Precision-5820-Tower Signed-off-by: Alexei Starovoitov <ast@kernel.org>
114 lines
2.6 KiB
C
114 lines
2.6 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// Copyright (c) 2020 Cloudflare
|
|
#include <error.h>
|
|
|
|
#include "test_progs.h"
|
|
#include "test_skmsg_load_helpers.skel.h"
|
|
|
|
#define TCP_REPAIR 19 /* TCP sock is under repair right now */
|
|
|
|
#define TCP_REPAIR_ON 1
|
|
#define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */
|
|
|
|
static int connected_socket_v4(void)
|
|
{
|
|
struct sockaddr_in addr = {
|
|
.sin_family = AF_INET,
|
|
.sin_port = htons(80),
|
|
.sin_addr = { inet_addr("127.0.0.1") },
|
|
};
|
|
socklen_t len = sizeof(addr);
|
|
int s, repair, err;
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (CHECK_FAIL(s == -1))
|
|
goto error;
|
|
|
|
repair = TCP_REPAIR_ON;
|
|
err = setsockopt(s, SOL_TCP, TCP_REPAIR, &repair, sizeof(repair));
|
|
if (CHECK_FAIL(err))
|
|
goto error;
|
|
|
|
err = connect(s, (struct sockaddr *)&addr, len);
|
|
if (CHECK_FAIL(err))
|
|
goto error;
|
|
|
|
repair = TCP_REPAIR_OFF_NO_WP;
|
|
err = setsockopt(s, SOL_TCP, TCP_REPAIR, &repair, sizeof(repair));
|
|
if (CHECK_FAIL(err))
|
|
goto error;
|
|
|
|
return s;
|
|
error:
|
|
perror(__func__);
|
|
close(s);
|
|
return -1;
|
|
}
|
|
|
|
/* Create a map, populate it with one socket, and free the map. */
|
|
static void test_sockmap_create_update_free(enum bpf_map_type map_type)
|
|
{
|
|
const int zero = 0;
|
|
int s, map, err;
|
|
|
|
s = connected_socket_v4();
|
|
if (CHECK_FAIL(s == -1))
|
|
return;
|
|
|
|
map = bpf_create_map(map_type, sizeof(int), sizeof(int), 1, 0);
|
|
if (CHECK_FAIL(map == -1)) {
|
|
perror("bpf_create_map");
|
|
goto out;
|
|
}
|
|
|
|
err = bpf_map_update_elem(map, &zero, &s, BPF_NOEXIST);
|
|
if (CHECK_FAIL(err)) {
|
|
perror("bpf_map_update");
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
close(map);
|
|
close(s);
|
|
}
|
|
|
|
static void test_skmsg_helpers(enum bpf_map_type map_type)
|
|
{
|
|
struct test_skmsg_load_helpers *skel;
|
|
int err, map, verdict;
|
|
|
|
skel = test_skmsg_load_helpers__open_and_load();
|
|
if (CHECK_FAIL(!skel)) {
|
|
perror("test_skmsg_load_helpers__open_and_load");
|
|
return;
|
|
}
|
|
|
|
verdict = bpf_program__fd(skel->progs.prog_msg_verdict);
|
|
map = bpf_map__fd(skel->maps.sock_map);
|
|
|
|
err = bpf_prog_attach(verdict, map, BPF_SK_MSG_VERDICT, 0);
|
|
if (CHECK_FAIL(err)) {
|
|
perror("bpf_prog_attach");
|
|
goto out;
|
|
}
|
|
|
|
err = bpf_prog_detach2(verdict, map, BPF_SK_MSG_VERDICT);
|
|
if (CHECK_FAIL(err)) {
|
|
perror("bpf_prog_detach2");
|
|
goto out;
|
|
}
|
|
out:
|
|
test_skmsg_load_helpers__destroy(skel);
|
|
}
|
|
|
|
void test_sockmap_basic(void)
|
|
{
|
|
if (test__start_subtest("sockmap create_update_free"))
|
|
test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP);
|
|
if (test__start_subtest("sockhash create_update_free"))
|
|
test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKHASH);
|
|
if (test__start_subtest("sockmap sk_msg load helpers"))
|
|
test_skmsg_helpers(BPF_MAP_TYPE_SOCKMAP);
|
|
if (test__start_subtest("sockhash sk_msg load helpers"))
|
|
test_skmsg_helpers(BPF_MAP_TYPE_SOCKHASH);
|
|
}
|