selftests/bpf: Add push/pop checking for msg_verify_data in test_sockmap

[ Upstream commit 862087c3d36219ed44569666eb263efc97f00c9a ]

Add push/pop checking for msg_verify_data in test_sockmap, except for
pop/push with cork tests, in these tests the logic will be different.
1. With corking, pop/push might not be invoked in each sendmsg, it makes
the layout of the received data difficult
2. It makes it hard to calculate the total_bytes in the recvmsg
Temporarily skip the data integrity test for these cases now, added a TODO

Fixes: ee9b352ce465 ("selftests/bpf: Fix msg_verify_data in test_sockmap")
Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
Reviewed-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/r/20241106222520.527076-5-zijianzhang@bytedance.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Zijian Zhang
2024-11-06 22:25:16 +00:00
committed by Greg Kroah-Hartman
parent 862b395de0
commit 9df2dddc08

View File

@@ -87,6 +87,10 @@ int ktls;
int peek_flag;
int skb_use_parser;
int txmsg_omit_skb_parser;
int verify_push_start;
int verify_push_len;
int verify_pop_start;
int verify_pop_len;
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h' },
@@ -513,12 +517,41 @@ unwind_iov:
return -ENOMEM;
}
/* TODO: Add verification logic for push, pull and pop data */
static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
unsigned char *k_p, int *bytes_cnt_p)
/* In push or pop test, we need to do some calculations for msg_verify_data */
static void msg_verify_date_prep(void)
{
int i, j, bytes_cnt = *bytes_cnt_p;
int push_range_end = txmsg_start_push + txmsg_end_push - 1;
int pop_range_end = txmsg_start_pop + txmsg_pop - 1;
if (txmsg_end_push && txmsg_pop &&
txmsg_start_push <= pop_range_end && txmsg_start_pop <= push_range_end) {
/* The push range and the pop range overlap */
int overlap_len;
verify_push_start = txmsg_start_push;
verify_pop_start = txmsg_start_pop;
if (txmsg_start_push < txmsg_start_pop)
overlap_len = min(push_range_end - txmsg_start_pop + 1, txmsg_pop);
else
overlap_len = min(pop_range_end - txmsg_start_push + 1, txmsg_end_push);
verify_push_len = max(txmsg_end_push - overlap_len, 0);
verify_pop_len = max(txmsg_pop - overlap_len, 0);
} else {
/* Otherwise */
verify_push_start = txmsg_start_push;
verify_pop_start = txmsg_start_pop;
verify_push_len = txmsg_end_push;
verify_pop_len = txmsg_pop;
}
}
static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
unsigned char *k_p, int *bytes_cnt_p,
int *check_cnt_p, int *push_p)
{
int bytes_cnt = *bytes_cnt_p, check_cnt = *check_cnt_p, push = *push_p;
unsigned char k = *k_p;
int i, j;
for (i = 0, j = 0; i < msg->msg_iovlen && size; i++, j = 0) {
unsigned char *d = msg->msg_iov[i].iov_base;
@@ -537,6 +570,37 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
}
for (; j < msg->msg_iov[i].iov_len && size; j++) {
if (push > 0 &&
check_cnt == verify_push_start + verify_push_len - push) {
int skipped;
revisit_push:
skipped = push;
if (j + push >= msg->msg_iov[i].iov_len)
skipped = msg->msg_iov[i].iov_len - j;
push -= skipped;
size -= skipped;
j += skipped - 1;
check_cnt += skipped;
continue;
}
if (verify_pop_len > 0 && check_cnt == verify_pop_start) {
bytes_cnt += verify_pop_len;
check_cnt += verify_pop_len;
k += verify_pop_len;
if (bytes_cnt == chunk_sz) {
k = 0;
bytes_cnt = 0;
check_cnt = 0;
push = verify_push_len;
}
if (push > 0 &&
check_cnt == verify_push_start + verify_push_len - push)
goto revisit_push;
}
if (d[j] != k++) {
fprintf(stderr,
"detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n",
@@ -544,15 +608,20 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
return -EDATAINTEGRITY;
}
bytes_cnt++;
check_cnt++;
if (bytes_cnt == chunk_sz) {
k = 0;
bytes_cnt = 0;
check_cnt = 0;
push = verify_push_len;
}
size--;
}
}
*k_p = k;
*bytes_cnt_p = bytes_cnt;
*check_cnt_p = check_cnt;
*push_p = push;
return 0;
}
@@ -611,6 +680,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
struct timeval timeout;
unsigned char k = 0;
int bytes_cnt = 0;
int check_cnt = 0;
int push = 0;
fd_set w;
fcntl(fd, fd_flags);
@@ -636,6 +707,10 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
}
total_bytes += txmsg_push_total;
total_bytes -= txmsg_pop_total;
if (data) {
msg_verify_date_prep();
push = verify_push_len;
}
err = clock_gettime(CLOCK_MONOTONIC, &s->start);
if (err < 0)
perror("recv start time");
@@ -711,7 +786,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
iov_length :
iov_length * iov_count;
errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt);
errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt,
&check_cnt, &push);
if (errno) {
perror("data verify msg failed");
goto out_errno;
@@ -721,7 +797,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
recvp,
chunk_sz,
&k,
&bytes_cnt);
&bytes_cnt,
&check_cnt,
&push);
if (errno) {
perror("data verify msg_peek failed");
goto out_errno;
@@ -1639,6 +1717,8 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
{
bool data = opt->data_test;
/* Test basic pop */
txmsg_pass = 1;
txmsg_start_pop = 1;
@@ -1657,6 +1737,12 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
txmsg_pop = 2;
test_send_many(opt, cgrp);
/* TODO: Test for pop + cork should be different,
* - It makes the layout of the received data difficult
* - It makes it hard to calculate the total_bytes in the recvmsg
* Temporarily skip the data integrity test for this case now.
*/
opt->data_test = false;
/* Test pop + cork */
txmsg_redir = 0;
txmsg_cork = 512;
@@ -1670,10 +1756,13 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
txmsg_start_pop = 1;
txmsg_pop = 2;
test_send_many(opt, cgrp);
opt->data_test = data;
}
static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
{
bool data = opt->data_test;
/* Test basic push */
txmsg_pass = 1;
txmsg_start_push = 1;
@@ -1692,12 +1781,19 @@ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
txmsg_end_push = 2;
test_send_many(opt, cgrp);
/* TODO: Test for push + cork should be different,
* - It makes the layout of the received data difficult
* - It makes it hard to calculate the total_bytes in the recvmsg
* Temporarily skip the data integrity test for this case now.
*/
opt->data_test = false;
/* Test push + cork */
txmsg_redir = 0;
txmsg_cork = 512;
txmsg_start_push = 1;
txmsg_end_push = 2;
test_send_many(opt, cgrp);
opt->data_test = data;
}
static void test_txmsg_push_pop(int cgrp, struct sockmap_options *opt)