xref: /linux/tools/testing/selftests/net/mptcp/pm_nl_ctl.c (revision ed5372634c5b936163d0760cc44599f6797b7236)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <errno.h>
4 #include <error.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <limits.h>
11 
12 #include <sys/socket.h>
13 #include <sys/types.h>
14 
15 #include <arpa/inet.h>
16 #include <net/if.h>
17 
18 #include <linux/rtnetlink.h>
19 #include <linux/genetlink.h>
20 
21 #include "linux/mptcp.h"
22 
23 #ifndef IPPROTO_MPTCP
24 #define IPPROTO_MPTCP 262
25 #endif
26 
27 #define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7)
28 
29 static void syntax(char *argv[])
30 {
31 	fprintf(stderr, "%s add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept [<args>]\n", argv[0]);
32 	fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n");
33 	fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n");
34 	fprintf(stderr, "\trem id <local-id> token <token>\n");
35 	fprintf(stderr, "\tcsf lip <local-ip> lid <local-id> rip <remote-ip> rport <remote-port> token <token>\n");
36 	fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
37 	fprintf(stderr, "\tdel <id> [<ip>]\n");
38 	fprintf(stderr, "\tget <id>\n");
39 	fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>] [token <token>] [rip <ip>] [rport <port>]\n");
40 	fprintf(stderr, "\tflush\n");
41 	fprintf(stderr, "\tdump\n");
42 	fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n");
43 	fprintf(stderr, "\tevents\n");
44 	fprintf(stderr, "\tlisten <local-ip> <local-port>\n");
45 	exit(0);
46 }
47 
48 static int init_genl_req(char *data, int family, int cmd, int version)
49 {
50 	struct nlmsghdr *nh = (void *)data;
51 	struct genlmsghdr *gh;
52 	int off = 0;
53 
54 	nh->nlmsg_type = family;
55 	nh->nlmsg_flags = NLM_F_REQUEST;
56 	nh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
57 	off += NLMSG_ALIGN(sizeof(*nh));
58 
59 	gh = (void *)(data + off);
60 	gh->cmd = cmd;
61 	gh->version = version;
62 	off += NLMSG_ALIGN(sizeof(*gh));
63 	return off;
64 }
65 
66 static int nl_error(struct nlmsghdr *nh)
67 {
68 	struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nh);
69 	int len = nh->nlmsg_len - sizeof(*nh);
70 	uint32_t off;
71 
72 	if (len < sizeof(struct nlmsgerr)) {
73 		error(1, 0, "netlink error message truncated %d min %ld", len,
74 		      sizeof(struct nlmsgerr));
75 		return -1;
76 	}
77 
78 	if (err->error) {
79 		/* check messages from kernel */
80 		struct rtattr *attrs = (struct rtattr *)NLMSG_DATA(nh);
81 
82 		fprintf(stderr, "netlink error %d (%s)\n",
83 			err->error, strerror(-err->error));
84 
85 		while (RTA_OK(attrs, len)) {
86 			if (attrs->rta_type == NLMSGERR_ATTR_MSG)
87 				fprintf(stderr, "netlink ext ack msg: %s\n",
88 					(char *)RTA_DATA(attrs));
89 			if (attrs->rta_type == NLMSGERR_ATTR_OFFS) {
90 				memcpy(&off, RTA_DATA(attrs), 4);
91 				fprintf(stderr, "netlink err off %d\n",
92 					(int)off);
93 			}
94 			attrs = RTA_NEXT(attrs, len);
95 		}
96 		return -1;
97 	}
98 
99 	return 0;
100 }
101 
102 static int capture_events(int fd, int event_group)
103 {
104 	u_int8_t buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
105 			NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1024];
106 	struct genlmsghdr *ghdr;
107 	struct rtattr *attrs;
108 	struct nlmsghdr *nh;
109 	int ret = 0;
110 	int res_len;
111 	int msg_len;
112 	fd_set rfds;
113 
114 	if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
115 		       &event_group, sizeof(event_group)) < 0)
116 		error(1, errno, "could not join the " MPTCP_PM_EV_GRP_NAME " mcast group");
117 
118 	do {
119 		bool server_side = false;
120 
121 		FD_ZERO(&rfds);
122 		FD_SET(fd, &rfds);
123 		res_len = NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
124 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1024;
125 
126 		ret = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
127 
128 		if (ret < 0)
129 			error(1, ret, "error in select() on NL socket");
130 
131 		res_len = recv(fd, buffer, res_len, 0);
132 		if (res_len < 0)
133 			error(1, res_len, "error on recv() from NL socket");
134 
135 		nh = (struct nlmsghdr *)buffer;
136 
137 		for (; NLMSG_OK(nh, res_len); nh = NLMSG_NEXT(nh, res_len)) {
138 			if (nh->nlmsg_type == NLMSG_ERROR)
139 				error(1, NLMSG_ERROR, "received invalid NL message");
140 
141 			ghdr = (struct genlmsghdr *)NLMSG_DATA(nh);
142 
143 			if (ghdr->cmd == 0)
144 				continue;
145 
146 			fprintf(stderr, "type:%d", ghdr->cmd);
147 
148 			msg_len = nh->nlmsg_len - NLMSG_LENGTH(GENL_HDRLEN);
149 
150 			attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
151 			while (RTA_OK(attrs, msg_len)) {
152 				if (attrs->rta_type == MPTCP_ATTR_TOKEN)
153 					fprintf(stderr, ",token:%u", *(__u32 *)RTA_DATA(attrs));
154 				else if (attrs->rta_type == MPTCP_ATTR_FAMILY)
155 					fprintf(stderr, ",family:%u", *(__u16 *)RTA_DATA(attrs));
156 				else if (attrs->rta_type == MPTCP_ATTR_LOC_ID)
157 					fprintf(stderr, ",loc_id:%u", *(__u8 *)RTA_DATA(attrs));
158 				else if (attrs->rta_type == MPTCP_ATTR_REM_ID)
159 					fprintf(stderr, ",rem_id:%u", *(__u8 *)RTA_DATA(attrs));
160 				else if (attrs->rta_type == MPTCP_ATTR_SADDR4) {
161 					u_int32_t saddr4 = ntohl(*(__u32 *)RTA_DATA(attrs));
162 
163 					fprintf(stderr, ",saddr4:%u.%u.%u.%u", saddr4 >> 24,
164 					       (saddr4 >> 16) & 0xFF, (saddr4 >> 8) & 0xFF,
165 					       (saddr4 & 0xFF));
166 				} else if (attrs->rta_type == MPTCP_ATTR_SADDR6) {
167 					char buf[INET6_ADDRSTRLEN];
168 
169 					if (inet_ntop(AF_INET6, RTA_DATA(attrs), buf,
170 						      sizeof(buf)) != NULL)
171 						fprintf(stderr, ",saddr6:%s", buf);
172 				} else if (attrs->rta_type == MPTCP_ATTR_DADDR4) {
173 					u_int32_t daddr4 = ntohl(*(__u32 *)RTA_DATA(attrs));
174 
175 					fprintf(stderr, ",daddr4:%u.%u.%u.%u", daddr4 >> 24,
176 					       (daddr4 >> 16) & 0xFF, (daddr4 >> 8) & 0xFF,
177 					       (daddr4 & 0xFF));
178 				} else if (attrs->rta_type == MPTCP_ATTR_DADDR6) {
179 					char buf[INET6_ADDRSTRLEN];
180 
181 					if (inet_ntop(AF_INET6, RTA_DATA(attrs), buf,
182 						      sizeof(buf)) != NULL)
183 						fprintf(stderr, ",daddr6:%s", buf);
184 				} else if (attrs->rta_type == MPTCP_ATTR_SPORT)
185 					fprintf(stderr, ",sport:%u",
186 						ntohs(*(__u16 *)RTA_DATA(attrs)));
187 				else if (attrs->rta_type == MPTCP_ATTR_DPORT)
188 					fprintf(stderr, ",dport:%u",
189 						ntohs(*(__u16 *)RTA_DATA(attrs)));
190 				else if (attrs->rta_type == MPTCP_ATTR_BACKUP)
191 					fprintf(stderr, ",backup:%u", *(__u8 *)RTA_DATA(attrs));
192 				else if (attrs->rta_type == MPTCP_ATTR_ERROR)
193 					fprintf(stderr, ",error:%u", *(__u8 *)RTA_DATA(attrs));
194 				else if (attrs->rta_type == MPTCP_ATTR_SERVER_SIDE)
195 					server_side = !!*(__u8 *)RTA_DATA(attrs);
196 				else if (attrs->rta_type == MPTCP_ATTR_FLAGS) {
197 					__u16 flags = *(__u16 *)RTA_DATA(attrs);
198 
199 					/* only print when present, easier */
200 					if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0)
201 						fprintf(stderr, ",deny_join_id0:1");
202 					if (flags & MPTCP_PM_EV_FLAG_SERVER_SIDE)
203 						server_side = true;
204 				}
205 
206 				attrs = RTA_NEXT(attrs, msg_len);
207 			}
208 		}
209 		if (server_side)
210 			fprintf(stderr, ",server_side:1");
211 		fprintf(stderr, "\n");
212 	} while (1);
213 
214 	return 0;
215 }
216 
217 /* do a netlink command and, if max > 0, fetch the reply ; nh's size >1024B */
218 static int do_nl_req(int fd, struct nlmsghdr *nh, int len, int max)
219 {
220 	void *data = nh;
221 	int rem, ret;
222 	int err = 0;
223 
224 	/* If no expected answer, ask for an ACK to look for errors if any */
225 	if (max == 0) {
226 		nh->nlmsg_flags |= NLM_F_ACK;
227 		max = 1024;
228 	}
229 
230 	nh->nlmsg_len = len;
231 	ret = send(fd, data, len, 0);
232 	if (ret != len)
233 		error(1, errno, "send netlink: %uB != %uB\n", ret, len);
234 
235 	ret = recv(fd, data, max, 0);
236 	if (ret < 0)
237 		error(1, errno, "recv netlink: %uB\n", ret);
238 
239 	rem = ret;
240 	/* Beware: the NLMSG_NEXT macro updates the 'rem' argument */
241 	for (; NLMSG_OK(nh, rem); nh = NLMSG_NEXT(nh, rem)) {
242 		if (nh->nlmsg_type == NLMSG_DONE)
243 			break;
244 
245 		if (nh->nlmsg_type == NLMSG_ERROR && nl_error(nh))
246 			err = 1;
247 	}
248 	if (err)
249 		error(1, 0, "bailing out due to netlink error[s]");
250 	return ret;
251 }
252 
253 static int genl_parse_getfamily(struct nlmsghdr *nlh, int *pm_family,
254 				int *events_mcast_grp)
255 {
256 	struct genlmsghdr *ghdr = NLMSG_DATA(nlh);
257 	int len = nlh->nlmsg_len;
258 	struct rtattr *attrs;
259 	struct rtattr *grps;
260 	struct rtattr *grp;
261 	int got_events_grp;
262 	int got_family;
263 	int grps_len;
264 	int grp_len;
265 
266 	if (nlh->nlmsg_type != GENL_ID_CTRL)
267 		error(1, errno, "Not a controller message, len=%d type=0x%x\n",
268 		      nlh->nlmsg_len, nlh->nlmsg_type);
269 
270 	len -= NLMSG_LENGTH(GENL_HDRLEN);
271 
272 	if (len < 0)
273 		error(1, errno, "wrong controller message len %d\n", len);
274 
275 	if (ghdr->cmd != CTRL_CMD_NEWFAMILY)
276 		error(1, errno, "Unknown controller command %d\n", ghdr->cmd);
277 
278 	attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
279 	got_family = 0;
280 	got_events_grp = 0;
281 
282 	while (RTA_OK(attrs, len)) {
283 		if (attrs->rta_type == CTRL_ATTR_FAMILY_ID) {
284 			*pm_family = *(__u16 *)RTA_DATA(attrs);
285 			got_family = 1;
286 		} else if (attrs->rta_type == CTRL_ATTR_MCAST_GROUPS) {
287 			grps = RTA_DATA(attrs);
288 			grps_len = RTA_PAYLOAD(attrs);
289 
290 			while (RTA_OK(grps, grps_len)) {
291 				grp = RTA_DATA(grps);
292 				grp_len = RTA_PAYLOAD(grps);
293 				got_events_grp = 0;
294 
295 				while (RTA_OK(grp, grp_len)) {
296 					if (grp->rta_type == CTRL_ATTR_MCAST_GRP_ID)
297 						*events_mcast_grp = *(__u32 *)RTA_DATA(grp);
298 					else if (grp->rta_type == CTRL_ATTR_MCAST_GRP_NAME &&
299 						 !strcmp(RTA_DATA(grp), MPTCP_PM_EV_GRP_NAME))
300 						got_events_grp = 1;
301 
302 					grp = RTA_NEXT(grp, grp_len);
303 				}
304 
305 				if (got_events_grp)
306 					break;
307 
308 				grps = RTA_NEXT(grps, grps_len);
309 			}
310 		}
311 
312 		if (got_family && got_events_grp)
313 			return 0;
314 
315 		attrs = RTA_NEXT(attrs, len);
316 	}
317 
318 	error(1, errno, "can't find CTRL_ATTR_FAMILY_ID attr");
319 	return -1;
320 }
321 
322 static int resolve_mptcp_pm_netlink(int fd, int *pm_family, int *events_mcast_grp)
323 {
324 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
325 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
326 		  1024];
327 	struct nlmsghdr *nh;
328 	struct rtattr *rta;
329 	int namelen;
330 	int off = 0;
331 
332 	memset(data, 0, sizeof(data));
333 	nh = (void *)data;
334 	off = init_genl_req(data, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, 0);
335 
336 	rta = (void *)(data + off);
337 	namelen = strlen(MPTCP_PM_NAME) + 1;
338 	rta->rta_type = CTRL_ATTR_FAMILY_NAME;
339 	rta->rta_len = RTA_LENGTH(namelen);
340 	memcpy(RTA_DATA(rta), MPTCP_PM_NAME, namelen);
341 	off += NLMSG_ALIGN(rta->rta_len);
342 
343 	do_nl_req(fd, nh, off, sizeof(data));
344 	return genl_parse_getfamily((void *)data, pm_family, events_mcast_grp);
345 }
346 
347 int dsf(int fd, int pm_family, int argc, char *argv[])
348 {
349 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
350 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
351 		  1024];
352 	struct rtattr *rta, *addr;
353 	u_int16_t family, port;
354 	struct nlmsghdr *nh;
355 	u_int32_t token;
356 	int addr_start;
357 	int off = 0;
358 	int arg;
359 
360 	const char *params[5];
361 
362 	memset(params, 0, 5 * sizeof(const char *));
363 
364 	memset(data, 0, sizeof(data));
365 	nh = (void *)data;
366 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_DESTROY,
367 			    MPTCP_PM_VER);
368 
369 	if (argc < 12)
370 		syntax(argv);
371 
372 	/* Params recorded in this order:
373 	 * <local-ip>, <local-port>, <remote-ip>, <remote-port>, <token>
374 	 */
375 	for (arg = 2; arg < argc; arg++) {
376 		if (!strcmp(argv[arg], "lip")) {
377 			if (++arg >= argc)
378 				error(1, 0, " missing local IP");
379 
380 			params[0] = argv[arg];
381 		} else if (!strcmp(argv[arg], "lport")) {
382 			if (++arg >= argc)
383 				error(1, 0, " missing local port");
384 
385 			params[1] = argv[arg];
386 		} else if (!strcmp(argv[arg], "rip")) {
387 			if (++arg >= argc)
388 				error(1, 0, " missing remote IP");
389 
390 			params[2] = argv[arg];
391 		} else if (!strcmp(argv[arg], "rport")) {
392 			if (++arg >= argc)
393 				error(1, 0, " missing remote port");
394 
395 			params[3] = argv[arg];
396 		} else if (!strcmp(argv[arg], "token")) {
397 			if (++arg >= argc)
398 				error(1, 0, " missing token");
399 
400 			params[4] = argv[arg];
401 		} else
402 			error(1, 0, "unknown keyword %s", argv[arg]);
403 	}
404 
405 	for (arg = 0; arg < 4; arg = arg + 2) {
406 		/*  addr header */
407 		addr_start = off;
408 		addr = (void *)(data + off);
409 		addr->rta_type = NLA_F_NESTED |
410 			((arg == 0) ? MPTCP_PM_ATTR_ADDR : MPTCP_PM_ATTR_ADDR_REMOTE);
411 		addr->rta_len = RTA_LENGTH(0);
412 		off += NLMSG_ALIGN(addr->rta_len);
413 
414 		/*  addr data */
415 		rta = (void *)(data + off);
416 		if (inet_pton(AF_INET, params[arg], RTA_DATA(rta))) {
417 			family = AF_INET;
418 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
419 			rta->rta_len = RTA_LENGTH(4);
420 		} else if (inet_pton(AF_INET6, params[arg], RTA_DATA(rta))) {
421 			family = AF_INET6;
422 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
423 			rta->rta_len = RTA_LENGTH(16);
424 		} else
425 			error(1, errno, "can't parse ip %s", params[arg]);
426 		off += NLMSG_ALIGN(rta->rta_len);
427 
428 		/* family */
429 		rta = (void *)(data + off);
430 		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
431 		rta->rta_len = RTA_LENGTH(2);
432 		memcpy(RTA_DATA(rta), &family, 2);
433 		off += NLMSG_ALIGN(rta->rta_len);
434 
435 		/*  port */
436 		port = atoi(params[arg + 1]);
437 		rta = (void *)(data + off);
438 		rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
439 		rta->rta_len = RTA_LENGTH(2);
440 		memcpy(RTA_DATA(rta), &port, 2);
441 		off += NLMSG_ALIGN(rta->rta_len);
442 
443 		addr->rta_len = off - addr_start;
444 	}
445 
446 	/* token */
447 	token = strtoul(params[4], NULL, 10);
448 	rta = (void *)(data + off);
449 	rta->rta_type = MPTCP_PM_ATTR_TOKEN;
450 	rta->rta_len = RTA_LENGTH(4);
451 	memcpy(RTA_DATA(rta), &token, 4);
452 	off += NLMSG_ALIGN(rta->rta_len);
453 
454 	do_nl_req(fd, nh, off, 0);
455 
456 	return 0;
457 }
458 
459 int csf(int fd, int pm_family, int argc, char *argv[])
460 {
461 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
462 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
463 		  1024];
464 	u_int32_t flags = MPTCP_PM_ADDR_FLAG_SUBFLOW;
465 	const char *params[5];
466 	struct nlmsghdr *nh;
467 	struct rtattr *addr;
468 	struct rtattr *rta;
469 	u_int16_t family;
470 	u_int32_t token;
471 	u_int16_t port;
472 	int addr_start;
473 	u_int8_t id;
474 	int off = 0;
475 	int arg;
476 
477 	memset(params, 0, 5 * sizeof(const char *));
478 
479 	memset(data, 0, sizeof(data));
480 	nh = (void *)data;
481 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_CREATE,
482 			    MPTCP_PM_VER);
483 
484 	if (argc < 12)
485 		syntax(argv);
486 
487 	/* Params recorded in this order:
488 	 * <local-ip>, <local-id>, <remote-ip>, <remote-port>, <token>
489 	 */
490 	for (arg = 2; arg < argc; arg++) {
491 		if (!strcmp(argv[arg], "lip")) {
492 			if (++arg >= argc)
493 				error(1, 0, " missing local IP");
494 
495 			params[0] = argv[arg];
496 		} else if (!strcmp(argv[arg], "lid")) {
497 			if (++arg >= argc)
498 				error(1, 0, " missing local id");
499 
500 			params[1] = argv[arg];
501 		} else if (!strcmp(argv[arg], "rip")) {
502 			if (++arg >= argc)
503 				error(1, 0, " missing remote ip");
504 
505 			params[2] = argv[arg];
506 		} else if (!strcmp(argv[arg], "rport")) {
507 			if (++arg >= argc)
508 				error(1, 0, " missing remote port");
509 
510 			params[3] = argv[arg];
511 		} else if (!strcmp(argv[arg], "token")) {
512 			if (++arg >= argc)
513 				error(1, 0, " missing token");
514 
515 			params[4] = argv[arg];
516 		} else
517 			error(1, 0, "unknown param %s", argv[arg]);
518 	}
519 
520 	for (arg = 0; arg < 4; arg = arg + 2) {
521 		/*  addr header */
522 		addr_start = off;
523 		addr = (void *)(data + off);
524 		addr->rta_type = NLA_F_NESTED |
525 			((arg == 0) ? MPTCP_PM_ATTR_ADDR : MPTCP_PM_ATTR_ADDR_REMOTE);
526 		addr->rta_len = RTA_LENGTH(0);
527 		off += NLMSG_ALIGN(addr->rta_len);
528 
529 		/*  addr data */
530 		rta = (void *)(data + off);
531 		if (inet_pton(AF_INET, params[arg], RTA_DATA(rta))) {
532 			family = AF_INET;
533 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
534 			rta->rta_len = RTA_LENGTH(4);
535 		} else if (inet_pton(AF_INET6, params[arg], RTA_DATA(rta))) {
536 			family = AF_INET6;
537 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
538 			rta->rta_len = RTA_LENGTH(16);
539 		} else
540 			error(1, errno, "can't parse ip %s", params[arg]);
541 		off += NLMSG_ALIGN(rta->rta_len);
542 
543 		/* family */
544 		rta = (void *)(data + off);
545 		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
546 		rta->rta_len = RTA_LENGTH(2);
547 		memcpy(RTA_DATA(rta), &family, 2);
548 		off += NLMSG_ALIGN(rta->rta_len);
549 
550 		if (arg == 2) {
551 			/*  port */
552 			port = atoi(params[arg + 1]);
553 			rta = (void *)(data + off);
554 			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
555 			rta->rta_len = RTA_LENGTH(2);
556 			memcpy(RTA_DATA(rta), &port, 2);
557 			off += NLMSG_ALIGN(rta->rta_len);
558 		}
559 
560 		if (arg == 0) {
561 			/* id */
562 			id = atoi(params[arg + 1]);
563 			rta = (void *)(data + off);
564 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
565 			rta->rta_len = RTA_LENGTH(1);
566 			memcpy(RTA_DATA(rta), &id, 1);
567 			off += NLMSG_ALIGN(rta->rta_len);
568 		}
569 
570 		/* addr flags */
571 		rta = (void *)(data + off);
572 		rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS;
573 		rta->rta_len = RTA_LENGTH(4);
574 		memcpy(RTA_DATA(rta), &flags, 4);
575 		off += NLMSG_ALIGN(rta->rta_len);
576 
577 		addr->rta_len = off - addr_start;
578 	}
579 
580 	/* token */
581 	token = strtoul(params[4], NULL, 10);
582 	rta = (void *)(data + off);
583 	rta->rta_type = MPTCP_PM_ATTR_TOKEN;
584 	rta->rta_len = RTA_LENGTH(4);
585 	memcpy(RTA_DATA(rta), &token, 4);
586 	off += NLMSG_ALIGN(rta->rta_len);
587 
588 	do_nl_req(fd, nh, off, 0);
589 
590 	return 0;
591 }
592 
593 int remove_addr(int fd, int pm_family, int argc, char *argv[])
594 {
595 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
596 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
597 		  1024];
598 	struct nlmsghdr *nh;
599 	struct rtattr *rta;
600 	u_int32_t token;
601 	u_int8_t id;
602 	int off = 0;
603 	int arg;
604 
605 	memset(data, 0, sizeof(data));
606 	nh = (void *)data;
607 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_REMOVE,
608 			    MPTCP_PM_VER);
609 
610 	if (argc < 6)
611 		syntax(argv);
612 
613 	for (arg = 2; arg < argc; arg++) {
614 		if (!strcmp(argv[arg], "id")) {
615 			if (++arg >= argc)
616 				error(1, 0, " missing id value");
617 
618 			id = atoi(argv[arg]);
619 			rta = (void *)(data + off);
620 			rta->rta_type = MPTCP_PM_ATTR_LOC_ID;
621 			rta->rta_len = RTA_LENGTH(1);
622 			memcpy(RTA_DATA(rta), &id, 1);
623 			off += NLMSG_ALIGN(rta->rta_len);
624 		} else if (!strcmp(argv[arg], "token")) {
625 			if (++arg >= argc)
626 				error(1, 0, " missing token value");
627 
628 			token = strtoul(argv[arg], NULL, 10);
629 			rta = (void *)(data + off);
630 			rta->rta_type = MPTCP_PM_ATTR_TOKEN;
631 			rta->rta_len = RTA_LENGTH(4);
632 			memcpy(RTA_DATA(rta), &token, 4);
633 			off += NLMSG_ALIGN(rta->rta_len);
634 		} else
635 			error(1, 0, "unknown keyword %s", argv[arg]);
636 	}
637 
638 	do_nl_req(fd, nh, off, 0);
639 	return 0;
640 }
641 
642 int announce_addr(int fd, int pm_family, int argc, char *argv[])
643 {
644 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
645 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
646 		  1024];
647 	u_int32_t flags = MPTCP_PM_ADDR_FLAG_SIGNAL;
648 	u_int32_t token = UINT_MAX;
649 	struct rtattr *rta, *addr;
650 	u_int32_t id = UINT_MAX;
651 	struct nlmsghdr *nh;
652 	u_int16_t family;
653 	int addr_start;
654 	int off = 0;
655 	int arg;
656 
657 	memset(data, 0, sizeof(data));
658 	nh = (void *)data;
659 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_ANNOUNCE,
660 			    MPTCP_PM_VER);
661 
662 	if (argc < 7)
663 		syntax(argv);
664 
665 	/* local-ip header */
666 	addr_start = off;
667 	addr = (void *)(data + off);
668 	addr->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
669 	addr->rta_len = RTA_LENGTH(0);
670 	off += NLMSG_ALIGN(addr->rta_len);
671 
672 	/* local-ip data */
673 	/* record addr type */
674 	rta = (void *)(data + off);
675 	if (inet_pton(AF_INET, argv[2], RTA_DATA(rta))) {
676 		family = AF_INET;
677 		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
678 		rta->rta_len = RTA_LENGTH(4);
679 	} else if (inet_pton(AF_INET6, argv[2], RTA_DATA(rta))) {
680 		family = AF_INET6;
681 		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
682 		rta->rta_len = RTA_LENGTH(16);
683 	} else
684 		error(1, errno, "can't parse ip %s", argv[2]);
685 	off += NLMSG_ALIGN(rta->rta_len);
686 
687 	/* addr family */
688 	rta = (void *)(data + off);
689 	rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
690 	rta->rta_len = RTA_LENGTH(2);
691 	memcpy(RTA_DATA(rta), &family, 2);
692 	off += NLMSG_ALIGN(rta->rta_len);
693 
694 	for (arg = 3; arg < argc; arg++) {
695 		if (!strcmp(argv[arg], "id")) {
696 			/* local-id */
697 			if (++arg >= argc)
698 				error(1, 0, " missing id value");
699 
700 			id = atoi(argv[arg]);
701 			rta = (void *)(data + off);
702 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
703 			rta->rta_len = RTA_LENGTH(1);
704 			memcpy(RTA_DATA(rta), &id, 1);
705 			off += NLMSG_ALIGN(rta->rta_len);
706 		} else if (!strcmp(argv[arg], "dev")) {
707 			/* for the if_index */
708 			int32_t ifindex;
709 
710 			if (++arg >= argc)
711 				error(1, 0, " missing dev name");
712 
713 			ifindex = if_nametoindex(argv[arg]);
714 			if (!ifindex)
715 				error(1, errno, "unknown device %s", argv[arg]);
716 
717 			rta = (void *)(data + off);
718 			rta->rta_type = MPTCP_PM_ADDR_ATTR_IF_IDX;
719 			rta->rta_len = RTA_LENGTH(4);
720 			memcpy(RTA_DATA(rta), &ifindex, 4);
721 			off += NLMSG_ALIGN(rta->rta_len);
722 		} else if (!strcmp(argv[arg], "port")) {
723 			/* local-port (optional) */
724 			u_int16_t port;
725 
726 			if (++arg >= argc)
727 				error(1, 0, " missing port value");
728 
729 			port = atoi(argv[arg]);
730 			rta = (void *)(data + off);
731 			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
732 			rta->rta_len = RTA_LENGTH(2);
733 			memcpy(RTA_DATA(rta), &port, 2);
734 			off += NLMSG_ALIGN(rta->rta_len);
735 		} else if (!strcmp(argv[arg], "token")) {
736 			/* MPTCP connection token */
737 			if (++arg >= argc)
738 				error(1, 0, " missing token value");
739 
740 			token = strtoul(argv[arg], NULL, 10);
741 		} else
742 			error(1, 0, "unknown keyword %s", argv[arg]);
743 	}
744 
745 	/* addr flags */
746 	rta = (void *)(data + off);
747 	rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS;
748 	rta->rta_len = RTA_LENGTH(4);
749 	memcpy(RTA_DATA(rta), &flags, 4);
750 	off += NLMSG_ALIGN(rta->rta_len);
751 
752 	addr->rta_len = off - addr_start;
753 
754 	if (id == UINT_MAX || token == UINT_MAX)
755 		error(1, 0, " missing mandatory inputs");
756 
757 	/* token */
758 	rta = (void *)(data + off);
759 	rta->rta_type = MPTCP_PM_ATTR_TOKEN;
760 	rta->rta_len = RTA_LENGTH(4);
761 	memcpy(RTA_DATA(rta), &token, 4);
762 	off += NLMSG_ALIGN(rta->rta_len);
763 
764 	do_nl_req(fd, nh, off, 0);
765 
766 	return 0;
767 }
768 
769 int add_addr(int fd, int pm_family, int argc, char *argv[])
770 {
771 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
772 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
773 		  1024];
774 	struct rtattr *rta, *nest;
775 	struct nlmsghdr *nh;
776 	u_int32_t flags = 0;
777 	u_int16_t family;
778 	int nest_start;
779 	u_int8_t id;
780 	int off = 0;
781 	int arg;
782 
783 	memset(data, 0, sizeof(data));
784 	nh = (void *)data;
785 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_ADD_ADDR,
786 			    MPTCP_PM_VER);
787 
788 	if (argc < 3)
789 		syntax(argv);
790 
791 	nest_start = off;
792 	nest = (void *)(data + off);
793 	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
794 	nest->rta_len = RTA_LENGTH(0);
795 	off += NLMSG_ALIGN(nest->rta_len);
796 
797 	/* addr data */
798 	rta = (void *)(data + off);
799 	if (inet_pton(AF_INET, argv[2], RTA_DATA(rta))) {
800 		family = AF_INET;
801 		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
802 		rta->rta_len = RTA_LENGTH(4);
803 	} else if (inet_pton(AF_INET6, argv[2], RTA_DATA(rta))) {
804 		family = AF_INET6;
805 		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
806 		rta->rta_len = RTA_LENGTH(16);
807 	} else
808 		error(1, errno, "can't parse ip %s", argv[2]);
809 	off += NLMSG_ALIGN(rta->rta_len);
810 
811 	/* family */
812 	rta = (void *)(data + off);
813 	rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
814 	rta->rta_len = RTA_LENGTH(2);
815 	memcpy(RTA_DATA(rta), &family, 2);
816 	off += NLMSG_ALIGN(rta->rta_len);
817 
818 	for (arg = 3; arg < argc; arg++) {
819 		if (!strcmp(argv[arg], "flags")) {
820 			char *tok, *str;
821 
822 			/* flags */
823 			if (++arg >= argc)
824 				error(1, 0, " missing flags value");
825 
826 			/* do not support flag list yet */
827 			for (str = argv[arg]; (tok = strtok(str, ","));
828 			     str = NULL) {
829 				if (!strcmp(tok, "subflow"))
830 					flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
831 				else if (!strcmp(tok, "signal"))
832 					flags |= MPTCP_PM_ADDR_FLAG_SIGNAL;
833 				else if (!strcmp(tok, "laminar"))
834 					flags |= MPTCP_PM_ADDR_FLAG_LAMINAR;
835 				else if (!strcmp(tok, "backup"))
836 					flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
837 				else if (!strcmp(tok, "fullmesh"))
838 					flags |= MPTCP_PM_ADDR_FLAG_FULLMESH;
839 				else if (!strcmp(tok, "unknown"))
840 					flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN;
841 				else
842 					error(1, errno,
843 					      "unknown flag %s", argv[arg]);
844 			}
845 
846 			if (flags & MPTCP_PM_ADDR_FLAG_SIGNAL &&
847 			    flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
848 				error(1, errno, "error flag fullmesh");
849 			}
850 
851 			rta = (void *)(data + off);
852 			rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS;
853 			rta->rta_len = RTA_LENGTH(4);
854 			memcpy(RTA_DATA(rta), &flags, 4);
855 			off += NLMSG_ALIGN(rta->rta_len);
856 		} else if (!strcmp(argv[arg], "id")) {
857 			if (++arg >= argc)
858 				error(1, 0, " missing id value");
859 
860 			id = atoi(argv[arg]);
861 			rta = (void *)(data + off);
862 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
863 			rta->rta_len = RTA_LENGTH(1);
864 			memcpy(RTA_DATA(rta), &id, 1);
865 			off += NLMSG_ALIGN(rta->rta_len);
866 		} else if (!strcmp(argv[arg], "dev")) {
867 			int32_t ifindex;
868 
869 			if (++arg >= argc)
870 				error(1, 0, " missing dev name");
871 
872 			ifindex = if_nametoindex(argv[arg]);
873 			if (!ifindex)
874 				error(1, errno, "unknown device %s", argv[arg]);
875 
876 			rta = (void *)(data + off);
877 			rta->rta_type = MPTCP_PM_ADDR_ATTR_IF_IDX;
878 			rta->rta_len = RTA_LENGTH(4);
879 			memcpy(RTA_DATA(rta), &ifindex, 4);
880 			off += NLMSG_ALIGN(rta->rta_len);
881 		} else if (!strcmp(argv[arg], "port")) {
882 			u_int16_t port;
883 
884 			if (++arg >= argc)
885 				error(1, 0, " missing port value");
886 			if (!(flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
887 				error(1, 0, " flags must be signal when using port");
888 
889 			port = atoi(argv[arg]);
890 			rta = (void *)(data + off);
891 			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
892 			rta->rta_len = RTA_LENGTH(2);
893 			memcpy(RTA_DATA(rta), &port, 2);
894 			off += NLMSG_ALIGN(rta->rta_len);
895 		} else
896 			error(1, 0, "unknown keyword %s", argv[arg]);
897 	}
898 	nest->rta_len = off - nest_start;
899 
900 	do_nl_req(fd, nh, off, 0);
901 	return 0;
902 }
903 
904 int del_addr(int fd, int pm_family, int argc, char *argv[])
905 {
906 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
907 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
908 		  1024];
909 	struct rtattr *rta, *nest;
910 	struct nlmsghdr *nh;
911 	u_int16_t family;
912 	int nest_start;
913 	u_int8_t id;
914 	int off = 0;
915 
916 	memset(data, 0, sizeof(data));
917 	nh = (void *)data;
918 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_DEL_ADDR,
919 			    MPTCP_PM_VER);
920 
921 	/* the only argument is the address id (nonzero) */
922 	if (argc != 3 && argc != 4)
923 		syntax(argv);
924 
925 	id = atoi(argv[2]);
926 	/* zero id with the IP address */
927 	if (!id && argc != 4)
928 		syntax(argv);
929 
930 	nest_start = off;
931 	nest = (void *)(data + off);
932 	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
933 	nest->rta_len =  RTA_LENGTH(0);
934 	off += NLMSG_ALIGN(nest->rta_len);
935 
936 	/* build a dummy addr with only the ID set */
937 	rta = (void *)(data + off);
938 	rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
939 	rta->rta_len = RTA_LENGTH(1);
940 	memcpy(RTA_DATA(rta), &id, 1);
941 	off += NLMSG_ALIGN(rta->rta_len);
942 
943 	if (!id) {
944 		/* addr data */
945 		rta = (void *)(data + off);
946 		if (inet_pton(AF_INET, argv[3], RTA_DATA(rta))) {
947 			family = AF_INET;
948 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
949 			rta->rta_len = RTA_LENGTH(4);
950 		} else if (inet_pton(AF_INET6, argv[3], RTA_DATA(rta))) {
951 			family = AF_INET6;
952 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
953 			rta->rta_len = RTA_LENGTH(16);
954 		} else {
955 			error(1, errno, "can't parse ip %s", argv[3]);
956 		}
957 		off += NLMSG_ALIGN(rta->rta_len);
958 
959 		/* family */
960 		rta = (void *)(data + off);
961 		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
962 		rta->rta_len = RTA_LENGTH(2);
963 		memcpy(RTA_DATA(rta), &family, 2);
964 		off += NLMSG_ALIGN(rta->rta_len);
965 	}
966 	nest->rta_len = off - nest_start;
967 
968 	do_nl_req(fd, nh, off, 0);
969 	return 0;
970 }
971 
972 static void print_addr(struct rtattr *attrs, int len)
973 {
974 	uint16_t family = 0;
975 	uint16_t port = 0;
976 	char str[1024];
977 	uint32_t flags;
978 	uint8_t id;
979 
980 	while (RTA_OK(attrs, len)) {
981 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_FAMILY)
982 			memcpy(&family, RTA_DATA(attrs), 2);
983 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_PORT)
984 			memcpy(&port, RTA_DATA(attrs), 2);
985 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR4) {
986 			if (family != AF_INET)
987 				error(1, errno, "wrong IP (v4) for family %d",
988 				      family);
989 			inet_ntop(AF_INET, RTA_DATA(attrs), str, sizeof(str));
990 			printf("%s", str);
991 			if (port)
992 				printf(" %d", port);
993 		}
994 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR6) {
995 			if (family != AF_INET6)
996 				error(1, errno, "wrong IP (v6) for family %d",
997 				      family);
998 			inet_ntop(AF_INET6, RTA_DATA(attrs), str, sizeof(str));
999 			printf("%s", str);
1000 			if (port)
1001 				printf(" %d", port);
1002 		}
1003 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ID) {
1004 			memcpy(&id, RTA_DATA(attrs), 1);
1005 			printf("id %d ", id);
1006 		}
1007 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_FLAGS) {
1008 			memcpy(&flags, RTA_DATA(attrs), 4);
1009 
1010 			printf("flags ");
1011 			if (flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
1012 				printf("signal");
1013 				flags &= ~MPTCP_PM_ADDR_FLAG_SIGNAL;
1014 				if (flags)
1015 					printf(",");
1016 			}
1017 
1018 			if (flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
1019 				printf("subflow");
1020 				flags &= ~MPTCP_PM_ADDR_FLAG_SUBFLOW;
1021 				if (flags)
1022 					printf(",");
1023 			}
1024 
1025 			if (flags & MPTCP_PM_ADDR_FLAG_LAMINAR) {
1026 				printf("laminar");
1027 				flags &= ~MPTCP_PM_ADDR_FLAG_LAMINAR;
1028 				if (flags)
1029 					printf(",");
1030 			}
1031 
1032 			if (flags & MPTCP_PM_ADDR_FLAG_BACKUP) {
1033 				printf("backup");
1034 				flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
1035 				if (flags)
1036 					printf(",");
1037 			}
1038 
1039 			if (flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
1040 				printf("fullmesh");
1041 				flags &= ~MPTCP_PM_ADDR_FLAG_FULLMESH;
1042 				if (flags)
1043 					printf(",");
1044 			}
1045 
1046 			if (flags & MPTCP_PM_ADDR_FLAG_IMPLICIT) {
1047 				printf("implicit");
1048 				flags &= ~MPTCP_PM_ADDR_FLAG_IMPLICIT;
1049 				if (flags)
1050 					printf(",");
1051 			}
1052 
1053 			if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) {
1054 				printf("unknown");
1055 				flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN;
1056 				if (flags)
1057 					printf(",");
1058 			}
1059 
1060 			/* bump unknown flags, if any */
1061 			if (flags)
1062 				printf("0x%x", flags);
1063 			printf(" ");
1064 		}
1065 		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_IF_IDX) {
1066 			char name[IF_NAMESIZE], *ret;
1067 			int32_t ifindex;
1068 
1069 			memcpy(&ifindex, RTA_DATA(attrs), 4);
1070 			ret = if_indextoname(ifindex, name);
1071 			if (ret)
1072 				printf("dev %s ", ret);
1073 			else
1074 				printf("dev unknown/%d", ifindex);
1075 		}
1076 
1077 		attrs = RTA_NEXT(attrs, len);
1078 	}
1079 	printf("\n");
1080 }
1081 
1082 static void print_addrs(struct nlmsghdr *nh, int pm_family, int total_len)
1083 {
1084 	struct rtattr *attrs;
1085 
1086 	for (; NLMSG_OK(nh, total_len); nh = NLMSG_NEXT(nh, total_len)) {
1087 		int len = nh->nlmsg_len;
1088 
1089 		if (nh->nlmsg_type == NLMSG_DONE)
1090 			break;
1091 		if (nh->nlmsg_type == NLMSG_ERROR)
1092 			nl_error(nh);
1093 		if (nh->nlmsg_type != pm_family)
1094 			continue;
1095 
1096 		len -= NLMSG_LENGTH(GENL_HDRLEN);
1097 		attrs = (struct rtattr *) ((char *) NLMSG_DATA(nh) +
1098 					   GENL_HDRLEN);
1099 		while (RTA_OK(attrs, len)) {
1100 			if (attrs->rta_type ==
1101 			    (MPTCP_PM_ATTR_ADDR | NLA_F_NESTED))
1102 				print_addr((void *)RTA_DATA(attrs),
1103 					   attrs->rta_len);
1104 			attrs = RTA_NEXT(attrs, len);
1105 		}
1106 	}
1107 }
1108 
1109 int get_addr(int fd, int pm_family, int argc, char *argv[])
1110 {
1111 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
1112 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
1113 		  1024];
1114 	struct rtattr *rta, *nest;
1115 	struct nlmsghdr *nh;
1116 	u_int32_t token = 0;
1117 	int nest_start;
1118 	u_int8_t id;
1119 	int off = 0;
1120 
1121 	memset(data, 0, sizeof(data));
1122 	nh = (void *)data;
1123 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_GET_ADDR,
1124 			    MPTCP_PM_VER);
1125 
1126 	/* the only argument is the address id */
1127 	if (argc != 3 && argc != 5)
1128 		syntax(argv);
1129 
1130 	id = atoi(argv[2]);
1131 	if (argc == 5 && !strcmp(argv[3], "token"))
1132 		token = strtoul(argv[4], NULL, 10);
1133 
1134 	nest_start = off;
1135 	nest = (void *)(data + off);
1136 	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
1137 	nest->rta_len =  RTA_LENGTH(0);
1138 	off += NLMSG_ALIGN(nest->rta_len);
1139 
1140 	/* build a dummy addr with only the ID set */
1141 	rta = (void *)(data + off);
1142 	rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
1143 	rta->rta_len = RTA_LENGTH(1);
1144 	memcpy(RTA_DATA(rta), &id, 1);
1145 	off += NLMSG_ALIGN(rta->rta_len);
1146 	nest->rta_len = off - nest_start;
1147 
1148 	/* token */
1149 	if (token) {
1150 		rta = (void *)(data + off);
1151 		rta->rta_type = MPTCP_PM_ATTR_TOKEN;
1152 		rta->rta_len = RTA_LENGTH(4);
1153 		memcpy(RTA_DATA(rta), &token, 4);
1154 		off += NLMSG_ALIGN(rta->rta_len);
1155 	}
1156 
1157 	print_addrs(nh, pm_family, do_nl_req(fd, nh, off, sizeof(data)));
1158 	return 0;
1159 }
1160 
1161 int dump_addrs(int fd, int pm_family, int argc, char *argv[])
1162 {
1163 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
1164 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
1165 		  1024];
1166 	pid_t pid = getpid();
1167 	struct nlmsghdr *nh;
1168 	u_int32_t token = 0;
1169 	struct rtattr *rta;
1170 	int off = 0;
1171 
1172 	if (argc != 2 && argc != 4)
1173 		syntax(argv);
1174 
1175 	if (argc == 4 && !strcmp(argv[2], "token"))
1176 		token = strtoul(argv[3], NULL, 10);
1177 
1178 	memset(data, 0, sizeof(data));
1179 	nh = (void *)data;
1180 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_GET_ADDR,
1181 			    MPTCP_PM_VER);
1182 	nh->nlmsg_flags |= NLM_F_DUMP;
1183 	nh->nlmsg_seq = 1;
1184 	nh->nlmsg_pid = pid;
1185 	nh->nlmsg_len = off;
1186 
1187 	/* token */
1188 	if (token) {
1189 		rta = (void *)(data + off);
1190 		rta->rta_type = MPTCP_PM_ATTR_TOKEN;
1191 		rta->rta_len = RTA_LENGTH(4);
1192 		memcpy(RTA_DATA(rta), &token, 4);
1193 		off += NLMSG_ALIGN(rta->rta_len);
1194 	}
1195 
1196 	print_addrs(nh, pm_family, do_nl_req(fd, nh, off, sizeof(data)));
1197 	return 0;
1198 }
1199 
1200 int flush_addrs(int fd, int pm_family, int argc, char *argv[])
1201 {
1202 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
1203 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
1204 		  1024];
1205 	struct nlmsghdr *nh;
1206 	int off = 0;
1207 
1208 	memset(data, 0, sizeof(data));
1209 	nh = (void *)data;
1210 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_FLUSH_ADDRS,
1211 			    MPTCP_PM_VER);
1212 
1213 	do_nl_req(fd, nh, off, 0);
1214 	return 0;
1215 }
1216 
1217 static void print_limits(struct nlmsghdr *nh, int pm_family, int total_len)
1218 {
1219 	struct rtattr *attrs;
1220 	uint32_t max;
1221 
1222 	for (; NLMSG_OK(nh, total_len); nh = NLMSG_NEXT(nh, total_len)) {
1223 		int len = nh->nlmsg_len;
1224 
1225 		if (nh->nlmsg_type == NLMSG_DONE)
1226 			break;
1227 		if (nh->nlmsg_type == NLMSG_ERROR)
1228 			nl_error(nh);
1229 		if (nh->nlmsg_type != pm_family)
1230 			continue;
1231 
1232 		len -= NLMSG_LENGTH(GENL_HDRLEN);
1233 		attrs = (struct rtattr *) ((char *) NLMSG_DATA(nh) +
1234 					   GENL_HDRLEN);
1235 		while (RTA_OK(attrs, len)) {
1236 			int type = attrs->rta_type;
1237 
1238 			if (type != MPTCP_PM_ATTR_RCV_ADD_ADDRS &&
1239 			    type != MPTCP_PM_ATTR_SUBFLOWS)
1240 				goto next;
1241 
1242 			memcpy(&max, RTA_DATA(attrs), 4);
1243 			printf("%s %u\n", type == MPTCP_PM_ATTR_SUBFLOWS ?
1244 					  "subflows" : "accept", max);
1245 
1246 next:
1247 			attrs = RTA_NEXT(attrs, len);
1248 		}
1249 	}
1250 }
1251 
1252 int get_set_limits(int fd, int pm_family, int argc, char *argv[])
1253 {
1254 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
1255 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
1256 		  1024];
1257 	uint32_t rcv_addr = 0, subflows = 0;
1258 	int cmd, len = sizeof(data);
1259 	struct nlmsghdr *nh;
1260 	int off = 0;
1261 
1262 	/* limit */
1263 	if (argc == 4) {
1264 		rcv_addr = atoi(argv[2]);
1265 		subflows = atoi(argv[3]);
1266 		cmd = MPTCP_PM_CMD_SET_LIMITS;
1267 	} else {
1268 		cmd = MPTCP_PM_CMD_GET_LIMITS;
1269 	}
1270 
1271 	memset(data, 0, sizeof(data));
1272 	nh = (void *)data;
1273 	off = init_genl_req(data, pm_family, cmd, MPTCP_PM_VER);
1274 
1275 	/* limit */
1276 	if (cmd == MPTCP_PM_CMD_SET_LIMITS) {
1277 		struct rtattr *rta = (void *)(data + off);
1278 
1279 		rta->rta_type = MPTCP_PM_ATTR_RCV_ADD_ADDRS;
1280 		rta->rta_len = RTA_LENGTH(4);
1281 		memcpy(RTA_DATA(rta), &rcv_addr, 4);
1282 		off += NLMSG_ALIGN(rta->rta_len);
1283 
1284 		rta = (void *)(data + off);
1285 		rta->rta_type = MPTCP_PM_ATTR_SUBFLOWS;
1286 		rta->rta_len = RTA_LENGTH(4);
1287 		memcpy(RTA_DATA(rta), &subflows, 4);
1288 		off += NLMSG_ALIGN(rta->rta_len);
1289 
1290 		/* do not expect a reply */
1291 		len = 0;
1292 	}
1293 
1294 	len = do_nl_req(fd, nh, off, len);
1295 	if (cmd == MPTCP_PM_CMD_GET_LIMITS)
1296 		print_limits(nh, pm_family, len);
1297 	return 0;
1298 }
1299 
1300 int add_listener(int argc, char *argv[])
1301 {
1302 	struct sockaddr_storage addr;
1303 	struct sockaddr_in6 *a6;
1304 	struct sockaddr_in *a4;
1305 	u_int16_t family = AF_UNSPEC;
1306 	int enable = 1;
1307 	int sock;
1308 	int err;
1309 
1310 	if (argc < 4)
1311 		syntax(argv);
1312 
1313 	memset(&addr, 0, sizeof(struct sockaddr_storage));
1314 	a4 = (struct sockaddr_in *)&addr;
1315 	a6 = (struct sockaddr_in6 *)&addr;
1316 
1317 	if (inet_pton(AF_INET, argv[2], &a4->sin_addr)) {
1318 		family = AF_INET;
1319 		a4->sin_family = family;
1320 		a4->sin_port = htons(atoi(argv[3]));
1321 	} else if (inet_pton(AF_INET6, argv[2], &a6->sin6_addr)) {
1322 		family = AF_INET6;
1323 		a6->sin6_family = family;
1324 		a6->sin6_port = htons(atoi(argv[3]));
1325 	} else
1326 		error(1, errno, "can't parse ip %s", argv[2]);
1327 
1328 	sock = socket(family, SOCK_STREAM, IPPROTO_MPTCP);
1329 	if (sock < 0)
1330 		error(1, errno, "can't create listener sock\n");
1331 
1332 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))) {
1333 		close(sock);
1334 		error(1, errno, "can't set SO_REUSEADDR on listener sock\n");
1335 	}
1336 
1337 	err = bind(sock, (struct sockaddr *)&addr,
1338 		   ((family == AF_INET) ? sizeof(struct sockaddr_in) :
1339 		    sizeof(struct sockaddr_in6)));
1340 
1341 	if (err == 0 && listen(sock, 30) == 0)
1342 		pause();
1343 
1344 	close(sock);
1345 	return 0;
1346 }
1347 
1348 int set_flags(int fd, int pm_family, int argc, char *argv[])
1349 {
1350 	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
1351 		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
1352 		  1024];
1353 	struct rtattr *rta, *nest;
1354 	struct nlmsghdr *nh;
1355 	u_int32_t flags = 0;
1356 	u_int32_t token = 0;
1357 	u_int16_t rport = 0;
1358 	u_int16_t family;
1359 	void *rip = NULL;
1360 	int nest_start;
1361 	int use_id = 0;
1362 	u_int8_t id;
1363 	int off = 0;
1364 	int arg = 2;
1365 
1366 	memset(data, 0, sizeof(data));
1367 	nh = (void *)data;
1368 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SET_FLAGS,
1369 			    MPTCP_PM_VER);
1370 
1371 	if (argc < 3)
1372 		syntax(argv);
1373 
1374 	nest_start = off;
1375 	nest = (void *)(data + off);
1376 	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
1377 	nest->rta_len = RTA_LENGTH(0);
1378 	off += NLMSG_ALIGN(nest->rta_len);
1379 
1380 	if (!strcmp(argv[arg], "id")) {
1381 		if (++arg >= argc)
1382 			error(1, 0, " missing id value");
1383 
1384 		use_id = 1;
1385 		id = atoi(argv[arg]);
1386 		rta = (void *)(data + off);
1387 		rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
1388 		rta->rta_len = RTA_LENGTH(1);
1389 		memcpy(RTA_DATA(rta), &id, 1);
1390 		off += NLMSG_ALIGN(rta->rta_len);
1391 	} else {
1392 		/* addr data */
1393 		rta = (void *)(data + off);
1394 		if (inet_pton(AF_INET, argv[arg], RTA_DATA(rta))) {
1395 			family = AF_INET;
1396 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
1397 			rta->rta_len = RTA_LENGTH(4);
1398 		} else if (inet_pton(AF_INET6, argv[arg], RTA_DATA(rta))) {
1399 			family = AF_INET6;
1400 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
1401 			rta->rta_len = RTA_LENGTH(16);
1402 		} else {
1403 			error(1, errno, "can't parse ip %s", argv[arg]);
1404 		}
1405 		off += NLMSG_ALIGN(rta->rta_len);
1406 
1407 		/* family */
1408 		rta = (void *)(data + off);
1409 		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
1410 		rta->rta_len = RTA_LENGTH(2);
1411 		memcpy(RTA_DATA(rta), &family, 2);
1412 		off += NLMSG_ALIGN(rta->rta_len);
1413 	}
1414 
1415 	if (++arg >= argc)
1416 		error(1, 0, " missing flags keyword");
1417 
1418 	for (; arg < argc; arg++) {
1419 		if (!strcmp(argv[arg], "token")) {
1420 			if (++arg >= argc)
1421 				error(1, 0, " missing token value");
1422 
1423 			/* token */
1424 			token = strtoul(argv[arg], NULL, 10);
1425 		} else if (!strcmp(argv[arg], "flags")) {
1426 			char *tok, *str;
1427 
1428 			/* flags */
1429 			if (++arg >= argc)
1430 				error(1, 0, " missing flags value");
1431 
1432 			for (str = argv[arg]; (tok = strtok(str, ","));
1433 			     str = NULL) {
1434 				if (!strcmp(tok, "backup"))
1435 					flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
1436 				else if (!strcmp(tok, "fullmesh"))
1437 					flags |= MPTCP_PM_ADDR_FLAG_FULLMESH;
1438 				else if (strcmp(tok, "nobackup") &&
1439 					 strcmp(tok, "nofullmesh"))
1440 					error(1, errno,
1441 					      "unknown flag %s", argv[arg]);
1442 			}
1443 
1444 			rta = (void *)(data + off);
1445 			rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS;
1446 			rta->rta_len = RTA_LENGTH(4);
1447 			memcpy(RTA_DATA(rta), &flags, 4);
1448 			off += NLMSG_ALIGN(rta->rta_len);
1449 		} else if (!strcmp(argv[arg], "port")) {
1450 			u_int16_t port;
1451 
1452 			if (use_id)
1453 				error(1, 0, " port can't be used with id");
1454 
1455 			if (++arg >= argc)
1456 				error(1, 0, " missing port value");
1457 
1458 			port = atoi(argv[arg]);
1459 			rta = (void *)(data + off);
1460 			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
1461 			rta->rta_len = RTA_LENGTH(2);
1462 			memcpy(RTA_DATA(rta), &port, 2);
1463 			off += NLMSG_ALIGN(rta->rta_len);
1464 		} else if (!strcmp(argv[arg], "rport")) {
1465 			if (++arg >= argc)
1466 				error(1, 0, " missing remote port");
1467 
1468 			rport = atoi(argv[arg]);
1469 		} else if (!strcmp(argv[arg], "rip")) {
1470 			if (++arg >= argc)
1471 				error(1, 0, " missing remote ip");
1472 
1473 			rip = argv[arg];
1474 		} else {
1475 			error(1, 0, "unknown keyword %s", argv[arg]);
1476 		}
1477 	}
1478 	nest->rta_len = off - nest_start;
1479 
1480 	/* token */
1481 	if (token) {
1482 		rta = (void *)(data + off);
1483 		rta->rta_type = MPTCP_PM_ATTR_TOKEN;
1484 		rta->rta_len = RTA_LENGTH(4);
1485 		memcpy(RTA_DATA(rta), &token, 4);
1486 		off += NLMSG_ALIGN(rta->rta_len);
1487 	}
1488 
1489 	/* remote addr/port */
1490 	if (rip) {
1491 		nest_start = off;
1492 		nest = (void *)(data + off);
1493 		nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE;
1494 		nest->rta_len = RTA_LENGTH(0);
1495 		off += NLMSG_ALIGN(nest->rta_len);
1496 
1497 		/* addr data */
1498 		rta = (void *)(data + off);
1499 		if (inet_pton(AF_INET, rip, RTA_DATA(rta))) {
1500 			family = AF_INET;
1501 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
1502 			rta->rta_len = RTA_LENGTH(4);
1503 		} else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) {
1504 			family = AF_INET6;
1505 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
1506 			rta->rta_len = RTA_LENGTH(16);
1507 		} else {
1508 			error(1, errno, "can't parse ip %s", (char *)rip);
1509 		}
1510 		off += NLMSG_ALIGN(rta->rta_len);
1511 
1512 		/* family */
1513 		rta = (void *)(data + off);
1514 		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
1515 		rta->rta_len = RTA_LENGTH(2);
1516 		memcpy(RTA_DATA(rta), &family, 2);
1517 		off += NLMSG_ALIGN(rta->rta_len);
1518 
1519 		if (rport) {
1520 			rta = (void *)(data + off);
1521 			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
1522 			rta->rta_len = RTA_LENGTH(2);
1523 			memcpy(RTA_DATA(rta), &rport, 2);
1524 			off += NLMSG_ALIGN(rta->rta_len);
1525 		}
1526 
1527 		nest->rta_len = off - nest_start;
1528 	}
1529 
1530 	do_nl_req(fd, nh, off, 0);
1531 	return 0;
1532 }
1533 
1534 int main(int argc, char *argv[])
1535 {
1536 	int events_mcast_grp;
1537 	int pm_family;
1538 	int fd;
1539 
1540 	if (argc < 2)
1541 		syntax(argv);
1542 
1543 	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
1544 	if (fd == -1)
1545 		error(1, errno, "socket netlink");
1546 
1547 	resolve_mptcp_pm_netlink(fd, &pm_family, &events_mcast_grp);
1548 
1549 	if (!strcmp(argv[1], "add"))
1550 		return add_addr(fd, pm_family, argc, argv);
1551 	else if (!strcmp(argv[1], "ann"))
1552 		return announce_addr(fd, pm_family, argc, argv);
1553 	else if (!strcmp(argv[1], "rem"))
1554 		return remove_addr(fd, pm_family, argc, argv);
1555 	else if (!strcmp(argv[1], "csf"))
1556 		return csf(fd, pm_family, argc, argv);
1557 	else if (!strcmp(argv[1], "dsf"))
1558 		return dsf(fd, pm_family, argc, argv);
1559 	else if (!strcmp(argv[1], "del"))
1560 		return del_addr(fd, pm_family, argc, argv);
1561 	else if (!strcmp(argv[1], "flush"))
1562 		return flush_addrs(fd, pm_family, argc, argv);
1563 	else if (!strcmp(argv[1], "get"))
1564 		return get_addr(fd, pm_family, argc, argv);
1565 	else if (!strcmp(argv[1], "dump"))
1566 		return dump_addrs(fd, pm_family, argc, argv);
1567 	else if (!strcmp(argv[1], "limits"))
1568 		return get_set_limits(fd, pm_family, argc, argv);
1569 	else if (!strcmp(argv[1], "set"))
1570 		return set_flags(fd, pm_family, argc, argv);
1571 	else if (!strcmp(argv[1], "events"))
1572 		return capture_events(fd, events_mcast_grp);
1573 	else if (!strcmp(argv[1], "listen"))
1574 		return add_listener(argc, argv);
1575 
1576 	fprintf(stderr, "unknown sub-command: %s", argv[1]);
1577 	syntax(argv);
1578 	return 0;
1579 }
1580