/* SPDX-License-Identifier: GPL-2.0 */
/*
 * m_ctinfo.c		netfilter ctinfo mark action
 *
 * Copyright (c) 2019 Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "utils.h"
#include "tc_util.h"
#include <linux/tc_act/tc_ctinfo.h>

static void
explain(void)
{
	fprintf(stderr,
		"Usage: ... ctinfo [dscp mask [statemask]] [cpmark [mask]] [zone ZONE] [CONTROL] [index <INDEX>]\n"
		"where :\n"
		"\tdscp   MASK bitmask location of stored DSCP\n"
		"\t       STATEMASK bitmask to determine conditional restoring\n"
		"\tcpmark MASK mask applied to mark on restoration\n"
		"\tZONE is the conntrack zone\n"
		"\tCONTROL := reclassify | pipe | drop | continue | ok |\n"
		"\t           goto chain <CHAIN_INDEX>\n");
}

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

static int
parse_ctinfo(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
	     struct nlmsghdr *n)
{
	unsigned int cpmarkmask = 0, dscpmask = 0, dscpstatemask = 0;
	struct tc_ctinfo sel = {};
	unsigned short zone = 0;
	char **argv = *argv_p;
	struct rtattr *tail;
	int argc = *argc_p;
	int ok = 0;
	__u8 i;

	while (argc > 0) {
		if (matches(*argv, "ctinfo") == 0) {
			ok = 1;
			NEXT_ARG_FWD();
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			break;
		}

	}

	if (!ok) {
		explain();
		return -1;
	}

	if (argc) {
		if (matches(*argv, "dscp") == 0) {
			NEXT_ARG();
			if (get_u32(&dscpmask, *argv, 0)) {
				fprintf(stderr,
					"ctinfo: Illegal dscp \"mask\"\n");
				return -1;
			}
			if (NEXT_ARG_OK()) {
				NEXT_ARG_FWD();
				if (!get_u32(&dscpstatemask, *argv, 0))
					NEXT_ARG_FWD(); /* was a statemask */
			} else {
				NEXT_ARG_FWD();
			}
		}
	}

	/* cpmark has optional mask parameter, so the next arg might not  */
	/* exist, or it might be the next option, or it may actually be a */
	/* 32bit mask */
	if (argc) {
		if (matches(*argv, "cpmark") == 0) {
			cpmarkmask = ~0;
			if (NEXT_ARG_OK()) {
				NEXT_ARG_FWD();
				if (!get_u32(&cpmarkmask, *argv, 0))
					NEXT_ARG_FWD(); /* was a mask */
			} else {
				NEXT_ARG_FWD();
			}
		}
	}

	if (argc) {
		if (matches(*argv, "zone") == 0) {
			NEXT_ARG();
			if (get_u16(&zone, *argv, 10)) {
				fprintf(stderr, "ctinfo: Illegal \"zone\"\n");
				return -1;
			}
			NEXT_ARG_FWD();
		}
	}

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

	if (argc) {
		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&sel.index, *argv, 10)) {
				fprintf(stderr, "ctinfo: Illegal \"index\"\n");
				return -1;
			}
			NEXT_ARG_FWD();
		}
	}

	if (dscpmask & dscpstatemask) {
		fprintf(stderr,
			"ctinfo: dscp mask & statemask must NOT overlap\n");
		return -1;
	}

	i = ffs(dscpmask);
	if (i && ((~0 & (dscpmask >> (i - 1))) != 0x3f)) {
		fprintf(stderr,
			"ctinfo: dscp mask must be 6 contiguous bits long\n");
		return -1;
	}

	tail = addattr_nest(n, MAX_MSG, tca_id);
	addattr_l(n, MAX_MSG, TCA_CTINFO_ACT, &sel, sizeof(sel));
	addattr16(n, MAX_MSG, TCA_CTINFO_ZONE, zone);

	if (dscpmask)
		addattr32(n, MAX_MSG,
			  TCA_CTINFO_PARMS_DSCP_MASK, dscpmask);

	if (dscpstatemask)
		addattr32(n, MAX_MSG,
			  TCA_CTINFO_PARMS_DSCP_STATEMASK, dscpstatemask);

	if (cpmarkmask)
		addattr32(n, MAX_MSG,
			  TCA_CTINFO_PARMS_CPMARK_MASK, cpmarkmask);

	addattr_nest_end(n, tail);

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

static void print_ctinfo_stats(FILE *f, struct rtattr *tb[TCA_CTINFO_MAX + 1])
{
	struct tcf_t *tm;

	if (tb[TCA_CTINFO_TM]) {
		tm = RTA_DATA(tb[TCA_CTINFO_TM]);

		print_tm(f, tm);
	}

	if (tb[TCA_CTINFO_STATS_DSCP_SET])
		print_lluint(PRINT_ANY, "dscpset", " DSCP set %llu",
			     rta_getattr_u64(tb[TCA_CTINFO_STATS_DSCP_SET]));
	if (tb[TCA_CTINFO_STATS_DSCP_ERROR])
		print_lluint(PRINT_ANY, "dscperror", " error %llu",
			     rta_getattr_u64(tb[TCA_CTINFO_STATS_DSCP_ERROR]));

	if (tb[TCA_CTINFO_STATS_CPMARK_SET])
		print_lluint(PRINT_ANY, "cpmarkset", " CPMARK set %llu",
			     rta_getattr_u64(tb[TCA_CTINFO_STATS_CPMARK_SET]));
}

static int print_ctinfo(struct action_util *au, FILE *f, struct rtattr *arg)
{
	unsigned int cpmarkmask = ~0, dscpmask = 0, dscpstatemask = 0;
	struct rtattr *tb[TCA_CTINFO_MAX + 1];
	unsigned short zone = 0;
	struct tc_ctinfo *ci;

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_CTINFO_MAX, arg);
	if (!tb[TCA_CTINFO_ACT]) {
		print_string(PRINT_FP, NULL, "%s",
			     "[NULL ctinfo action parameters]");
		return -1;
	}

	ci = RTA_DATA(tb[TCA_CTINFO_ACT]);

	if (tb[TCA_CTINFO_PARMS_DSCP_MASK]) {
		if (RTA_PAYLOAD(tb[TCA_CTINFO_PARMS_DSCP_MASK]) >=
		    sizeof(__u32))
			dscpmask = rta_getattr_u32(
					tb[TCA_CTINFO_PARMS_DSCP_MASK]);
		else
			print_string(PRINT_FP, NULL, "%s",
				     "[invalid dscp mask parameter]");
	}

	if (tb[TCA_CTINFO_PARMS_DSCP_STATEMASK]) {
		if (RTA_PAYLOAD(tb[TCA_CTINFO_PARMS_DSCP_STATEMASK]) >=
		    sizeof(__u32))
			dscpstatemask = rta_getattr_u32(
					tb[TCA_CTINFO_PARMS_DSCP_STATEMASK]);
		else
			print_string(PRINT_FP, NULL, "%s",
				     "[invalid dscp statemask parameter]");
	}

	if (tb[TCA_CTINFO_PARMS_CPMARK_MASK]) {
		if (RTA_PAYLOAD(tb[TCA_CTINFO_PARMS_CPMARK_MASK]) >=
		    sizeof(__u32))
			cpmarkmask = rta_getattr_u32(
					tb[TCA_CTINFO_PARMS_CPMARK_MASK]);
		else
			print_string(PRINT_FP, NULL, "%s",
				     "[invalid cpmark mask parameter]");
	}

	if (tb[TCA_CTINFO_ZONE] && RTA_PAYLOAD(tb[TCA_CTINFO_ZONE]) >=
	    sizeof(__u16))
		zone = rta_getattr_u16(tb[TCA_CTINFO_ZONE]);

	print_string(PRINT_ANY, "kind", "%s ", "ctinfo");
	print_hu(PRINT_ANY, "zone", "zone %u", zone);
	print_action_control(f, " ", ci->action, "");

	print_string(PRINT_FP, NULL, "%s", _SL_);
	print_uint(PRINT_ANY, "index", "\t index %u", ci->index);
	print_int(PRINT_ANY, "ref", " ref %d", ci->refcnt);
	print_int(PRINT_ANY, "bind", " bind %d", ci->bindcnt);

	if (tb[TCA_CTINFO_PARMS_DSCP_MASK]) {
		print_0xhex(PRINT_ANY, "dscpmask", " dscp %#010llx", dscpmask);
		print_0xhex(PRINT_ANY, "dscpstatemask", " %#010llx",
			    dscpstatemask);
	}

	if (tb[TCA_CTINFO_PARMS_CPMARK_MASK])
		print_0xhex(PRINT_ANY, "cpmark", " cpmark %#010llx",
			    cpmarkmask);

	if (show_stats)
		print_ctinfo_stats(f, tb);

	print_string(PRINT_FP, NULL, "%s", _SL_);

	return 0;
}

struct action_util ctinfo_action_util = {
	.id = "ctinfo",
	.parse_aopt = parse_ctinfo,
	.print_aopt = print_ctinfo,
};
