On Wed, Jan 24, 2024 at 10:54 AM -08, John Fastabend wrote: > 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++) { Always nice to use ARRAY_SIZE. > + 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"); 390 bytes, why not have it on stack? > + > + 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); Isn't the start offset here past the end? 15*26=390? > + > close_sockets: > close(client); > close(server);