/*
 * ipila.c	ILA (Identifier Locator Addressing) support
 *
 *              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:	Tom Herbert <tom@herbertland.com>
 */

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <linux/ila.h>
#include <linux/genetlink.h>
#include <linux/ip.h>
#include <arpa/inet.h>

#include "libgenl.h"
#include "utils.h"
#include "ip_common.h"
#include "ila_common.h"
#include "json_print.h"

static void usage(void)
{
	fprintf(stderr,
		"Usage: ip ila add loc_match LOCATOR_MATCH loc LOCATOR [ dev DEV ] OPTIONS\n"
		"       ip ila del loc_match LOCATOR_MATCH [ loc LOCATOR ] [ dev DEV ]\n"
		"       ip ila list\n"
		"OPTIONS := [ csum-mode { adj-transport | neutral-map |\n"
		"                         neutral-map-auto | no-action } ]\n"
		"           [ ident-type { luid | use-format } ]\n");

	exit(-1);
}

/* netlink socket */
static struct rtnl_handle genl_rth = { .fd = -1 };
static int genl_family = -1;

#define ILA_REQUEST(_req, _bufsiz, _cmd, _flags)	\
	GENL_REQUEST(_req, _bufsiz, genl_family, 0,	\
		     ILA_GENL_VERSION, _cmd, _flags)

#define ILA_RTA(g) ((struct rtattr *)(((char *)(g)) +	\
	NLMSG_ALIGN(sizeof(struct genlmsghdr))))

static void print_addr64(__u64 addr, char *buff, size_t len)
{
	__u16 *words = (__u16 *)&addr;
	__u16 v;
	int i, ret;
	size_t written = 0;
	char *sep = ":";

	for (i = 0; i < 4; i++) {
		v = ntohs(words[i]);

		if (i == 3)
			sep = "";

		ret = snprintf(&buff[written], len - written, "%x%s", v, sep);
		written += ret;
	}
}

static void print_ila_locid(const char *tag, int attr, struct rtattr *tb[])
{
	char abuf[256];

	if (tb[attr])
		print_addr64(rta_getattr_u64(tb[attr]),
			     abuf, sizeof(abuf));
	else
		snprintf(abuf, sizeof(abuf), "-");

	/* 20 = sizeof("xxxx:xxxx:xxxx:xxxx") */
	print_string(PRINT_ANY, tag, "%-20s", abuf);
}

static int print_ila_mapping(struct nlmsghdr *n, void *arg)
{
	struct genlmsghdr *ghdr;
	struct rtattr *tb[ILA_ATTR_MAX + 1];
	int len = n->nlmsg_len;

	if (n->nlmsg_type != genl_family)
		return 0;

	len -= NLMSG_LENGTH(GENL_HDRLEN);
	if (len < 0)
		return -1;

	ghdr = NLMSG_DATA(n);
	parse_rtattr(tb, ILA_ATTR_MAX, (void *) ghdr + GENL_HDRLEN, len);

	open_json_object(NULL);
	print_ila_locid("locator_match", ILA_ATTR_LOCATOR_MATCH, tb);
	print_ila_locid("locator", ILA_ATTR_LOCATOR, tb);

	if (tb[ILA_ATTR_IFINDEX]) {
		__u32 ifindex
			= rta_getattr_u32(tb[ILA_ATTR_IFINDEX]);

		print_color_string(PRINT_ANY, COLOR_IFNAME,
				   "interface", "%-16s",
				   ll_index_to_name(ifindex));
	} else {
		print_string(PRINT_FP, NULL, "%-10s ", "-");
	}

	if (tb[ILA_ATTR_CSUM_MODE]) {
		__u8 csum = rta_getattr_u8(tb[ILA_ATTR_CSUM_MODE]);

		print_string(PRINT_ANY, "csum_mode", "%s",
			     ila_csum_mode2name(csum));
	} else
		print_string(PRINT_FP, NULL, "%-10s ", "-");

	if (tb[ILA_ATTR_IDENT_TYPE])
		print_string(PRINT_ANY, "ident_type", "%s",
			ila_ident_type2name(rta_getattr_u8(
						tb[ILA_ATTR_IDENT_TYPE])));
	else
		print_string(PRINT_FP, NULL, "%s", "-");

	print_nl();
	close_json_object();

	return 0;
}

#define NLMSG_BUF_SIZE 4096

static int do_list(int argc, char **argv)
{
	ILA_REQUEST(req, 1024, ILA_CMD_GET, NLM_F_REQUEST | NLM_F_DUMP);

	if (argc > 0) {
		fprintf(stderr, "\"ip ila show\" does not take "
			"any arguments.\n");
		return -1;
	}

	if (rtnl_send(&genl_rth, (void *)&req, req.n.nlmsg_len) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}

	new_json_obj(json);
	if (rtnl_dump_filter(&genl_rth, print_ila_mapping, stdout) < 0) {
		fprintf(stderr, "Dump terminated\n");
		return 1;
	}
	delete_json_obj();
	fflush(stdout);

	return 0;
}

static int ila_parse_opt(int argc, char **argv, struct nlmsghdr *n,
			 bool adding)
{
	__u64 locator = 0;
	__u64 locator_match = 0;
	int ifindex = 0;
	int csum_mode = 0;
	int ident_type = 0;
	bool loc_set = false;
	bool loc_match_set = false;
	bool ifindex_set = false;
	bool csum_mode_set = false;
	bool ident_type_set = false;

	while (argc > 0) {
		if (!matches(*argv, "loc")) {
			NEXT_ARG();

			if (get_addr64(&locator, *argv) < 0) {
				fprintf(stderr, "Bad locator: %s\n", *argv);
				return -1;
			}
			loc_set = true;
		} else if (!matches(*argv, "loc_match")) {
			NEXT_ARG();

			if (get_addr64(&locator_match, *argv) < 0) {
				fprintf(stderr, "Bad locator to match: %s\n",
					*argv);
				return -1;
			}
			loc_match_set = true;
		} else if (!matches(*argv, "csum-mode")) {
			NEXT_ARG();

			csum_mode = ila_csum_name2mode(*argv);
			if (csum_mode < 0) {
				fprintf(stderr, "Bad csum-mode: %s\n",
					*argv);
				return -1;
			}
			csum_mode_set = true;
		} else if (!matches(*argv, "ident-type")) {
			NEXT_ARG();

			ident_type = ila_ident_name2type(*argv);
			if (ident_type < 0) {
				fprintf(stderr, "Bad ident-type: %s\n",
					*argv);
				return -1;
			}
			ident_type_set = true;
		} else if (!matches(*argv, "dev")) {
			NEXT_ARG();

			ifindex = ll_name_to_index(*argv);
			if (ifindex == 0) {
				fprintf(stderr, "No such interface: %s\n",
					*argv);
				return -1;
			}
			ifindex_set = true;
		} else {
			usage();
			return -1;
		}
		argc--, argv++;
	}

	if (adding) {
		if (!loc_set) {
			fprintf(stderr, "ila: missing locator\n");
			return -1;
		}
		if (!loc_match_set) {
			fprintf(stderr, "ila: missing locator0match\n");
			return -1;
		}
	}

	if (loc_match_set)
		addattr64(n, 1024, ILA_ATTR_LOCATOR_MATCH, locator_match);

	if (loc_set)
		addattr64(n, 1024, ILA_ATTR_LOCATOR, locator);

	if (ifindex_set)
		addattr32(n, 1024, ILA_ATTR_IFINDEX, ifindex);

	if (csum_mode_set)
		addattr8(n, 1024, ILA_ATTR_CSUM_MODE, csum_mode);

	if (ident_type_set)
		addattr8(n, 1024, ILA_ATTR_IDENT_TYPE, ident_type);

	return 0;
}

static int do_add(int argc, char **argv)
{
	ILA_REQUEST(req, 1024, ILA_CMD_ADD, NLM_F_REQUEST);

	ila_parse_opt(argc, argv, &req.n, true);

	if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
		return -2;

	return 0;
}

static int do_del(int argc, char **argv)
{
	ILA_REQUEST(req, 1024, ILA_CMD_DEL, NLM_F_REQUEST);

	ila_parse_opt(argc, argv, &req.n, false);

	if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
		return -2;

	return 0;
}

int do_ipila(int argc, char **argv)
{
	if (argc < 1)
		usage();

	if (matches(*argv, "help") == 0)
		usage();

	if (genl_init_handle(&genl_rth, ILA_GENL_NAME, &genl_family))
		exit(1);

	if (matches(*argv, "add") == 0)
		return do_add(argc-1, argv+1);
	if (matches(*argv, "delete") == 0)
		return do_del(argc-1, argv+1);
	if (matches(*argv, "list") == 0)
		return do_list(argc-1, argv+1);

	fprintf(stderr, "Command \"%s\" is unknown, try \"ip ila help\".\n",
		*argv);
	exit(-1);
}
