Commit 1d9c037a authored by John Fastabend's avatar John Fastabend Committed by Alexei Starovoitov

bpf, selftests: Add sk_msg helpers load and attach test

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: default avatarJohn Fastabend <john.fastabend@gmail.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAndrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/159033909665.12355.6166415847337547879.stgit@john-Precision-5820-TowerSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 13d70f5a
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Cloudflare // Copyright (c) 2020 Cloudflare
#include <error.h>
#include "test_progs.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 19 /* TCP sock is under repair right now */
...@@ -70,10 +72,43 @@ static void test_sockmap_create_update_free(enum bpf_map_type map_type) ...@@ -70,10 +72,43 @@ static void test_sockmap_create_update_free(enum bpf_map_type map_type)
close(s); 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) void test_sockmap_basic(void)
{ {
if (test__start_subtest("sockmap create_update_free")) if (test__start_subtest("sockmap create_update_free"))
test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP); test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP);
if (test__start_subtest("sockhash create_update_free")) if (test__start_subtest("sockhash create_update_free"))
test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKHASH); 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);
} }
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Isovalent, Inc.
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
struct {
__uint(type, BPF_MAP_TYPE_SOCKMAP);
__uint(max_entries, 2);
__type(key, __u32);
__type(value, __u64);
} sock_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_SOCKHASH);
__uint(max_entries, 2);
__type(key, __u32);
__type(value, __u64);
} sock_hash SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_SK_STORAGE);
__uint(map_flags, BPF_F_NO_PREALLOC);
__type(key, __u32);
__type(value, __u64);
} socket_storage SEC(".maps");
SEC("sk_msg")
int prog_msg_verdict(struct sk_msg_md *msg)
{
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
int verdict = SK_PASS;
__u32 pid, tpid;
__u64 *sk_stg;
pid = bpf_get_current_pid_tgid() >> 32;
sk_stg = bpf_sk_storage_get(&socket_storage, msg->sk, 0, BPF_SK_STORAGE_GET_F_CREATE);
if (!sk_stg)
return SK_DROP;
*sk_stg = pid;
bpf_probe_read_kernel(&tpid , sizeof(tpid), &task->tgid);
if (pid != tpid)
verdict = SK_DROP;
bpf_sk_storage_delete(&socket_storage, (void *)msg->sk);
return verdict;
}
char _license[] SEC("license") = "GPL";
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment