xref: /freebsd/sys/netinet/ip_dummynet.h (revision 31cf66d7554c2fa6a5aea77f4cd54712e611cdd0)
1c398230bSWarner Losh /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni  *
4cc4d3c30SLuigi Rizzo  * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
5988790bfSLuigi Rizzo  * Portions Copyright (c) 2000 Akamba Corp.
6988790bfSLuigi Rizzo  * All rights reserved
72655eb49SLuigi Rizzo  *
8988790bfSLuigi Rizzo  * Redistribution and use in source and binary forms, with or without
9988790bfSLuigi Rizzo  * modification, are permitted provided that the following conditions
10988790bfSLuigi Rizzo  * are met:
11988790bfSLuigi Rizzo  * 1. Redistributions of source code must retain the above copyright
12988790bfSLuigi Rizzo  *    notice, this list of conditions and the following disclaimer.
13988790bfSLuigi Rizzo  * 2. Redistributions in binary form must reproduce the above copyright
14988790bfSLuigi Rizzo  *    notice, this list of conditions and the following disclaimer in the
15988790bfSLuigi Rizzo  *    documentation and/or other materials provided with the distribution.
162655eb49SLuigi Rizzo  *
17988790bfSLuigi Rizzo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18988790bfSLuigi Rizzo  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19988790bfSLuigi Rizzo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20988790bfSLuigi Rizzo  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21988790bfSLuigi Rizzo  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22988790bfSLuigi Rizzo  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23988790bfSLuigi Rizzo  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24988790bfSLuigi Rizzo  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25988790bfSLuigi Rizzo  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26988790bfSLuigi Rizzo  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27988790bfSLuigi Rizzo  * SUCH DAMAGE.
282655eb49SLuigi Rizzo  */
292655eb49SLuigi Rizzo 
302655eb49SLuigi Rizzo #ifndef _IP_DUMMYNET_H
312655eb49SLuigi Rizzo #define _IP_DUMMYNET_H
3291336b40SDon Lewis #define NEW_AQM
332655eb49SLuigi Rizzo /*
34cc4d3c30SLuigi Rizzo  * Definition of the kernel-userland API for dummynet.
35ec97c79eSLuigi Rizzo  *
36cc4d3c30SLuigi Rizzo  * Setsockopt() and getsockopt() pass a batch of objects, each
37cc4d3c30SLuigi Rizzo  * of them starting with a "struct dn_id" which should fully identify
38cc4d3c30SLuigi Rizzo  * the object and its relation with others in the sequence.
39cc4d3c30SLuigi Rizzo  * The first object in each request should have
40cc4d3c30SLuigi Rizzo  *	 type= DN_CMD_*, id = DN_API_VERSION.
41cc4d3c30SLuigi Rizzo  * For other objects, type and subtype specify the object, len indicates
42cc4d3c30SLuigi Rizzo  * the total length including the header, and 'id' identifies the specific
43cc4d3c30SLuigi Rizzo  * object.
44ec97c79eSLuigi Rizzo  *
45cc4d3c30SLuigi Rizzo  * Most objects are numbered with an identifier in the range 1..65535.
46cc4d3c30SLuigi Rizzo  * DN_MAX_ID indicates the first value outside the range.
475d3fe434SLuigi Rizzo  */
485d3fe434SLuigi Rizzo 
49cc4d3c30SLuigi Rizzo #define	DN_API_VERSION	12500000
50cc4d3c30SLuigi Rizzo #define	DN_MAX_ID	0x10000
51988790bfSLuigi Rizzo 
52cc4d3c30SLuigi Rizzo struct dn_id {
53cc4d3c30SLuigi Rizzo 	uint16_t	len;	/* total obj len including this header */
54cc4d3c30SLuigi Rizzo 	uint8_t		type;
55cc4d3c30SLuigi Rizzo 	uint8_t		subtype;
56cc4d3c30SLuigi Rizzo 	uint32_t	id;	/* generic id */
575d3fe434SLuigi Rizzo };
585d3fe434SLuigi Rizzo 
59ec97c79eSLuigi Rizzo /*
60cc4d3c30SLuigi Rizzo  * These values are in the type field of struct dn_id.
61cc4d3c30SLuigi Rizzo  * To preserve the ABI, never rearrange the list or delete
62cc4d3c30SLuigi Rizzo  * entries with the exception of DN_LAST
63ec97c79eSLuigi Rizzo  */
64cc4d3c30SLuigi Rizzo enum {
65cc4d3c30SLuigi Rizzo 	DN_NONE = 0,
66cc4d3c30SLuigi Rizzo 	DN_LINK = 1,
67cc4d3c30SLuigi Rizzo 	DN_FS,
68cc4d3c30SLuigi Rizzo 	DN_SCH,
69cc4d3c30SLuigi Rizzo 	DN_SCH_I,
70cc4d3c30SLuigi Rizzo 	DN_QUEUE,
71cc4d3c30SLuigi Rizzo 	DN_DELAY_LINE,
72cc4d3c30SLuigi Rizzo 	DN_PROFILE,
73cc4d3c30SLuigi Rizzo 	DN_FLOW,		/* struct dn_flow */
74cc4d3c30SLuigi Rizzo 	DN_TEXT,		/* opaque text is the object */
755d3fe434SLuigi Rizzo 
76cc4d3c30SLuigi Rizzo 	DN_CMD_CONFIG = 0x80,	/* objects follow */
77cc4d3c30SLuigi Rizzo 	DN_CMD_DELETE,		/* subtype + list of entries */
78cc4d3c30SLuigi Rizzo 	DN_CMD_GET,		/* subtype + list of entries */
79cc4d3c30SLuigi Rizzo 	DN_CMD_FLUSH,
80cc4d3c30SLuigi Rizzo 	/* for compatibility with FreeBSD 7.2/8 */
81cc4d3c30SLuigi Rizzo 	DN_COMPAT_PIPE,
82cc4d3c30SLuigi Rizzo 	DN_COMPAT_QUEUE,
83cc4d3c30SLuigi Rizzo 	DN_GET_COMPAT,
845d3fe434SLuigi Rizzo 
85cc4d3c30SLuigi Rizzo 	/* special commands for emulation of sysctl variables */
86cc4d3c30SLuigi Rizzo 	DN_SYSCTL_GET,
87cc4d3c30SLuigi Rizzo 	DN_SYSCTL_SET,
8891336b40SDon Lewis #ifdef NEW_AQM
8991336b40SDon Lewis 	/* subtypes used for setting/getting extra parameters.
9091336b40SDon Lewis 	 * these subtypes used with IP_DUMMYNET3 command (get)
9191336b40SDon Lewis 	 * and DN_TEXT (set). */
9291336b40SDon Lewis 	DN_AQM_PARAMS, /* AQM extra params */
9391336b40SDon Lewis 	DN_SCH_PARAMS, /* scheduler extra params */
9491336b40SDon Lewis #endif
95cc4d3c30SLuigi Rizzo 	DN_LAST,
96cc4d3c30SLuigi Rizzo };
97cc4d3c30SLuigi Rizzo 
98cc4d3c30SLuigi Rizzo enum { /* subtype for schedulers, flowset and the like */
99cc4d3c30SLuigi Rizzo 	DN_SCHED_UNKNOWN = 0,
100cc4d3c30SLuigi Rizzo 	DN_SCHED_FIFO = 1,
101cc4d3c30SLuigi Rizzo 	DN_SCHED_WF2QP = 2,
102cc4d3c30SLuigi Rizzo 	/* others are in individual modules */
103cc4d3c30SLuigi Rizzo };
104cc4d3c30SLuigi Rizzo 
105cc4d3c30SLuigi Rizzo enum {	/* user flags */
106cc4d3c30SLuigi Rizzo 	DN_HAVE_MASK	= 0x0001,	/* fs or sched has a mask */
107cc4d3c30SLuigi Rizzo 	DN_NOERROR	= 0x0002,	/* do not report errors */
108cc4d3c30SLuigi Rizzo 	DN_QHT_HASH	= 0x0004,	/* qht is a hash table */
109cc4d3c30SLuigi Rizzo 	DN_QSIZE_BYTES	= 0x0008,	/* queue size is in bytes */
110cc4d3c30SLuigi Rizzo 	DN_HAS_PROFILE	= 0x0010,	/* a link has a profile */
111cc4d3c30SLuigi Rizzo 	DN_IS_RED	= 0x0020,
112cc4d3c30SLuigi Rizzo 	DN_IS_GENTLE_RED= 0x0040,
113fc5e1956SHiren Panchasara 	DN_IS_ECN	= 0x0080,
11491336b40SDon Lewis 	#ifdef NEW_AQM
11591336b40SDon Lewis 	DN_IS_AQM = 0x0100,     /* AQMs: e.g Codel & PIE */
11691336b40SDon Lewis 	#endif
117cc4d3c30SLuigi Rizzo 	DN_PIPE_CMD	= 0x1000,	/* pipe config... */
118cc4d3c30SLuigi Rizzo };
119cc4d3c30SLuigi Rizzo 
120cc4d3c30SLuigi Rizzo /*
121cc4d3c30SLuigi Rizzo  * link template.
122cc4d3c30SLuigi Rizzo  */
123cc4d3c30SLuigi Rizzo struct dn_link {
124cc4d3c30SLuigi Rizzo 	struct dn_id oid;
125cc4d3c30SLuigi Rizzo 
126cc4d3c30SLuigi Rizzo 	/*
127cc4d3c30SLuigi Rizzo 	 * Userland sets bw and delay in bits/s and milliseconds.
128cc4d3c30SLuigi Rizzo 	 * The kernel converts this back and forth to bits/tick and ticks.
129cc4d3c30SLuigi Rizzo 	 * XXX what about burst ?
130cc4d3c30SLuigi Rizzo 	 */
131cc4d3c30SLuigi Rizzo 	int32_t		link_nr;
13220ffd88eSLuiz Otavio O Souza 	uint32_t	bandwidth;	/* bit/s or bits/tick.   */
133cc4d3c30SLuigi Rizzo 	int		delay;		/* ms and ticks */
134cc4d3c30SLuigi Rizzo 	uint64_t	burst;		/* scaled. bits*Hz  XXX */
135cc4d3c30SLuigi Rizzo };
136cc4d3c30SLuigi Rizzo 
137cc4d3c30SLuigi Rizzo /*
138cc4d3c30SLuigi Rizzo  * A flowset, which is a template for flows. Contains parameters
139cc4d3c30SLuigi Rizzo  * from the command line: id, target scheduler, queue sizes, plr,
140cc4d3c30SLuigi Rizzo  * flow masks, buckets for the flow hash, and possibly scheduler-
141cc4d3c30SLuigi Rizzo  * specific parameters (weight, quantum and so on).
142cc4d3c30SLuigi Rizzo  */
143cc4d3c30SLuigi Rizzo struct dn_fs {
144cc4d3c30SLuigi Rizzo 	struct dn_id oid;
145cc4d3c30SLuigi Rizzo 	uint32_t fs_nr;		/* the flowset number */
146cc4d3c30SLuigi Rizzo 	uint32_t flags;		/* userland flags */
1475d3fe434SLuigi Rizzo 	int qsize;		/* queue size in slots or bytes */
148*31cf66d7SRichard Scheffenegger 	int32_t pl_state;	/* packet loss state */
149cc4d3c30SLuigi Rizzo 	uint32_t buckets;	/* buckets used for the queue hash table */
1505d3fe434SLuigi Rizzo 
1515d3fe434SLuigi Rizzo 	struct ipfw_flow_id flow_mask;
152cc4d3c30SLuigi Rizzo 	uint32_t sched_nr;	/* the scheduler we attach to */
153cc4d3c30SLuigi Rizzo 	/* generic scheduler parameters. Leave them at -1 if unset.
154cc4d3c30SLuigi Rizzo 	 * Now we use 0: weight, 1: lmax, 2: priority
155cc4d3c30SLuigi Rizzo 	 */
156cc4d3c30SLuigi Rizzo 	int par[4];
15743d11e84SLuigi Rizzo 
158cc4d3c30SLuigi Rizzo 	/* RED/GRED parameters.
159cc4d3c30SLuigi Rizzo 	 * weight and probabilities are in the range 0..1 represented
160cc4d3c30SLuigi Rizzo 	 * in fixed point arithmetic with SCALE_RED decimal bits.
161cc4d3c30SLuigi Rizzo 	 */
1625d3fe434SLuigi Rizzo #define SCALE_RED	16
1635d3fe434SLuigi Rizzo #define SCALE(x)	( (x) << SCALE_RED )
1645d3fe434SLuigi Rizzo #define SCALE_VAL(x)	( (x) >> SCALE_RED )
1655d3fe434SLuigi Rizzo #define SCALE_MUL(x,y)	( ( (x) * (y) ) >> SCALE_RED )
1665d3fe434SLuigi Rizzo 	int w_q ;		/* queue weight (scaled) */
1675d3fe434SLuigi Rizzo 	int max_th ;		/* maximum threshold for queue (scaled) */
1685d3fe434SLuigi Rizzo 	int min_th ;		/* minimum threshold for queue (scaled) */
1695d3fe434SLuigi Rizzo 	int max_p ;		/* maximum value for p_b (scaled) */
170988790bfSLuigi Rizzo 
171*31cf66d7SRichard Scheffenegger 	int32_t plr[4];		/* PLR, pkt loss rate (2^31-1 means 100%) */
1722655eb49SLuigi Rizzo };
1734bb7ae9dSLuigi Rizzo 
174cc4d3c30SLuigi Rizzo /*
175cc4d3c30SLuigi Rizzo  * dn_flow collects flow_id and stats for queues and scheduler
176cc4d3c30SLuigi Rizzo  * instances, and is used to pass these info to userland.
177cc4d3c30SLuigi Rizzo  * oid.type/oid.subtype describe the object, oid.id is number
178cc4d3c30SLuigi Rizzo  * of the parent object.
179cc4d3c30SLuigi Rizzo  */
180cc4d3c30SLuigi Rizzo struct dn_flow {
181cc4d3c30SLuigi Rizzo 	struct dn_id	oid;
182cc4d3c30SLuigi Rizzo 	struct ipfw_flow_id fid;
183cc4d3c30SLuigi Rizzo 	uint64_t	tot_pkts; /* statistics counters  */
184cc4d3c30SLuigi Rizzo 	uint64_t	tot_bytes;
185e5813a3bSLuigi Rizzo 	uint32_t	length; /* Queue length, in packets */
186e5813a3bSLuigi Rizzo 	uint32_t	len_bytes; /* Queue length, in bytes */
187cc4d3c30SLuigi Rizzo 	uint32_t	drops;
188cc4d3c30SLuigi Rizzo };
189cc4d3c30SLuigi Rizzo 
190cc4d3c30SLuigi Rizzo /*
191cc4d3c30SLuigi Rizzo  * Scheduler template, mostly indicating the name, number,
192cc4d3c30SLuigi Rizzo  * sched_mask and buckets.
193cc4d3c30SLuigi Rizzo  */
194cc4d3c30SLuigi Rizzo struct dn_sch {
195cc4d3c30SLuigi Rizzo 	struct dn_id	oid;
196cc4d3c30SLuigi Rizzo 	uint32_t	sched_nr; /* N, scheduler number */
197cc4d3c30SLuigi Rizzo 	uint32_t	buckets; /* number of buckets for the instances */
198cc4d3c30SLuigi Rizzo 	uint32_t	flags;	/* have_mask, ... */
199cc4d3c30SLuigi Rizzo 
200cc4d3c30SLuigi Rizzo 	char name[16];	/* null terminated */
201cc4d3c30SLuigi Rizzo 	/* mask to select the appropriate scheduler instance */
202cc4d3c30SLuigi Rizzo 	struct ipfw_flow_id sched_mask; /* M */
203cc4d3c30SLuigi Rizzo };
204cc4d3c30SLuigi Rizzo 
205cc4d3c30SLuigi Rizzo /* A delay profile is attached to a link.
206cc4d3c30SLuigi Rizzo  * Note that a profile, as any other object, cannot be longer than 2^16
2074bb7ae9dSLuigi Rizzo  */
2084bb7ae9dSLuigi Rizzo #define	ED_MAX_SAMPLES_NO	1024
209cc4d3c30SLuigi Rizzo struct dn_profile {
210cc4d3c30SLuigi Rizzo 	struct dn_id	oid;
211cc4d3c30SLuigi Rizzo 	/* fields to simulate a delay profile */
212cc4d3c30SLuigi Rizzo #define ED_MAX_NAME_LEN		32
213cc4d3c30SLuigi Rizzo 	char	name[ED_MAX_NAME_LEN];
214cc4d3c30SLuigi Rizzo 	int	link_nr;
215cc4d3c30SLuigi Rizzo 	int	loss_level;
21620ffd88eSLuiz Otavio O Souza 	uint32_t	bandwidth;			// XXX use link bandwidth?
2176ba1ccc0SLuigi Rizzo 	int	samples_no;			/* actual len of samples[] */
218cc4d3c30SLuigi Rizzo 	int	samples[ED_MAX_SAMPLES_NO];	/* may be shorter */
2194bb7ae9dSLuigi Rizzo };
2204bb7ae9dSLuigi Rizzo 
22191336b40SDon Lewis #ifdef NEW_AQM
22291336b40SDon Lewis /* Extra parameters for AQM and scheduler.
22391336b40SDon Lewis  * This struct is used to pass and retrieve parameters (configurations)
22491336b40SDon Lewis  * to/from AQM and Scheduler.
22591336b40SDon Lewis  */
22691336b40SDon Lewis struct dn_extra_parms {
22791336b40SDon Lewis 	struct dn_id oid;
22891336b40SDon Lewis 	char name[16];
22991336b40SDon Lewis 	uint32_t nr;
23091336b40SDon Lewis #define DN_MAX_EXTRA_PARM	10
23191336b40SDon Lewis 	int64_t par[DN_MAX_EXTRA_PARM];
23291336b40SDon Lewis };
23391336b40SDon Lewis #endif
234cc4d3c30SLuigi Rizzo 
235cc4d3c30SLuigi Rizzo /*
236cc4d3c30SLuigi Rizzo  * Overall structure of dummynet
237cc4d3c30SLuigi Rizzo 
238cc4d3c30SLuigi Rizzo In dummynet, packets are selected with the firewall rules, and passed
239cc4d3c30SLuigi Rizzo to two different objects: PIPE or QUEUE (bad name).
240cc4d3c30SLuigi Rizzo 
241cc4d3c30SLuigi Rizzo A QUEUE defines a classifier, which groups packets into flows
242cc4d3c30SLuigi Rizzo according to a 'mask', puts them into independent queues (one
243cc4d3c30SLuigi Rizzo per flow) with configurable size and queue management policy,
244cc4d3c30SLuigi Rizzo and passes flows to a scheduler:
245cc4d3c30SLuigi Rizzo 
246cc4d3c30SLuigi Rizzo                  (flow_mask|sched_mask)  sched_mask
247cc4d3c30SLuigi Rizzo 	 +---------+   weight Wx  +-------------+
248cc4d3c30SLuigi Rizzo          |         |->-[flow]-->--|             |-+
249cc4d3c30SLuigi Rizzo     -->--| QUEUE x |   ...        |             | |
250cc4d3c30SLuigi Rizzo          |         |->-[flow]-->--| SCHEDuler N | |
251cc4d3c30SLuigi Rizzo 	 +---------+              |             | |
252cc4d3c30SLuigi Rizzo 	     ...                  |             +--[LINK N]-->--
253cc4d3c30SLuigi Rizzo 	 +---------+   weight Wy  |             | +--[LINK N]-->--
254cc4d3c30SLuigi Rizzo          |         |->-[flow]-->--|             | |
255cc4d3c30SLuigi Rizzo     -->--| QUEUE y |   ...        |             | |
256cc4d3c30SLuigi Rizzo          |         |->-[flow]-->--|             | |
257cc4d3c30SLuigi Rizzo 	 +---------+              +-------------+ |
258cc4d3c30SLuigi Rizzo 	                            +-------------+
259cc4d3c30SLuigi Rizzo 
260cc4d3c30SLuigi Rizzo Many QUEUE objects can connect to the same scheduler, each
261cc4d3c30SLuigi Rizzo QUEUE object can have its own set of parameters.
262cc4d3c30SLuigi Rizzo 
263cc4d3c30SLuigi Rizzo In turn, the SCHEDuler 'forks' multiple instances according
264cc4d3c30SLuigi Rizzo to a 'sched_mask', each instance manages its own set of queues
265cc4d3c30SLuigi Rizzo and transmits on a private instance of a configurable LINK.
266cc4d3c30SLuigi Rizzo 
267cc4d3c30SLuigi Rizzo A PIPE is a simplified version of the above, where there
268cc4d3c30SLuigi Rizzo is no flow_mask, and each scheduler instance handles a single queue.
269cc4d3c30SLuigi Rizzo 
270cc4d3c30SLuigi Rizzo The following data structures (visible from userland) describe
271cc4d3c30SLuigi Rizzo the objects used by dummynet:
272cc4d3c30SLuigi Rizzo 
273cc4d3c30SLuigi Rizzo  + dn_link, contains the main configuration parameters related
274cc4d3c30SLuigi Rizzo    to delay and bandwidth;
275cc4d3c30SLuigi Rizzo  + dn_profile describes a delay profile;
276cc4d3c30SLuigi Rizzo  + dn_flow describes the flow status (flow id, statistics)
277cc4d3c30SLuigi Rizzo 
278cc4d3c30SLuigi Rizzo  + dn_sch describes a scheduler
279cc4d3c30SLuigi Rizzo  + dn_fs describes a flowset (msk, weight, queue parameters)
280cc4d3c30SLuigi Rizzo 
281cc4d3c30SLuigi Rizzo  *
282cc4d3c30SLuigi Rizzo  */
2832655eb49SLuigi Rizzo 
2842655eb49SLuigi Rizzo #endif /* _IP_DUMMYNET_H */
285