// SPDX-License-Identifier: GPL-2.0

#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/types.h>

#include <arpa/inet.h>
#include <net/if.h>

#include <linux/rtnetlink.h>
#include <linux/genetlink.h>

#include "linux/mptcp.h"

#ifndef MPTCP_PM_NAME
#define MPTCP_PM_NAME		"mptcp_pm"
#endif

static void syntax(char *argv[])
{
	fprintf(stderr, "%s add|get|set|del|flush|dump|accept [<args>]\n", argv[0]);
	fprintf(stderr, "\tadd [flags signal|subflow|backup] [id <nr>] [dev <name>] <ip>\n");
	fprintf(stderr, "\tdel <id> [<ip>]\n");
	fprintf(stderr, "\tget <id>\n");
	fprintf(stderr, "\tset <ip> [flags backup|nobackup]\n");
	fprintf(stderr, "\tflush\n");
	fprintf(stderr, "\tdump\n");
	fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n");
	exit(0);
}

static int init_genl_req(char *data, int family, int cmd, int version)
{
	struct nlmsghdr *nh = (void *)data;
	struct genlmsghdr *gh;
	int off = 0;

	nh->nlmsg_type = family;
	nh->nlmsg_flags = NLM_F_REQUEST;
	nh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	off += NLMSG_ALIGN(sizeof(*nh));

	gh = (void *)(data + off);
	gh->cmd = cmd;
	gh->version = version;
	off += NLMSG_ALIGN(sizeof(*gh));
	return off;
}

static void nl_error(struct nlmsghdr *nh)
{
	struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nh);
	int len = nh->nlmsg_len - sizeof(*nh);
	uint32_t off;

	if (len < sizeof(struct nlmsgerr))
		error(1, 0, "netlink error message truncated %d min %ld", len,
		      sizeof(struct nlmsgerr));

	if (!err->error) {
		/* check messages from kernel */
		struct rtattr *attrs = (struct rtattr *)NLMSG_DATA(nh);

		while (RTA_OK(attrs, len)) {
			if (attrs->rta_type == NLMSGERR_ATTR_MSG)
				fprintf(stderr, "netlink ext ack msg: %s\n",
					(char *)RTA_DATA(attrs));
			if (attrs->rta_type == NLMSGERR_ATTR_OFFS) {
				memcpy(&off, RTA_DATA(attrs), 4);
				fprintf(stderr, "netlink err off %d\n",
					(int)off);
			}
			attrs = RTA_NEXT(attrs, len);
		}
	} else {
		fprintf(stderr, "netlink error %d", err->error);
	}
}

/* do a netlink command and, if max > 0, fetch the reply  */
static int do_nl_req(int fd, struct nlmsghdr *nh, int len, int max)
{
	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
	socklen_t addr_len;
	void *data = nh;
	int rem, ret;
	int err = 0;

	nh->nlmsg_len = len;
	ret = sendto(fd, data, len, 0, (void *)&nladdr, sizeof(nladdr));
	if (ret != len)
		error(1, errno, "send netlink: %uB != %uB\n", ret, len);
	if (max == 0)
		return 0;

	addr_len = sizeof(nladdr);
	rem = ret = recvfrom(fd, data, max, 0, (void *)&nladdr, &addr_len);
	if (ret < 0)
		error(1, errno, "recv netlink: %uB\n", ret);

	/* Beware: the NLMSG_NEXT macro updates the 'rem' argument */
	for (; NLMSG_OK(nh, rem); nh = NLMSG_NEXT(nh, rem)) {
		if (nh->nlmsg_type == NLMSG_ERROR) {
			nl_error(nh);
			err = 1;
		}
	}
	if (err)
		error(1, 0, "bailing out due to netlink error[s]");
	return ret;
}

static int genl_parse_getfamily(struct nlmsghdr *nlh)
{
	struct genlmsghdr *ghdr = NLMSG_DATA(nlh);
	int len = nlh->nlmsg_len;
	struct rtattr *attrs;

	if (nlh->nlmsg_type != GENL_ID_CTRL)
		error(1, errno, "Not a controller message, len=%d type=0x%x\n",
		      nlh->nlmsg_len, nlh->nlmsg_type);

	len -= NLMSG_LENGTH(GENL_HDRLEN);

	if (len < 0)
		error(1, errno, "wrong controller message len %d\n", len);

	if (ghdr->cmd != CTRL_CMD_NEWFAMILY)
		error(1, errno, "Unknown controller command %d\n", ghdr->cmd);

	attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
	while (RTA_OK(attrs, len)) {
		if (attrs->rta_type == CTRL_ATTR_FAMILY_ID)
			return *(__u16 *)RTA_DATA(attrs);
		attrs = RTA_NEXT(attrs, len);
	}

	error(1, errno, "can't find CTRL_ATTR_FAMILY_ID attr");
	return -1;
}

static int resolve_mptcp_pm_netlink(int fd)
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	struct nlmsghdr *nh;
	struct rtattr *rta;
	int namelen;
	int off = 0;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, 0);

	rta = (void *)(data + off);
	namelen = strlen(MPTCP_PM_NAME) + 1;
	rta->rta_type = CTRL_ATTR_FAMILY_NAME;
	rta->rta_len = RTA_LENGTH(namelen);
	memcpy(RTA_DATA(rta), MPTCP_PM_NAME, namelen);
	off += NLMSG_ALIGN(rta->rta_len);

	do_nl_req(fd, nh, off, sizeof(data));
	return genl_parse_getfamily((void *)data);
}

int add_addr(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	struct rtattr *rta, *nest;
	struct nlmsghdr *nh;
	u_int32_t flags = 0;
	u_int16_t family;
	int nest_start;
	u_int8_t id;
	int off = 0;
	int arg;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_ADD_ADDR,
			    MPTCP_PM_VER);

	if (argc < 3)
		syntax(argv);

	nest_start = off;
	nest = (void *)(data + off);
	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
	nest->rta_len = RTA_LENGTH(0);
	off += NLMSG_ALIGN(nest->rta_len);

	/* addr data */
	rta = (void *)(data + off);
	if (inet_pton(AF_INET, argv[2], RTA_DATA(rta))) {
		family = AF_INET;
		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
		rta->rta_len = RTA_LENGTH(4);
	} else if (inet_pton(AF_INET6, argv[2], RTA_DATA(rta))) {
		family = AF_INET6;
		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
		rta->rta_len = RTA_LENGTH(16);
	} else
		error(1, errno, "can't parse ip %s", argv[2]);
	off += NLMSG_ALIGN(rta->rta_len);

	/* family */
	rta = (void *)(data + off);
	rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
	rta->rta_len = RTA_LENGTH(2);
	memcpy(RTA_DATA(rta), &family, 2);
	off += NLMSG_ALIGN(rta->rta_len);

	for (arg = 3; arg < argc; arg++) {
		if (!strcmp(argv[arg], "flags")) {
			char *tok, *str;

			/* flags */
			if (++arg >= argc)
				error(1, 0, " missing flags value");

			/* do not support flag list yet */
			for (str = argv[arg]; (tok = strtok(str, ","));
			     str = NULL) {
				if (!strcmp(tok, "subflow"))
					flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
				else if (!strcmp(tok, "signal"))
					flags |= MPTCP_PM_ADDR_FLAG_SIGNAL;
				else if (!strcmp(tok, "backup"))
					flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
				else
					error(1, errno,
					      "unknown flag %s", argv[arg]);
			}

			rta = (void *)(data + off);
			rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS;
			rta->rta_len = RTA_LENGTH(4);
			memcpy(RTA_DATA(rta), &flags, 4);
			off += NLMSG_ALIGN(rta->rta_len);
		} else if (!strcmp(argv[arg], "id")) {
			if (++arg >= argc)
				error(1, 0, " missing id value");

			id = atoi(argv[arg]);
			rta = (void *)(data + off);
			rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
			rta->rta_len = RTA_LENGTH(1);
			memcpy(RTA_DATA(rta), &id, 1);
			off += NLMSG_ALIGN(rta->rta_len);
		} else if (!strcmp(argv[arg], "dev")) {
			int32_t ifindex;

			if (++arg >= argc)
				error(1, 0, " missing dev name");

			ifindex = if_nametoindex(argv[arg]);
			if (!ifindex)
				error(1, errno, "unknown device %s", argv[arg]);

			rta = (void *)(data + off);
			rta->rta_type = MPTCP_PM_ADDR_ATTR_IF_IDX;
			rta->rta_len = RTA_LENGTH(4);
			memcpy(RTA_DATA(rta), &ifindex, 4);
			off += NLMSG_ALIGN(rta->rta_len);
		} else if (!strcmp(argv[arg], "port")) {
			u_int16_t port;

			if (++arg >= argc)
				error(1, 0, " missing port value");
			if (!(flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
				error(1, 0, " flags must be signal when using port");

			port = atoi(argv[arg]);
			rta = (void *)(data + off);
			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
			rta->rta_len = RTA_LENGTH(2);
			memcpy(RTA_DATA(rta), &port, 2);
			off += NLMSG_ALIGN(rta->rta_len);
		} else
			error(1, 0, "unknown keyword %s", argv[arg]);
	}
	nest->rta_len = off - nest_start;

	do_nl_req(fd, nh, off, 0);
	return 0;
}

int del_addr(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	struct rtattr *rta, *nest;
	struct nlmsghdr *nh;
	u_int16_t family;
	int nest_start;
	u_int8_t id;
	int off = 0;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_DEL_ADDR,
			    MPTCP_PM_VER);

	/* the only argument is the address id (nonzero) */
	if (argc != 3 && argc != 4)
		syntax(argv);

	id = atoi(argv[2]);
	/* zero id with the IP address */
	if (!id && argc != 4)
		syntax(argv);

	nest_start = off;
	nest = (void *)(data + off);
	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
	nest->rta_len =  RTA_LENGTH(0);
	off += NLMSG_ALIGN(nest->rta_len);

	/* build a dummy addr with only the ID set */
	rta = (void *)(data + off);
	rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
	rta->rta_len = RTA_LENGTH(1);
	memcpy(RTA_DATA(rta), &id, 1);
	off += NLMSG_ALIGN(rta->rta_len);

	if (!id) {
		/* addr data */
		rta = (void *)(data + off);
		if (inet_pton(AF_INET, argv[3], RTA_DATA(rta))) {
			family = AF_INET;
			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
			rta->rta_len = RTA_LENGTH(4);
		} else if (inet_pton(AF_INET6, argv[3], RTA_DATA(rta))) {
			family = AF_INET6;
			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
			rta->rta_len = RTA_LENGTH(16);
		} else {
			error(1, errno, "can't parse ip %s", argv[3]);
		}
		off += NLMSG_ALIGN(rta->rta_len);

		/* family */
		rta = (void *)(data + off);
		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
		rta->rta_len = RTA_LENGTH(2);
		memcpy(RTA_DATA(rta), &family, 2);
		off += NLMSG_ALIGN(rta->rta_len);
	}
	nest->rta_len = off - nest_start;

	do_nl_req(fd, nh, off, 0);
	return 0;
}

static void print_addr(struct rtattr *attrs, int len)
{
	uint16_t family = 0;
	uint16_t port = 0;
	char str[1024];
	uint32_t flags;
	uint8_t id;

	while (RTA_OK(attrs, len)) {
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_FAMILY)
			memcpy(&family, RTA_DATA(attrs), 2);
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_PORT)
			memcpy(&port, RTA_DATA(attrs), 2);
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR4) {
			if (family != AF_INET)
				error(1, errno, "wrong IP (v4) for family %d",
				      family);
			inet_ntop(AF_INET, RTA_DATA(attrs), str, sizeof(str));
			printf("%s", str);
			if (port)
				printf(" %d", port);
		}
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR6) {
			if (family != AF_INET6)
				error(1, errno, "wrong IP (v6) for family %d",
				      family);
			inet_ntop(AF_INET6, RTA_DATA(attrs), str, sizeof(str));
			printf("%s", str);
			if (port)
				printf(" %d", port);
		}
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ID) {
			memcpy(&id, RTA_DATA(attrs), 1);
			printf("id %d ", id);
		}
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_FLAGS) {
			memcpy(&flags, RTA_DATA(attrs), 4);

			printf("flags ");
			if (flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
				printf("signal");
				flags &= ~MPTCP_PM_ADDR_FLAG_SIGNAL;
				if (flags)
					printf(",");
			}

			if (flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
				printf("subflow");
				flags &= ~MPTCP_PM_ADDR_FLAG_SUBFLOW;
				if (flags)
					printf(",");
			}

			if (flags & MPTCP_PM_ADDR_FLAG_BACKUP) {
				printf("backup");
				flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
				if (flags)
					printf(",");
			}

			/* bump unknown flags, if any */
			if (flags)
				printf("0x%x", flags);
			printf(" ");
		}
		if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_IF_IDX) {
			char name[IF_NAMESIZE], *ret;
			int32_t ifindex;

			memcpy(&ifindex, RTA_DATA(attrs), 4);
			ret = if_indextoname(ifindex, name);
			if (ret)
				printf("dev %s ", ret);
			else
				printf("dev unknown/%d", ifindex);
		}

		attrs = RTA_NEXT(attrs, len);
	}
	printf("\n");
}

static void print_addrs(struct nlmsghdr *nh, int pm_family, int total_len)
{
	struct rtattr *attrs;

	for (; NLMSG_OK(nh, total_len); nh = NLMSG_NEXT(nh, total_len)) {
		int len = nh->nlmsg_len;

		if (nh->nlmsg_type == NLMSG_DONE)
			break;
		if (nh->nlmsg_type == NLMSG_ERROR)
			nl_error(nh);
		if (nh->nlmsg_type != pm_family)
			continue;

		len -= NLMSG_LENGTH(GENL_HDRLEN);
		attrs = (struct rtattr *) ((char *) NLMSG_DATA(nh) +
					   GENL_HDRLEN);
		while (RTA_OK(attrs, len)) {
			if (attrs->rta_type ==
			    (MPTCP_PM_ATTR_ADDR | NLA_F_NESTED))
				print_addr((void *)RTA_DATA(attrs),
					   attrs->rta_len);
			attrs = RTA_NEXT(attrs, len);
		}
	}
}

int get_addr(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	struct rtattr *rta, *nest;
	struct nlmsghdr *nh;
	int nest_start;
	u_int8_t id;
	int off = 0;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_GET_ADDR,
			    MPTCP_PM_VER);

	/* the only argument is the address id */
	if (argc != 3)
		syntax(argv);

	id = atoi(argv[2]);

	nest_start = off;
	nest = (void *)(data + off);
	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
	nest->rta_len =  RTA_LENGTH(0);
	off += NLMSG_ALIGN(nest->rta_len);

	/* build a dummy addr with only the ID set */
	rta = (void *)(data + off);
	rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
	rta->rta_len = RTA_LENGTH(1);
	memcpy(RTA_DATA(rta), &id, 1);
	off += NLMSG_ALIGN(rta->rta_len);
	nest->rta_len = off - nest_start;

	print_addrs(nh, pm_family, do_nl_req(fd, nh, off, sizeof(data)));
	return 0;
}

int dump_addrs(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	pid_t pid = getpid();
	struct nlmsghdr *nh;
	int off = 0;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_GET_ADDR,
			    MPTCP_PM_VER);
	nh->nlmsg_flags |= NLM_F_DUMP;
	nh->nlmsg_seq = 1;
	nh->nlmsg_pid = pid;
	nh->nlmsg_len = off;

	print_addrs(nh, pm_family, do_nl_req(fd, nh, off, sizeof(data)));
	return 0;
}

int flush_addrs(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	struct nlmsghdr *nh;
	int off = 0;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_FLUSH_ADDRS,
			    MPTCP_PM_VER);

	do_nl_req(fd, nh, off, 0);
	return 0;
}

static void print_limits(struct nlmsghdr *nh, int pm_family, int total_len)
{
	struct rtattr *attrs;
	uint32_t max;

	for (; NLMSG_OK(nh, total_len); nh = NLMSG_NEXT(nh, total_len)) {
		int len = nh->nlmsg_len;

		if (nh->nlmsg_type == NLMSG_DONE)
			break;
		if (nh->nlmsg_type == NLMSG_ERROR)
			nl_error(nh);
		if (nh->nlmsg_type != pm_family)
			continue;

		len -= NLMSG_LENGTH(GENL_HDRLEN);
		attrs = (struct rtattr *) ((char *) NLMSG_DATA(nh) +
					   GENL_HDRLEN);
		while (RTA_OK(attrs, len)) {
			int type = attrs->rta_type;

			if (type != MPTCP_PM_ATTR_RCV_ADD_ADDRS &&
			    type != MPTCP_PM_ATTR_SUBFLOWS)
				goto next;

			memcpy(&max, RTA_DATA(attrs), 4);
			printf("%s %u\n", type == MPTCP_PM_ATTR_SUBFLOWS ?
					  "subflows" : "accept", max);

next:
			attrs = RTA_NEXT(attrs, len);
		}
	}
}

int get_set_limits(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	uint32_t rcv_addr = 0, subflows = 0;
	int cmd, len = sizeof(data);
	struct nlmsghdr *nh;
	int off = 0;

	/* limit */
	if (argc == 4) {
		rcv_addr = atoi(argv[2]);
		subflows = atoi(argv[3]);
		cmd = MPTCP_PM_CMD_SET_LIMITS;
	} else {
		cmd = MPTCP_PM_CMD_GET_LIMITS;
	}

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, cmd, MPTCP_PM_VER);

	/* limit */
	if (cmd == MPTCP_PM_CMD_SET_LIMITS) {
		struct rtattr *rta = (void *)(data + off);

		rta->rta_type = MPTCP_PM_ATTR_RCV_ADD_ADDRS;
		rta->rta_len = RTA_LENGTH(4);
		memcpy(RTA_DATA(rta), &rcv_addr, 4);
		off += NLMSG_ALIGN(rta->rta_len);

		rta = (void *)(data + off);
		rta->rta_type = MPTCP_PM_ATTR_SUBFLOWS;
		rta->rta_len = RTA_LENGTH(4);
		memcpy(RTA_DATA(rta), &subflows, 4);
		off += NLMSG_ALIGN(rta->rta_len);

		/* do not expect a reply */
		len = 0;
	}

	len = do_nl_req(fd, nh, off, len);
	if (cmd == MPTCP_PM_CMD_GET_LIMITS)
		print_limits(nh, pm_family, len);
	return 0;
}

int set_flags(int fd, int pm_family, int argc, char *argv[])
{
	char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
		  NLMSG_ALIGN(sizeof(struct genlmsghdr)) +
		  1024];
	struct rtattr *rta, *nest;
	struct nlmsghdr *nh;
	u_int32_t flags = 0;
	u_int16_t family;
	int nest_start;
	int off = 0;
	int arg;

	memset(data, 0, sizeof(data));
	nh = (void *)data;
	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SET_FLAGS,
			    MPTCP_PM_VER);

	if (argc < 3)
		syntax(argv);

	nest_start = off;
	nest = (void *)(data + off);
	nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR;
	nest->rta_len = RTA_LENGTH(0);
	off += NLMSG_ALIGN(nest->rta_len);

	/* addr data */
	rta = (void *)(data + off);
	if (inet_pton(AF_INET, argv[2], RTA_DATA(rta))) {
		family = AF_INET;
		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
		rta->rta_len = RTA_LENGTH(4);
	} else if (inet_pton(AF_INET6, argv[2], RTA_DATA(rta))) {
		family = AF_INET6;
		rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
		rta->rta_len = RTA_LENGTH(16);
	} else {
		error(1, errno, "can't parse ip %s", argv[2]);
	}
	off += NLMSG_ALIGN(rta->rta_len);

	/* family */
	rta = (void *)(data + off);
	rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
	rta->rta_len = RTA_LENGTH(2);
	memcpy(RTA_DATA(rta), &family, 2);
	off += NLMSG_ALIGN(rta->rta_len);

	for (arg = 3; arg < argc; arg++) {
		if (!strcmp(argv[arg], "flags")) {
			char *tok, *str;

			/* flags */
			if (++arg >= argc)
				error(1, 0, " missing flags value");

			/* do not support flag list yet */
			for (str = argv[arg]; (tok = strtok(str, ","));
			     str = NULL) {
				if (!strcmp(tok, "backup"))
					flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
				else if (strcmp(tok, "nobackup"))
					error(1, errno,
					      "unknown flag %s", argv[arg]);
			}

			rta = (void *)(data + off);
			rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS;
			rta->rta_len = RTA_LENGTH(4);
			memcpy(RTA_DATA(rta), &flags, 4);
			off += NLMSG_ALIGN(rta->rta_len);
		} else {
			error(1, 0, "unknown keyword %s", argv[arg]);
		}
	}
	nest->rta_len = off - nest_start;

	do_nl_req(fd, nh, off, 0);
	return 0;
}

int main(int argc, char *argv[])
{
	int fd, pm_family;

	if (argc < 2)
		syntax(argv);

	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
	if (fd == -1)
		error(1, errno, "socket netlink");

	pm_family = resolve_mptcp_pm_netlink(fd);

	if (!strcmp(argv[1], "add"))
		return add_addr(fd, pm_family, argc, argv);
	else if (!strcmp(argv[1], "del"))
		return del_addr(fd, pm_family, argc, argv);
	else if (!strcmp(argv[1], "flush"))
		return flush_addrs(fd, pm_family, argc, argv);
	else if (!strcmp(argv[1], "get"))
		return get_addr(fd, pm_family, argc, argv);
	else if (!strcmp(argv[1], "dump"))
		return dump_addrs(fd, pm_family, argc, argv);
	else if (!strcmp(argv[1], "limits"))
		return get_set_limits(fd, pm_family, argc, argv);
	else if (!strcmp(argv[1], "set"))
		return set_flags(fd, pm_family, argc, argv);

	fprintf(stderr, "unknown sub-command: %s", argv[1]);
	syntax(argv);
	return 0;
}
