[PATCH mptcp-next v14 09/12] selftests: mptcp: sockopt: use recvmsg instead of read
Geliang Tang <[email protected]> Thu, 30 Jul 2026 11:15:20 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <9e7fcfd11333a4faa521fed797c3328f92f4bcd9.1785380422.git.tanggeliang@kylinos.cn> |
From: Geliang Tang <[email protected]> Replace read() with recvmsg() in process_one_client() to enable control message (CMSG) handling. The original read(fd, buf, sizeof(buf)) is split into two recvmsg() calls: the first reads exactly one byte, and the second reads the remaining bytes. This allows the code to access CMSG data for each received segment, facilitating the upcoming TCP_INQ validation. Introduce inq_msg_init() and inq_msg_reset() helpers to manage the struct inq_msg control buffer and iovec, enabling reuse of the same msghdr across multiple recvmsg() calls with different payload buffers. Signed-off-by: Geliang Tang <[email protected]> --- .../selftests/net/mptcp/mptcp_sockopt.c | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c index e404aecc7115..080f9d9e34d5 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -698,36 +698,74 @@ static void check_stat_equal(const char *name, uint64_t actual, name, actual, expected, (int64_t)(actual - expected)); } +struct inq_msg { + char buf[4096]; + union { + struct cmsghdr cmsg; + char msg_buf[4096]; + } control; + struct iovec iov; + struct msghdr hdr; +}; + +static void inq_msg_init(struct inq_msg *m, size_t iov_len) +{ + memset(m, 0, sizeof(*m)); + m->iov.iov_base = m->buf; + m->iov.iov_len = iov_len; + m->hdr.msg_iov = &m->iov; + m->hdr.msg_iovlen = 1; + m->hdr.msg_control = m->control.msg_buf; + m->hdr.msg_controllen = sizeof(m->control.msg_buf); +} + +static void inq_msg_reset(struct inq_msg *m, size_t iov_len, void *base) +{ + m->iov.iov_base = base; + m->iov.iov_len = iov_len; + m->hdr.msg_controllen = sizeof(m->control.msg_buf); +} + static void process_one_client(int fd, int unixfd) { struct so_state s; - char buf[4096]; + struct inq_msg m; ssize_t ret; size_t r, w; + inq_msg_init(&m, 1); + memset(&s, 0, sizeof(s)); do_getsockopts(&s, fd, 0, 0); ret = write(unixfd, "xmit", 4); assert(ret == 4); - ret = read(fd, buf, sizeof(buf)); + /* read one byte */ + ret = recvmsg(fd, &m.hdr, 0); if (ret < 0) - die_perror("read"); + die_perror("recvmsg"); r = ret; + inq_msg_reset(&m, sizeof(m.buf) - 1, m.buf + 1); + ret = recvmsg(fd, &m.hdr, 0); + if (ret < 0) + die_perror("recvmsg"); + r += ret; + assert(s.mptcpi_rcv_delta <= (uint64_t)r); if (s.tcpi_rcv_delta) assert(s.tcpi_rcv_delta == (uint64_t)r); - ret = write(fd, buf, r); + ret = write(fd, m.buf, r); if (ret < 0) die_perror("write"); w = ret; /* wait for hangup */ - ret = read(fd, buf, 1); + inq_msg_reset(&m, 1, m.buf); + ret = recvmsg(fd, &m.hdr, 0); if (ret != 0) xerror("expected EOF, got %zd", ret); r += ret; -- 2.53.0