/*
 * f_route.c		ROUTE filter.
 *
 *		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:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#include "utils.h"
#include "rt_names.h"
#include "tc_util.h"

static void explain(void)
{
	fprintf(stderr, "Usage: ... route [ from REALM | fromif TAG ] [ to REALM ]\n");
	fprintf(stderr, "                [ flowid CLASSID ] [ police POLICE_SPEC ]\n");
	fprintf(stderr, "       POLICE_SPEC := ... look at TBF\n");
	fprintf(stderr, "       CLASSID := X:Y\n");
}

#define usage() return(-1)

static int route_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	__u32 fh = 0xFFFF8000;
	__u32 order = 0;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	if (argc == 0)
		return 0;

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "to") == 0) {
			__u32 id;
			NEXT_ARG();
			if (rtnl_rtrealm_a2n(&id, *argv)) {
				fprintf(stderr, "Illegal \"to\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_ROUTE4_TO, &id, 4);
			fh &= ~0x80FF;
			fh |= id&0xFF;
		} else if (matches(*argv, "from") == 0) {
			__u32 id;
			NEXT_ARG();
			if (rtnl_rtrealm_a2n(&id, *argv)) {
				fprintf(stderr, "Illegal \"from\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_ROUTE4_FROM, &id, 4);
			fh &= 0xFFFF;
			fh |= id<<16;
		} else if (matches(*argv, "fromif") == 0) {
			struct rtnl_handle rth;
			__u32 id;
			NEXT_ARG();
			if (rtnl_open(&rth, 0) == 0) {
				ll_init_map(&rth);
				rtnl_close(&rth);
			}
			if ((id=ll_name_to_index(*argv)) <= 0) {
				fprintf(stderr, "Illegal \"fromif\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_ROUTE4_IIF, &id, 4);
			fh &= 0xFFFF;
			fh |= (0x8000|id)<<16;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_ROUTE4_CLASSID, &handle, 4);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_ROUTE4_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}
	tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail;
	if (order) {
		fh &= ~0x7F00;
		fh |= (order<<8)&0x7F00;
	}
	if (!t->tcm_handle)
		t->tcm_handle = fh;
	return 0;
}

static int route_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle)
{
	struct rtattr *tb[TCA_ROUTE4_MAX+1];
	SPRINT_BUF(b1);

	if (opt == NULL)
		return 0;

	memset(tb, 0, sizeof(tb));
	if (opt)
		parse_rtattr(tb, TCA_ROUTE4_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt));

	if (handle)
		fprintf(f, "fh 0x%08x ", handle);
	if (handle&0x7F00)
		fprintf(f, "order %d ", (handle>>8)&0x7F);

	if (tb[TCA_ROUTE4_CLASSID]) {
		SPRINT_BUF(b1);
		fprintf(f, "flowid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID]), b1));
	}
	if (tb[TCA_ROUTE4_TO])
		fprintf(f, "to %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_TO]), b1, sizeof(b1)));
	if (tb[TCA_ROUTE4_FROM])
		fprintf(f, "from %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_FROM]), b1, sizeof(b1)));
	if (tb[TCA_ROUTE4_IIF])
		fprintf(f, "fromif %s", ll_index_to_name(*(int*)RTA_DATA(tb[TCA_ROUTE4_IIF])));
	if (tb[TCA_ROUTE4_POLICE])
		tc_print_police(f, tb[TCA_ROUTE4_POLICE]);
	return 0;
}

struct filter_util route_filter_util = {
	.id = "route",
	.parse_fopt = route_parse_opt,
	.print_fopt = route_print_opt,
};
