/*
 * m_egress.c		ingress/egress packet mirror/redir actions module
 *
 *		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: Add Ingress support
 *
 */

#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 "tc_util.h"
#include "tc_common.h"
#include <linux/tc_act/tc_mirred.h>

static void
explain(void)
{
	fprintf(stderr, "Usage: mirred <DIRECTION> <ACTION> [index INDEX] <dev DEVICENAME>\n");
	fprintf(stderr, "where:\n");
	fprintf(stderr, "\tDIRECTION := <ingress | egress>\n");
	fprintf(stderr, "\tACTION := <mirror | redirect>\n");
	fprintf(stderr, "\tINDEX  is the specific policy instance id\n");
	fprintf(stderr, "\tDEVICENAME is the devicename\n");

}

static void
usage(void)
{
	explain();
	exit(-1);
}

static const char *mirred_n2a(int action)
{
	switch (action) {
	case TCA_EGRESS_REDIR:
		return "Egress Redirect";
	case TCA_INGRESS_REDIR:
		return "Ingress Redirect";
	case TCA_EGRESS_MIRROR:
		return "Egress Mirror";
	case TCA_INGRESS_MIRROR:
		return "Ingress Mirror";
	default:
		return "unknown";
	}
}

static int
parse_egress(struct action_util *a, int *argc_p, char ***argv_p,
	     int tca_id, struct nlmsghdr *n)
{

	int argc = *argc_p;
	char **argv = *argv_p;
	int ok = 0, iok = 0, mirror = 0, redir = 0;
	struct tc_mirred p = {};
	struct rtattr *tail;
	char d[16] = {};

	while (argc > 0) {

		if (matches(*argv, "action") == 0) {
			break;
		} else if (matches(*argv, "egress") == 0) {
			NEXT_ARG();
			ok++;
			continue;
		} else {

			if (matches(*argv, "index") == 0) {
				NEXT_ARG();
				if (get_u32(&p.index, *argv, 10)) {
					fprintf(stderr, "Illegal \"index\"\n");
					return -1;
				}
				iok++;
				if (!ok) {
					argc--;
					argv++;
					break;
				}
			} else if (!ok) {
				fprintf(stderr, "was expecting egress (%s)\n", *argv);
				break;

			} else if (!mirror && matches(*argv, "mirror") == 0) {
				mirror = 1;
				if (redir) {
					fprintf(stderr, "Can't have both mirror and redir\n");
					return -1;
				}
				p.eaction = TCA_EGRESS_MIRROR;
				p.action = TC_ACT_PIPE;
				ok++;
			} else if (!redir && matches(*argv, "redirect") == 0) {
				redir = 1;
				if (mirror) {
					fprintf(stderr, "Can't have both mirror and redir\n");
					return -1;
				}
				p.eaction = TCA_EGRESS_REDIR;
				p.action = TC_ACT_STOLEN;
				ok++;
			} else if ((redir || mirror) && matches(*argv, "dev") == 0) {
				NEXT_ARG();
				if (strlen(d))
					duparg("dev", *argv);

				strncpy(d, *argv, sizeof(d)-1);
				argc--;
				argv++;

				break;

			}
		}

		NEXT_ARG();
	}

	if (!ok && !iok) {
		return -1;
	}



	if (d[0])  {
		int idx;

		ll_init_map(&rth);

		if ((idx = ll_name_to_index(d)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", d);
			return -1;
		}

		p.ifindex = idx;
	}


	if (argc && p.eaction == TCA_EGRESS_MIRROR) {

		if (matches(*argv, "reclassify") == 0) {
			p.action = TC_POLICE_RECLASSIFY;
			NEXT_ARG();
		} else if (matches(*argv, "pipe") == 0) {
			p.action = TC_POLICE_PIPE;
			NEXT_ARG();
		} else if (matches(*argv, "drop") == 0 ||
			   matches(*argv, "shot") == 0) {
			p.action = TC_POLICE_SHOT;
			NEXT_ARG();
		} else if (matches(*argv, "continue") == 0) {
			p.action = TC_POLICE_UNSPEC;
			NEXT_ARG();
		} else if (matches(*argv, "pass") == 0 ||
			   matches(*argv, "ok") == 0) {
			p.action = TC_POLICE_OK;
			NEXT_ARG();
		}

	}

	if (argc) {
		if (iok && matches(*argv, "index") == 0) {
			fprintf(stderr, "mirred: Illegal double index\n");
			return -1;
		} else {
			if (matches(*argv, "index") == 0) {
				NEXT_ARG();
				if (get_u32(&p.index, *argv, 10)) {
					fprintf(stderr, "mirred: Illegal \"index\"\n");
					return -1;
				}
				argc--;
				argv++;
			}
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
	addattr_l(n, MAX_MSG, TCA_MIRRED_PARMS, &p, sizeof(p));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;

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


static int
parse_mirred(struct action_util *a, int *argc_p, char ***argv_p,
	     int tca_id, struct nlmsghdr *n)
{

	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc < 0) {
		fprintf(stderr, "mirred bad argument count %d\n", argc);
		return -1;
	}

	if (matches(*argv, "mirred") == 0) {
		NEXT_ARG();
	} else {
		fprintf(stderr, "mirred bad argument %s\n", *argv);
		return -1;
	}


	if (matches(*argv, "egress") == 0 || matches(*argv, "index") == 0) {
		int ret = parse_egress(a, &argc, &argv, tca_id, n);

		if (ret == 0) {
			*argc_p = argc;
			*argv_p = argv;
			return 0;
		}

	} else if (matches(*argv, "ingress") == 0) {
		fprintf(stderr, "mirred ingress not supported at the moment\n");
	} else if (matches(*argv, "help") == 0) {
		usage();
	} else {
		fprintf(stderr, "mirred option not supported %s\n", *argv);
	}

	return -1;

}

static int
print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
{
	struct tc_mirred *p;
	struct rtattr *tb[TCA_MIRRED_MAX + 1];
	const char *dev;

	SPRINT_BUF(b1);

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_MIRRED_MAX, arg);

	if (tb[TCA_MIRRED_PARMS] == NULL) {
		fprintf(f, "[NULL mirred parameters]");
		return -1;
	}
	p = RTA_DATA(tb[TCA_MIRRED_PARMS]);

	/*
	ll_init_map(&rth);
	*/


	if ((dev = ll_index_to_name(p->ifindex)) == 0) {
		fprintf(stderr, "Cannot find device %d\n", p->ifindex);
		return -1;
	}

	fprintf(f, "mirred (%s to device %s) %s", mirred_n2a(p->eaction), dev, action_n2a(p->action, b1, sizeof (b1)));

	fprintf(f, "\n ");
	fprintf(f, "\tindex %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);

	if (show_stats) {
		if (tb[TCA_MIRRED_TM]) {
			struct tcf_t *tm = RTA_DATA(tb[TCA_MIRRED_TM]);

			print_tm(f, tm);
		}
	}
	fprintf(f, "\n ");
	return 0;
}

struct action_util mirred_action_util = {
	.id = "mirred",
	.parse_aopt = parse_mirred,
	.print_aopt = print_mirred,
};
