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

/**
 * @ingroup qdisc
 * @defgroup qdisc_tbf Token Bucket Filter (TBF)
 * @{
 */

#include "nl-default.h"

#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
#include <netlink/route/qdisc.h>
#include <netlink/route/class.h>
#include <netlink/route/link.h>
#include <netlink/route/qdisc/tbf.h>

#include "tc-api.h"

/** @cond SKIP */
struct rtnl_tbf {
	uint32_t qt_limit;
	struct rtnl_ratespec qt_rate;
	uint32_t qt_rate_bucket;
	uint32_t qt_rate_txtime;
	struct rtnl_ratespec qt_peakrate;
	uint32_t qt_peakrate_bucket;
	uint32_t qt_peakrate_txtime;
	uint32_t qt_mask;
};

#define TBF_ATTR_LIMIT			0x01
#define TBF_ATTR_RATE			0x02
#define TBF_ATTR_PEAKRATE		0x10
/** @endcond */

static struct nla_policy tbf_policy[TCA_TBF_MAX+1] = {
	[TCA_TBF_PARMS]	= { .minlen = sizeof(struct tc_tbf_qopt) },
};

static int tbf_msg_parser(struct rtnl_tc *tc, void *data)
{
	struct nlattr *tb[TCA_TBF_MAX + 1];
	struct rtnl_tbf *tbf = data;
	int err;

	if ((err = tca_parse(tb, TCA_TBF_MAX, tc, tbf_policy)) < 0)
		return err;

	if (tb[TCA_TBF_PARMS]) {
		struct tc_tbf_qopt opts;
		int bufsize;

		nla_memcpy(&opts, tb[TCA_TBF_PARMS], sizeof(opts));
		tbf->qt_limit = opts.limit;

		rtnl_copy_ratespec(&tbf->qt_rate, &opts.rate);
		tbf->qt_rate_txtime = opts.buffer;
		bufsize = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.buffer),
		                                 tbf->qt_rate.rs_rate64);
		tbf->qt_rate_bucket = bufsize;

		rtnl_copy_ratespec(&tbf->qt_peakrate, &opts.peakrate);
		tbf->qt_peakrate_txtime = opts.mtu;
		bufsize = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.mtu),
		                                 tbf->qt_peakrate.rs_rate64);
		tbf->qt_peakrate_bucket = bufsize;

		rtnl_tc_set_mpu(tc, tbf->qt_rate.rs_mpu);
		rtnl_tc_set_overhead(tc, tbf->qt_rate.rs_overhead);

		tbf->qt_mask = (TBF_ATTR_LIMIT | TBF_ATTR_RATE | TBF_ATTR_PEAKRATE);
	}

	return 0;
}

static void tbf_dump_line(struct rtnl_tc *tc, void *data,
			  struct nl_dump_params *p)
{
	double r, rbit, lim;
	char *ru, *rubit, *limu;
	struct rtnl_tbf *tbf = data;

	if (!tbf)
		return;

	r = nl_cancel_down_bytes(tbf->qt_rate.rs_rate64, &ru);
	rbit = nl_cancel_down_bits(tbf->qt_rate.rs_rate64*8, &rubit);
	lim = nl_cancel_down_bytes(tbf->qt_limit, &limu);

	nl_dump(p, " rate %.2f%s/s (%.0f%s) limit %.2f%s",
		r, ru, rbit, rubit, lim, limu);
}

static void tbf_dump_details(struct rtnl_tc *tc, void *data,
			     struct nl_dump_params *p)
{
	struct rtnl_tbf *tbf = data;

	if (!tbf)
		return;

	if (1) {
		char *bu, *cu;
		double bs = nl_cancel_down_bytes(tbf->qt_rate_bucket, &bu);
		double cl = nl_cancel_down_bytes(1 << tbf->qt_rate.rs_cell_log,
						 &cu);

		nl_dump(p, "rate-bucket-size %1.f%s "
			   "rate-cell-size %.1f%s\n",
			bs, bu, cl, cu);

	}

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE) {
		char *pru, *prbu, *bsu, *clu;
		double pr, prb, bs, cl;

		pr = nl_cancel_down_bytes(tbf->qt_peakrate.rs_rate64, &pru);
		prb = nl_cancel_down_bits(tbf->qt_peakrate.rs_rate64 * 8, &prbu);
		bs = nl_cancel_down_bits(tbf->qt_peakrate_bucket, &bsu);
		cl = nl_cancel_down_bits(1 << tbf->qt_peakrate.rs_cell_log,
					 &clu);

		nl_dump_line(p,
			     "    peak-rate %.2f%s/s (%.0f%s) "
			     "bucket-size %.1f%s cell-size %.1f%s",
			     pr, pru, prb, prbu, bs, bsu, cl, clu);
	}
}

static int tbf_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
{
	uint32_t rtab[RTNL_TC_RTABLE_SIZE], ptab[RTNL_TC_RTABLE_SIZE];
	struct tc_tbf_qopt opts;
	struct rtnl_tbf *tbf = data;
	int required = TBF_ATTR_RATE | TBF_ATTR_LIMIT;

	if ((tbf->qt_mask & required) != required)
		return -NLE_MISSING_ATTR;

	memset(&opts, 0, sizeof(opts));
	opts.limit = tbf->qt_limit;
	opts.buffer = tbf->qt_rate_txtime;

	rtnl_tc_build_rate_table(tc, &tbf->qt_rate, rtab);
	rtnl_rcopy_ratespec(&opts.rate, &tbf->qt_rate);

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE) {
		opts.mtu = tbf->qt_peakrate_txtime;
		rtnl_tc_build_rate_table(tc, &tbf->qt_peakrate, ptab);
		rtnl_rcopy_ratespec(&opts.peakrate, &tbf->qt_peakrate);

	}

	NLA_PUT(msg, TCA_TBF_PARMS, sizeof(opts), &opts);
	NLA_PUT(msg, TCA_TBF_RTAB, sizeof(rtab), rtab);

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE)
		NLA_PUT(msg, TCA_TBF_PTAB, sizeof(ptab), ptab);

	return 0;

nla_put_failure:
	return -NLE_MSGSIZE;
}

/**
 * @name Attribute Access
 * @{
 */

/**
 * Set limit of TBF qdisc.
 * @arg qdisc		TBF qdisc to be modified.
 * @arg limit		New limit in bytes.
 * @return 0 on success or a negative error code.
 */
void rtnl_qdisc_tbf_set_limit(struct rtnl_qdisc *qdisc, int limit)
{
	struct rtnl_tbf *tbf;
	
	if (!(tbf = rtnl_tc_data(TC_CAST(qdisc))))
		BUG();

	tbf->qt_limit = limit;
	tbf->qt_mask |= TBF_ATTR_LIMIT;
}

static inline double calc_limit(struct rtnl_ratespec *spec, int latency,
				int bucket)
{
	double limit;

	limit = (double) spec->rs_rate64 * ((double) latency / 1000000.);
	limit += bucket;

	return limit;
}

/**
 * Set limit of TBF qdisc by latency.
 * @arg qdisc		TBF qdisc to be modified.
 * @arg latency		Latency in micro seconds.
 *
 * Calculates and sets the limit based on the desired latency and the
 * configured rate and peak rate. In order for this operation to succeed,
 * the rate and if required the peak rate must have been set in advance.
 *
 * @f[
 *   limit_n = \frac{{rate_n} \times {latency}}{10^6}+{bucketsize}_n
 * @f]
 * @f[
 *   limit = min(limit_{rate},limit_{peak})
 * @f]
 * 
 * @return 0 on success or a negative error code.
 */
int rtnl_qdisc_tbf_set_limit_by_latency(struct rtnl_qdisc *qdisc, int latency)
{
	struct rtnl_tbf *tbf;
	double limit, limit2;

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

	if (!(tbf->qt_mask & TBF_ATTR_RATE))
		return -NLE_MISSING_ATTR;

	limit = calc_limit(&tbf->qt_rate, latency, tbf->qt_rate_bucket);

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE) {
		limit2 = calc_limit(&tbf->qt_peakrate, latency,
				    tbf->qt_peakrate_bucket);

		if (limit2 < limit)
			limit = limit2;
	}

	rtnl_qdisc_tbf_set_limit(qdisc, (int) limit);

	return 0;
}

/**
 * Get limit of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Limit in bytes or a negative error code.
 */
int rtnl_qdisc_tbf_get_limit(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;
	
	if (!(tbf = rtnl_tc_data(TC_CAST(qdisc))))
		BUG();

	if (tbf->qt_mask & TBF_ATTR_LIMIT)
		return tbf->qt_limit;
	else
		return -NLE_NOATTR;
}

static inline int calc_cell_log(int cell, int bucket)
{
		cell = rtnl_tc_calc_cell_log(cell);
	return cell;
}

/**
 * Set rate of TBF qdisc.
 * @arg qdisc		TBF qdisc to be modified.
 * @arg rate		New rate in bytes per second.
 * @arg bucket		Size of bucket in bytes.
 * @arg cell		Size of a rate cell or 0 to get default value.
 * @return 0 on success or a negative error code.
 */
void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *qdisc, int rate, int bucket,
			    int cell)
{
	struct rtnl_tbf *tbf;
	int cell_log;

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

	if (!cell)
		cell_log = UINT8_MAX;
	else
		cell_log = rtnl_tc_calc_cell_log(cell);

	tbf->qt_rate.rs_rate64 = (uint32_t)rate;
	tbf->qt_rate_bucket = bucket;
	tbf->qt_rate.rs_cell_log = cell_log;
	tbf->qt_rate_txtime = nl_us2ticks(rtnl_tc_calc_txtime64(bucket, tbf->qt_rate.rs_rate64));
	tbf->qt_mask |= TBF_ATTR_RATE;
}

/**
 * Get rate of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Rate in bytes per seconds or a negative error code.
 */
int rtnl_qdisc_tbf_get_rate(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;

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

	if (tbf->qt_mask & TBF_ATTR_RATE)
		return tbf->qt_rate.rs_rate64;
	else
		return -1;
}

/**
 * Get rate bucket size of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Size of rate bucket or a negative error code.
 */
int rtnl_qdisc_tbf_get_rate_bucket(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;

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

	if (tbf->qt_mask & TBF_ATTR_RATE)
		return tbf->qt_rate_bucket;
	else
		return -1;
}

/**
 * Get rate cell size of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Size of rate cell in bytes or a negative error code.
 */
int rtnl_qdisc_tbf_get_rate_cell(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;

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

	if (tbf->qt_mask & TBF_ATTR_RATE)
		return (1 << tbf->qt_rate.rs_cell_log);
	else
		return -1;
}

/**
 * Set peak rate of TBF qdisc.
 * @arg qdisc		TBF qdisc to be modified.
 * @arg rate		New peak rate in bytes per second.
 * @arg bucket		Size of peakrate bucket.
 * @arg cell		Size of a peakrate cell or 0 to get default value.
 * @return 0 on success or a negative error code.
 */
int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *qdisc, int rate, int bucket,
				int cell)
{
	struct rtnl_tbf *tbf;
	int cell_log;

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

	cell_log = calc_cell_log(cell, bucket);
	if (cell_log < 0)
		return cell_log;

	tbf->qt_peakrate.rs_rate64 = (uint32_t)rate;
	tbf->qt_peakrate_bucket = bucket;
	tbf->qt_peakrate.rs_cell_log = cell_log;
	tbf->qt_peakrate_txtime = nl_us2ticks(rtnl_tc_calc_txtime64(bucket, tbf->qt_peakrate.rs_rate64));

	tbf->qt_mask |= TBF_ATTR_PEAKRATE;

	return 0;
}

/**
 * Get peak rate of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Peak rate in bytes per seconds or a negative error code.
 */
int rtnl_qdisc_tbf_get_peakrate(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;

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

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE)
		return tbf->qt_peakrate.rs_rate64;
	else
		return -1;
}

/**
 * Get peak rate bucket size of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Size of peak rate bucket or a negative error code.
 */
int rtnl_qdisc_tbf_get_peakrate_bucket(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;

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

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE)
		return tbf->qt_peakrate_bucket;
	else
		return -1;
}

/**
 * Get peak rate cell size of TBF qdisc.
 * @arg qdisc		TBF qdisc.
 * @return Size of peak rate cell in bytes or a negative error code.
 */
int rtnl_qdisc_tbf_get_peakrate_cell(struct rtnl_qdisc *qdisc)
{
	struct rtnl_tbf *tbf;

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

	if (tbf->qt_mask & TBF_ATTR_PEAKRATE)
		return (1 << tbf->qt_peakrate.rs_cell_log);
	else
		return -1;
}

/** @} */

static struct rtnl_tc_ops tbf_tc_ops = {
	.to_kind		= "tbf",
	.to_type		= RTNL_TC_TYPE_QDISC,
	.to_size		= sizeof(struct rtnl_tbf),
	.to_msg_parser		= tbf_msg_parser,
	.to_dump = {
	    [NL_DUMP_LINE]	= tbf_dump_line,
	    [NL_DUMP_DETAILS]	= tbf_dump_details,
	},
	.to_msg_fill		= tbf_msg_fill,
};

static void _nl_init tbf_init(void)
{
	rtnl_tc_register(&tbf_tc_ops);
}

static void _nl_exit tbf_exit(void)
{
	rtnl_tc_unregister(&tbf_tc_ops);
}

/** @} */
