All of lore.kernel.org
 help / color / mirror / Atom feed
* [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing
@ 2025-02-20  7:11 Gang Yan
  2025-02-20  7:11 ` [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info Gang Yan
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Gang Yan @ 2025-02-20  7:11 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

These patches provide a method to verify the 'mptcp_diag_dump_one'
function, and the new tool 'mptcp_diag' can get the specific mptcp_info
through multi msks.

Gang Yan (2):
  selftests: mptcp: Add a tool to get specific msk_info
  selftests: mptcp: add a test for mptcp_diag_dump_one

 tools/testing/selftests/net/mptcp/Makefile    |   2 +-
 tools/testing/selftests/net/mptcp/diag.sh     |  23 ++
 .../testing/selftests/net/mptcp/mptcp_diag.c  | 235 ++++++++++++++++++
 3 files changed, 259 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/net/mptcp/mptcp_diag.c

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info
  2025-02-20  7:11 [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing Gang Yan
@ 2025-02-20  7:11 ` Gang Yan
  2025-02-20 11:22   ` Matthieu Baerts
  2025-02-20  7:11 ` [mptcp-next v2 2/2] selftests: mptcp: add a test for mptcp_diag_dump_one Gang Yan
  2025-02-20  8:21 ` [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing MPTCP CI
  2 siblings, 1 reply; 6+ messages in thread
From: Gang Yan @ 2025-02-20  7:11 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

This patch enables the retrieval of the mptcp_info structure corresponding
to a specified MPTCP socket (msk). When multiple MPTCP connections are
present, specific information can be obtained for a given connection
through the 'mptcp_diag_dump_one' by using the 'token' associated with
the msk.

Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/Makefile    |   2 +-
 .../testing/selftests/net/mptcp/mptcp_diag.c  | 235 ++++++++++++++++++
 2 files changed, 236 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/net/mptcp/mptcp_diag.c

diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile
index c76525fe2b84..340e1a777e16 100644
--- a/tools/testing/selftests/net/mptcp/Makefile
+++ b/tools/testing/selftests/net/mptcp/Makefile
@@ -7,7 +7,7 @@ CFLAGS += -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INC
 TEST_PROGS := mptcp_connect.sh pm_netlink.sh mptcp_join.sh diag.sh \
 	      simult_flows.sh mptcp_sockopt.sh userspace_pm.sh
 
-TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_inq
+TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_inq mptcp_diag
 
 TEST_FILES := mptcp_lib.sh settings
 
diff --git a/tools/testing/selftests/net/mptcp/mptcp_diag.c b/tools/testing/selftests/net/mptcp/mptcp_diag.c
new file mode 100644
index 000000000000..3e0be9e58912
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptcp_diag.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025, Kylin Software*/
+
+#include <linux/sock_diag.h>
+#include <linux/rtnetlink.h>
+#include <linux/inet_diag.h>
+#include <linux/netlink.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/tcp.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+
+#ifndef MPTCP_INFO
+struct mptcp_info {
+	__u8    mptcpi_subflows;
+	__u8    mptcpi_add_addr_signal;
+	__u8    mptcpi_add_addr_accepted;
+	__u8    mptcpi_subflows_max;
+	__u8    mptcpi_add_addr_signal_max;
+	__u8    mptcpi_add_addr_accepted_max;
+	__u32   mptcpi_flags;
+	__u32   mptcpi_token;
+	__u64   mptcpi_write_seq;
+	__u64   mptcpi_snd_una;
+	__u64   mptcpi_rcv_nxt;
+	__u8    mptcpi_local_addr_used;
+	__u8    mptcpi_local_addr_max;
+	__u8    mptcpi_csum_enabled;
+	__u32   mptcpi_retransmits;
+	__u64   mptcpi_bytes_retrans;
+	__u64   mptcpi_bytes_sent;
+	__u64   mptcpi_bytes_received;
+	__u64   mptcpi_bytes_acked;
+};
+
+#define MPTCP_INFO              1
+#endif
+
+static void die_perror(const char *msg)
+{
+	perror(msg);
+	exit(1);
+}
+
+static void die_usage(int r)
+{
+	fprintf(stderr, "Usage: mptcp_diag -t\n");
+	exit(r);
+}
+
+static void send_query(int fd, __u32 token)
+{
+	struct sockaddr_nl nladdr = {
+		.nl_family = AF_NETLINK
+	};
+	struct {
+		struct nlmsghdr nlh;
+		struct inet_diag_req_v2 r;
+	} req = {
+		.nlh = {
+			.nlmsg_len = sizeof(req),
+			.nlmsg_type = SOCK_DIAG_BY_FAMILY,
+			.nlmsg_flags = NLM_F_REQUEST
+		},
+		.r = {
+			.sdiag_family = AF_INET,
+			.sdiag_protocol = IPPROTO_MPTCP,
+			.id.idiag_cookie[0] = token,
+		}
+	};
+	struct rtattr rta_proto;
+	struct iovec iov[6];
+	int iovlen = 1;
+	__u32 proto;
+
+	req.r.idiag_ext |= (1 << (INET_DIAG_INFO - 1));
+	proto = IPPROTO_MPTCP;
+	rta_proto.rta_type = INET_DIAG_REQ_PROTOCOL;
+	rta_proto.rta_len = RTA_LENGTH(sizeof(proto));
+
+	iov[0] = (struct iovec) {
+		.iov_base = &req,
+		.iov_len = sizeof(req)
+	};
+	iov[iovlen] = (struct iovec){ &rta_proto, sizeof(rta_proto)};
+	iov[iovlen + 1] = (struct iovec){ &proto, sizeof(proto)};
+	req.nlh.nlmsg_len += RTA_LENGTH(sizeof(proto));
+	iovlen += 2;
+	struct msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = iov,
+		.msg_iovlen = iovlen
+	};
+
+	for (;;) {
+		if (sendmsg(fd, &msg, 0) < 0) {
+			if (errno == EINTR)
+				continue;
+			die_perror("sendmsg");
+		}
+		break;
+	}
+}
+
+static void parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+		       int len, unsigned short flags)
+{
+	unsigned short type;
+
+	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
+	while (RTA_OK(rta, len)) {
+		type = rta->rta_type & ~flags;
+		if ((type <= max) && (!tb[type]))
+			tb[type] = rta;
+		rta = RTA_NEXT(rta, len);
+	}
+}
+
+static struct mptcp_info *parse_nlmsg(struct nlmsghdr *nlh)
+{
+	struct inet_diag_msg *r = NLMSG_DATA(nlh);
+	struct rtattr *tb[INET_DIAG_MAX+1];
+	struct mptcp_info *info;
+
+	parse_rtattr_flags(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
+			   nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)),
+			   NLA_F_NESTED);
+
+	if (tb[INET_DIAG_INFO]) {
+		info = RTA_DATA(tb[INET_DIAG_INFO]);
+		return info;
+	}
+
+	die_perror("Has no INET_DIAG_INFO");
+	return info;
+}
+
+static struct mptcp_info *recv_nlmsg(int fd, struct nlmsghdr *nlh)
+{
+	char rcv_buff[8192];
+	struct sockaddr_nl rcv_nladdr = {
+		.nl_family = AF_NETLINK
+	};
+	struct iovec rcv_iov = {
+		.iov_base = rcv_buff,
+		.iov_len = sizeof(rcv_buff)
+	};
+	struct msghdr rcv_msg = {
+		.msg_name = &rcv_nladdr,
+		.msg_namelen = sizeof(rcv_nladdr),
+		.msg_iov = &rcv_iov,
+		.msg_iovlen = 1
+	};
+	struct mptcp_info *info = NULL;
+	int len;
+
+	len = recvmsg(fd, &rcv_msg, 0);
+	nlh = (struct nlmsghdr *)rcv_buff;
+
+	while (NLMSG_OK(nlh, len)) {
+		if (nlh->nlmsg_type == NLMSG_DONE) {
+			printf("NLMSG_DONE\n");
+			break;
+		} else if (nlh->nlmsg_type == NLMSG_ERROR) {
+			struct nlmsgerr *err;
+
+			err = (struct nlmsgerr *)NLMSG_DATA(nlh);
+			printf("Error %d:%s\n", -(err->error), strerror(-(err->error)));
+			break;
+		}
+		info = parse_nlmsg(nlh);
+		nlh = NLMSG_NEXT(nlh, len);
+	}
+	close(fd);
+	return info;
+}
+
+static struct mptcp_info *get_mptcpinfo(__u32 token)
+{
+	struct nlmsghdr *nlh = NULL;
+	int fd;
+
+	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
+	if (fd < 0)
+		die_perror("Netlink socket");
+
+	send_query(fd, token);
+	return recv_nlmsg(fd, nlh);
+}
+
+static void parse_opts(int argc, char **argv, __u32 *target_token)
+{
+	int c;
+
+	while ((c = getopt(argc, argv, "ht:")) != -1) {
+		switch (c) {
+		case 'h':
+			die_usage(1);
+			break;
+		case 't':
+			sscanf(optarg, "%x", target_token);
+			break;
+		default:
+			die_usage(1);
+			break;
+		}
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	struct mptcp_info *info = NULL;
+	__u32 target_token;
+
+	parse_opts(argc, argv, &target_token);
+	info = get_mptcpinfo(target_token);
+
+	if (info)
+		printf("token:%x\n", info->mptcpi_token);
+	else
+		perror("No Such msk using this token!\n");
+
+	return 0;
+}
+
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [mptcp-next v2 2/2] selftests: mptcp: add a test for mptcp_diag_dump_one
  2025-02-20  7:11 [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing Gang Yan
  2025-02-20  7:11 ` [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info Gang Yan
@ 2025-02-20  7:11 ` Gang Yan
  2025-02-20 11:36   ` Matthieu Baerts
  2025-02-20  8:21 ` [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing MPTCP CI
  2 siblings, 1 reply; 6+ messages in thread
From: Gang Yan @ 2025-02-20  7:11 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

This patch introduces a new 'chk_diag' test in diag.sh. It retrieves
the token for a specified MPTCP socket (msk) using the 'ss' command and
then accesses the 'mptcp_diag_dump_one' in kernel via ./mptcp_diag
to verify if the correct token is returned.

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/524
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/diag.sh | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/diag.sh b/tools/testing/selftests/net/mptcp/diag.sh
index 2bd0c1eb70c5..9a57c27b14b9 100755
--- a/tools/testing/selftests/net/mptcp/diag.sh
+++ b/tools/testing/selftests/net/mptcp/diag.sh
@@ -200,6 +200,28 @@ chk_msk_cestab()
 		 "${expected}" "${msg}" ""
 }
 
+chk_dumpone()
+{
+	local ss_token="$(ss -inmHMN $ns | grep 'token:' |\
+			  head -n 1 |\
+			  sed 's/.*token:\([0-9a-f]*\).*/\1/')"
+	local token="$(ip netns exec $ns ./mptcp_diag -t $ss_token |\
+		       grep 'token:' |\
+		       sed 's/.*token:\([0-9a-f]*\).*/\1/')"
+	local msg="...chk dumpone"
+
+	mptcp_lib_print_title "$msg"
+        if [ "$ss_token" != "$token" ]; then
+		mptcp_lib_pr_fail "expected $ss_token found $token"
+		mptcp_lib_result_fail "${msg}"
+		ret=${KSFT_FAIL}
+	else
+                mptcp_lib_pr_ok
+                mptcp_lib_result_pass "${msg}"
+	fi
+
+}
+
 msk_info_get_value()
 {
 	local port="${1}"
@@ -290,6 +312,7 @@ chk_msk_remote_key_nr 2 "....chk remote_key"
 chk_msk_fallback_nr 0 "....chk no fallback"
 chk_msk_inuse 2
 chk_msk_cestab 2
+chk_dumpone
 flush_pids
 
 chk_msk_inuse 0 "2->0"
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing
  2025-02-20  7:11 [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing Gang Yan
  2025-02-20  7:11 ` [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info Gang Yan
  2025-02-20  7:11 ` [mptcp-next v2 2/2] selftests: mptcp: add a test for mptcp_diag_dump_one Gang Yan
@ 2025-02-20  8:21 ` MPTCP CI
  2 siblings, 0 replies; 6+ messages in thread
From: MPTCP CI @ 2025-02-20  8:21 UTC (permalink / raw)
  To: Gang Yan; +Cc: mptcp

Hi Gang,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal: Success! ✅
- KVM Validation: debug: Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/13430040097

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/3073cb86b512
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=935869


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info
  2025-02-20  7:11 ` [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info Gang Yan
@ 2025-02-20 11:22   ` Matthieu Baerts
  0 siblings, 0 replies; 6+ messages in thread
From: Matthieu Baerts @ 2025-02-20 11:22 UTC (permalink / raw)
  To: Gang Yan, mptcp

Hi Gang Yan,

On 20/02/2025 08:11, Gang Yan wrote:
> This patch enables the retrieval of the mptcp_info structure corresponding
> to a specified MPTCP socket (msk). When multiple MPTCP connections are
> present, specific information can be obtained for a given connection
> through the 'mptcp_diag_dump_one' by using the 'token' associated with
> the msk.

Thank you for the v2. I had a very quick look, mainly because I saw
CheckPatch and Shellcheck were complaining about this series.

Do you mind looking at that please?

https://github.com/multipath-tcp/mptcp_net-next/actions/runs/13430040104

> 
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
>  tools/testing/selftests/net/mptcp/Makefile    |   2 +-
>  .../testing/selftests/net/mptcp/mptcp_diag.c  | 235 ++++++++++++++++++
>  2 files changed, 236 insertions(+), 1 deletion(-)
>  create mode 100644 tools/testing/selftests/net/mptcp/mptcp_diag.c
> 
> diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile
> index c76525fe2b84..340e1a777e16 100644
> --- a/tools/testing/selftests/net/mptcp/Makefile
> +++ b/tools/testing/selftests/net/mptcp/Makefile
> @@ -7,7 +7,7 @@ CFLAGS += -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INC
>  TEST_PROGS := mptcp_connect.sh pm_netlink.sh mptcp_join.sh diag.sh \
>  	      simult_flows.sh mptcp_sockopt.sh userspace_pm.sh
>  
> -TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_inq
> +TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_inq mptcp_diag
>  
>  TEST_FILES := mptcp_lib.sh settings
>  
> diff --git a/tools/testing/selftests/net/mptcp/mptcp_diag.c b/tools/testing/selftests/net/mptcp/mptcp_diag.c
> new file mode 100644
> index 000000000000..3e0be9e58912
> --- /dev/null
> +++ b/tools/testing/selftests/net/mptcp/mptcp_diag.c
> @@ -0,0 +1,235 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2025, Kylin Software*/
> +
> +#include <linux/sock_diag.h>
> +#include <linux/rtnetlink.h>
> +#include <linux/inet_diag.h>
> +#include <linux/netlink.h>
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <linux/tcp.h>
> +
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <stdio.h>
> +
> +#ifndef IPPROTO_MPTCP
> +#define IPPROTO_MPTCP 262
> +#endif
> +
> +#ifndef MPTCP_INFO
> +struct mptcp_info {
> +	__u8    mptcpi_subflows;
> +	__u8    mptcpi_add_addr_signal;
> +	__u8    mptcpi_add_addr_accepted;
> +	__u8    mptcpi_subflows_max;
> +	__u8    mptcpi_add_addr_signal_max;
> +	__u8    mptcpi_add_addr_accepted_max;
> +	__u32   mptcpi_flags;
> +	__u32   mptcpi_token;
> +	__u64   mptcpi_write_seq;
> +	__u64   mptcpi_snd_una;
> +	__u64   mptcpi_rcv_nxt;
> +	__u8    mptcpi_local_addr_used;
> +	__u8    mptcpi_local_addr_max;
> +	__u8    mptcpi_csum_enabled;
> +	__u32   mptcpi_retransmits;
> +	__u64   mptcpi_bytes_retrans;
> +	__u64   mptcpi_bytes_sent;
> +	__u64   mptcpi_bytes_received;
> +	__u64   mptcpi_bytes_acked;
> +};
> +
> +#define MPTCP_INFO              1
> +#endif
> +
> +static void die_perror(const char *msg)
> +{
> +	perror(msg);
> +	exit(1);
> +}
> +
> +static void die_usage(int r)
> +{
> +	fprintf(stderr, "Usage: mptcp_diag -t\n");
> +	exit(r);
> +}
> +
> +static void send_query(int fd, __u32 token)
> +{
> +	struct sockaddr_nl nladdr = {
> +		.nl_family = AF_NETLINK
> +	};
> +	struct {
> +		struct nlmsghdr nlh;
> +		struct inet_diag_req_v2 r;
> +	} req = {
> +		.nlh = {
> +			.nlmsg_len = sizeof(req),
> +			.nlmsg_type = SOCK_DIAG_BY_FAMILY,
> +			.nlmsg_flags = NLM_F_REQUEST
> +		},
> +		.r = {
> +			.sdiag_family = AF_INET,
> +			.sdiag_protocol = IPPROTO_MPTCP,
> +			.id.idiag_cookie[0] = token,
> +		}
> +	};
> +	struct rtattr rta_proto;
> +	struct iovec iov[6];
> +	int iovlen = 1;
> +	__u32 proto;
> +
> +	req.r.idiag_ext |= (1 << (INET_DIAG_INFO - 1));
> +	proto = IPPROTO_MPTCP;
> +	rta_proto.rta_type = INET_DIAG_REQ_PROTOCOL;
> +	rta_proto.rta_len = RTA_LENGTH(sizeof(proto));
> +
> +	iov[0] = (struct iovec) {
> +		.iov_base = &req,
> +		.iov_len = sizeof(req)
> +	};
> +	iov[iovlen] = (struct iovec){ &rta_proto, sizeof(rta_proto)};
> +	iov[iovlen + 1] = (struct iovec){ &proto, sizeof(proto)};
> +	req.nlh.nlmsg_len += RTA_LENGTH(sizeof(proto));
> +	iovlen += 2;
> +	struct msghdr msg = {
> +		.msg_name = &nladdr,
> +		.msg_namelen = sizeof(nladdr),
> +		.msg_iov = iov,
> +		.msg_iovlen = iovlen
> +	};
> +
> +	for (;;) {
> +		if (sendmsg(fd, &msg, 0) < 0) {
> +			if (errno == EINTR)
> +				continue;
> +			die_perror("sendmsg");
> +		}
> +		break;
> +	}
> +}
> +
> +static void parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
> +		       int len, unsigned short flags)

(the indentation doesn't look OK)

> +{
> +	unsigned short type;
> +
> +	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
> +	while (RTA_OK(rta, len)) {
> +		type = rta->rta_type & ~flags;
> +		if ((type <= max) && (!tb[type]))
> +			tb[type] = rta;
> +		rta = RTA_NEXT(rta, len);
> +	}
> +}
> +
> +static struct mptcp_info *parse_nlmsg(struct nlmsghdr *nlh)
> +{
> +	struct inet_diag_msg *r = NLMSG_DATA(nlh);
> +	struct rtattr *tb[INET_DIAG_MAX+1];
> +	struct mptcp_info *info;
> +
> +	parse_rtattr_flags(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
> +			   nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)),
> +			   NLA_F_NESTED);
> +
> +	if (tb[INET_DIAG_INFO]) {
> +		info = RTA_DATA(tb[INET_DIAG_INFO]);
> +		return info;

The cope of "info" is local if it is a pointer from 'tb' that as been
allocated on the stack. A pointer to this local structure should then
not be returned.

Either allocate memory on heap, or probably better: a pointer to an
mptcp_info structure should be passed to get_mptcpinfo() -> recv_nlmsg()
-> parse_nlmsg(). Or use a global variable. So here, we would fill this
space, and read it later on.

(Or, if you only need the token, only return that, but that's strange to
give the token, and only get the token in return...)

(Or: don't return anything here, but simply print each field of the
mptcp_info structure → but that sounds better to do that after having
called get_mptcpinfo().)

> +	}
> +
> +	die_perror("Has no INET_DIAG_INFO");
> +	return info;

"info" might not have been assigned.

> +}
> +
> +static struct mptcp_info *recv_nlmsg(int fd, struct nlmsghdr *nlh)
> +{
> +	char rcv_buff[8192];
> +	struct sockaddr_nl rcv_nladdr = {
> +		.nl_family = AF_NETLINK
> +	};
> +	struct iovec rcv_iov = {
> +		.iov_base = rcv_buff,
> +		.iov_len = sizeof(rcv_buff)
> +	};
> +	struct msghdr rcv_msg = {
> +		.msg_name = &rcv_nladdr,
> +		.msg_namelen = sizeof(rcv_nladdr),
> +		.msg_iov = &rcv_iov,
> +		.msg_iovlen = 1
> +	};
> +	struct mptcp_info *info = NULL;
> +	int len;
> +
> +	len = recvmsg(fd, &rcv_msg, 0);
> +	nlh = (struct nlmsghdr *)rcv_buff;
> +
> +	while (NLMSG_OK(nlh, len)) {
> +		if (nlh->nlmsg_type == NLMSG_DONE) {
> +			printf("NLMSG_DONE\n");
> +			break;
> +		} else if (nlh->nlmsg_type == NLMSG_ERROR) {
> +			struct nlmsgerr *err;
> +
> +			err = (struct nlmsgerr *)NLMSG_DATA(nlh);
> +			printf("Error %d:%s\n", -(err->error), strerror(-(err->error)));
> +			break;
> +		}
> +		info = parse_nlmsg(nlh);
> +		nlh = NLMSG_NEXT(nlh, len);
> +	}
> +	close(fd);

That's strange to close the fd here. Probably best to do that in
get_mptcpinfo() where it has been opened.

> +	return info;
> +}
> +
> +static struct mptcp_info *get_mptcpinfo(__u32 token)
> +{
> +	struct nlmsghdr *nlh = NULL;
> +	int fd;
> +
> +	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
> +	if (fd < 0)
> +		die_perror("Netlink socket");
> +
> +	send_query(fd, token);
> +	return recv_nlmsg(fd, nlh);
> +}
> +
> +static void parse_opts(int argc, char **argv, __u32 *target_token)
> +{
> +	int c;
> +
> +	while ((c = getopt(argc, argv, "ht:")) != -1) {
> +		switch (c) {
> +		case 'h':
> +			die_usage(1);

exit(0) for -h.

> +			break;
> +		case 't':
> +			sscanf(optarg, "%x", target_token);
> +			break;
> +		default:
> +			die_usage(1);
> +			break;
> +		}
> +	}

It might be good to call "die_usage(1)" if the program has not been
called with '-t'.

> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct mptcp_info *info = NULL;
> +	__u32 target_token;
> +
> +	parse_opts(argc, argv, &target_token);
> +	info = get_mptcpinfo(target_token);
> +
> +	if (info)
> +		printf("token:%x\n", info->mptcpi_token);
> +	else
> +		perror("No Such msk using this token!\n");
> +
> +	return 0;
> +}
> +

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [mptcp-next v2 2/2] selftests: mptcp: add a test for mptcp_diag_dump_one
  2025-02-20  7:11 ` [mptcp-next v2 2/2] selftests: mptcp: add a test for mptcp_diag_dump_one Gang Yan
@ 2025-02-20 11:36   ` Matthieu Baerts
  0 siblings, 0 replies; 6+ messages in thread
From: Matthieu Baerts @ 2025-02-20 11:36 UTC (permalink / raw)
  To: Gang Yan, mptcp

Hi Gang Yan,

On 20/02/2025 08:11, Gang Yan wrote:
> This patch introduces a new 'chk_diag' test in diag.sh. It retrieves
> the token for a specified MPTCP socket (msk) using the 'ss' command and
> then accesses the 'mptcp_diag_dump_one' in kernel via ./mptcp_diag
> to verify if the correct token is returned.
> 
> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/524
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
>  tools/testing/selftests/net/mptcp/diag.sh | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/tools/testing/selftests/net/mptcp/diag.sh b/tools/testing/selftests/net/mptcp/diag.sh
> index 2bd0c1eb70c5..9a57c27b14b9 100755
> --- a/tools/testing/selftests/net/mptcp/diag.sh
> +++ b/tools/testing/selftests/net/mptcp/diag.sh
> @@ -200,6 +200,28 @@ chk_msk_cestab()
>  		 "${expected}" "${msg}" ""
>  }
>  
> +chk_dumpone()
> +{
> +	local ss_token="$(ss -inmHMN $ns | grep 'token:' |\
> +			  head -n 1 |\
> +			  sed 's/.*token:\([0-9a-f]*\).*/\1/')"
> +	local token="$(ip netns exec $ns ./mptcp_diag -t $ss_token |\
> +		       grep 'token:' |\
> +		       sed 's/.*token:\([0-9a-f]*\).*/\1/')"

(Or use "grep 'token:' | cut -d: -f2")

BTW, mptcp_diag should probably print all the different fields from
mptcp_info, and add a space after ':'

  token: (...)
  bytes_sent: (...)

And then we could do this:

  ./mptcp_diag -t (...) | awk '/^token: / { print $2 }'

> +	local msg="...chk dumpone"
There should be one more '.'. See the tests logs:

  # 13 ....chk 2 cestab                                  [ OK ]
  # 14 ...chk dumpone                                    [ OK ]
  # 15 ....chk 2->0 msk in use after flush               [ OK ]


Also, probably better with 'dump_one'.

> +
> +	mptcp_lib_print_title "$msg"
> +        if [ "$ss_token" != "$token" ]; then

Please use tabs for the indentation.

> +		mptcp_lib_pr_fail "expected $ss_token found $token"
> +		mptcp_lib_result_fail "${msg}"
> +		ret=${KSFT_FAIL}
> +	else
> +                mptcp_lib_pr_ok
> +                mptcp_lib_result_pass "${msg}"

Please use tabs for the indentation.

> +	fi
> +
> +}
> +
>  msk_info_get_value()
>  {
>  	local port="${1}"
> @@ -290,6 +312,7 @@ chk_msk_remote_key_nr 2 "....chk remote_key"
>  chk_msk_fallback_nr 0 "....chk no fallback"
>  chk_msk_inuse 2
>  chk_msk_cestab 2
> +chk_dumpone
>  flush_pids
>  
>  chk_msk_inuse 0 "2->0"

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-02-20 11:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-20  7:11 [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing Gang Yan
2025-02-20  7:11 ` [mptcp-next v2 1/2] selftests: mptcp: Add a tool to get specific msk_info Gang Yan
2025-02-20 11:22   ` Matthieu Baerts
2025-02-20  7:11 ` [mptcp-next v2 2/2] selftests: mptcp: add a test for mptcp_diag_dump_one Gang Yan
2025-02-20 11:36   ` Matthieu Baerts
2025-02-20  8:21 ` [mptcp-next v2 0/2] selftests: mptcp: add tests for increasing MPTCP CI

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.