linux/net/sched/sch_tbf.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * net/sched/sch_tbf.c	Token Bucket Filter queue.
 *
 * Authors:	Alexey Kuznetsov, <[email protected]>
 *		Dmitry Torokhov <[email protected]> - allow attaching inner qdiscs -
 *						 original idea by Martin Devera
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <net/gso.h>
#include <net/netlink.h>
#include <net/sch_generic.h>
#include <net/pkt_cls.h>
#include <net/pkt_sched.h>


/*	Simple Token Bucket Filter.
	=======================================

	SOURCE.
	-------

	None.

	Description.
	------------

	A data flow obeys TBF with rate R and depth B, if for any
	time interval t_i...t_f the number of transmitted bits
	does not exceed B + R*(t_f-t_i).

	Packetized version of this definition:
	The sequence of packets of sizes s_i served at moments t_i
	obeys TBF, if for any i<=k:

	s_i+....+s_k <= B + R*(t_k - t_i)

	Algorithm.
	----------

	Let N(t_i) be B/R initially and N(t) grow continuously with time as:

	N(t+delta) = min{B/R, N(t) + delta}

	If the first packet in queue has length S, it may be
	transmitted only at the time t_* when S/R <= N(t_*),
	and in this case N(t) jumps:

	N(t_* + 0) = N(t_* - 0) - S/R.



	Actually, QoS requires two TBF to be applied to a data stream.
	One of them controls steady state burst size, another
	one with rate P (peak rate) and depth M (equal to link MTU)
	limits bursts at a smaller time scale.

	It is easy to see that P>R, and B>M. If P is infinity, this double
	TBF is equivalent to a single one.

	When TBF works in reshaping mode, latency is estimated as:

	lat = max ((L-B)/R, (L-M)/P)


	NOTES.
	------

	If TBF throttles, it starts a watchdog timer, which will wake it up
	when it is ready to transmit.
	Note that the minimal timer resolution is 1/HZ.
	If no new packets arrive during this period,
	or if the device is not awaken by EOI for some previous packet,
	TBF can stop its activity for 1/HZ.


	This means, that with depth B, the maximal rate is

	R_crit = B*HZ

	F.e. for 10Mbit ethernet and HZ=100 the minimal allowed B is ~10Kbytes.

	Note that the peak rate TBF is much more tough: with MTU 1500
	P_crit = 150Kbytes/sec. So, if you need greater peak
	rates, use alpha with HZ=1000 :-)

	With classful TBF, limit is just kept for backwards compatibility.
	It is passed to the default bfifo qdisc - if the inner qdisc is
	changed the limit is not effective anymore.
*/

struct tbf_sched_data {};


/* Time to Length, convert time in ns to length in bytes
 * to determinate how many bytes can be sent in given time.
 */
static u64 psched_ns_t2l(const struct psched_ratecfg *r,
			 u64 time_in_ns)
{}

static void tbf_offload_change(struct Qdisc *sch)
{}

static void tbf_offload_destroy(struct Qdisc *sch)
{}

static int tbf_offload_dump(struct Qdisc *sch)
{}

static void tbf_offload_graft(struct Qdisc *sch, struct Qdisc *new,
			      struct Qdisc *old, struct netlink_ext_ack *extack)
{}

/* GSO packet is too big, segment it so that tbf can transmit
 * each segment in time
 */
static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
		       struct sk_buff **to_free)
{}

static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
		       struct sk_buff **to_free)
{}

static bool tbf_peak_present(const struct tbf_sched_data *q)
{}

static struct sk_buff *tbf_dequeue(struct Qdisc *sch)
{}

static void tbf_reset(struct Qdisc *sch)
{}

static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] =;

static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
		      struct netlink_ext_ack *extack)
{}

static int tbf_init(struct Qdisc *sch, struct nlattr *opt,
		    struct netlink_ext_ack *extack)
{}

static void tbf_destroy(struct Qdisc *sch)
{}

static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
{}

static int tbf_dump_class(struct Qdisc *sch, unsigned long cl,
			  struct sk_buff *skb, struct tcmsg *tcm)
{}

static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
		     struct Qdisc **old, struct netlink_ext_ack *extack)
{}

static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg)
{}

static unsigned long tbf_find(struct Qdisc *sch, u32 classid)
{}

static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{}

static const struct Qdisc_class_ops tbf_class_ops =;

static struct Qdisc_ops tbf_qdisc_ops __read_mostly =;
MODULE_ALIAS_NET_SCH();

static int __init tbf_module_init(void)
{}

static void __exit tbf_module_exit(void)
{}
module_init()
module_exit()
MODULE_LICENSE();
MODULE_DESCRIPTION();