/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @ingroup cls
 * @defgroup cls_basic Basic Classifier
 *
 * @par Introduction
 * The basic classifier is the simplest form of a classifier. It does
 * not have any special classification capabilities, instead it can be
 * used to classify exclusively based on extended matches or to
 * create a "catch-all" filter.
 *
 * @{
 */

#include "nl-default.h"

#include <netlink/netlink.h>
#include <netlink/route/classifier.h>
#include <netlink/route/action.h>
#include <netlink/route/cls/basic.h>
#include <netlink/route/cls/ematch.h>

#include "tc-api.h"
#include "nl-aux-route/nl-route.h"

struct rtnl_basic
{
	uint32_t			b_target;
	struct rtnl_ematch_tree *	b_ematch;
	int				b_mask;
	struct rtnl_act *		b_act;
};

/** @cond SKIP */
#define BASIC_ATTR_TARGET	0x001
#define BASIC_ATTR_EMATCH	0x002
#define BASIC_ATTR_ACTION	0x004
/** @endcond */

static struct nla_policy basic_policy[TCA_BASIC_MAX+1] = {
	[TCA_BASIC_CLASSID]	= { .type = NLA_U32 },
	[TCA_BASIC_EMATCHES]	= { .type = NLA_NESTED },
};

static int basic_clone(void *_dst, void *_src)
{
	return -NLE_OPNOTSUPP;
}

static void basic_free_data(struct rtnl_tc *tc, void *data)
{
	struct rtnl_basic *b = data;

	if (!b)
		return;

	if (b->b_act)
		rtnl_act_put_all(&b->b_act);
	rtnl_ematch_tree_free(b->b_ematch);
}

static int basic_msg_parser(struct rtnl_tc *tc, void *data)
{
	struct nlattr *tb[TCA_BASIC_MAX + 1];
	struct rtnl_basic *b = data;
	int err;

	err = tca_parse(tb, TCA_BASIC_MAX, tc, basic_policy);
	if (err < 0)
		return err;

	if (tb[TCA_BASIC_CLASSID]) {
		b->b_target = nla_get_u32(tb[TCA_BASIC_CLASSID]);
		b->b_mask |= BASIC_ATTR_TARGET;
	}

	if (tb[TCA_BASIC_EMATCHES]) {
		if ((err = rtnl_ematch_parse_attr(tb[TCA_BASIC_EMATCHES],
					     &b->b_ematch)) < 0)
			return err;

		if (b->b_ematch)
			b->b_mask |= BASIC_ATTR_EMATCH;
	}
	if (tb[TCA_BASIC_ACT]) {
		b->b_mask |= BASIC_ATTR_ACTION;
		err = rtnl_act_parse(&b->b_act, tb[TCA_BASIC_ACT]);
		if (err < 0)
			return err;
	}

	return 0;
}

static void basic_dump_line(struct rtnl_tc *tc, void *data,
			    struct nl_dump_params *p)
{
	struct rtnl_basic *b = data;
	char buf[32];

	if (!b)
		return;

	if (b->b_mask & BASIC_ATTR_EMATCH)
		nl_dump(p, " ematch");
	else
		nl_dump(p, " match-all");

	if (b->b_mask & BASIC_ATTR_TARGET)
		nl_dump(p, " target %s",
			rtnl_tc_handle2str(b->b_target, buf, sizeof(buf)));
}

static void basic_dump_details(struct rtnl_tc *tc, void *data,
			       struct nl_dump_params *p)
{
	struct rtnl_basic *b = data;

	if (!b)
		return;

	if (b->b_mask & BASIC_ATTR_EMATCH) {
		nl_dump_line(p, "    ematch ");
		rtnl_ematch_tree_dump(b->b_ematch, p);
	} else
		nl_dump(p, "no options.\n");
}

static int basic_msg_fill(struct rtnl_tc *tc, void *data,
			  struct nl_msg *msg)
{
	struct rtnl_basic *b = data;

	if (!b)
		return 0;

	if (b->b_mask & BASIC_ATTR_TARGET)
		NLA_PUT_U32(msg, TCA_BASIC_CLASSID, b->b_target);

	if (b->b_mask & BASIC_ATTR_EMATCH &&
	    rtnl_ematch_fill_attr(msg, TCA_BASIC_EMATCHES, b->b_ematch) < 0)
		goto nla_put_failure;

	if (b->b_mask & BASIC_ATTR_ACTION) {
		int err;

		err = rtnl_act_fill(msg, TCA_BASIC_ACT, b->b_act);
		if (err)
			return err;
	}

	return 0;

nla_put_failure:
	return -NLE_NOMEM;
}

/**
 * @name Attribute Modifications
 * @{
 */

void rtnl_basic_set_target(struct rtnl_cls *cls, uint32_t target)
{
	struct rtnl_basic *b;

	if (!(b = rtnl_tc_data(TC_CAST(cls))))
		return;

	b->b_target = target;
	b->b_mask |= BASIC_ATTR_TARGET;
}

uint32_t rtnl_basic_get_target(struct rtnl_cls *cls)
{
	struct rtnl_basic *b;

	if (!(b = rtnl_tc_data(TC_CAST(cls))))
		return 0;

	return b->b_target;
}

void rtnl_basic_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
{
	struct rtnl_basic *b;

	if (!(b = rtnl_tc_data(TC_CAST(cls))))
		return;

	if (b->b_ematch) {
		rtnl_ematch_tree_free(b->b_ematch);
		b->b_mask &= ~BASIC_ATTR_EMATCH;
	}

	b->b_ematch = tree;

	if (tree)
		b->b_mask |= BASIC_ATTR_EMATCH;
}

struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *cls)
{
	struct rtnl_basic *b;

	if (!(b = rtnl_tc_data(TC_CAST(cls))))
		return NULL;

	return b->b_ematch;
}

int rtnl_basic_add_action(struct rtnl_cls *cls, struct rtnl_act *act)
{
	struct rtnl_basic *b;
	int err;

	if (!act)
		return 0;

	if (!(b = rtnl_tc_data(TC_CAST(cls))))
		return -NLE_NOMEM;

	if ((err = _rtnl_act_append_get(&b->b_act, act)) < 0)
		return err;

	b->b_mask |= BASIC_ATTR_ACTION;
	return 0;
}

struct rtnl_act* rtnl_basic_get_action(struct rtnl_cls *cls)
{
	struct rtnl_basic *b;

	if (!(b = rtnl_tc_data_peek(TC_CAST(cls))))
		return NULL;

	if (!(b->b_mask & BASIC_ATTR_ACTION))
		return NULL;

	return b->b_act;
}

int rtnl_basic_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
{
	struct rtnl_basic *b;
	int ret;

	if (!act)
		return 0;

	if (!(b = rtnl_tc_data(TC_CAST(cls))))
		return -NLE_NOMEM;

	if (!(b->b_mask & BASIC_ATTR_ACTION))
		return -NLE_INVAL;
	ret = rtnl_act_remove(&b->b_act, act);
	if (ret)
		return ret;

	if (!b->b_act)
		b->b_mask &= ~BASIC_ATTR_ACTION;
	rtnl_act_put(act);
	return 0;
}
/** @} */

static struct rtnl_tc_ops basic_ops = {
	.to_kind		= "basic",
	.to_type		= RTNL_TC_TYPE_CLS,
	.to_size		= sizeof(struct rtnl_basic),
	.to_msg_parser		= basic_msg_parser,
	.to_clone		= basic_clone,
	.to_free_data		= basic_free_data,
	.to_msg_fill		= basic_msg_fill,
	.to_dump = {
	    [NL_DUMP_LINE]	= basic_dump_line,
	    [NL_DUMP_DETAILS]	= basic_dump_details,
	},
};

static void _nl_init basic_init(void)
{
	rtnl_tc_register(&basic_ops);
}

static void _nl_exit basic_exit(void)
{
	rtnl_tc_unregister(&basic_ops);
}

/** @} */
