Skip to content

ktls, sockmap: Fix missing uncharge operation and add selfttest #8842

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: bpf-next_base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions net/tls/tls_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,13 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
&msg_redir, send, flags);
lock_sock(sk);
if (err < 0) {
/* Regardless of whether the data represented by
* msg_redir is sent successfully, we have already
* uncharged it via sk_msg_return_zero(). The
* msg->sg.size represents the remaining unprocessed
* data, which needs to be uncharged here.
*/
sk_mem_uncharge(sk, msg->sg.size);
*copied -= sk_msg_free_nocharge(sk, &msg_redir);
msg->sg.size = 0;
}
Expand Down
76 changes: 76 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,80 @@ static void test_sockmap_ktls_tx_cork(int family, int sotype, bool push)
test_sockmap_ktls__destroy(skel);
}

static void test_sockmap_ktls_tx_no_buf(int family, int sotype, bool push)
{
int c = 0, p = 0, one = 1, two = 2;
struct test_sockmap_ktls *skel;
unsigned char *data = NULL;
struct msghdr msg = {0};
struct iovec iov[2];
int prog_fd, map_fd;
int txrx_buf = 1024;
int iov_length = 8192;
int err;

skel = test_sockmap_ktls__open_and_load();
if (!ASSERT_TRUE(skel, "open ktls skel"))
return;

err = create_pair(family, sotype, &c, &p);
if (!ASSERT_OK(err, "create_pair()"))
goto out;

err = setsockopt(c, SOL_SOCKET, SO_RCVBUFFORCE, &txrx_buf, sizeof(int));
err |= setsockopt(p, SOL_SOCKET, SO_SNDBUFFORCE, &txrx_buf, sizeof(int));
if (!ASSERT_OK(err, "set buf limit"))
goto out;

prog_fd = bpf_program__fd(skel->progs.prog_sk_policy_redir);
map_fd = bpf_map__fd(skel->maps.sock_map);

err = bpf_prog_attach(prog_fd, map_fd, BPF_SK_MSG_VERDICT, 0);
if (!ASSERT_OK(err, "bpf_prog_attach sk msg"))
goto out;

err = bpf_map_update_elem(map_fd, &one, &c, BPF_NOEXIST);
if (!ASSERT_OK(err, "bpf_map_update_elem(c)"))
goto out;

err = bpf_map_update_elem(map_fd, &two, &p, BPF_NOEXIST);
if (!ASSERT_OK(err, "bpf_map_update_elem(p)"))
goto out;

skel->bss->apply_bytes = 1024;

err = init_ktls_pairs(c, p);
if (!ASSERT_OK(err, "init_ktls_pairs(c, p)"))
goto out;

data = calloc(iov_length, sizeof(char));
if (!data)
goto out;

iov[0].iov_base = data;
iov[0].iov_len = iov_length;
iov[1].iov_base = data;
iov[1].iov_len = iov_length;
msg.msg_iov = iov;
msg.msg_iovlen = 2;

for (;;) {
err = sendmsg(c, &msg, MSG_DONTWAIT);
if (err <= 0)
break;
}

out:
if (data)
free(data);
if (c)
close(c);
if (p)
close(p);

test_sockmap_ktls__destroy(skel);
}

static void run_tests(int family, enum bpf_map_type map_type)
{
int map;
Expand All @@ -262,6 +336,8 @@ static void run_ktls_test(int family, int sotype)
test_sockmap_ktls_tx_cork(family, sotype, false);
if (test__start_subtest("tls tx cork with push"))
test_sockmap_ktls_tx_cork(family, sotype, true);
if (test__start_subtest("tls tx egress with no buf"))
test_sockmap_ktls_tx_no_buf(family, sotype, true);
}

void test_sockmap_ktls(void)
Expand Down
10 changes: 10 additions & 0 deletions tools/testing/selftests/bpf/progs/test_sockmap_ktls.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
int cork_byte;
int push_start;
int push_end;
int apply_bytes;

struct {
__uint(type, BPF_MAP_TYPE_SOCKMAP);
Expand All @@ -24,3 +25,12 @@ int prog_sk_policy(struct sk_msg_md *msg)

return SK_PASS;
}

SEC("sk_msg")
int prog_sk_policy_redir(struct sk_msg_md *msg)
{
int two = 2;

bpf_msg_apply_bytes(msg, apply_bytes);
return bpf_msg_redirect_map(msg, &sock_map, two, 0);
}
Loading