/* SPDX-License-Identifier: GPL-2.0 */
/*
 * f_tcindex.c		Traffic control index filter
 *
 * Written 1998,1999 by Werner Almesberger
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>

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

static void explain(void)
{
	fprintf(stderr,
		" Usage: ... tcindex	[ hash SIZE ] [ mask MASK ] [ shift SHIFT ]\n"
		"			[ pass_on | fall_through ]\n"
		"			[ classid CLASSID ] [ action ACTION_SPEC ]\n");
}

static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
			     char **argv, struct nlmsghdr *n)
{
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	char *end;

	if (handle) {
		t->tcm_handle = strtoul(handle, &end, 0);
		if (*end) {
			fprintf(stderr, "Illegal filter ID\n");
			return -1;
		}
	}
	if (!argc) return 0;
	tail = addattr_nest(n, 4096, TCA_OPTIONS);
	while (argc) {
		if (!strcmp(*argv, "hash")) {
			int hash;

			NEXT_ARG();
			hash = strtoul(*argv, &end, 0);
			if (*end || !hash || hash > 0x10000) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_HASH, &hash,
				  sizeof(hash));
		} else if (!strcmp(*argv,"mask")) {
			__u16 mask;

			NEXT_ARG();
			mask = strtoul(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_MASK, &mask,
				  sizeof(mask));
		} else if (!strcmp(*argv,"shift")) {
			int shift;

			NEXT_ARG();
			shift = strtoul(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_SHIFT, &shift,
			    sizeof(shift));
		} else if (!strcmp(*argv,"fall_through")) {
			int value = 1;

			addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
			    sizeof(value));
		} else if (!strcmp(*argv,"pass_on")) {
			int value = 0;

			addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
			    sizeof(value));
		} else if (!strcmp(*argv,"classid")) {
			__u32 handle;

			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4);
		} else if (!strcmp(*argv,"police")) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (!strcmp(*argv,"action")) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_TCINDEX_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;
		} else {
			explain();
			return -1;
		}
		argc--;
		argv++;
	}
	addattr_nest_end(n, tail);
	return 0;
}


static int tcindex_print_opt(struct filter_util *qu, FILE *f,
			     struct rtattr *opt, __u32 handle)
{
	struct rtattr *tb[TCA_TCINDEX_MAX+1];

	if (opt == NULL)
		return 0;

	parse_rtattr_nested(tb, TCA_TCINDEX_MAX, opt);

	if (handle != ~0) fprintf(f, "handle 0x%04x ", handle);
	if (tb[TCA_TCINDEX_HASH]) {
		__u16 hash;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH]) < sizeof(hash))
			return -1;
		hash = rta_getattr_u16(tb[TCA_TCINDEX_HASH]);
		fprintf(f, "hash %d ", hash);
	}
	if (tb[TCA_TCINDEX_MASK]) {
		__u16 mask;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK]) < sizeof(mask))
			return -1;
		mask = rta_getattr_u16(tb[TCA_TCINDEX_MASK]);
		fprintf(f, "mask 0x%04x ", mask);
	}
	if (tb[TCA_TCINDEX_SHIFT]) {
		int shift;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT]) < sizeof(shift))
			return -1;
		shift = rta_getattr_u32(tb[TCA_TCINDEX_SHIFT]);
		fprintf(f, "shift %d ", shift);
	}
	if (tb[TCA_TCINDEX_FALL_THROUGH]) {
		int fall_through;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH]) <
		    sizeof(fall_through))
			return -1;
		fall_through = rta_getattr_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
		fprintf(f, fall_through ? "fall_through " : "pass_on ");
	}
	if (tb[TCA_TCINDEX_CLASSID]) {
		SPRINT_BUF(b1);
		fprintf(f, "classid %s ", sprint_tc_classid(*(__u32 *)
		    RTA_DATA(tb[TCA_TCINDEX_CLASSID]), b1));
	}
	if (tb[TCA_TCINDEX_POLICE]) {
		fprintf(f, "\n");
		tc_print_police(f, tb[TCA_TCINDEX_POLICE]);
	}
	if (tb[TCA_TCINDEX_ACT]) {
		fprintf(f, "\n");
		tc_print_action(f, tb[TCA_TCINDEX_ACT], 0);
	}
	return 0;
}

struct filter_util tcindex_filter_util = {
	.id = "tcindex",
	.parse_fopt = tcindex_parse_opt,
	.print_fopt = tcindex_print_opt,
};
