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

#include "nl-default.h"

#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/qdisc.h>
#include <netlink/route/class.h>
#include <netlink/route/link.h>
#include <netlink/route/qdisc/cbq.h>
#include <netlink/route/cls/police.h>

#include "tc-api.h"

struct rtnl_cbq {
	struct tc_cbq_lssopt cbq_lss;
	struct tc_ratespec cbq_rate;
	struct tc_cbq_wrropt cbq_wrr;
	struct tc_cbq_ovl cbq_ovl;
	struct tc_cbq_fopt cbq_fopt;
	struct tc_cbq_police cbq_police;
};

/**
 * @ingroup qdisc
 * @ingroup class
 * @defgroup qdisc_cbq Class Based Queueing (CBQ)
 * @{
 */

static const struct trans_tbl ovl_strategies[] = {
	__ADD(TC_CBQ_OVL_CLASSIC,classic),
	__ADD(TC_CBQ_OVL_DELAY,delay),
	__ADD(TC_CBQ_OVL_LOWPRIO,lowprio),
	__ADD(TC_CBQ_OVL_DROP,drop),
	__ADD(TC_CBQ_OVL_RCLASSIC,rclassic),
};

/**
 * Convert a CBQ OVL strategy to a character string
 * @arg type		CBQ OVL strategy
 * @arg buf		destination buffer
 * @arg len		length of destination buffer
 *
 * Converts a CBQ OVL strategy to a character string and stores in the
 * provided buffer. Returns the destination buffer or the type
 * encoded in hex if no match was found.
 */
char *nl_ovl_strategy2str(int type, char *buf, size_t len)
{
	return __type2str(type, buf, len, ovl_strategies,
			    ARRAY_SIZE(ovl_strategies));
}

/**
 * Convert a string to a CBQ OVL strategy
 * @arg name		CBQ OVL stragegy name
 *
 * Converts a CBQ OVL stragegy name to it's corresponding CBQ OVL strategy
 * type. Returns the type or -1 if none was found.
 */
int nl_str2ovl_strategy(const char *name)
{
	return __str2type(name, ovl_strategies, ARRAY_SIZE(ovl_strategies));
}

static struct nla_policy cbq_policy[TCA_CBQ_MAX+1] = {
	[TCA_CBQ_LSSOPT]	= { .minlen = sizeof(struct tc_cbq_lssopt) },
	[TCA_CBQ_RATE]		= { .minlen = sizeof(struct tc_ratespec) },
	[TCA_CBQ_WRROPT]	= { .minlen = sizeof(struct tc_cbq_wrropt) },
	[TCA_CBQ_OVL_STRATEGY]	= { .minlen = sizeof(struct tc_cbq_ovl) },
	[TCA_CBQ_FOPT]		= { .minlen = sizeof(struct tc_cbq_fopt) },
	[TCA_CBQ_POLICE]	= { .minlen = sizeof(struct tc_cbq_police) },
};

static int cbq_msg_parser(struct rtnl_tc *tc, void *data)
{
	struct nlattr *tb[TCA_CBQ_MAX + 1];
	struct rtnl_cbq *cbq = data;
	int err;

	err = tca_parse(tb, TCA_CBQ_MAX, tc, cbq_policy);
	if (err < 0)
		return err;

	nla_memcpy(&cbq->cbq_lss, tb[TCA_CBQ_LSSOPT], sizeof(cbq->cbq_lss));
	nla_memcpy(&cbq->cbq_rate, tb[TCA_CBQ_RATE], sizeof(cbq->cbq_rate));
	nla_memcpy(&cbq->cbq_wrr, tb[TCA_CBQ_WRROPT], sizeof(cbq->cbq_wrr));
	nla_memcpy(&cbq->cbq_fopt, tb[TCA_CBQ_FOPT], sizeof(cbq->cbq_fopt));
	nla_memcpy(&cbq->cbq_ovl, tb[TCA_CBQ_OVL_STRATEGY],
		   sizeof(cbq->cbq_ovl));
	nla_memcpy(&cbq->cbq_police, tb[TCA_CBQ_POLICE],
		    sizeof(cbq->cbq_police));
	
	return 0;
}

static void cbq_dump_line(struct rtnl_tc *tc, void *data,
			  struct nl_dump_params *p)
{
	struct rtnl_cbq *cbq = data;
	double r, rbit;
	char *ru, *rubit;

	if (!cbq)
		return;

	r = nl_cancel_down_bytes(cbq->cbq_rate.rate, &ru);
	rbit = nl_cancel_down_bits(cbq->cbq_rate.rate * 8, &rubit);

	nl_dump(p, " rate %.2f%s/s (%.0f%s) prio %u",
		r, ru, rbit, rubit, cbq->cbq_wrr.priority);
}

static void cbq_dump_details(struct rtnl_tc *tc, void *data,
			     struct nl_dump_params *p)
{
	struct rtnl_cbq *cbq = data;
	char *unit, buf[32];
	double w;
	uint32_t el;

	if (!cbq)
		return;

	w = nl_cancel_down_bits(cbq->cbq_wrr.weight * 8, &unit);

	nl_dump(p, "avgpkt %u mpu %u cell %u allot %u weight %.0f%s\n",
		cbq->cbq_lss.avpkt,
		cbq->cbq_rate.mpu,
		1 << cbq->cbq_rate.cell_log,
		cbq->cbq_wrr.allot, w, unit);

	el = cbq->cbq_lss.ewma_log;
	nl_dump_line(p, "  minidle %uus maxidle %uus offtime "
				"%uus level %u ewma_log %u\n",
		nl_ticks2us(cbq->cbq_lss.minidle >> el),
		nl_ticks2us(cbq->cbq_lss.maxidle >> el),
		nl_ticks2us(cbq->cbq_lss.offtime >> el),
		cbq->cbq_lss.level,
		cbq->cbq_lss.ewma_log);

	nl_dump_line(p, "  penalty %uus strategy %s ",
		nl_ticks2us(cbq->cbq_ovl.penalty),
		nl_ovl_strategy2str(cbq->cbq_ovl.strategy, buf, sizeof(buf)));

	nl_dump(p, "split %s defmap 0x%08x ",
		rtnl_tc_handle2str(cbq->cbq_fopt.split, buf, sizeof(buf)),
		cbq->cbq_fopt.defmap);
	
	nl_dump(p, "police %s",
		nl_police2str(cbq->cbq_police.police, buf, sizeof(buf)));
}

static void cbq_dump_stats(struct rtnl_tc *tc, void *data,
			   struct nl_dump_params *p)
{
	struct tc_cbq_xstats *x;
	
	if (!(x = tca_xstats(tc)))
		return;

	nl_dump_line(p, "            borrows    overact  "
			"  avgidle  undertime\n");
	nl_dump_line(p, "         %10u %10u %10u %10u\n",
		     x->borrows, x->overactions, x->avgidle, x->undertime);
}

static struct rtnl_tc_ops cbq_qdisc_ops = {
	.to_kind		= "cbq",
	.to_type		= RTNL_TC_TYPE_QDISC,
	.to_size		= sizeof(struct rtnl_cbq),
	.to_msg_parser		= cbq_msg_parser,
	.to_dump = {
	    [NL_DUMP_LINE]	= cbq_dump_line,
	    [NL_DUMP_DETAILS]	= cbq_dump_details,
	    [NL_DUMP_STATS]	= cbq_dump_stats,
	},
};

static struct rtnl_tc_ops cbq_class_ops = {
	.to_kind		= "cbq",
	.to_type		= RTNL_TC_TYPE_CLASS,
	.to_size		= sizeof(struct rtnl_cbq),
	.to_msg_parser		= cbq_msg_parser,
	.to_dump = {
	    [NL_DUMP_LINE]	= cbq_dump_line,
	    [NL_DUMP_DETAILS]	= cbq_dump_details,
	    [NL_DUMP_STATS]	= cbq_dump_stats,
	},
};

static void _nl_init cbq_init(void)
{
	rtnl_tc_register(&cbq_qdisc_ops);
	rtnl_tc_register(&cbq_class_ops);
}

static void _nl_exit cbq_exit(void)
{
	rtnl_tc_unregister(&cbq_qdisc_ops);
	rtnl_tc_unregister(&cbq_class_ops);
}

/** @} */
