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: releng/10.3/sys/netinet/ip_dummynet.h 239124 2012-08-07 07:52:25Z luigi $
2839119Sluigi */
2939119Sluigi
3039119Sluigi#ifndef _IP_DUMMYNET_H
3139119Sluigi#define _IP_DUMMYNET_H
3239119Sluigi
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,
88204591Sluigi
89204591Sluigi	DN_LAST,
90206845Sluigi};
9155597Sluigi
92204591Sluigienum { /* subtype for schedulers, flowset and the like */
93204591Sluigi	DN_SCHED_UNKNOWN = 0,
94204591Sluigi	DN_SCHED_FIFO = 1,
95204591Sluigi	DN_SCHED_WF2QP = 2,
96204591Sluigi	/* others are in individual modules */
97206845Sluigi};
9855597Sluigi
99204591Sluigienum {	/* user flags */
100204591Sluigi	DN_HAVE_MASK	= 0x0001,	/* fs or sched has a mask */
101204591Sluigi	DN_NOERROR	= 0x0002,	/* do not report errors */
102204591Sluigi	DN_QHT_HASH	= 0x0004,	/* qht is a hash table */
103204591Sluigi	DN_QSIZE_BYTES	= 0x0008,	/* queue size is in bytes */
104204591Sluigi	DN_HAS_PROFILE	= 0x0010,	/* a link has a profile */
105204591Sluigi	DN_IS_RED	= 0x0020,
106204591Sluigi	DN_IS_GENTLE_RED= 0x0040,
107204591Sluigi	DN_PIPE_CMD	= 0x1000,	/* pipe config... */
10839119Sluigi};
10939119Sluigi
11061413Sluigi/*
111204591Sluigi * link template.
11261413Sluigi */
113204591Sluigistruct dn_link {
114204591Sluigi	struct dn_id oid;
11561413Sluigi
116206845Sluigi	/*
117204591Sluigi	 * Userland sets bw and delay in bits/s and milliseconds.
118204591Sluigi	 * The kernel converts this back and forth to bits/tick and ticks.
119204591Sluigi	 * XXX what about burst ?
120206845Sluigi	 */
121204591Sluigi	int32_t		link_nr;
122204591Sluigi	int		bandwidth;	/* bit/s or bits/tick.   */
123204591Sluigi	int		delay;		/* ms and ticks */
124204591Sluigi	uint64_t	burst;		/* scaled. bits*Hz  XXX */
125206845Sluigi};
12655597Sluigi
12771137Sluigi/*
128204591Sluigi * A flowset, which is a template for flows. Contains parameters
129204591Sluigi * from the command line: id, target scheduler, queue sizes, plr,
130204591Sluigi * flow masks, buckets for the flow hash, and possibly scheduler-
131204591Sluigi * specific parameters (weight, quantum and so on).
13271137Sluigi */
133204591Sluigistruct dn_fs {
134204591Sluigi	struct dn_id oid;
135206845Sluigi	uint32_t fs_nr;		/* the flowset number */
136206845Sluigi	uint32_t flags;		/* userland flags */
137206845Sluigi	int qsize;		/* queue size in slots or bytes */
138206845Sluigi	int32_t plr;		/* PLR, pkt loss rate (2^31-1 means 100%) */
139204591Sluigi	uint32_t buckets;	/* buckets used for the queue hash table */
14061413Sluigi
141206845Sluigi	struct ipfw_flow_id flow_mask;
142204591Sluigi	uint32_t sched_nr;	/* the scheduler we attach to */
143204591Sluigi	/* generic scheduler parameters. Leave them at -1 if unset.
144204591Sluigi	 * Now we use 0: weight, 1: lmax, 2: priority
145204591Sluigi	 */
146204591Sluigi	int par[4];
14796077Sluigi
148204591Sluigi	/* RED/GRED parameters.
149204591Sluigi	 * weight and probabilities are in the range 0..1 represented
150204591Sluigi	 * in fixed point arithmetic with SCALE_RED decimal bits.
151204591Sluigi	 */
152206845Sluigi#define SCALE_RED	16
153206845Sluigi#define SCALE(x)	( (x) << SCALE_RED )
154206845Sluigi#define SCALE_VAL(x)	( (x) >> SCALE_RED )
155206845Sluigi#define SCALE_MUL(x,y)	( ( (x) * (y) ) >> SCALE_RED )
156206845Sluigi	int w_q ;		/* queue weight (scaled) */
157206845Sluigi	int max_th ;		/* maximum threshold for queue (scaled) */
158206845Sluigi	int min_th ;		/* minimum threshold for queue (scaled) */
159206845Sluigi	int max_p ;		/* maximum value for p_b (scaled) */
160204591Sluigi
161152910Sglebius};
16261413Sluigi
16355597Sluigi/*
164204591Sluigi * dn_flow collects flow_id and stats for queues and scheduler
165204591Sluigi * instances, and is used to pass these info to userland.
166204591Sluigi * oid.type/oid.subtype describe the object, oid.id is number
167204591Sluigi * of the parent object.
16855597Sluigi */
169204591Sluigistruct dn_flow {
170204591Sluigi	struct dn_id	oid;
171204591Sluigi	struct ipfw_flow_id fid;
172204591Sluigi	uint64_t	tot_pkts; /* statistics counters  */
173204591Sluigi	uint64_t	tot_bytes;
174239124Sluigi	uint32_t	length; /* Queue length, in packets */
175239124Sluigi	uint32_t	len_bytes; /* Queue length, in bytes */
176204591Sluigi	uint32_t	drops;
177204591Sluigi};
17839119Sluigi
17939119Sluigi
180206845Sluigi/*
181204591Sluigi * Scheduler template, mostly indicating the name, number,
182204591Sluigi * sched_mask and buckets.
183206845Sluigi */
184204591Sluigistruct dn_sch {
185204591Sluigi	struct dn_id	oid;
186204591Sluigi	uint32_t	sched_nr; /* N, scheduler number */
187204591Sluigi	uint32_t	buckets; /* number of buckets for the instances */
188204591Sluigi	uint32_t	flags;	/* have_mask, ... */
18961413Sluigi
190204591Sluigi	char name[16];	/* null terminated */
191204591Sluigi	/* mask to select the appropriate scheduler instance */
192204591Sluigi	struct ipfw_flow_id sched_mask; /* M */
193204591Sluigi};
194190865Sluigi
195204591Sluigi
196204591Sluigi/* A delay profile is attached to a link.
197204591Sluigi * Note that a profile, as any other object, cannot be longer than 2^16
198204591Sluigi */
199204591Sluigi#define	ED_MAX_SAMPLES_NO	1024
200204591Sluigistruct dn_profile {
201204591Sluigi	struct dn_id	oid;
202206845Sluigi	/* fields to simulate a delay profile */
203190865Sluigi#define ED_MAX_NAME_LEN		32
204206845Sluigi	char	name[ED_MAX_NAME_LEN];
205206845Sluigi	int	link_nr;
206206845Sluigi	int	loss_level;
207206845Sluigi	int	bandwidth;			// XXX use link bandwidth?
208206845Sluigi	int	samples_no;			/* actual len of samples[] */
209206845Sluigi	int	samples[ED_MAX_SAMPLES_NO];	/* may be shorter */
21039119Sluigi};
211190865Sluigi
212204591Sluigi
213204591Sluigi
214204591Sluigi/*
215204591Sluigi * Overall structure of dummynet
216204591Sluigi
217204591SluigiIn dummynet, packets are selected with the firewall rules, and passed
218204591Sluigito two different objects: PIPE or QUEUE (bad name).
219204591Sluigi
220204591SluigiA QUEUE defines a classifier, which groups packets into flows
221204591Sluigiaccording to a 'mask', puts them into independent queues (one
222204591Sluigiper flow) with configurable size and queue management policy,
223204591Sluigiand passes flows to a scheduler:
224204591Sluigi
225204591Sluigi                 (flow_mask|sched_mask)  sched_mask
226204591Sluigi	 +---------+   weight Wx  +-------------+
227204591Sluigi         |         |->-[flow]-->--|             |-+
228204591Sluigi    -->--| QUEUE x |   ...        |             | |
229204591Sluigi         |         |->-[flow]-->--| SCHEDuler N | |
230204591Sluigi	 +---------+              |             | |
231204591Sluigi	     ...                  |             +--[LINK N]-->--
232204591Sluigi	 +---------+   weight Wy  |             | +--[LINK N]-->--
233204591Sluigi         |         |->-[flow]-->--|             | |
234204591Sluigi    -->--| QUEUE y |   ...        |             | |
235204591Sluigi         |         |->-[flow]-->--|             | |
236204591Sluigi	 +---------+              +-------------+ |
237204591Sluigi	                            +-------------+
238204591Sluigi
239204591SluigiMany QUEUE objects can connect to the same scheduler, each
240204591SluigiQUEUE object can have its own set of parameters.
241204591Sluigi
242204591SluigiIn turn, the SCHEDuler 'forks' multiple instances according
243204591Sluigito a 'sched_mask', each instance manages its own set of queues
244204591Sluigiand transmits on a private instance of a configurable LINK.
245204591Sluigi
246204591SluigiA PIPE is a simplified version of the above, where there
247204591Sluigiis no flow_mask, and each scheduler instance handles a single queue.
248204591Sluigi
249204591SluigiThe following data structures (visible from userland) describe
250204591Sluigithe objects used by dummynet:
251204591Sluigi
252204591Sluigi + dn_link, contains the main configuration parameters related
253204591Sluigi   to delay and bandwidth;
254204591Sluigi + dn_profile describes a delay profile;
255204591Sluigi + dn_flow describes the flow status (flow id, statistics)
256204591Sluigi
257204591Sluigi + dn_sch describes a scheduler
258204591Sluigi + dn_fs describes a flowset (msk, weight, queue parameters)
259204591Sluigi
260204591Sluigi *
261190865Sluigi */
262190865Sluigi
26339119Sluigi#endif /* _IP_DUMMYNET_H */
264