/*
 * link_vti6.c	VTI driver module
 *
 *		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:	Herbert Xu <herbert@gondor.apana.org.au>
 *		Saurabh Mohan <saurabh.mohan@vyatta.com> Modified link_gre.c for VTI
 *		Steffen Klassert <steffen.klassert@secunet.com> Modified link_vti.c for IPv6
 */

#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <linux/ip.h>
#include <linux/if_tunnel.h>
#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"
#include "tunnel.h"


static void usage(void) __attribute__((noreturn));
static void usage(void)
{
	fprintf(stderr, "Usage: ip link { add | set | change | replace | del } NAME\n");
	fprintf(stderr, "          type { vti6 } [ remote ADDR ] [ local ADDR ]\n");
	fprintf(stderr, "          [ [i|o]key KEY ]\n");
	fprintf(stderr, "          [ dev PHYS_DEV ]\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "Where: NAME := STRING\n");
	fprintf(stderr, "       ADDR := { IPV6_ADDRESS }\n");
	fprintf(stderr, "       KEY  := { DOTTED_QUAD | NUMBER }\n");
	exit(-1);
}

static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
			  struct nlmsghdr *n)
{
	struct {
		struct nlmsghdr n;
		struct ifinfomsg i;
		char buf[1024];
	} req;
	struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
	struct rtattr *tb[IFLA_MAX + 1];
	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
	struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
	struct in6_addr saddr;
	struct in6_addr daddr;
	unsigned ikey = 0;
	unsigned okey = 0;
	unsigned link = 0;
	int len;

	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
		memset(&req, 0, sizeof(req));

		req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
		req.n.nlmsg_flags = NLM_F_REQUEST;
		req.n.nlmsg_type = RTM_GETLINK;
		req.i.ifi_family = preferred_family;
		req.i.ifi_index = ifi->ifi_index;

		if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
get_failed:
			fprintf(stderr,
				"Failed to get existing tunnel info.\n");
			return -1;
		}

		len = req.n.nlmsg_len;
		len -= NLMSG_LENGTH(sizeof(*ifi));
		if (len < 0)
			goto get_failed;

		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);

		if (!tb[IFLA_LINKINFO])
			goto get_failed;

		parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);

		if (!linkinfo[IFLA_INFO_DATA])
			goto get_failed;

		parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX,
				    linkinfo[IFLA_INFO_DATA]);

		if (vtiinfo[IFLA_VTI_IKEY])
			ikey = rta_getattr_u32(vtiinfo[IFLA_VTI_IKEY]);

		if (vtiinfo[IFLA_VTI_OKEY])
			okey = rta_getattr_u32(vtiinfo[IFLA_VTI_OKEY]);

		if (vtiinfo[IFLA_VTI_LOCAL])
			memcpy(&saddr, RTA_DATA(vtiinfo[IFLA_VTI_LOCAL]), sizeof(saddr));

		if (vtiinfo[IFLA_VTI_REMOTE])
			memcpy(&daddr, RTA_DATA(vtiinfo[IFLA_VTI_REMOTE]), sizeof(daddr));

		if (vtiinfo[IFLA_VTI_LINK])
			link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]);
	}

	while (argc > 0) {
		if (!matches(*argv, "key")) {
			unsigned uval;

			NEXT_ARG();
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0) < 0) {
					fprintf(stderr,
						"Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv);
					exit(-1);
				}
				uval = htonl(uval);
			}

			ikey = okey = uval;
		} else if (!matches(*argv, "ikey")) {
			unsigned uval;

			NEXT_ARG();
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0) < 0) {
					fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv);
					exit(-1);
				}
				uval = htonl(uval);
			}
			ikey = uval;
		} else if (!matches(*argv, "okey")) {
			unsigned uval;

			NEXT_ARG();
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0) < 0) {
					fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv);
					exit(-1);
				}
				uval = htonl(uval);
			}
			okey = uval;
		} else if (!matches(*argv, "remote")) {
			NEXT_ARG();
			if (!strcmp(*argv, "any")) {
				fprintf(stderr, "invalid value for \"remote\": \"%s\"\n", *argv);
				exit(-1);
			} else {
				inet_prefix addr;
				get_prefix(&addr, *argv, AF_INET6);
				memcpy(&daddr, addr.data, addr.bytelen);
			}
		} else if (!matches(*argv, "local")) {
			NEXT_ARG();
			if (!strcmp(*argv, "any")) {
				fprintf(stderr, "invalid value for \"local\": \"%s\"\n", *argv);
				exit(-1);
			} else {
				inet_prefix addr;
				get_prefix(&addr, *argv, AF_INET6);
				memcpy(&saddr, addr.data, addr.bytelen);
			}
		} else if (!matches(*argv, "dev")) {
			NEXT_ARG();
			link = if_nametoindex(*argv);
			if (link == 0)
				exit(-1);
		} else
			usage();
		argc--; argv++;
	}

	addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
	addattr32(n, 1024, IFLA_VTI_OKEY, okey);
	addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
	addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
	if (link)
		addattr32(n, 1024, IFLA_VTI_LINK, link);

	return 0;
}

static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	char s1[1024];
	char s2[64];
	const char *local = "any";
	const char *remote = "any";
	struct in6_addr saddr;
	struct in6_addr daddr;

	if (!tb)
		return;

	if (tb[IFLA_VTI_REMOTE]) {
		memcpy(&daddr, RTA_DATA(tb[IFLA_VTI_REMOTE]), sizeof(daddr));

		remote = format_host(AF_INET6, 16, &daddr, s1, sizeof(s1));
	}

	fprintf(f, "remote %s ", remote);

	if (tb[IFLA_VTI_LOCAL]) {
		memcpy(&saddr, RTA_DATA(tb[IFLA_VTI_LOCAL]), sizeof(saddr));

		local = format_host(AF_INET6, 16, &saddr, s1, sizeof(s1));
	}

	fprintf(f, "local %s ", local);

	if (tb[IFLA_VTI_LINK] && *(__u32 *)RTA_DATA(tb[IFLA_VTI_LINK])) {
		unsigned link = *(__u32 *)RTA_DATA(tb[IFLA_VTI_LINK]);
		const char *n = if_indextoname(link, s2);

		if (n)
			fprintf(f, "dev %s ", n);
		else
			fprintf(f, "dev %u ", link);
	}

	if (tb[IFLA_VTI_IKEY]) {
		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_VTI_IKEY]), s2, sizeof(s2));
		fprintf(f, "ikey %s ", s2);
	}

	if (tb[IFLA_VTI_OKEY]) {
		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_VTI_OKEY]), s2, sizeof(s2));
		fprintf(f, "okey %s ", s2);
	}
}

struct link_util vti6_link_util = {
	.id = "vti6",
	.maxattr = IFLA_VTI_MAX,
	.parse_opt = vti6_parse_opt,
	.print_opt = vti6_print_opt,
};
