/*
 * bearer.c	TIPC bearer functionality.
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Richard Alpe <richard.alpe@ericsson.com>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>

#include <linux/tipc_netlink.h>
#include <linux/tipc.h>
#include <linux/genetlink.h>
#include <linux/if.h>
#include <libmnl/libmnl.h>

#include "mnl_utils.h"
#include "utils.h"
#include "cmdl.h"
#include "msg.h"
#include "bearer.h"

#define UDP_PROP_IP 1
#define UDP_PROP_PORT 2

struct cb_data {
	int attr;
	int prop;
	struct nlmsghdr *nlh;
};

static void _print_bearer_opts(void)
{
	fprintf(stderr,
		"OPTIONS\n"
		" priority		- Bearer link priority\n"
		" tolerance		- Bearer link tolerance\n"
		" window		- Bearer link window\n"
		" mtu			- Bearer link mtu\n");
}

void print_bearer_media(void)
{
	fprintf(stderr,
		"\nMEDIA\n"
		" udp			- User Datagram Protocol\n"
		" ib			- Infiniband\n"
		" eth			- Ethernet\n");
}

static void cmd_bearer_enable_l2_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr,
		"Usage: %s bearer enable media %s device DEVICE [OPTIONS]\n"
		"\nOPTIONS\n"
		" domain DOMAIN		- Discovery domain\n"
		" priority PRIORITY	- Bearer priority\n",
		cmdl->argv[0], media);
}

static void cmd_bearer_enable_udp_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr,
		"Usage: %s bearer enable [OPTIONS] media %s name NAME [localip IP|device DEVICE] [UDP OPTIONS]\n\n"
		"OPTIONS\n"
		" domain DOMAIN		- Discovery domain\n"
		" priority PRIORITY	- Bearer priority\n\n"
		"UDP OPTIONS\n"
		" localport PORT	- Local UDP port (default 6118)\n"
		" remoteip IP		- Remote IP address\n"
		" remoteport PORT	- Remote UDP port (default 6118)\n",
		cmdl->argv[0], media);
}

static int get_netid_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
	int *netid = (int*)data;

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_NET])
		return MNL_CB_ERROR;
	mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_NET_ID])
		return MNL_CB_ERROR;
	*netid = mnl_attr_get_u32(attrs[TIPC_NLA_NET_ID]);

	return MNL_CB_OK;
}

static int generate_multicast(short af, char *buf, int bufsize)
{
	struct mnlu_gen_socket bearer_nlg;
	struct nlmsghdr *nlh;
	int netid;
	int err = 0;

	err = mnlu_gen_socket_open(&bearer_nlg, TIPC_GENL_V2_NAME,
				   TIPC_GENL_V2_VERSION);
	if (err)
		return -1;

	nlh = mnlu_gen_socket_cmd_prepare(&bearer_nlg, TIPC_NL_NET_GET,
					  NLM_F_REQUEST | NLM_F_DUMP);
	if (!nlh) {
		fprintf(stderr, "error, message initialization failed\n");
		mnlu_gen_socket_close(&bearer_nlg);
		return -1;
	}

	err = mnlu_gen_socket_sndrcv(&bearer_nlg, nlh, get_netid_cb, &netid);
	if (err) {
		fprintf(stderr, "error, failed to fetch TIPC network id from kernel\n");
		mnlu_gen_socket_close(&bearer_nlg);
		return -EINVAL;
	}
	if (af == AF_INET)
		snprintf(buf, bufsize, "228.0.%u.%u", (netid>>8) & 0xFF, netid & 0xFF);
	else
		snprintf(buf, bufsize, "ff02::%u", netid);

	mnlu_gen_socket_close(&bearer_nlg);
	return 0;
}

static struct ifreq ifr;
static int nl_dump_req_filter(struct nlmsghdr *nlh, int reqlen)
{
	struct ifaddrmsg *ifa = NLMSG_DATA(nlh);

	ifa->ifa_index = ifr.ifr_ifindex;

	return 0;
}

static int nl_dump_addr_filter(struct nlmsghdr *nlh, void *arg)
{
	struct ifaddrmsg *ifa = NLMSG_DATA(nlh);
	char *r_addr = (char *)arg;
	int len = nlh->nlmsg_len;
	struct rtattr *addr_attr;

	if (ifr.ifr_ifindex != ifa->ifa_index)
		return 0;

	if (strlen(r_addr) > 0)
		return 0;

	addr_attr = parse_rtattr_one(IFA_ADDRESS, IFA_RTA(ifa),
				     len - NLMSG_LENGTH(sizeof(*ifa)));
	if (!addr_attr)
		return 0;

	if (ifa->ifa_family == AF_INET) {
		struct sockaddr_in ip4addr;
		memcpy(&ip4addr.sin_addr, RTA_DATA(addr_attr),
		       sizeof(struct in_addr));
		inet_ntop(AF_INET, &ip4addr.sin_addr, r_addr,
			  INET_ADDRSTRLEN);
	} else if (ifa->ifa_family == AF_INET6) {
		struct sockaddr_in6 ip6addr;
		memcpy(&ip6addr.sin6_addr, RTA_DATA(addr_attr),
		       sizeof(struct in6_addr));
		inet_ntop(AF_INET6, &ip6addr.sin6_addr, r_addr,
			  INET6_ADDRSTRLEN);
	}
	return 0;
}

static int cmd_bearer_validate_and_get_addr(const char *name, char *r_addr)
{
	struct rtnl_handle rth = { .fd = -1 };
	int err = -1;

	memset(&ifr, 0, sizeof(ifr));
	if (!name || !r_addr || get_ifname(ifr.ifr_name, name))
		return err;

	ifr.ifr_ifindex = ll_name_to_index(ifr.ifr_name);
	if (!ifr.ifr_ifindex)
		return err;

	/* remove from cache */
	ll_drop_by_index(ifr.ifr_ifindex);

	if ((err = rtnl_open(&rth, 0)) < 0)
		return err;

	if ((err = rtnl_addrdump_req(&rth, AF_UNSPEC, nl_dump_req_filter)) > 0)
		err = rtnl_dump_filter(&rth, nl_dump_addr_filter, r_addr);

	rtnl_close(&rth);
	return err;
}

static int nl_add_udp_enable_opts(struct nlmsghdr *nlh, struct opt *opts,
				  struct cmdl *cmdl)
{
	int err;
	struct opt *opt;
	struct nlattr *nest;
	char buf[INET6_ADDRSTRLEN];
	char *locport = "6118";
	char *remport = "6118";
	char *locip = NULL;
	char *remip = NULL;
	struct addrinfo *loc = NULL;
	struct addrinfo *rem = NULL;
	struct addrinfo hints = {
		.ai_family = AF_UNSPEC,
		.ai_socktype = SOCK_DGRAM
	};
	char addr[INET6_ADDRSTRLEN] = {0};

	opt = get_opt(opts, "device");
	if (opt && cmd_bearer_validate_and_get_addr(opt->val, addr) < 0) {
		fprintf(stderr, "error, no device name available\n");
		return -EINVAL;
	}

	if (strlen(addr) > 0) {
		locip = addr;
	} else {
		opt = get_opt(opts, "localip");
		if (!opt) {
			fprintf(stderr, "error, udp bearer localip/device missing\n");
			cmd_bearer_enable_udp_help(cmdl, "udp");
			return -EINVAL;
		}
		locip = opt->val;
	}

	if ((opt = get_opt(opts, "remoteip")))
		remip = opt->val;

	if ((opt = get_opt(opts, "localport")))
		locport = opt->val;

	if ((opt = get_opt(opts, "remoteport")))
		remport = opt->val;

	if ((err = getaddrinfo(locip, locport, &hints, &loc))) {
		fprintf(stderr, "UDP local address error: %s\n",
			gai_strerror(err));
		return err;
	}

	if (!remip) {
		if (generate_multicast(loc->ai_family, buf, sizeof(buf))) {
			fprintf(stderr, "Failed to generate multicast address\n");
			freeaddrinfo(loc);
			return -EINVAL;
		}
		remip = buf;
	}

	if ((err = getaddrinfo(remip, remport, &hints, &rem))) {
		fprintf(stderr, "UDP remote address error: %s\n",
			gai_strerror(err));
		freeaddrinfo(loc);
		return err;
	}

	if (rem->ai_family != loc->ai_family) {
		fprintf(stderr, "UDP local and remote AF mismatch\n");
		freeaddrinfo(rem);
		freeaddrinfo(loc);
		return -EINVAL;
	}

	nest = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER_UDP_OPTS);
	mnl_attr_put(nlh, TIPC_NLA_UDP_LOCAL, loc->ai_addrlen, loc->ai_addr);
	mnl_attr_put(nlh, TIPC_NLA_UDP_REMOTE, rem->ai_addrlen, rem->ai_addr);
	mnl_attr_nest_end(nlh, nest);

	freeaddrinfo(rem);
	freeaddrinfo(loc);

	return 0;
}

static char *cmd_get_media_type(const struct cmd *cmd, struct cmdl *cmdl,
				struct opt *opts)
{
	struct opt *opt = get_opt(opts, "media");

	if (!opt) {
		if (help_flag)
			(cmd->help)(cmdl);
		else
			fprintf(stderr, "error, missing bearer media\n");
		return NULL;
	}
	return opt->val;
}

static int nl_add_bearer_name(struct nlmsghdr *nlh, const struct cmd *cmd,
			      struct cmdl *cmdl, struct opt *opts,
			      const struct tipc_sup_media *sup_media)
{
	char bname[TIPC_MAX_BEARER_NAME];
	int err;

	if ((err = cmd_get_unique_bearer_name(cmd, cmdl, opts, bname, sup_media)))
		return err;

	mnl_attr_put_strz(nlh, TIPC_NLA_BEARER_NAME, bname);
	return 0;
}

int cmd_get_unique_bearer_name(const struct cmd *cmd, struct cmdl *cmdl,
			       struct opt *opts, char *bname,
			       const struct tipc_sup_media *sup_media)
{
	char *media;
	char *identifier;
	struct opt *opt;
	const struct tipc_sup_media *entry;

	if (!(media = cmd_get_media_type(cmd, cmdl, opts)))
		return -EINVAL;

	for (entry = sup_media; entry->media; entry++) {
		if (strcmp(entry->media, media))
			continue;

		if (!(opt = get_opt(opts, entry->identifier))) {
			if (help_flag)
				(entry->help)(cmdl, media);
			else
				fprintf(stderr, "error, missing bearer %s\n",
					entry->identifier);
			return -EINVAL;
		}

		identifier = opt->val;
		snprintf(bname, TIPC_MAX_BEARER_NAME, "%s:%s", media, identifier);

		return 0;
	}

	fprintf(stderr, "error, invalid media type %s\n", media);

	return -EINVAL;
}

static void cmd_bearer_add_udp_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr, "Usage: %s bearer add media %s name NAME remoteip REMOTEIP\n\n",
		cmdl->argv[0], media);
}

static void cmd_bearer_add_help(struct cmdl *cmdl)
{
	fprintf(stderr, "Usage: %s bearer add media udp name NAME remoteip REMOTEIP\n",
		cmdl->argv[0]);
}

static int udp_bearer_add(struct nlmsghdr *nlh, struct opt *opts,
			  struct cmdl *cmdl)
{
	int err;
	struct opt *opt;
	struct nlattr *opts_nest;
	char *remport = "6118";

	opts_nest = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER_UDP_OPTS);

	if ((opt = get_opt(opts, "remoteport")))
		remport = opt->val;

	if ((opt = get_opt(opts, "remoteip"))) {
		char *ip = opt->val;
		struct addrinfo *addr = NULL;
		struct addrinfo hints = {
			.ai_family = AF_UNSPEC,
			.ai_socktype = SOCK_DGRAM
		};

		if ((err = getaddrinfo(ip, remport, &hints, &addr))) {
			fprintf(stderr, "UDP address error: %s\n",
				gai_strerror(err));
			freeaddrinfo(addr);
			return err;
		}

		mnl_attr_put(nlh, TIPC_NLA_UDP_REMOTE, addr->ai_addrlen,
			     addr->ai_addr);
		freeaddrinfo(addr);
	} else {
		fprintf(stderr, "error, missing remoteip\n");
		return -EINVAL;
	}
	mnl_attr_nest_end(nlh, opts_nest);

	return 0;
}

static int cmd_bearer_add_media(struct nlmsghdr *nlh, const struct cmd *cmd,
				struct cmdl *cmdl, void *data)
{
	int err;
	char *media;
	struct opt *opt;
	struct nlattr *attrs;
	struct opt opts[] = {
		{ "remoteip",		OPT_KEYVAL,	NULL },
		{ "remoteport",		OPT_KEYVAL,	NULL },
		{ "name",		OPT_KEYVAL,	NULL },
		{ "media",		OPT_KEYVAL,	NULL },
		{ NULL }
	};
	const struct tipc_sup_media sup_media[] = {
		{ "udp",	"name",		cmd_bearer_add_udp_help},
		{ NULL, },
	};

	/* Rewind optind to include media in the option list */
	cmdl->optind--;
	if (parse_opts(opts, cmdl) < 0)
		return -EINVAL;

	if (!(opt = get_opt(opts, "media"))) {
		fprintf(stderr, "error, missing media value\n");
		return -EINVAL;
	}
	media = opt->val;

	if (strcmp(media, "udp") != 0) {
		fprintf(stderr, "error, no \"%s\" media specific options available\n",
			media);
		return -EINVAL;
	}
	if (!(opt = get_opt(opts, "name"))) {
		fprintf(stderr, "error, missing media name\n");
		return -EINVAL;
	}

	nlh = msg_init(TIPC_NL_BEARER_ADD);
	if (!nlh) {
		fprintf(stderr, "error, message initialisation failed\n");
		return -1;
	}

	attrs = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER);
	err = nl_add_bearer_name(nlh, cmd, cmdl, opts, sup_media);
	if (err)
		return err;

	err = udp_bearer_add(nlh, opts, cmdl);
	if (err)
		return err;

	mnl_attr_nest_end(nlh, attrs);

	return msg_doit(nlh, NULL, NULL);
}

static int cmd_bearer_add(struct nlmsghdr *nlh, const struct cmd *cmd,
			  struct cmdl *cmdl, void *data)
{
	const struct cmd cmds[] = {
		{ "media",	cmd_bearer_add_media,	cmd_bearer_add_help },
		{ NULL }
	};

	return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}

static void cmd_bearer_enable_help(struct cmdl *cmdl)
{
	fprintf(stderr,
		"Usage: %s bearer enable [OPTIONS] media MEDIA ARGS...\n\n"
		"OPTIONS\n"
		" domain DOMAIN         - Discovery domain\n"
		" priority PRIORITY     - Bearer priority\n",
		cmdl->argv[0]);
	print_bearer_media();
}

static int cmd_bearer_enable(struct nlmsghdr *nlh, const struct cmd *cmd,
			     struct cmdl *cmdl, void *data)
{
	int err;
	struct opt *opt;
	struct nlattr *nest;
	struct opt opts[] = {
		{ "device",		OPT_KEYVAL,	NULL },
		{ "domain",		OPT_KEYVAL,	NULL },
		{ "localip",		OPT_KEYVAL,	NULL },
		{ "localport",		OPT_KEYVAL,	NULL },
		{ "media",		OPT_KEYVAL,	NULL },
		{ "name",		OPT_KEYVAL,	NULL },
		{ "priority",		OPT_KEYVAL,	NULL },
		{ "remoteip",		OPT_KEYVAL,	NULL },
		{ "remoteport",		OPT_KEYVAL,	NULL },
		{ NULL }
	};
	struct tipc_sup_media sup_media[] = {
		{ "udp",        "name",         cmd_bearer_enable_udp_help},
		{ "eth",        "device",       cmd_bearer_enable_l2_help },
		{ "ib",         "device",       cmd_bearer_enable_l2_help },
		{ NULL, },
	};

	if (parse_opts(opts, cmdl) < 0) {
		if (help_flag)
			(cmd->help)(cmdl);
		return -EINVAL;
	}

	nlh = msg_init(TIPC_NL_BEARER_ENABLE);
	if (!nlh) {
		fprintf(stderr, "error: message initialisation failed\n");
		return -1;
	}
	nest = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER);

	if ((opt = get_opt(opts, "domain")))
		mnl_attr_put_u32(nlh, TIPC_NLA_BEARER_DOMAIN, atoi(opt->val));

	if ((opt = get_opt(opts, "priority"))) {
		struct nlattr *props;

		props = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER_PROP);
		mnl_attr_put_u32(nlh, TIPC_NLA_PROP_PRIO, atoi(opt->val));
		mnl_attr_nest_end(nlh, props);
	}

	err = nl_add_bearer_name(nlh, cmd, cmdl, opts, sup_media);
	if (err)
		return err;

	opt = get_opt(opts, "media");
	if (opt && strcmp(opt->val, "udp") == 0) {
		err = nl_add_udp_enable_opts(nlh, opts, cmdl);
		if (err)
			return err;
	}
	mnl_attr_nest_end(nlh, nest);

	return msg_doit(nlh, NULL, NULL);
}

static void cmd_bearer_disable_l2_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr, "Usage: %s bearer disable media %s device DEVICE\n",
		cmdl->argv[0], media);
}

static void cmd_bearer_disable_udp_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr, "Usage: %s bearer disable media %s name NAME\n",
		cmdl->argv[0], media);
}

static void cmd_bearer_disable_help(struct cmdl *cmdl)
{
	fprintf(stderr, "Usage: %s bearer disable media MEDIA ARGS...\n",
		cmdl->argv[0]);
	print_bearer_media();
}

static int cmd_bearer_disable(struct nlmsghdr *nlh, const struct cmd *cmd,
			      struct cmdl *cmdl, void *data)
{
	int err;
	struct nlattr *nest;
	struct opt opts[] = {
		{ "device",		OPT_KEYVAL,	NULL },
		{ "name",		OPT_KEYVAL,	NULL },
		{ "media",		OPT_KEYVAL,	NULL },
		{ NULL }
	};
	struct tipc_sup_media sup_media[] = {
		{ "udp",        "name",         cmd_bearer_disable_udp_help},
		{ "eth",        "device",       cmd_bearer_disable_l2_help },
		{ "ib",         "device",       cmd_bearer_disable_l2_help },
		{ NULL, },
	};

	if (parse_opts(opts, cmdl) < 0) {
		if (help_flag)
			(cmd->help)(cmdl);
		return -EINVAL;
	}

	nlh = msg_init(TIPC_NL_BEARER_DISABLE);
	if (!nlh) {
		fprintf(stderr, "error, message initialisation failed\n");
		return -1;
	}

	nest = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER);
	err = nl_add_bearer_name(nlh, cmd, cmdl, opts, sup_media);
	if (err)
		return err;
	mnl_attr_nest_end(nlh, nest);

	return msg_doit(nlh, NULL, NULL);

}

static void cmd_bearer_set_help(struct cmdl *cmdl)
{
	fprintf(stderr, "Usage: %s bearer set OPTION media MEDIA ARGS...\n",
		cmdl->argv[0]);
	_print_bearer_opts();
	print_bearer_media();
}

static void cmd_bearer_set_udp_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr, "Usage: %s bearer set OPTION media %s name NAME\n\n",
		cmdl->argv[0], media);
	_print_bearer_opts();
}

static void cmd_bearer_set_l2_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr,
		"Usage: %s bearer set [OPTION]... media %s device DEVICE\n",
		cmdl->argv[0], media);
	_print_bearer_opts();
}

static int cmd_bearer_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
			       struct cmdl *cmdl, void *data)
{
	int err;
	int val;
	int prop;
	struct nlattr *props;
	struct nlattr *attrs;
	struct opt opts[] = {
		{ "device",		OPT_KEYVAL,	NULL },
		{ "media",		OPT_KEYVAL,	NULL },
		{ "name",		OPT_KEYVAL,	NULL },
		{ NULL }
	};
	struct tipc_sup_media sup_media[] = {
		{ "udp",        "name",         cmd_bearer_set_udp_help},
		{ "eth",        "device",       cmd_bearer_set_l2_help },
		{ "ib",         "device",       cmd_bearer_set_l2_help },
		{ NULL, },
	};

	if (strcmp(cmd->cmd, "priority") == 0)
		prop = TIPC_NLA_PROP_PRIO;
	else if ((strcmp(cmd->cmd, "tolerance") == 0))
		prop = TIPC_NLA_PROP_TOL;
	else if ((strcmp(cmd->cmd, "window") == 0))
		prop = TIPC_NLA_PROP_WIN;
	else if ((strcmp(cmd->cmd, "mtu") == 0))
		prop = TIPC_NLA_PROP_MTU;
	else
		return -EINVAL;

	if (cmdl->optind >= cmdl->argc) {
		fprintf(stderr, "error, missing value\n");
		return -EINVAL;
	}
	val = atoi(shift_cmdl(cmdl));

	if (parse_opts(opts, cmdl) < 0)
		return -EINVAL;

	if (prop == TIPC_NLA_PROP_MTU) {
		char *media = cmd_get_media_type(cmd, cmdl, opts);

		if (!media)
			return -EINVAL;
		else if (strcmp(media, "udp")) {
			fprintf(stderr, "error, not supported for media\n");
			return -EINVAL;
		}
	}

	nlh = msg_init(TIPC_NL_BEARER_SET);
	if (!nlh) {
		fprintf(stderr, "error, message initialisation failed\n");
		return -1;
	}
	attrs = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER);

	props = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER_PROP);
	mnl_attr_put_u32(nlh, prop, val);
	mnl_attr_nest_end(nlh, props);

	err = nl_add_bearer_name(nlh, cmd, cmdl, opts, sup_media);
	if (err)
		return err;

	mnl_attr_nest_end(nlh, attrs);

	return msg_doit(nlh, NULL, NULL);
}

static int cmd_bearer_set(struct nlmsghdr *nlh, const struct cmd *cmd,
			  struct cmdl *cmdl, void *data)
{
	const struct cmd cmds[] = {
		{ "priority",	cmd_bearer_set_prop,	cmd_bearer_set_help },
		{ "tolerance",	cmd_bearer_set_prop,	cmd_bearer_set_help },
		{ "window",	cmd_bearer_set_prop,	cmd_bearer_set_help },
		{ "mtu",	cmd_bearer_set_prop,	cmd_bearer_set_help },
		{ NULL }
	};

	return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}

static void cmd_bearer_get_help(struct cmdl *cmdl)
{
	fprintf(stderr, "Usage: %s bearer get [OPTION] media MEDIA ARGS...\n",
		cmdl->argv[0]);
	_print_bearer_opts();
	print_bearer_media();
}

static void cmd_bearer_get_udp_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr, "Usage: %s bearer get [OPTION] media %s name NAME [UDP OPTIONS]\n\n",
		cmdl->argv[0], media);
	fprintf(stderr,
		"UDP OPTIONS\n"
		" remoteip              - Remote ip address\n"
		" remoteport            - Remote port\n"
		" localip               - Local ip address\n"
		" localport             - Local port\n\n");
	_print_bearer_opts();
}

static void cmd_bearer_get_l2_help(struct cmdl *cmdl, char *media)
{
	fprintf(stderr,
		"Usage: %s bearer get OPTION media %s device DEVICE\n",
		cmdl->argv[0], media);
	_print_bearer_opts();
}


static int bearer_dump_udp_cb(const struct nlmsghdr *nlh, void *data)
{
	struct sockaddr_storage *addr;
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_UDP_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);

	if (!info[TIPC_NLA_UDP_REMOTE])
		return MNL_CB_ERROR;

	addr = mnl_attr_get_payload(info[TIPC_NLA_UDP_REMOTE]);

	if (addr->ss_family == AF_INET) {
		struct sockaddr_in *ipv4 = (struct sockaddr_in *) addr;

		printf("%s\n", inet_ntoa(ipv4->sin_addr));
	} else if (addr->ss_family == AF_INET6) {
		char straddr[INET6_ADDRSTRLEN];
		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) addr;

		if (!inet_ntop(AF_INET6, &ipv6->sin6_addr, straddr,
			       sizeof(straddr))) {
			fprintf(stderr, "error, parsing IPv6 addr\n");
			return MNL_CB_ERROR;
		}
		printf("%s\n", straddr);

	} else {
		return MNL_CB_ERROR;
	}

	return MNL_CB_OK;
}

static int bearer_get_udp_cb(const struct nlmsghdr *nlh, void *data)
{
	struct cb_data *cb_data = (struct cb_data *) data;
	struct sockaddr_storage *addr;
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1] = {};
	struct nlattr *opts[TIPC_NLA_UDP_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_BEARER])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_BEARER], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(attrs[TIPC_NLA_BEARER_UDP_OPTS], parse_attrs, opts);
	if (!opts[TIPC_NLA_UDP_LOCAL])
		return MNL_CB_ERROR;

	if ((cb_data->attr == TIPC_NLA_UDP_REMOTE) &&
	    (cb_data->prop == UDP_PROP_IP) &&
	    opts[TIPC_NLA_UDP_MULTI_REMOTEIP]) {
		struct mnlu_gen_socket bearer_nlg;
		struct nlattr *attr;
		struct nlmsghdr *h;
		const char *bname;
		int err = 0;

		err = mnlu_gen_socket_open(&bearer_nlg, TIPC_GENL_V2_NAME,
					   TIPC_GENL_V2_VERSION);
		if (err)
			return -1;

		h = mnlu_gen_socket_cmd_prepare(&bearer_nlg,
						TIPC_NL_UDP_GET_REMOTEIP,
						NLM_F_REQUEST | NLM_F_DUMP);
		if (!h) {
			fprintf(stderr, "error, message initialization failed\n");
			mnlu_gen_socket_close(&bearer_nlg);
			return -1;
		}

		attr = mnl_attr_nest_start(h, TIPC_NLA_BEARER);
		bname = mnl_attr_get_str(attrs[TIPC_NLA_BEARER_NAME]);
		mnl_attr_put_strz(h, TIPC_NLA_BEARER_NAME, bname);
		mnl_attr_nest_end(h, attr);

		err = mnlu_gen_socket_sndrcv(&bearer_nlg, h,
					     bearer_dump_udp_cb, NULL);
		mnlu_gen_socket_close(&bearer_nlg);
		return err;
	}

	addr = mnl_attr_get_payload(opts[cb_data->attr]);

	if (addr->ss_family == AF_INET) {
		struct sockaddr_in *ipv4 = (struct sockaddr_in *) addr;

		switch (cb_data->prop) {
		case UDP_PROP_IP:
			printf("%s\n", inet_ntoa(ipv4->sin_addr));
			break;
		case UDP_PROP_PORT:
			printf("%u\n", ntohs(ipv4->sin_port));
			break;
		default:
			return MNL_CB_ERROR;
		}

	} else if (addr->ss_family == AF_INET6) {
		char straddr[INET6_ADDRSTRLEN];
		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) addr;

		switch (cb_data->prop) {
		case UDP_PROP_IP:
			if (!inet_ntop(AF_INET6, &ipv6->sin6_addr, straddr,
				       sizeof(straddr))) {
				fprintf(stderr, "error, parsing IPv6 addr\n");
				return MNL_CB_ERROR;
			}
			printf("%s\n", straddr);
			break;
		case UDP_PROP_PORT:
			printf("%u\n", ntohs(ipv6->sin6_port));
			break;
		default:
			return MNL_CB_ERROR;
		}

	} else {
		return MNL_CB_ERROR;
	}

	return MNL_CB_OK;
}

static int bearer_get_cb(const struct nlmsghdr *nlh, void *data)
{
	int *prop = data;
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1] = {};
	struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_BEARER])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_BEARER], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_BEARER_PROP])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(attrs[TIPC_NLA_BEARER_PROP], parse_attrs, props);
	if (!props[*prop])
		return MNL_CB_ERROR;

	printf("%u\n", mnl_attr_get_u32(props[*prop]));

	return MNL_CB_OK;
}

static int cmd_bearer_get_media(struct nlmsghdr *nlh, const struct cmd *cmd,
				struct cmdl *cmdl, void *data)
{
	int err;
	char *media;
	struct opt *opt;
	struct cb_data cb_data = {0};
	struct nlattr *attrs;
	struct opt opts[] = {
		{ "localip",		OPT_KEY,	NULL },
		{ "localport",		OPT_KEY,	NULL },
		{ "remoteip",		OPT_KEY,	NULL },
		{ "remoteport",		OPT_KEY,	NULL },
		{ "name",		OPT_KEYVAL,	NULL },
		{ "media",		OPT_KEYVAL,	NULL },
		{ NULL }
	};
	struct tipc_sup_media sup_media[] = {
		{ "udp",        "name",         cmd_bearer_get_udp_help},
		{ NULL, },
	};

	/* Rewind optind to include media in the option list */
	cmdl->optind--;
	if (parse_opts(opts, cmdl) < 0)
		return -EINVAL;

	if (!(opt = get_opt(opts, "media"))) {
		fprintf(stderr, "error, missing media value\n");
		return -EINVAL;
	}
	media = opt->val;

	if (help_flag) {
		cmd_bearer_get_udp_help(cmdl, media);
		return -EINVAL;
	}
	if (strcmp(media, "udp") != 0) {
		fprintf(stderr, "error, no \"%s\" media specific options\n", media);
		return -EINVAL;
	}
	if (!(opt = get_opt(opts, "name"))) {
		fprintf(stderr, "error, missing media name\n");
		return -EINVAL;
	}

	nlh = msg_init(TIPC_NL_BEARER_GET);
	if (!nlh) {
		fprintf(stderr, "error, message initialisation failed\n");
		return -1;
	}

	attrs = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER);
	err = nl_add_bearer_name(nlh, cmd, cmdl, opts, sup_media);
	if (err)
		return err;
	mnl_attr_nest_end(nlh, attrs);
	cb_data.nlh = nlh;

	if (has_opt(opts, "localip")) {
		cb_data.attr = TIPC_NLA_UDP_LOCAL;
		cb_data.prop = UDP_PROP_IP;
		return msg_doit(nlh, bearer_get_udp_cb, &cb_data);
	} else if (has_opt(opts, "localport")) {
		cb_data.attr = TIPC_NLA_UDP_LOCAL;
		cb_data.prop = UDP_PROP_PORT;
		return msg_doit(nlh, bearer_get_udp_cb, &cb_data);
	} else if (has_opt(opts, "remoteip")) {
		cb_data.attr = TIPC_NLA_UDP_REMOTE;
		cb_data.prop = UDP_PROP_IP;
		return msg_doit(nlh, bearer_get_udp_cb, &cb_data);
	} else if (has_opt(opts, "remoteport")) {
		cb_data.attr = TIPC_NLA_UDP_REMOTE;
		cb_data.prop = UDP_PROP_PORT;
		return msg_doit(nlh, bearer_get_udp_cb, &cb_data);
	}
	fprintf(stderr, "error, missing UDP option\n");
	return -EINVAL;
}

static int cmd_bearer_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
			       struct cmdl *cmdl, void *data)
{
	int err;
	int prop;
	struct nlattr *attrs;
	struct opt opts[] = {
		{ "device",		OPT_KEYVAL,	NULL },
		{ "media",		OPT_KEYVAL,	NULL },
		{ "name",		OPT_KEYVAL,	NULL },
		{ NULL }
	};
	struct tipc_sup_media sup_media[] = {
		{ "udp",        "name",         cmd_bearer_get_udp_help},
		{ "eth",        "device",       cmd_bearer_get_l2_help },
		{ "ib",         "device",       cmd_bearer_get_l2_help },
		{ NULL, },
	};

	if (help_flag) {
		(cmd->help)(cmdl);
		return -EINVAL;
	}

	if (strcmp(cmd->cmd, "priority") == 0)
		prop = TIPC_NLA_PROP_PRIO;
	else if ((strcmp(cmd->cmd, "tolerance") == 0))
		prop = TIPC_NLA_PROP_TOL;
	else if ((strcmp(cmd->cmd, "window") == 0))
		prop = TIPC_NLA_PROP_WIN;
	else if ((strcmp(cmd->cmd, "mtu") == 0))
		prop = TIPC_NLA_PROP_MTU;
	else
		return -EINVAL;

	if (parse_opts(opts, cmdl) < 0)
		return -EINVAL;

	if (prop == TIPC_NLA_PROP_MTU) {
		char *media = cmd_get_media_type(cmd, cmdl, opts);

		if (!media)
			return -EINVAL;
		else if (strcmp(media, "udp")) {
			fprintf(stderr, "error, not supported for media\n");
			return -EINVAL;
		}
	}

	nlh = msg_init(TIPC_NL_BEARER_GET);
	if (!nlh) {
		fprintf(stderr, "error, message initialisation failed\n");
		return -1;
	}

	attrs = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER);
	err = nl_add_bearer_name(nlh, cmd, cmdl, opts, sup_media);
	if (err)
		return err;
	mnl_attr_nest_end(nlh, attrs);

	return msg_doit(nlh, bearer_get_cb, &prop);
}

static int cmd_bearer_get(struct nlmsghdr *nlh, const struct cmd *cmd,
			  struct cmdl *cmdl, void *data)
{
	const struct cmd cmds[] = {
		{ "priority",	cmd_bearer_get_prop,	cmd_bearer_get_help },
		{ "tolerance",	cmd_bearer_get_prop,	cmd_bearer_get_help },
		{ "window",	cmd_bearer_get_prop,	cmd_bearer_get_help },
		{ "mtu",	cmd_bearer_get_prop,	cmd_bearer_get_help },
		{ "media",	cmd_bearer_get_media,	cmd_bearer_get_help },
		{ NULL }
	};

	return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}

static int bearer_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_BEARER]) {
		fprintf(stderr, "No bearer in netlink response\n");
		return MNL_CB_ERROR;
	}

	mnl_attr_parse_nested(info[TIPC_NLA_BEARER], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_BEARER_NAME]) {
		fprintf(stderr, "Bearer name missing in netlink response\n");
		return MNL_CB_ERROR;
	}

	printf("%s\n", mnl_attr_get_str(attrs[TIPC_NLA_BEARER_NAME]));

	return MNL_CB_OK;
}

static int cmd_bearer_list(struct nlmsghdr *nlh, const struct cmd *cmd,
			   struct cmdl *cmdl, void *data)
{
	if (help_flag) {
		fprintf(stderr, "Usage: %s bearer list\n", cmdl->argv[0]);
		return -EINVAL;
	}

	nlh = msg_init(TIPC_NL_BEARER_GET);
	if (!nlh) {
		fprintf(stderr, "error, message initialisation failed\n");
		return -1;
	}

	return msg_dumpit(nlh, bearer_list_cb, NULL);
}

void cmd_bearer_help(struct cmdl *cmdl)
{
	fprintf(stderr,
		"Usage: %s bearer COMMAND [ARGS] ...\n"
		"\n"
		"COMMANDS\n"
		" add			- Add data to existing bearer\n"
		" enable		- Enable a bearer\n"
		" disable		- Disable a bearer\n"
		" set			- Set various bearer properties\n"
		" get			- Get various bearer properties\n"
		" list			- List bearers\n", cmdl->argv[0]);
}

int cmd_bearer(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
	       void *data)
{
	const struct cmd cmds[] = {
		{ "add",	cmd_bearer_add,		cmd_bearer_add_help },
		{ "disable",	cmd_bearer_disable,	cmd_bearer_disable_help },
		{ "enable",	cmd_bearer_enable,	cmd_bearer_enable_help },
		{ "get",	cmd_bearer_get,		cmd_bearer_get_help },
		{ "list",	cmd_bearer_list,	NULL },
		{ "set",	cmd_bearer_set,		cmd_bearer_set_help },
		{ NULL }
	};

	return run_cmd(nlh, cmd, cmds, cmdl, NULL);
}
