1139823Simp/*-
2204591Sluigi * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
355597Sluigi * Portions Copyright (c) 2000 Akamba Corp.
455597Sluigi * All rights reserved
539119Sluigi *
655597Sluigi * Redistribution and use in source and binary forms, with or without
755597Sluigi * modification, are permitted provided that the following conditions
855597Sluigi * are met:
955597Sluigi * 1. Redistributions of source code must retain the above copyright
1055597Sluigi *    notice, this list of conditions and the following disclaimer.
1155597Sluigi * 2. Redistributions in binary form must reproduce the above copyright
1255597Sluigi *    notice, this list of conditions and the following disclaimer in the
1355597Sluigi *    documentation and/or other materials provided with the distribution.
1439119Sluigi *
1555597Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1655597Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1755597Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1855597Sluigi * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1955597Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2055597Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2155597Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2255597Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2355597Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2455597Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2555597Sluigi * SUCH DAMAGE.
2639119Sluigi *
2750477Speter * $FreeBSD$
2839119Sluigi */
2939119Sluigi
3039119Sluigi#ifndef _IP_DUMMYNET_H
3139119Sluigi#define _IP_DUMMYNET_H
32300779Struckman#define NEW_AQM
3339119Sluigi/*
34204591Sluigi * Definition of the kernel-userland API for dummynet.
3571137Sluigi *
36204591Sluigi * Setsockopt() and getsockopt() pass a batch of objects, each
37204591Sluigi * of them starting with a "struct dn_id" which should fully identify
38204591Sluigi * the object and its relation with others in the sequence.
39204591Sluigi * The first object in each request should have
40204591Sluigi *	 type= DN_CMD_*, id = DN_API_VERSION.
41204591Sluigi * For other objects, type and subtype specify the object, len indicates
42204591Sluigi * the total length including the header, and 'id' identifies the specific
43204591Sluigi * object.
4471137Sluigi *
45204591Sluigi * Most objects are numbered with an identifier in the range 1..65535.
46204591Sluigi * DN_MAX_ID indicates the first value outside the range.
4761413Sluigi */
4871137Sluigi
49204591Sluigi#define	DN_API_VERSION	12500000
50204591Sluigi#define	DN_MAX_ID	0x10000
5161413Sluigi
52204591Sluigistruct dn_id {
53204591Sluigi	uint16_t	len;	/* total obj len including this header */
54204591Sluigi	uint8_t		type;
55204591Sluigi	uint8_t		subtype;
56204591Sluigi	uint32_t	id;	/* generic id */
57204591Sluigi};
5861413Sluigi
5971137Sluigi/*
60204591Sluigi * These values are in the type field of struct dn_id.
61204591Sluigi * To preserve the ABI, never rearrange the list or delete
62204591Sluigi * entries with the exception of DN_LAST
63104975Sseanc */
64204591Sluigienum {
65204591Sluigi	DN_NONE = 0,
66204591Sluigi	DN_LINK = 1,
67204591Sluigi	DN_FS,
68204591Sluigi	DN_SCH,
69204591Sluigi	DN_SCH_I,
70204591Sluigi	DN_QUEUE,
71204591Sluigi	DN_DELAY_LINE,
72204591Sluigi	DN_PROFILE,
73204591Sluigi	DN_FLOW,		/* struct dn_flow */
74204591Sluigi	DN_TEXT,		/* opaque text is the object */
75104975Sseanc
76204591Sluigi	DN_CMD_CONFIG = 0x80,	/* objects follow */
77204591Sluigi	DN_CMD_DELETE,		/* subtype + list of entries */
78204591Sluigi	DN_CMD_GET,		/* subtype + list of entries */
79204591Sluigi	DN_CMD_FLUSH,
80204591Sluigi	/* for compatibility with FreeBSD 7.2/8 */
81204591Sluigi	DN_COMPAT_PIPE,
82204591Sluigi	DN_COMPAT_QUEUE,
83204591Sluigi	DN_GET_COMPAT,
84204591Sluigi
85204591Sluigi	/* special commands for emulation of sysctl variables */
86204591Sluigi	DN_SYSCTL_GET,
87204591Sluigi	DN_SYSCTL_SET,
88300779Struckman#ifdef NEW_AQM
89300779Struckman	/* subtypes used for setting/getting extra parameters.
90300779Struckman	 * these subtypes used with IP_DUMMYNET3 command (get)
91300779Struckman	 * and DN_TEXT (set). */
92300779Struckman	DN_AQM_PARAMS, /* AQM extra params */
93300779Struckman	DN_SCH_PARAMS, /* scheduler extra params */
94300779Struckman#endif
95204591Sluigi	DN_LAST,
96206845Sluigi};
9755597Sluigi
98204591Sluigienum { /* subtype for schedulers, flowset and the like */
99204591Sluigi	DN_SCHED_UNKNOWN = 0,
100204591Sluigi	DN_SCHED_FIFO = 1,
101204591Sluigi	DN_SCHED_WF2QP = 2,
102204591Sluigi	/* others are in individual modules */
103206845Sluigi};
10455597Sluigi
105204591Sluigienum {	/* user flags */
106204591Sluigi	DN_HAVE_MASK	= 0x0001,	/* fs or sched has a mask */
107204591Sluigi	DN_NOERROR	= 0x0002,	/* do not report errors */
108204591Sluigi	DN_QHT_HASH	= 0x0004,	/* qht is a hash table */
109204591Sluigi	DN_QSIZE_BYTES	= 0x0008,	/* queue size is in bytes */
110204591Sluigi	DN_HAS_PROFILE	= 0x0010,	/* a link has a profile */
111204591Sluigi	DN_IS_RED	= 0x0020,
112204591Sluigi	DN_IS_GENTLE_RED= 0x0040,
113266941Shiren	DN_IS_ECN	= 0x0080,
114300779Struckman	#ifdef NEW_AQM
115300779Struckman	DN_IS_AQM = 0x0100,     /* AQMs: e.g Codel & PIE */
116300779Struckman	#endif
117204591Sluigi	DN_PIPE_CMD	= 0x1000,	/* pipe config... */
11839119Sluigi};
11939119Sluigi
12061413Sluigi/*
121204591Sluigi * link template.
12261413Sluigi */
123204591Sluigistruct dn_link {
124204591Sluigi	struct dn_id oid;
12561413Sluigi
126206845Sluigi	/*
127204591Sluigi	 * Userland sets bw and delay in bits/s and milliseconds.
128204591Sluigi	 * The kernel converts this back and forth to bits/tick and ticks.
129204591Sluigi	 * XXX what about burst ?
130206845Sluigi	 */
131204591Sluigi	int32_t		link_nr;
132204591Sluigi	int		bandwidth;	/* bit/s or bits/tick.   */
133204591Sluigi	int		delay;		/* ms and ticks */
134204591Sluigi	uint64_t	burst;		/* scaled. bits*Hz  XXX */
135206845Sluigi};
13655597Sluigi
13771137Sluigi/*
138204591Sluigi * A flowset, which is a template for flows. Contains parameters
139204591Sluigi * from the command line: id, target scheduler, queue sizes, plr,
140204591Sluigi * flow masks, buckets for the flow hash, and possibly scheduler-
141204591Sluigi * specific parameters (weight, quantum and so on).
14271137Sluigi */
143204591Sluigistruct dn_fs {
144204591Sluigi	struct dn_id oid;
145206845Sluigi	uint32_t fs_nr;		/* the flowset number */
146206845Sluigi	uint32_t flags;		/* userland flags */
147206845Sluigi	int qsize;		/* queue size in slots or bytes */
148206845Sluigi	int32_t plr;		/* PLR, pkt loss rate (2^31-1 means 100%) */
149204591Sluigi	uint32_t buckets;	/* buckets used for the queue hash table */
15061413Sluigi
151206845Sluigi	struct ipfw_flow_id flow_mask;
152204591Sluigi	uint32_t sched_nr;	/* the scheduler we attach to */
153204591Sluigi	/* generic scheduler parameters. Leave them at -1 if unset.
154204591Sluigi	 * Now we use 0: weight, 1: lmax, 2: priority
155204591Sluigi	 */
156204591Sluigi	int par[4];
15796077Sluigi
158204591Sluigi	/* RED/GRED parameters.
159204591Sluigi	 * weight and probabilities are in the range 0..1 represented
160204591Sluigi	 * in fixed point arithmetic with SCALE_RED decimal bits.
161204591Sluigi	 */
162206845Sluigi#define SCALE_RED	16
163206845Sluigi#define SCALE(x)	( (x) << SCALE_RED )
164206845Sluigi#define SCALE_VAL(x)	( (x) >> SCALE_RED )
165206845Sluigi#define SCALE_MUL(x,y)	( ( (x) * (y) ) >> SCALE_RED )
166206845Sluigi	int w_q ;		/* queue weight (scaled) */
167206845Sluigi	int max_th ;		/* maximum threshold for queue (scaled) */
168206845Sluigi	int min_th ;		/* minimum threshold for queue (scaled) */
169206845Sluigi	int max_p ;		/* maximum value for p_b (scaled) */
170204591Sluigi
171152910Sglebius};
17261413Sluigi
17355597Sluigi/*
174204591Sluigi * dn_flow collects flow_id and stats for queues and scheduler
175204591Sluigi * instances, and is used to pass these info to userland.
176204591Sluigi * oid.type/oid.subtype describe the object, oid.id is number
177204591Sluigi * of the parent object.
17855597Sluigi */
179204591Sluigistruct dn_flow {
180204591Sluigi	struct dn_id	oid;
181204591Sluigi	struct ipfw_flow_id fid;
182204591Sluigi	uint64_t	tot_pkts; /* statistics counters  */
183204591Sluigi	uint64_t	tot_bytes;
184239124Sluigi	uint32_t	length; /* Queue length, in packets */
185239124Sluigi	uint32_t	len_bytes; /* Queue length, in bytes */
186204591Sluigi	uint32_t	drops;
187204591Sluigi};
18839119Sluigi
18939119Sluigi
190206845Sluigi/*
191204591Sluigi * Scheduler template, mostly indicating the name, number,
192204591Sluigi * sched_mask and buckets.
193206845Sluigi */
194204591Sluigistruct dn_sch {
195204591Sluigi	struct dn_id	oid;
196204591Sluigi	uint32_t	sched_nr; /* N, scheduler number */
197204591Sluigi	uint32_t	buckets; /* number of buckets for the instances */
198204591Sluigi	uint32_t	flags;	/* have_mask, ... */
19961413Sluigi
200204591Sluigi	char name[16];	/* null terminated */
201204591Sluigi	/* mask to select the appropriate scheduler instance */
202204591Sluigi	struct ipfw_flow_id sched_mask; /* M */
203204591Sluigi};
204190865Sluigi
205204591Sluigi
206204591Sluigi/* A delay profile is attached to a link.
207204591Sluigi * Note that a profile, as any other object, cannot be longer than 2^16
208204591Sluigi */
209204591Sluigi#define	ED_MAX_SAMPLES_NO	1024
210204591Sluigistruct dn_profile {
211204591Sluigi	struct dn_id	oid;
212206845Sluigi	/* fields to simulate a delay profile */
213190865Sluigi#define ED_MAX_NAME_LEN		32
214206845Sluigi	char	name[ED_MAX_NAME_LEN];
215206845Sluigi	int	link_nr;
216206845Sluigi	int	loss_level;
217206845Sluigi	int	bandwidth;			// XXX use link bandwidth?
218206845Sluigi	int	samples_no;			/* actual len of samples[] */
219206845Sluigi	int	samples[ED_MAX_SAMPLES_NO];	/* may be shorter */
22039119Sluigi};
221190865Sluigi
222300779Struckman#ifdef NEW_AQM
223300779Struckman/* Extra parameters for AQM and scheduler.
224300779Struckman * This struct is used to pass and retrieve parameters (configurations)
225300779Struckman * to/from AQM and Scheduler.
226300779Struckman */
227300779Struckmanstruct dn_extra_parms {
228300779Struckman	struct dn_id oid;
229300779Struckman	char name[16];
230300779Struckman	uint32_t nr;
231300779Struckman#define DN_MAX_EXTRA_PARM	10
232300779Struckman	int64_t par[DN_MAX_EXTRA_PARM];
233300779Struckman};
234300779Struckman#endif
235204591Sluigi
236204591Sluigi/*
237204591Sluigi * Overall structure of dummynet
238204591Sluigi
239204591SluigiIn dummynet, packets are selected with the firewall rules, and passed
240204591Sluigito two different objects: PIPE or QUEUE (bad name).
241204591Sluigi
242204591SluigiA QUEUE defines a classifier, which groups packets into flows
243204591Sluigiaccording to a 'mask', puts them into independent queues (one
244204591Sluigiper flow) with configurable size and queue management policy,
245204591Sluigiand passes flows to a scheduler:
246204591Sluigi
247204591Sluigi                 (flow_mask|sched_mask)  sched_mask
248204591Sluigi	 +---------+   weight Wx  +-------------+
249204591Sluigi         |         |->-[flow]-->--|             |-+
250204591Sluigi    -->--| QUEUE x |   ...        |             | |
251204591Sluigi         |         |->-[flow]-->--| SCHEDuler N | |
252204591Sluigi	 +---------+              |             | |
253204591Sluigi	     ...                  |             +--[LINK N]-->--
254204591Sluigi	 +---------+   weight Wy  |             | +--[LINK N]-->--
255204591Sluigi         |         |->-[flow]-->--|             | |
256204591Sluigi    -->--| QUEUE y |   ...        |             | |
257204591Sluigi         |         |->-[flow]-->--|             | |
258204591Sluigi	 +---------+              +-------------+ |
259204591Sluigi	                            +-------------+
260204591Sluigi
261204591SluigiMany QUEUE objects can connect to the same scheduler, each
262204591SluigiQUEUE object can have its own set of parameters.
263204591Sluigi
264204591SluigiIn turn, the SCHEDuler 'forks' multiple instances according
265204591Sluigito a 'sched_mask', each instance manages its own set of queues
266204591Sluigiand transmits on a private instance of a configurable LINK.
267204591Sluigi
268204591SluigiA PIPE is a simplified version of the above, where there
269204591Sluigiis no flow_mask, and each scheduler instance handles a single queue.
270204591Sluigi
271204591SluigiThe following data structures (visible from userland) describe
272204591Sluigithe objects used by dummynet:
273204591Sluigi
274204591Sluigi + dn_link, contains the main configuration parameters related
275204591Sluigi   to delay and bandwidth;
276204591Sluigi + dn_profile describes a delay profile;
277204591Sluigi + dn_flow describes the flow status (flow id, statistics)
278204591Sluigi
279204591Sluigi + dn_sch describes a scheduler
280204591Sluigi + dn_fs describes a flowset (msk, weight, queue parameters)
281204591Sluigi
282204591Sluigi *
283190865Sluigi */
284190865Sluigi
28539119Sluigi#endif /* _IP_DUMMYNET_H */
286