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

/**
 * @ingroup qdisc
 * @defgroup qdisc_netem Network Emulator
 * @brief
 *
 * For further documentation see http://linux-net.osdl.org/index.php/Netem
 * @{
 */

#include "nl-default.h"

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

#include "tc-api.h"
#include "nl-priv-dynamic-core/nl-core.h"

/** @cond SKIP */
struct rtnl_netem_corr {
	uint32_t nmc_delay;
	uint32_t nmc_loss;
	uint32_t nmc_duplicate;
};

struct rtnl_netem_reo {
	uint32_t nmro_probability;
	uint32_t nmro_correlation;
};

struct rtnl_netem_crpt {
	uint32_t nmcr_probability;
	uint32_t nmcr_correlation;
};

struct rtnl_netem_dist {
	int16_t *dist_data;
	size_t dist_size;
};

struct rtnl_netem {
	uint32_t qnm_latency;
	uint32_t qnm_limit;
	uint32_t qnm_loss;
	uint32_t qnm_gap;
	uint32_t qnm_duplicate;
	uint32_t qnm_jitter;
	uint32_t qnm_mask;
	struct rtnl_netem_corr qnm_corr;
	struct rtnl_netem_reo qnm_ro;
	struct rtnl_netem_crpt qnm_crpt;
	struct rtnl_netem_dist qnm_dist;
};

#define SCH_NETEM_ATTR_LATENCY		0x0001
#define SCH_NETEM_ATTR_LIMIT		0x0002
#define SCH_NETEM_ATTR_LOSS		0x0004
#define SCH_NETEM_ATTR_GAP		0x0008
#define SCH_NETEM_ATTR_DUPLICATE	0x0010
#define SCH_NETEM_ATTR_JITTER		0x0020
#define SCH_NETEM_ATTR_DELAY_CORR	0x0040
#define SCH_NETEM_ATTR_LOSS_CORR	0x0080
#define SCH_NETEM_ATTR_DUP_CORR		0x0100
#define SCH_NETEM_ATTR_RO_PROB		0x0200
#define SCH_NETEM_ATTR_RO_CORR		0x0400
#define SCH_NETEM_ATTR_CORRUPT_PROB	0x0800
#define SCH_NETEM_ATTR_CORRUPT_CORR	0x1000
#define SCH_NETEM_ATTR_DIST		0x2000
/** @endcond */

static struct nla_policy netem_policy[TCA_NETEM_MAX+1] = {
	[TCA_NETEM_CORR]	= { .minlen = sizeof(struct tc_netem_corr) },
	[TCA_NETEM_REORDER]	= { .minlen = sizeof(struct tc_netem_reorder) },
	[TCA_NETEM_CORRUPT]	= { .minlen = sizeof(struct tc_netem_corrupt) },
};

static int netem_msg_parser(struct rtnl_tc *tc, void *data)
{
	struct rtnl_netem *netem = data;
	struct tc_netem_qopt *opts;
	int len, err = 0;

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

	opts = (struct tc_netem_qopt *) tc->tc_opts->d_data;
	netem->qnm_latency = opts->latency;
	netem->qnm_limit = opts->limit;
	netem->qnm_loss = opts->loss;
	netem->qnm_gap = opts->gap;
	netem->qnm_duplicate = opts->duplicate;
	netem->qnm_jitter = opts->jitter;

	netem->qnm_mask = (SCH_NETEM_ATTR_LATENCY | SCH_NETEM_ATTR_LIMIT |
			   SCH_NETEM_ATTR_LOSS | SCH_NETEM_ATTR_GAP |
			   SCH_NETEM_ATTR_DUPLICATE | SCH_NETEM_ATTR_JITTER);

	len = tc->tc_opts->d_size - sizeof(*opts);

	if (len > 0) {
		struct nlattr *tb[TCA_NETEM_MAX+1];

		err = nla_parse(tb, TCA_NETEM_MAX, (struct nlattr *)
				((char *) tc->tc_opts->d_data + sizeof(*opts)),
				len, netem_policy);
		if (err < 0) {
			free(netem);
			return err;
		}

		if (tb[TCA_NETEM_CORR]) {
			struct tc_netem_corr cor;

			nla_memcpy(&cor, tb[TCA_NETEM_CORR], sizeof(cor));
			netem->qnm_corr.nmc_delay = cor.delay_corr;
			netem->qnm_corr.nmc_loss = cor.loss_corr;
			netem->qnm_corr.nmc_duplicate = cor.dup_corr;

			netem->qnm_mask |= (SCH_NETEM_ATTR_DELAY_CORR |
					    SCH_NETEM_ATTR_LOSS_CORR |
					SCH_NETEM_ATTR_DUP_CORR);
		}

		if (tb[TCA_NETEM_REORDER]) {
			struct tc_netem_reorder ro;

			nla_memcpy(&ro, tb[TCA_NETEM_REORDER], sizeof(ro));
			netem->qnm_ro.nmro_probability = ro.probability;
			netem->qnm_ro.nmro_correlation = ro.correlation;

			netem->qnm_mask |= (SCH_NETEM_ATTR_RO_PROB |
					    SCH_NETEM_ATTR_RO_CORR);
		}

		if (tb[TCA_NETEM_CORRUPT]) {
			struct tc_netem_corrupt corrupt;

			nla_memcpy(&corrupt, tb[TCA_NETEM_CORRUPT], sizeof(corrupt));
			netem->qnm_crpt.nmcr_probability = corrupt.probability;
			netem->qnm_crpt.nmcr_correlation = corrupt.correlation;

			netem->qnm_mask |= (SCH_NETEM_ATTR_CORRUPT_PROB |
						SCH_NETEM_ATTR_CORRUPT_CORR);
		}

		/* sch_netem does not currently dump TCA_NETEM_DELAY_DIST */
		netem->qnm_dist.dist_data = NULL;
		netem->qnm_dist.dist_size = 0;
	}

	return 0;
}

static void netem_free_data(struct rtnl_tc *tc, void *data)
{
	struct rtnl_netem *netem = data;

	if (!netem)
		return;

	free(netem->qnm_dist.dist_data);
}

static void netem_dump_line(struct rtnl_tc *tc, void *data,
			    struct nl_dump_params *p)
{
	struct rtnl_netem *netem = data;

	if (netem) {
		if (netem->qnm_mask & SCH_NETEM_ATTR_LIMIT && netem->qnm_limit > 0)
			nl_dump(p, " limit %dpkts", netem->qnm_limit);
		else
			nl_dump(p, " no limit");
	}
}

static void netem_dump_details(struct rtnl_tc *tc, void *data,
                               struct nl_dump_params *p)
{
	struct rtnl_netem *netem = data;
	char buf[32];

	if (netem) {
		if (netem->qnm_mask & SCH_NETEM_ATTR_LATENCY && netem->qnm_latency > 0) {
			nl_msec2str(nl_ticks2us(netem->qnm_latency) / 1000, buf, sizeof(buf));
			nl_dump(p, " latency %s", buf);

			if (netem->qnm_mask & SCH_NETEM_ATTR_JITTER && netem->qnm_jitter > 0) {
				nl_msec2str(nl_ticks2us(netem->qnm_jitter) / 1000, buf, sizeof(buf));
				nl_dump(p, " jitter %s", buf);

				if (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR && netem->qnm_corr.nmc_delay > 0)
					nl_dump(p, " %d", netem->qnm_corr.nmc_delay);
			}
		}

		if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS && netem->qnm_loss > 0) {
			nl_dump(p, " loss %d", netem->qnm_loss);

			if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR && netem->qnm_corr.nmc_loss > 0)
				nl_dump(p, " %d", netem->qnm_corr.nmc_loss);
		}

		if (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE && netem->qnm_duplicate > 0) {
			nl_dump(p, " duplicate %d", netem->qnm_duplicate);

			if (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR && netem->qnm_corr.nmc_duplicate > 0)
				nl_dump(p, " %d", netem->qnm_corr.nmc_duplicate);
		}

		if (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB && netem->qnm_ro.nmro_probability > 0) {
			nl_dump(p, " reorder %d", netem->qnm_ro.nmro_probability);

			if (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR && netem->qnm_ro.nmro_correlation > 0)
				nl_dump(p, " %d", netem->qnm_ro.nmro_correlation);

			if (netem->qnm_mask & SCH_NETEM_ATTR_GAP && netem->qnm_gap > 0)
				nl_dump(p, " gap %d", netem->qnm_gap);
		}

		if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_PROB && netem->qnm_crpt.nmcr_probability > 0) {
			nl_dump(p, " reorder %d", netem->qnm_crpt.nmcr_probability);

			if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_CORR && netem->qnm_crpt.nmcr_correlation > 0)
				nl_dump(p, " %d", netem->qnm_crpt.nmcr_correlation);
		}
	}
}

static int netem_msg_fill_raw(struct rtnl_tc *tc, void *data,
                              struct nl_msg *msg)
{
	int err = 0;
	struct tc_netem_qopt opts;
	struct tc_netem_corr cor;
	struct tc_netem_reorder reorder;
	struct tc_netem_corrupt corrupt;
	struct rtnl_netem *netem = data;

	unsigned char set_correlation = 0, set_reorder = 0;
	unsigned char set_corrupt = 0, set_dist = 0;

	struct nlattr* head;
	struct nlattr* tail;
	int old_len;

	if (!netem)
		BUG();

	memset(&opts, 0, sizeof(opts));
	memset(&cor, 0, sizeof(cor));
	memset(&reorder, 0, sizeof(reorder));
	memset(&corrupt, 0, sizeof(corrupt));

	msg->nm_nlh->nlmsg_flags |= NLM_F_REQUEST;

	if (netem->qnm_ro.nmro_probability != 0) {
		if (netem->qnm_latency == 0)
			return -NLE_MISSING_ATTR;
		if (netem->qnm_gap == 0)
			netem->qnm_gap = 1;
	} else if (netem->qnm_gap)
		return -NLE_MISSING_ATTR;

	if (netem->qnm_corr.nmc_delay != 0) {
		if (netem->qnm_latency == 0 || netem->qnm_jitter == 0)
			return -NLE_MISSING_ATTR;
		set_correlation = 1;
	}

	if (netem->qnm_corr.nmc_loss != 0) {
		if (netem->qnm_loss == 0)
			return -NLE_MISSING_ATTR;
		set_correlation = 1;
	}

	if (netem->qnm_corr.nmc_duplicate != 0) {
		if (netem->qnm_duplicate == 0)
			return -NLE_MISSING_ATTR;
		set_correlation = 1;
	}

	if (netem->qnm_ro.nmro_probability != 0)
		set_reorder = 1;
	else if (netem->qnm_ro.nmro_correlation != 0)
		return -NLE_MISSING_ATTR;

	if (netem->qnm_crpt.nmcr_probability != 0)
		set_corrupt = 1;
	else if (netem->qnm_crpt.nmcr_correlation != 0)
		return -NLE_MISSING_ATTR;

	if (netem->qnm_dist.dist_data && netem->qnm_dist.dist_size) {
		if (netem->qnm_latency == 0 || netem->qnm_jitter == 0)
			return -NLE_MISSING_ATTR;
		else {
			/* Resize to accomodate the large distribution table */
			int new_msg_len = msg->nm_size + netem->qnm_dist.dist_size *
			                  sizeof(netem->qnm_dist.dist_data[0]);
			struct nlmsghdr *new_nlh = realloc(msg->nm_nlh, new_msg_len);

			if (new_nlh == NULL)
				return -NLE_NOMEM;
			msg->nm_nlh = new_nlh;
			msg->nm_size = new_msg_len;
			set_dist = 1;
		}
	}

	opts.latency = netem->qnm_latency;
	opts.limit = netem->qnm_limit ? netem->qnm_limit : 1000;
	opts.loss = netem->qnm_loss;
	opts.gap = netem->qnm_gap;
	opts.duplicate = netem->qnm_duplicate;
	opts.jitter = netem->qnm_jitter;

	NLA_PUT(msg, TCA_OPTIONS, sizeof(opts), &opts);

	if (set_correlation) {
		cor.delay_corr = netem->qnm_corr.nmc_delay;
		cor.loss_corr = netem->qnm_corr.nmc_loss;
		cor.dup_corr = netem->qnm_corr.nmc_duplicate;

		NLA_PUT(msg, TCA_NETEM_CORR, sizeof(cor), &cor);
	}

	if (set_reorder) {
		reorder.probability = netem->qnm_ro.nmro_probability;
		reorder.correlation = netem->qnm_ro.nmro_correlation;

		NLA_PUT(msg, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
	}

	if (set_corrupt) {
		corrupt.probability = netem->qnm_crpt.nmcr_probability;
		corrupt.correlation = netem->qnm_crpt.nmcr_correlation;

		NLA_PUT(msg, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
	}

	if (set_dist) {
		NLA_PUT(msg, TCA_NETEM_DELAY_DIST,
		        netem->qnm_dist.dist_size * sizeof(netem->qnm_dist.dist_data[0]),
		        netem->qnm_dist.dist_data);
	}

	/* Length specified in the TCA_OPTIONS section must span the entire
	 * remainder of the message. That's just the way that sch_netem expects it.
	 * Maybe there's a more succinct way to do this at a higher level.
	 */
	head = (struct nlattr *)(((char *) NLMSG_DATA(msg->nm_nlh)) +
	                         NLMSG_LENGTH(sizeof(struct tcmsg)) - NLMSG_ALIGNTO);

	tail = (struct nlattr *)(((char *) (msg->nm_nlh)) +
	                         NLMSG_ALIGN(msg->nm_nlh->nlmsg_len));

	old_len = head->nla_len;
	head->nla_len = (char *)tail - (char *)head;
	msg->nm_nlh->nlmsg_len += (head->nla_len - old_len);

	return err;
nla_put_failure:
	return -NLE_MSGSIZE;
}

/**
 * @name Queue Limit
 * @{
 */

/**
 * Set limit of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg limit		New limit in bytes.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_limit(struct rtnl_qdisc *qdisc, int limit)
{
	struct rtnl_netem *netem;

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

	netem->qnm_limit = limit;
	netem->qnm_mask |= SCH_NETEM_ATTR_LIMIT;
}

/**
 * Get limit of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Limit in bytes or a negative error code.
 */
int rtnl_netem_get_limit(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

	if (!(netem = rtnl_tc_data(TC_CAST(qdisc))))
		return -NLE_NOMEM;

	if (netem->qnm_mask & SCH_NETEM_ATTR_LIMIT)
		return netem->qnm_limit;
	else
		return -NLE_NOATTR;
}

/** @} */

/**
 * @name Packet Re-ordering
 * @{
 */

/**
 * Set re-ordering gap of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg gap		New gap in number of packets.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_gap(struct rtnl_qdisc *qdisc, int gap)
{
	struct rtnl_netem *netem;

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

	netem->qnm_gap = gap;
	netem->qnm_mask |= SCH_NETEM_ATTR_GAP;
}

/**
 * Get re-ordering gap of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Re-ordering gap in packets or a negative error code.
 */
int rtnl_netem_get_gap(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

	if (!(netem = rtnl_tc_data(TC_CAST(qdisc))))
		return -NLE_NOMEM;

	if (netem->qnm_mask & SCH_NETEM_ATTR_GAP)
		return netem->qnm_gap;
	else
		return -NLE_NOATTR;
}

/**
 * Set re-ordering probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New re-ordering probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_reorder_probability(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_ro.nmro_probability = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_RO_PROB;
}

/**
 * Get re-ordering probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Re-ordering probability or a negative error code.
 */
int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

	if (!(netem = rtnl_tc_data(TC_CAST(qdisc))))
		return -NLE_NOMEM;

	if (netem->qnm_mask & SCH_NETEM_ATTR_RO_PROB)
		return netem->qnm_ro.nmro_probability;
	else
		return -NLE_NOATTR;
}

/**
 * Set re-order correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New re-ordering correlation probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_ro.nmro_correlation = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_RO_CORR;
}

/**
 * Get re-ordering correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Re-ordering correlation probability or a negative error code.
 */
int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

	if (!(netem = rtnl_tc_data(TC_CAST(qdisc))))
		return -NLE_NOMEM;

	if (netem->qnm_mask & SCH_NETEM_ATTR_RO_CORR)
		return netem->qnm_ro.nmro_correlation;
	else
		return -NLE_NOATTR;
}

/** @} */

/**
 * @name Corruption
 * @{
 */

/**
 * Set corruption probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New corruption probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_corruption_probability(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_crpt.nmcr_probability = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_CORRUPT_PROB;
}

/**
 * Get corruption probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Corruption probability or a negative error code.
 */
int rtnl_netem_get_corruption_probability(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_PROB)
		return netem->qnm_crpt.nmcr_probability;
	else
		return -NLE_NOATTR;
}

/**
 * Set corruption correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New corruption correlation probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_corruption_correlation(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_crpt.nmcr_correlation = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_CORRUPT_CORR;
}

/**
 * Get corruption correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Corruption correlation probability or a negative error code.
 */
int rtnl_netem_get_corruption_correlation(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_CORRUPT_CORR)
		return netem->qnm_crpt.nmcr_correlation;
	else
		return -NLE_NOATTR;
}

/** @} */

/**
 * @name Packet Loss
 * @{
 */

/**
 * Set packet loss probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New packet loss probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_loss(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_loss = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_LOSS;
}

/**
 * Get packet loss probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet loss probability or a negative error code.
 */
int rtnl_netem_get_loss(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS)
		return netem->qnm_loss;
	else
		return -NLE_NOATTR;
}

/**
 * Set packet loss correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob	New packet loss correlation.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_loss_correlation(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_corr.nmc_loss = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_LOSS_CORR;
}

/**
 * Get packet loss correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet loss correlation probability or a negative error code.
 */
int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_LOSS_CORR)
		return netem->qnm_corr.nmc_loss;
	else
		return -NLE_NOATTR;
}

/** @} */

/**
 * @name Packet Duplication
 * @{
 */

/**
 * Set packet duplication probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob	New packet duplication probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_duplicate(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_duplicate = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_DUPLICATE;
}

/**
 * Get packet duplication probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet duplication probability or a negative error code.
 */
int rtnl_netem_get_duplicate(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_DUPLICATE)
		return netem->qnm_duplicate;
	else
		return -NLE_NOATTR;
}

/**
 * Set packet duplication correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New packet duplication correlation probability.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_corr.nmc_duplicate = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_DUP_CORR;
}

/**
 * Get packet duplication correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet duplication correlation probability or a negative error code.
 */
int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_DUP_CORR)
		return netem->qnm_corr.nmc_duplicate;
	else
		return -NLE_NOATTR;
}

/** @} */

/**
 * @name Packet Delay
 * @{
 */

/**
 * Set packet delay of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg delay		New packet delay in micro seconds.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_delay(struct rtnl_qdisc *qdisc, int delay)
{
	struct rtnl_netem *netem;

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

	netem->qnm_latency = nl_us2ticks(delay);
	netem->qnm_mask |= SCH_NETEM_ATTR_LATENCY;
}

/**
 * Get packet delay of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet delay in micro seconds or a negative error code.
 */
int rtnl_netem_get_delay(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_LATENCY)
		return nl_ticks2us(netem->qnm_latency);
	else
		return -NLE_NOATTR;
}

/**
 * Set packet delay jitter of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg jitter		New packet delay jitter in micro seconds.
 * @return 0 on success or a negative error code.
 */
void rtnl_netem_set_jitter(struct rtnl_qdisc *qdisc, int jitter)
{
	struct rtnl_netem *netem;

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

	netem->qnm_jitter = nl_us2ticks(jitter);
	netem->qnm_mask |= SCH_NETEM_ATTR_JITTER;
}

/**
 * Get packet delay jitter of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet delay jitter in micro seconds or a negative error code.
 */
int rtnl_netem_get_jitter(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_JITTER)
		return nl_ticks2us(netem->qnm_jitter);
	else
		return -NLE_NOATTR;
}

/**
 * Set packet delay correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc to be modified.
 * @arg prob		New packet delay correlation probability.
 */
void rtnl_netem_set_delay_correlation(struct rtnl_qdisc *qdisc, int prob)
{
	struct rtnl_netem *netem;

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

	netem->qnm_corr.nmc_delay = prob;
	netem->qnm_mask |= SCH_NETEM_ATTR_DELAY_CORR;
}

/**
 * Get packet delay correlation probability of netem qdisc.
 * @arg qdisc		Netem qdisc.
 * @return Packet delay correlation probability or a negative error code.
 */
int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_DELAY_CORR)
		return netem->qnm_corr.nmc_delay;
	else
		return -NLE_NOATTR;
}

/**
 * Get the size of the distribution table.
 * @arg qdisc		Netem qdisc.
 * @return Distribution table size or a negative error code.
 */
int rtnl_netem_get_delay_distribution_size(struct rtnl_qdisc *qdisc)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_DIST)
		return netem->qnm_dist.dist_size;
	else
		return -NLE_NOATTR;
}

/**
 * Get a pointer to the distribution table.
 * @arg qdisc		Netem qdisc.
 * @arg dist_ptr	The pointer to set.
 * @return Negative error code on failure or 0 on success.
 */
int rtnl_netem_get_delay_distribution(struct rtnl_qdisc *qdisc, int16_t **dist_ptr)
{
	struct rtnl_netem *netem;

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

	if (netem->qnm_mask & SCH_NETEM_ATTR_DIST) {
		*dist_ptr = netem->qnm_dist.dist_data;
		return 0;
	} else
		return -NLE_NOATTR;
}

/**
 * Set the delay distribution data. Latency/jitter must be set before applying.
 * @arg qdisc Netem qdisc.
 * @return 0 on success, error code on failure.
 */
int rtnl_netem_set_delay_distribution_data(struct rtnl_qdisc *qdisc, const int16_t *data, size_t len) {
	struct rtnl_netem *netem;
	int16_t *new_data;

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

	if (len > MAXDIST)
		return -NLE_INVAL;

	new_data = (int16_t *) calloc(len, sizeof(int16_t));
	if (!new_data)
		return -NLE_NOMEM;

	free (netem->qnm_dist.dist_data);
	netem->qnm_dist.dist_data = new_data;

	memcpy(netem->qnm_dist.dist_data, data, len * sizeof(int16_t));

	netem->qnm_dist.dist_size = len;
	netem->qnm_mask |= SCH_NETEM_ATTR_DIST;

	return 0;
}

/**
 * Load the delay distribution from a file. Latency/jitter must be set before applying.
 * @arg qdisc Netem qdisc.
 * @arg dist_type The name of the distribution (type, file, path/file).
 * @return 0 on success, error code on failure.
 */
int rtnl_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, const char *dist_type) {
	FILE *f;
	int n = 0;
	size_t i;
	size_t len = 2048;
	_nl_auto_free char *line = NULL;
	char name[NAME_MAX];
	char dist_suffix[] = ".dist";
	_nl_auto_free int16_t *data = NULL;
	char *test_suffix;

	/* Check several locations for the dist file */
	char *test_path[] = {
		"",
		"./",
		"/usr/lib/tc/",
		"/usr/lib64/tc/",
		"/usr/local/lib/tc/",
	};

	/* If the given filename already ends in .dist, don't append it later */
	test_suffix = strstr(dist_type, dist_suffix);
	if (test_suffix != NULL && strlen(test_suffix) == 5)
		strcpy(dist_suffix, "");

	for (i = 0; i < ARRAY_SIZE(test_path); i++) {
		snprintf(name, NAME_MAX, "%s%s%s", test_path[i], dist_type, dist_suffix);
		if ((f = fopen(name, "re")))
			break;
	}

	if (f == NULL)
		return -nl_syserr2nlerr(errno);

	data = (int16_t *) calloc(MAXDIST, sizeof(int16_t));
	line = (char *) calloc(sizeof(char), len + 1);
	if (!data || !line) {
	    fclose(f);
	    return -NLE_NOMEM;
	}

	while (getline(&line, &len, f) != -1) {
		char *p, *endp;

		if (*line == '\n' || *line == '#')
			continue;

		for (p = line; ; p = endp) {
			long x = strtol(p, &endp, 0);
			if (endp == p) break;

			if (n >= MAXDIST) {
				fclose(f);
				return -NLE_INVAL;
			}
			data[n++] = x;
		}
	}

	fclose(f);
	i = rtnl_netem_set_delay_distribution_data(qdisc, data, n);
	return i;
}

/** @} */

static struct rtnl_tc_ops netem_ops = {
	.to_kind		= "netem",
	.to_type		= RTNL_TC_TYPE_QDISC,
	.to_size		= sizeof(struct rtnl_netem),
	.to_msg_parser		= netem_msg_parser,
	.to_free_data		= netem_free_data,
	.to_dump[NL_DUMP_LINE]	= netem_dump_line,
	.to_dump[NL_DUMP_DETAILS] = netem_dump_details,
	.to_msg_fill_raw	= netem_msg_fill_raw,
};

static void _nl_init netem_init(void)
{
	rtnl_tc_register(&netem_ops);
}

static void _nl_exit netem_exit(void)
{
	rtnl_tc_unregister(&netem_ops);
}

/** @} */
