/*
 * m_skbmod.c	skb modifier action 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 (jhs@mojatatu.com)
 *
 */

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

#include "rt_names.h"
#include "utils.h"
#include "tc_util.h"
#include <linux/tc_act/tc_skbmod.h>

static void skbmod_explain(void)
{
	fprintf(stderr,
		"Usage:... skbmod {[set <SETTABLE>] [swap <SWAPABLE>]} [CONTROL] [index INDEX]\n"
		"where SETTABLE is: [dmac DMAC] [smac SMAC] [etype ETYPE]\n"
		"where SWAPABLE is: \"mac\" to swap mac addresses\n"
		"note: \"swap mac\" is done after any outstanding D/SMAC change\n"
		"\tDMAC := 6 byte Destination MAC address\n"
		"\tSMAC := optional 6 byte Source MAC address\n"
		"\tETYPE := optional 16 bit ethertype\n"
		"\tCONTROL := reclassify | pipe | drop | continue | ok |\n"
		"\t           goto chain <CHAIN_INDEX>\n"
		"\tINDEX := skbmod index value to use\n");
}

static void skbmod_usage(void)
{
	skbmod_explain();
	exit(-1);
}

static int parse_skbmod(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;
	struct tc_skbmod p;
	struct rtattr *tail;
	char dbuf[ETH_ALEN];
	char sbuf[ETH_ALEN];
	__u16 skbmod_etype = 0;
	char *daddr = NULL;
	char *saddr = NULL;

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

	if (argc <= 0)
		return -1;

	while (argc > 0) {
		if (matches(*argv, "skbmod") == 0) {
			NEXT_ARG();
			continue;
		} else if (matches(*argv, "swap") == 0) {
			NEXT_ARG();
			continue;
		} else if (matches(*argv, "mac") == 0) {
			p.flags |= SKBMOD_F_SWAPMAC;
			ok += 1;
		} else if (matches(*argv, "set") == 0) {
			NEXT_ARG();
			continue;
		} else if (matches(*argv, "etype") == 0) {
			NEXT_ARG();
			if (get_u16(&skbmod_etype, *argv, 0))
				invarg("ethertype is invalid", *argv);
			fprintf(stderr, "skbmod etype 0x%x\n", skbmod_etype);
			p.flags |= SKBMOD_F_ETYPE;
			ok += 1;
		} else if (matches(*argv, "dmac") == 0) {
			NEXT_ARG();
			daddr = *argv;
			if (sscanf(daddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
				   dbuf, dbuf + 1, dbuf + 2,
				   dbuf + 3, dbuf + 4, dbuf + 5) != 6) {
				fprintf(stderr, "Invalid dst mac address %s\n",
					daddr);
				return -1;
			}
			p.flags |= SKBMOD_F_DMAC;
			fprintf(stderr, "dst MAC address <%s>\n", daddr);
			ok += 1;

		} else if (matches(*argv, "smac") == 0) {
			NEXT_ARG();
			saddr = *argv;
			if (sscanf(saddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
				   sbuf, sbuf + 1, sbuf + 2,
				   sbuf + 3, sbuf + 4, sbuf + 5) != 6) {
				fprintf(stderr, "Invalid smac address %s\n",
					saddr);
				return -1;
			}
			p.flags |= SKBMOD_F_SMAC;
			fprintf(stderr, "src MAC address <%s>\n", saddr);
			ok += 1;
		} else if (matches(*argv, "help") == 0) {
			skbmod_usage();
		} else {
			break;
		}

		argc--;
		argv++;
	}

	parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);

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

	if (!ok) {
		fprintf(stderr, "skbmod requires at least one option\n");
		skbmod_usage();
	}

	tail = addattr_nest(n, MAX_MSG, tca_id);
	addattr_l(n, MAX_MSG, TCA_SKBMOD_PARMS, &p, sizeof(p));

	if (daddr)
		addattr_l(n, MAX_MSG, TCA_SKBMOD_DMAC, dbuf, ETH_ALEN);
	if (skbmod_etype)
		addattr16(n, MAX_MSG, TCA_SKBMOD_ETYPE, skbmod_etype);
	if (saddr)
		addattr_l(n, MAX_MSG, TCA_SKBMOD_SMAC, sbuf, ETH_ALEN);

	addattr_nest_end(n, tail);

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

static int print_skbmod(struct action_util *au, FILE *f, struct rtattr *arg)
{
	struct tc_skbmod *p;
	struct rtattr *tb[TCA_SKBMOD_MAX + 1];
	__u16 skbmod_etype = 0;
	int has_optional = 0;
	SPRINT_BUF(b1);
	SPRINT_BUF(b2);

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_SKBMOD_MAX, arg);

	if (tb[TCA_SKBMOD_PARMS] == NULL) {
		fprintf(stderr, "Missing skbmod parameters\n");
		return -1;
	}

	p = RTA_DATA(tb[TCA_SKBMOD_PARMS]);

	fprintf(f, "skbmod ");
	print_action_control(f, "", p->action, " ");

	if (tb[TCA_SKBMOD_ETYPE]) {
		skbmod_etype = rta_getattr_u16(tb[TCA_SKBMOD_ETYPE]);
		has_optional = 1;
		fprintf(f, "set etype 0x%X ", skbmod_etype);
	}

	if (has_optional)
		fprintf(f, "\n\t ");

	if (tb[TCA_SKBMOD_DMAC]) {
		has_optional = 1;
		fprintf(f, "set dmac %s ",
			ll_addr_n2a(RTA_DATA(tb[TCA_SKBMOD_DMAC]),
				    RTA_PAYLOAD(tb[TCA_SKBMOD_DMAC]), 0, b1,
				    sizeof(b1)));

	}

	if (tb[TCA_SKBMOD_SMAC]) {
		has_optional = 1;
		fprintf(f, "set smac %s ",
			ll_addr_n2a(RTA_DATA(tb[TCA_SKBMOD_SMAC]),
				    RTA_PAYLOAD(tb[TCA_SKBMOD_SMAC]), 0, b2,
				    sizeof(b2)));
	}

	if (p->flags & SKBMOD_F_SWAPMAC)
		fprintf(f, "swap mac ");

	fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt,
		p->bindcnt);
	if (show_stats) {
		if (tb[TCA_SKBMOD_TM]) {
			struct tcf_t *tm = RTA_DATA(tb[TCA_SKBMOD_TM]);

			print_tm(f, tm);
		}
	}

	fprintf(f, "\n");

	return 0;
}

struct action_util skbmod_action_util = {
	.id = "skbmod",
	.parse_aopt = parse_skbmod,
	.print_aopt = print_skbmod,
};
