Skip to content

Commit a3d274d

Browse files
Dwyane-Yanintel-lab-lkp
authored andcommitted
selftests: mptcp: add a helper to get subflow_info
This patch adds 'get_subflow_info' in 'mptcp_diag', which can check whether a TCP connection is an MPTCP subflow based on the "INET_ULP_INFO_MPTCP" with tcp_diag method. Co-developed-by: Geliang Tang <[email protected]> Signed-off-by: Geliang Tang <[email protected]> Signed-off-by: Gang Yan <[email protected]>
1 parent 54ba681 commit a3d274d

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

tools/testing/selftests/net/mptcp/mptcp_diag.c

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <sys/socket.h>
99
#include <netinet/in.h>
1010
#include <linux/tcp.h>
11+
#include <arpa/inet.h>
1112

1213
#include <unistd.h>
1314
#include <stdlib.h>
@@ -19,8 +20,13 @@
1920
#define IPPROTO_MPTCP 262
2021
#endif
2122

23+
#define parse_rtattr_nested(tb, max, rta) \
24+
(parse_rtattr_flags((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta), \
25+
NLA_F_NESTED))
26+
2227
struct params {
2328
__u32 target_token;
29+
char subflow_addr[1024];
2430
};
2531

2632
struct mptcp_info {
@@ -58,7 +64,9 @@ static void die_perror(const char *msg)
5864

5965
static void die_usage(int r)
6066
{
61-
fprintf(stderr, "Usage: mptcp_diag -t\n");
67+
fprintf(stderr, "Usage:\n"
68+
"mptcp_diag -t <token>\n"
69+
"mptcp_diag -s \"<saddr> <sport> <daddr> <dport>\"\n");
6270
exit(r);
6371
}
6472

@@ -182,6 +190,21 @@ static void parse_nlmsg(struct nlmsghdr *nlh, __u32 proto)
182190
}
183191
print_info_msg(info);
184192
}
193+
if (proto == IPPROTO_TCP && tb[INET_DIAG_ULP_INFO]) {
194+
struct rtattr *ulpinfo[INET_ULP_INFO_MAX + 1] = { 0 };
195+
196+
parse_rtattr_nested(ulpinfo, INET_ULP_INFO_MAX,
197+
tb[INET_DIAG_ULP_INFO]);
198+
199+
if (ulpinfo[INET_ULP_INFO_MPTCP]) {
200+
struct rtattr *sfinfo[MPTCP_SUBFLOW_ATTR_MAX + 1] = { 0 };
201+
202+
parse_rtattr_nested(sfinfo, MPTCP_SUBFLOW_ATTR_MAX,
203+
ulpinfo[INET_ULP_INFO_MPTCP]);
204+
} else {
205+
printf("It's a normal TCP!\n");
206+
}
207+
}
185208
}
186209

187210
static void recv_nlmsg(int fd, __u32 proto)
@@ -244,21 +267,59 @@ static void get_mptcpinfo(__u32 token)
244267
close(fd);
245268
}
246269

270+
static void get_subflow_info(char *subflow_addr)
271+
{
272+
struct inet_diag_req_v2 r = {
273+
.sdiag_family = AF_INET,
274+
.sdiag_protocol = IPPROTO_TCP,
275+
};
276+
int sport, dport;
277+
char saddr[64]; // Take ipv6 into consideration
278+
char daddr[64];
279+
int ret;
280+
int fd;
281+
282+
ret = sscanf(subflow_addr, "%s %d %s %d", saddr, &sport, daddr, &dport);
283+
if (ret != 4)
284+
die_perror("IP PORT Pairs has style problems!");
285+
286+
printf("%s:%d -> %s:%d\n", saddr, sport, daddr, dport);
287+
288+
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
289+
if (fd < 0)
290+
die_perror("Netlink socket");
291+
292+
r.id.idiag_cookie[0] = INET_DIAG_NOCOOKIE;
293+
r.id.idiag_cookie[1] = INET_DIAG_NOCOOKIE;
294+
r.id.idiag_sport = htons(sport);
295+
r.id.idiag_dport = htons(dport);
296+
r.id.idiag_if = 0;
297+
298+
inet_pton(AF_INET, saddr, &r.id.idiag_src);
299+
inet_pton(AF_INET, daddr, &r.id.idiag_dst);
300+
r.idiag_ext |= (1 << (INET_DIAG_INFO - 1));
301+
send_query(fd, &r, IPPROTO_TCP);
302+
recv_nlmsg(fd, IPPROTO_TCP);
303+
}
304+
247305
static void parse_opts(int argc, char **argv, struct params *p)
248306
{
249307
int c;
250308

251309
if (argc < 2)
252310
die_usage(1);
253311

254-
while ((c = getopt(argc, argv, "ht:")) != -1) {
312+
while ((c = getopt(argc, argv, "ht:s:")) != -1) {
255313
switch (c) {
256314
case 'h':
257315
die_usage(0);
258316
break;
259317
case 't':
260318
sscanf(optarg, "%x", &p->target_token);
261319
break;
320+
case 's':
321+
snprintf(p->subflow_addr, strlen(optarg) + 1, "%s", optarg);
322+
break;
262323
default:
263324
die_usage(1);
264325
break;
@@ -275,6 +336,9 @@ int main(int argc, char *argv[])
275336
if (p.target_token)
276337
get_mptcpinfo(p.target_token);
277338

339+
if (strlen(p.subflow_addr) != 0)
340+
get_subflow_info(p.subflow_addr);
341+
278342
return 0;
279343
}
280344

0 commit comments

Comments
 (0)