Sendmsg path with multiple buffers is slightly different from a single send in how we have to handle and walk the sg when doing pops. Lets ensure this walk is correct. Signed-off-by: John Fastabend <john.fastabend@xxxxxxxxx> --- .../bpf/prog_tests/sockmap_helpers.h | 8 +++ .../bpf/prog_tests/sockmap_msg_helpers.c | 53 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h index 781cbdf01d7b..4d8d24482032 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h @@ -103,6 +103,14 @@ __ret; \ }) +#define xsendmsg(fd, msg, flags) \ + ({ \ + ssize_t __ret = sendmsg((fd), (msg), (flags)); \ + if (__ret == -1) \ + FAIL_ERRNO("sendmsg"); \ + __ret; \ + }) + #define xrecv_nonblock(fd, buf, len, flags) \ ({ \ ssize_t __ret = recv_timeout((fd), (buf), (len), (flags), \ diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_msg_helpers.c b/tools/testing/selftests/bpf/prog_tests/sockmap_msg_helpers.c index 9ffe02f45808..e5e618e84950 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_msg_helpers.c +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_msg_helpers.c @@ -52,6 +52,50 @@ static void pop_simple_send(struct msg_test_opts *opts, int start, int len) ASSERT_OK(cmp, "pop cmp end bytes failed"); } +static void pop_complex_send(struct msg_test_opts *opts, int start, int len) +{ + struct test_sockmap_msg_helpers *skel = opts->skel; + char buf[] = "abcdefghijklmnopqrstuvwxyz"; + size_t sent, recv, total = 0; + struct msghdr msg = {0}; + struct iovec iov[15]; + char *recvbuf; + int i; + + for (i = 0; i < 15; i++) { + iov[i].iov_base = buf; + iov[i].iov_len = sizeof(buf); + total += sizeof(buf); + } + + recvbuf = malloc(total); + if (!recvbuf) + FAIL("pop complex send malloc failure\n"); + + msg.msg_iov = iov; + msg.msg_iovlen = 15; + + skel->bss->pop = true; + + if (start == -1) + start = sizeof(buf) - len - 1; + + skel->bss->pop_start = start; + skel->bss->pop_len = len; + + sent = xsendmsg(opts->client, &msg, 0); + if (sent != total) + FAIL("xsend failed"); + + ASSERT_OK(skel->bss->err, "pop error"); + + recv = xrecv_nonblock(opts->server, recvbuf, total, 0); + if (recv != sent - skel->bss->pop_len) + FAIL("Received incorrect number number of bytes after pop"); + + free(recvbuf); +} + static void test_sockmap_pop(void) { struct msg_test_opts opts; @@ -92,6 +136,15 @@ static void test_sockmap_pop(void) /* Pop from end */ pop_simple_send(&opts, POP_END, 5); + /* Empty pop from start of sendmsg */ + pop_complex_send(&opts, 0, 0); + /* Pop from start of sendmsg */ + pop_complex_send(&opts, 0, 10); + /* Pop from middle of sendmsg */ + pop_complex_send(&opts, 100, 10); + /* Pop from end of sendmsg */ + pop_complex_send(&opts, 394, 10); + close_sockets: close(client); close(server); -- 2.33.0