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

/**
 * @ingroup qdisc
 * @defgroup qdisc_prio (Fast) Prio
 * @brief
 *
 * @par 1) Typical PRIO configuration
 * @code
 * // Specify the maximal number of bands to be used for this PRIO qdisc.
 * rtnl_qdisc_prio_set_bands(qdisc, QDISC_PRIO_DEFAULT_BANDS);
 *
 * // Provide a map assigning each priority to a band number.
 * uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP;
 * rtnl_qdisc_prio_set_priomap(qdisc, map, sizeof(map));
 * @endcode
 * @{
 */

#include "nl-default.h"

#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/qdisc.h>
#include <netlink/route/qdisc/prio.h>

#include "tc-api.h"

/** @cond SKIP */
struct rtnl_prio {
	uint32_t qp_bands;
	uint8_t qp_priomap[TC_PRIO_MAX + 1];
	uint32_t qp_mask;
};

#define SCH_PRIO_ATTR_BANDS	1
#define SCH_PRIO_ATTR_PRIOMAP	2
/** @endcond */

static int prio_msg_parser(struct rtnl_tc *tc, void *data)
{
	struct rtnl_prio *prio = data;
	struct tc_prio_qopt *opt;

	if (tc->tc_opts->d_size < sizeof(*opt))
		return -NLE_INVAL;

	opt = (struct tc_prio_qopt *) tc->tc_opts->d_data;
	prio->qp_bands = opt->bands;
	memcpy(prio->qp_priomap, opt->priomap, sizeof(prio->qp_priomap));
	prio->qp_mask = (SCH_PRIO_ATTR_BANDS | SCH_PRIO_ATTR_PRIOMAP);
	
	return 0;
}

static void prio_dump_line(struct rtnl_tc *tc, void *data,
			   struct nl_dump_params *p)
{
	struct rtnl_prio *prio = data;

	if (prio)
		nl_dump(p, " bands %u", prio->qp_bands);
}

static void prio_dump_details(struct rtnl_tc *tc, void *data,
			      struct nl_dump_params *p)
{
	struct rtnl_prio *prio = data;
	int i, hp;

	if (!prio)
		return;

	nl_dump(p, "priomap [");
	
	for (i = 0; i <= TC_PRIO_MAX; i++)
		nl_dump(p, "%u%s", prio->qp_priomap[i],
			i < TC_PRIO_MAX ? " " : "");

	nl_dump(p, "]\n");
	nl_new_line(p);

	hp = (((TC_PRIO_MAX/2) + 1) & ~1);

	for (i = 0; i < hp; i++) {
		char a[32];
		nl_dump(p, "    %18s => %u",
			rtnl_prio2str(i, a, sizeof(a)),
			prio->qp_priomap[i]);
		if (hp+i <= TC_PRIO_MAX) {
			nl_dump(p, " %18s => %u",
				rtnl_prio2str(hp+i, a, sizeof(a)),
				prio->qp_priomap[hp+i]);
			if (i < (hp - 1)) {
				nl_dump(p, "\n");
				nl_new_line(p);
			}
		}
	}
}

static int prio_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
{
	struct rtnl_prio *prio = data;
	struct tc_prio_qopt opts;

	if (!prio || !(prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP))
		BUG();

	opts.bands = prio->qp_bands;
	memcpy(opts.priomap, prio->qp_priomap, sizeof(opts.priomap));

	return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD);
}

/**
 * @name Attribute Modification
 * @{
 */

/**
 * Set number of bands of PRIO qdisc.
 * @arg qdisc		PRIO qdisc to be modified.
 * @arg bands		New number of bands.
 * @return 0 on success or a negative error code.
 */
void rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *qdisc, int bands)
{
	struct rtnl_prio *prio;

	if (!(prio = rtnl_tc_data(TC_CAST(qdisc))))
		BUG();

	prio->qp_bands = bands;
	prio->qp_mask |= SCH_PRIO_ATTR_BANDS;
}

/**
 * Get number of bands of PRIO qdisc.
 * @arg qdisc		PRIO qdisc.
 * @return Number of bands or a negative error code.
 */
int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *qdisc)
{
	struct rtnl_prio *prio;

	if (!(prio = rtnl_tc_data(TC_CAST(qdisc))))
		BUG();

	if (prio->qp_mask & SCH_PRIO_ATTR_BANDS)
		return prio->qp_bands;
	else
		return -NLE_NOMEM;
}

/**
 * Set priomap of the PRIO qdisc.
 * @arg qdisc		PRIO qdisc to be modified.
 * @arg priomap		New priority mapping.
 * @arg len		Length of priomap (# of elements).
 * @return 0 on success or a negative error code.
 */
int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[],
				int len)
{
	struct rtnl_prio *prio;
	int i;

	if (!(prio = rtnl_tc_data(TC_CAST(qdisc))))
		BUG();

	if (!(prio->qp_mask & SCH_PRIO_ATTR_BANDS))
		return -NLE_MISSING_ATTR;

	if ((len / sizeof(uint8_t)) > (TC_PRIO_MAX+1))
		return -NLE_RANGE;

	for (i = 0; i <= TC_PRIO_MAX; i++) {
		if (priomap[i] > prio->qp_bands)
			return -NLE_RANGE;
	}

	memcpy(prio->qp_priomap, priomap, len);
	prio->qp_mask |= SCH_PRIO_ATTR_PRIOMAP;

	return 0;
}

/**
 * Get priomap of a PRIO qdisc.
 * @arg qdisc		PRIO qdisc.
 * @return Priority mapping as array of size TC_PRIO_MAX+1
 *         or NULL if an error occured.
 */
uint8_t *rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *qdisc)
{
	struct rtnl_prio *prio;

	if (!(prio = rtnl_tc_data(TC_CAST(qdisc))))
		BUG();

	if (prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP)
		return prio->qp_priomap;
	else
		return NULL;
}

/** @} */

/**
 * @name Priority Band Translations
 * @{
 */

static const struct trans_tbl prios[] = {
	__ADD(TC_PRIO_BESTEFFORT,besteffort),
	__ADD(TC_PRIO_FILLER,filler),
	__ADD(TC_PRIO_BULK,bulk),
	__ADD(TC_PRIO_INTERACTIVE_BULK,interactive_bulk),
	__ADD(TC_PRIO_INTERACTIVE,interactive),
	__ADD(TC_PRIO_CONTROL,control),
};

/**
 * Convert priority to character string.
 * @arg prio		Priority.
 * @arg buf		Destination buffer
 * @arg size		Size of destination buffer.
 *
 * Converts a priority to a character string and stores the result in
 * the specified destination buffer.
 *
 * @return Name of priority as character string.
 */
char * rtnl_prio2str(int prio, char *buf, size_t size)
{
	return __type2str(prio, buf, size, prios, ARRAY_SIZE(prios));
}

/**
 * Convert character string to priority.
 * @arg name		Name of priority.
 *
 * Converts the provided character string specifying a priority
 * to the corresponding numeric value.
 *
 * @return Numeric priority or a negative value if no match was found.
 */
int rtnl_str2prio(const char *name)
{
	return __str2type(name, prios, ARRAY_SIZE(prios));
}

/** @} */

static struct rtnl_tc_ops prio_ops = {
	.to_kind		= "prio",
	.to_type		= RTNL_TC_TYPE_QDISC,
	.to_size		= sizeof(struct rtnl_prio),
	.to_msg_parser		= prio_msg_parser,
	.to_dump = {
	    [NL_DUMP_LINE]	= prio_dump_line,
	    [NL_DUMP_DETAILS]	= prio_dump_details,
	},
	.to_msg_fill		= prio_msg_fill,
};

static struct rtnl_tc_ops pfifo_fast_ops = {
	.to_kind		= "pfifo_fast",
	.to_type		= RTNL_TC_TYPE_QDISC,
	.to_size		= sizeof(struct rtnl_prio),
	.to_msg_parser		= prio_msg_parser,
	.to_dump = {
	    [NL_DUMP_LINE]	= prio_dump_line,
	    [NL_DUMP_DETAILS]	= prio_dump_details,
	},
	.to_msg_fill		= prio_msg_fill,
};

static void _nl_init prio_init(void)
{
	rtnl_tc_register(&prio_ops);
	rtnl_tc_register(&pfifo_fast_ops);
}

static void _nl_exit prio_exit(void)
{
	rtnl_tc_unregister(&prio_ops);
	rtnl_tc_unregister(&pfifo_fast_ops);
}

/** @} */
