/*
 * m_action.c		Action Management
 *
 *		This program is free software; you can distribute 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:  J Hadi Salim (hadi@cyberus.ca)
 *
 * TODO:
 * - parse to be passed a filedescriptor for logging purposes
 *
*/

#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 <dlfcn.h>

#include "utils.h"
#include "tc_common.h"
#include "tc_util.h"

static struct action_util *action_list;

#ifdef CONFIG_GACT
int gact_ld; /* f*ckin backward compatibility */
#endif
int tab_flush;

static void act_usage(void)
{
	/*XXX: In the near future add a action->print_help to improve
	 * usability
	 * This would mean new tc will not be backward compatible
	 * with any action .so from the old days. But if someone really
	 * does that, they would know how to fix this ..
	 *
	*/
	fprintf(stderr, "usage: tc actions <ACTSPECOP>*\n");
	fprintf(stderr,
		"Where: \tACTSPECOP := ACR | GD | FL\n"
			"\tACR := add | change | replace <ACTSPEC>*\n"
			"\tGD := get | delete | <ACTISPEC>*\n"
			"\tFL := ls | list | flush | <ACTNAMESPEC>\n"
			"\tACTNAMESPEC :=  action <ACTNAME>\n"
			"\tACTISPEC := <ACTNAMESPEC> <INDEXSPEC>\n"
			"\tACTSPEC := action <ACTDETAIL> [INDEXSPEC]\n"
			"\tINDEXSPEC := index <32 bit indexvalue>\n"
			"\tACTDETAIL := <ACTNAME> <ACTPARAMS>\n"
			"\t\tExample ACTNAME is gact, mirred, bpf, etc\n"
			"\t\tEach action has its own parameters (ACTPARAMS)\n"
			"\n");

	exit(-1);
}

static int print_noaopt(struct action_util *au, FILE *f, struct rtattr *opt)
{
	if (opt && RTA_PAYLOAD(opt))
		fprintf(f, "[Unknown action, optlen=%u] ",
			(unsigned int) RTA_PAYLOAD(opt));
	return 0;
}

static int parse_noaopt(struct action_util *au, int *argc_p, char ***argv_p, int code, struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc) {
		fprintf(stderr, "Unknown action \"%s\", hence option \"%s\" is unparsable\n", au->id, *argv);
	} else {
		fprintf(stderr, "Unknown action \"%s\"\n", au->id);
	}
	return -1;
}

static struct action_util *get_action_kind(char *str)
{
	static void *aBODY;
	void *dlh;
	char buf[256];
	struct action_util *a;
#ifdef CONFIG_GACT
	int looked4gact = 0;
restart_s:
#endif
	for (a = action_list; a; a = a->next) {
		if (strcmp(a->id, str) == 0)
			return a;
	}

	snprintf(buf, sizeof(buf), "%s/m_%s.so", get_tc_lib(), str);
	dlh = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
	if (dlh == NULL) {
		dlh = aBODY;
		if (dlh == NULL) {
			dlh = aBODY = dlopen(NULL, RTLD_LAZY);
			if (dlh == NULL)
				goto noexist;
		}
	}

	snprintf(buf, sizeof(buf), "%s_action_util", str);
	a = dlsym(dlh, buf);
	if (a == NULL)
		goto noexist;

reg:
	a->next = action_list;
	action_list = a;
	return a;

noexist:
#ifdef CONFIG_GACT
	if (!looked4gact) {
		looked4gact = 1;
		strcpy(str, "gact");
		goto restart_s;
	}
#endif
	a = calloc(1, sizeof(*a));
	if (a) {
		strncpy(a->id, "noact", 15);
		a->parse_aopt = parse_noaopt;
		a->print_aopt = print_noaopt;
		goto reg;
	}
	return a;
}

static int
new_cmd(char **argv)
{
	if ((matches(*argv, "change") == 0) ||
		(matches(*argv, "replace") == 0) ||
		(matches(*argv, "delete") == 0) ||
		(matches(*argv, "get") == 0) ||
		(matches(*argv, "add") == 0))
			return 1;

	return 0;

}

int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	struct rtattr *tail, *tail2;
	char k[16];
	int act_ck_len = 0;
	int ok = 0;
	int eap = 0; /* expect action parameters */

	int ret = 0;
	int prio = 0;
	unsigned char act_ck[TC_COOKIE_MAX_SIZE];

	if (argc <= 0)
		return -1;

	tail = tail2 = NLMSG_TAIL(n);

	addattr_l(n, MAX_MSG, tca_id, NULL, 0);

	while (argc > 0) {

		memset(k, 0, sizeof(k));

		if (strcmp(*argv, "action") == 0) {
			argc--;
			argv++;
			eap = 1;
#ifdef CONFIG_GACT
			if (!gact_ld) {
				get_action_kind("gact");
			}
#endif
			continue;
		} else if (strcmp(*argv, "flowid") == 0) {
			break;
		} else if (strcmp(*argv, "classid") == 0) {
			break;
		} else if (strcmp(*argv, "help") == 0) {
			return -1;
		} else if (new_cmd(argv)) {
			goto done0;
		} else {
			struct action_util *a = NULL;

			strncpy(k, *argv, sizeof(k) - 1);
			eap = 0;
			if (argc > 0) {
				a = get_action_kind(k);
			} else {
done0:
				if (ok)
					break;
				else
					goto done;
			}

			if (a == NULL) {
				goto bad_val;
			}

			tail = NLMSG_TAIL(n);
			addattr_l(n, MAX_MSG, ++prio, NULL, 0);
			addattr_l(n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);

			ret = a->parse_aopt(a, &argc, &argv, TCA_ACT_OPTIONS,
					    n);

			if (ret < 0) {
				fprintf(stderr, "bad action parsing\n");
				goto bad_val;
			}

			if (*argv && strcmp(*argv, "cookie") == 0) {
				size_t slen;

				NEXT_ARG();
				slen = strlen(*argv);
				if (slen > TC_COOKIE_MAX_SIZE * 2) {
					char cookie_err_m[128];

					snprintf(cookie_err_m, 128,
						 "%zd Max allowed size %d",
						 slen, TC_COOKIE_MAX_SIZE*2);
					invarg(cookie_err_m, *argv);
				}

				if (hex2mem(*argv, act_ck, slen / 2) < 0)
					invarg("cookie must be a hex string\n",
					       *argv);

				act_ck_len = slen / 2;
				argc--;
				argv++;
			}

			if (act_ck_len)
				addattr_l(n, MAX_MSG, TCA_ACT_COOKIE,
					  &act_ck, act_ck_len);

			tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
			ok++;
		}
	}

	if (eap > 0) {
		fprintf(stderr, "bad action empty %d\n", eap);
		goto bad_val;
	}

	tail2->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail2;

done:
	*argc_p = argc;
	*argv_p = argv;
	return 0;
bad_val:
	/* no need to undo things, returning from here should
	 * cause enough pain */
	fprintf(stderr, "parse_action: bad value (%d:%s)!\n", argc, *argv);
	return -1;
}

static int tc_print_one_action(FILE *f, struct rtattr *arg)
{

	struct rtattr *tb[TCA_ACT_MAX + 1];
	int err = 0;
	struct action_util *a = NULL;

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_ACT_MAX, arg);

	if (tb[TCA_ACT_KIND] == NULL) {
		fprintf(stderr, "NULL Action!\n");
		return -1;
	}


	a = get_action_kind(RTA_DATA(tb[TCA_ACT_KIND]));
	if (a == NULL)
		return err;

	err = a->print_aopt(a, f, tb[TCA_ACT_OPTIONS]);

	if (err < 0)
		return err;

	if (show_stats && tb[TCA_ACT_STATS]) {

		fprintf(f, "\tAction statistics:\n");
		print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL);
		if (tb[TCA_ACT_COOKIE]) {
			int strsz = RTA_PAYLOAD(tb[TCA_ACT_COOKIE]);
			char b1[strsz * 2 + 1];

			fprintf(f, "\n\tcookie len %d %s ", strsz,
				hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]),
					      strsz, b1, sizeof(b1)));
		}
		fprintf(f, "\n");
	}

	return 0;
}

static int
tc_print_action_flush(FILE *f, const struct rtattr *arg)
{

	struct rtattr *tb[TCA_MAX + 1];
	int err = 0;
	struct action_util *a = NULL;
	__u32 *delete_count = 0;

	parse_rtattr_nested(tb, TCA_MAX, arg);

	if (tb[TCA_KIND] == NULL) {
		fprintf(stderr, "NULL Action!\n");
		return -1;
	}

	a = get_action_kind(RTA_DATA(tb[TCA_KIND]));
	if (a == NULL)
		return err;

	delete_count = RTA_DATA(tb[TCA_FCNT]);
	fprintf(f, " %s (%d entries)\n", a->id, *delete_count);
	tab_flush = 0;
	return 0;
}

int
tc_print_action(FILE *f, const struct rtattr *arg, unsigned short tot_acts)
{

	int i;

	if (arg == NULL)
		return 0;

	if (!tot_acts)
		tot_acts = TCA_ACT_MAX_PRIO;

	struct rtattr *tb[tot_acts + 1];

	parse_rtattr_nested(tb, tot_acts, arg);

	if (tab_flush && NULL != tb[0]  && NULL == tb[1])
		return tc_print_action_flush(f, tb[0]);

	for (i = 0; i < tot_acts; i++) {
		if (tb[i]) {
			fprintf(f, "\n\taction order %d: ", i);
			if (tc_print_one_action(f, tb[i]) < 0) {
				fprintf(f, "Error printing action\n");
			}
		}

	}

	return 0;
}

int print_action(const struct sockaddr_nl *who,
			   struct nlmsghdr *n,
			   void *arg)
{
	FILE *fp = (FILE *)arg;
	struct tcamsg *t = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	__u32 *tot_acts = NULL;
	struct rtattr *tb[TCA_ROOT_MAX+1];

	len -= NLMSG_LENGTH(sizeof(*t));

	if (len < 0) {
		fprintf(stderr, "Wrong len %d\n", len);
		return -1;
	}

	parse_rtattr(tb, TCA_ROOT_MAX, TA_RTA(t), len);

	if (tb[TCA_ROOT_COUNT])
		tot_acts = RTA_DATA(tb[TCA_ROOT_COUNT]);

	fprintf(fp, "total acts %d\n", tot_acts ? *tot_acts:0);
	if (tb[TCA_ACT_TAB] == NULL) {
		if (n->nlmsg_type != RTM_GETACTION)
			fprintf(stderr, "print_action: NULL kind\n");
		return -1;
	}

	if (n->nlmsg_type == RTM_DELACTION) {
		if (n->nlmsg_flags & NLM_F_ROOT) {
			fprintf(fp, "Flushed table ");
			tab_flush = 1;
		} else {
			fprintf(fp, "Deleted action ");
		}
	}

	if (n->nlmsg_type == RTM_NEWACTION) {
		if ((n->nlmsg_flags & NLM_F_CREATE) &&
		    !(n->nlmsg_flags & NLM_F_REPLACE)) {
			fprintf(fp, "Added action ");
		} else if (n->nlmsg_flags & NLM_F_REPLACE) {
			fprintf(fp, "Replaced action ");
		}
	}


	tc_print_action(fp, tb[TCA_ACT_TAB], tot_acts ? *tot_acts:0);

	return 0;
}

static int tc_action_gd(int cmd, unsigned int flags, int *argc_p, char ***argv_p)
{
	char k[16];
	struct action_util *a = NULL;
	int argc = *argc_p;
	char **argv = *argv_p;
	int prio = 0;
	int ret = 0;
	__u32 i = 0;
	struct rtattr *tail;
	struct rtattr *tail2;
	struct nlmsghdr *ans = NULL;

	struct {
		struct nlmsghdr         n;
		struct tcamsg           t;
		char                    buf[MAX_MSG];
	} req = {
		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)),
		.n.nlmsg_flags = NLM_F_REQUEST | flags,
		.n.nlmsg_type = cmd,
		.t.tca_family = AF_UNSPEC,
	};

	argc -= 1;
	argv += 1;


	tail = NLMSG_TAIL(&req.n);
	addattr_l(&req.n, MAX_MSG, TCA_ACT_TAB, NULL, 0);

	while (argc > 0) {
		if (strcmp(*argv, "action") == 0) {
			argc--;
			argv++;
			continue;
		} else if (strcmp(*argv, "help") == 0) {
			return -1;
		}

		strncpy(k, *argv, sizeof(k) - 1);
		a = get_action_kind(k);
		if (a == NULL) {
			fprintf(stderr, "Error: non existent action: %s\n", k);
			ret = -1;
			goto bad_val;
		}
		if (strcmp(a->id, k) != 0) {
			fprintf(stderr, "Error: non existent action: %s\n", k);
			ret = -1;
			goto bad_val;
		}

		argc -= 1;
		argv += 1;
		if (argc <= 0) {
			fprintf(stderr, "Error: no index specified action: %s\n", k);
			ret = -1;
			goto bad_val;
		}

		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&i, *argv, 10)) {
				fprintf(stderr, "Illegal \"index\"\n");
				ret = -1;
				goto bad_val;
			}
			argc -= 1;
			argv += 1;
		} else {
			fprintf(stderr, "Error: no index specified action: %s\n", k);
			ret = -1;
			goto bad_val;
		}

		tail2 = NLMSG_TAIL(&req.n);
		addattr_l(&req.n, MAX_MSG, ++prio, NULL, 0);
		addattr_l(&req.n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);
		if (i > 0)
			addattr32(&req.n, MAX_MSG, TCA_ACT_INDEX, i);
		tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2;

	}

	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;

	req.n.nlmsg_seq = rth.dump = ++rth.seq;
	if (cmd == RTM_GETACTION)
		ans = &req.n;

	if (rtnl_talk(&rth, &req.n, ans, MAX_MSG) < 0) {
		fprintf(stderr, "We have an error talking to the kernel\n");
		return 1;
	}

	if (ans && print_action(NULL, &req.n, (void *)stdout) < 0) {
		fprintf(stderr, "Dump terminated\n");
		return 1;
	}

	*argc_p = argc;
	*argv_p = argv;
bad_val:
	return ret;
}

static int tc_action_modify(int cmd, unsigned int flags, int *argc_p, char ***argv_p)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int ret = 0;
	struct {
		struct nlmsghdr         n;
		struct tcamsg           t;
		char                    buf[MAX_MSG];
	} req = {
		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)),
		.n.nlmsg_flags = NLM_F_REQUEST | flags,
		.n.nlmsg_type = cmd,
		.t.tca_family = AF_UNSPEC,
	};
	struct rtattr *tail = NLMSG_TAIL(&req.n);

	argc -= 1;
	argv += 1;
	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) {
		fprintf(stderr, "Illegal \"action\"\n");
		return -1;
	}
	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;

	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) {
		fprintf(stderr, "We have an error talking to the kernel\n");
		ret = -1;
	}

	*argc_p = argc;
	*argv_p = argv;

	return ret;
}

static int tc_act_list_or_flush(int *argc_p, char ***argv_p, int event)
{
	struct rtattr *tail, *tail2, *tail3, *tail4;
	int ret = 0, prio = 0, msg_size = 0;
	struct action_util *a = NULL;
	struct nla_bitfield32 flag_select = { 0 };
	char **argv = *argv_p;
	__u32 msec_since = 0;
	int argc = *argc_p;
	char k[16];
	struct {
		struct nlmsghdr         n;
		struct tcamsg           t;
		char                    buf[MAX_MSG];
	} req = {
		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)),
		.t.tca_family = AF_UNSPEC,
	};

	tail = NLMSG_TAIL(&req.n);
	addattr_l(&req.n, MAX_MSG, TCA_ACT_TAB, NULL, 0);
	tail2 = NLMSG_TAIL(&req.n);

	strncpy(k, *argv, sizeof(k) - 1);
#ifdef CONFIG_GACT
	if (!gact_ld) {
		get_action_kind("gact");
	}
#endif
	a = get_action_kind(k);
	if (a == NULL) {
		fprintf(stderr, "bad action %s\n", k);
		goto bad_val;
	}
	if (strcmp(a->id, k) != 0) {
		fprintf(stderr, "bad action %s\n", k);
		goto bad_val;
	}
	strncpy(k, *argv, sizeof(k) - 1);

	argc -= 1;
	argv += 1;

	if (argc && (strcmp(*argv, "since") == 0)) {
		NEXT_ARG();
		if (get_u32(&msec_since, *argv, 0))
			invarg("dump time \"since\" is invalid", *argv);
	}

	addattr_l(&req.n, MAX_MSG, ++prio, NULL, 0);
	addattr_l(&req.n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);
	tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2;
	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;

	tail3 = NLMSG_TAIL(&req.n);
	flag_select.value |= TCA_FLAG_LARGE_DUMP_ON;
	flag_select.selector |= TCA_FLAG_LARGE_DUMP_ON;
	addattr_l(&req.n, MAX_MSG, TCA_ROOT_FLAGS, &flag_select,
		  sizeof(struct nla_bitfield32));
	tail3->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail3;
	if (msec_since) {
		tail4 = NLMSG_TAIL(&req.n);
		addattr32(&req.n, MAX_MSG, TCA_ROOT_TIME_DELTA, msec_since);
		tail4->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail4;
	}
	msg_size = NLMSG_ALIGN(req.n.nlmsg_len) - NLMSG_ALIGN(sizeof(struct nlmsghdr));

	if (event == RTM_GETACTION) {
		if (rtnl_dump_request(&rth, event, (void *)&req.t, msg_size) < 0) {
			perror("Cannot send dump request");
			return 1;
		}
		ret = rtnl_dump_filter(&rth, print_action, stdout);
	}

	if (event == RTM_DELACTION) {
		req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len);
		req.n.nlmsg_type = RTM_DELACTION;
		req.n.nlmsg_flags |= NLM_F_ROOT;
		req.n.nlmsg_flags |= NLM_F_REQUEST;
		if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) {
			fprintf(stderr, "We have an error flushing\n");
			return 1;
		}

	}

bad_val:

	*argc_p = argc;
	*argv_p = argv;
	return ret;
}

int do_action(int argc, char **argv)
{

	int ret = 0;

	while (argc > 0) {

		if (matches(*argv, "add") == 0) {
			ret =  tc_action_modify(RTM_NEWACTION, NLM_F_EXCL|NLM_F_CREATE, &argc, &argv);
		} else if (matches(*argv, "change") == 0 ||
			  matches(*argv, "replace") == 0) {
			ret = tc_action_modify(RTM_NEWACTION, NLM_F_CREATE|NLM_F_REPLACE, &argc, &argv);
		} else if (matches(*argv, "delete") == 0) {
			argc -= 1;
			argv += 1;
			ret = tc_action_gd(RTM_DELACTION, 0,  &argc, &argv);
		} else if (matches(*argv, "get") == 0) {
			argc -= 1;
			argv += 1;
			ret = tc_action_gd(RTM_GETACTION, 0,  &argc, &argv);
		} else if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
						|| matches(*argv, "lst") == 0) {
			if (argc <= 2) {
				act_usage();
				return -1;
			}

			argc -= 2;
			argv += 2;
			return tc_act_list_or_flush(&argc, &argv,
						    RTM_GETACTION);
		} else if (matches(*argv, "flush") == 0) {
			if (argc <= 2) {
				act_usage();
				return -1;
			}

			argc -= 2;
			argv += 2;
			return tc_act_list_or_flush(&argc, &argv,
						    RTM_DELACTION);
		} else if (matches(*argv, "help") == 0) {
			act_usage();
			return -1;
		} else {
			fprintf(stderr, "Command \"%s\" is unknown, try \"tc actions help\".\n", *argv);
			return -1;
		}

		if (ret < 0)
			return -1;
	}

	return 0;
}
