1126385Smlaier/*	$FreeBSD$	*/
2126385Smlaier/*	$KAME: altq_hfsc.h,v 1.10 2003/07/10 12:07:48 kjc Exp $	*/
3126385Smlaier
4126385Smlaier/*
5126385Smlaier * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved.
6126385Smlaier *
7126385Smlaier * Permission to use, copy, modify, and distribute this software and
8126385Smlaier * its documentation is hereby granted (including for commercial or
9126385Smlaier * for-profit use), provided that both the copyright notice and this
10126385Smlaier * permission notice appear in all copies of the software, derivative
11126385Smlaier * works, or modified versions, and any portions thereof, and that
12126385Smlaier * both notices appear in supporting documentation, and that credit
13126385Smlaier * is given to Carnegie Mellon University in all publications reporting
14126385Smlaier * on direct or indirect use of this code or its derivatives.
15126385Smlaier *
16126385Smlaier * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF
17126385Smlaier * WHICH MAY HAVE SERIOUS CONSEQUENCES.  CARNEGIE MELLON PROVIDES THIS
18126385Smlaier * SOFTWARE IN ITS ``AS IS'' CONDITION, AND ANY EXPRESS OR IMPLIED
19126385Smlaier * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20126385Smlaier * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21126385Smlaier * DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
22126385Smlaier * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23126385Smlaier * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24126385Smlaier * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25126385Smlaier * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26126385Smlaier * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27126385Smlaier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
28126385Smlaier * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29126385Smlaier * DAMAGE.
30126385Smlaier *
31126385Smlaier * Carnegie Mellon encourages (but does not require) users of this
32126385Smlaier * software to return any improvements or extensions that they make,
33126385Smlaier * and to grant Carnegie Mellon the rights to redistribute these
34126385Smlaier * changes without encumbrance.
35126385Smlaier */
36126385Smlaier#ifndef _ALTQ_ALTQ_HFSC_H_
37126385Smlaier#define	_ALTQ_ALTQ_HFSC_H_
38126385Smlaier
39126385Smlaier#include <altq/altq.h>
40126385Smlaier#include <altq/altq_classq.h>
41126385Smlaier#include <altq/altq_red.h>
42126385Smlaier#include <altq/altq_rio.h>
43126385Smlaier
44126385Smlaier#ifdef __cplusplus
45126385Smlaierextern "C" {
46126385Smlaier#endif
47126385Smlaier
48126385Smlaierstruct service_curve {
49126385Smlaier	u_int	m1;	/* slope of the first segment in bits/sec */
50126385Smlaier	u_int	d;	/* the x-projection of the first segment in msec */
51126385Smlaier	u_int	m2;	/* slope of the second segment in bits/sec */
52126385Smlaier};
53126385Smlaier
54126385Smlaier/* special class handles */
55126385Smlaier#define	HFSC_NULLCLASS_HANDLE	0
56126385Smlaier#define	HFSC_ROOTCLASS_HANDLE	1
57126385Smlaier#define	HFSC_MAX_CLASSES	64
58126385Smlaier
59126385Smlaier/* hfsc class flags */
60126385Smlaier#define	HFCF_RED		0x0001	/* use RED */
61126385Smlaier#define	HFCF_ECN		0x0002  /* use RED/ECN */
62126385Smlaier#define	HFCF_RIO		0x0004  /* use RIO */
63126385Smlaier#define	HFCF_CLEARDSCP		0x0010  /* clear diffserv codepoint */
64126385Smlaier#define	HFCF_DEFAULTCLASS	0x1000	/* default class */
65126385Smlaier
66126385Smlaier/* service curve types */
67126385Smlaier#define	HFSC_REALTIMESC		1
68126385Smlaier#define	HFSC_LINKSHARINGSC	2
69126385Smlaier#define	HFSC_UPPERLIMITSC	4
70126385Smlaier#define	HFSC_DEFAULTSC		(HFSC_REALTIMESC|HFSC_LINKSHARINGSC)
71126385Smlaier
72126385Smlaierstruct hfsc_classstats {
73126385Smlaier	u_int			class_id;
74126385Smlaier	u_int32_t		class_handle;
75126385Smlaier	struct service_curve	rsc;
76126385Smlaier	struct service_curve	fsc;
77126385Smlaier	struct service_curve	usc;	/* upper limit service curve */
78126385Smlaier
79126385Smlaier	u_int64_t		total;	/* total work in bytes */
80126385Smlaier	u_int64_t		cumul;	/* cumulative work in bytes
81126385Smlaier					   done by real-time criteria */
82126385Smlaier	u_int64_t		d;		/* deadline */
83126385Smlaier	u_int64_t		e;		/* eligible time */
84126385Smlaier	u_int64_t		vt;		/* virtual time */
85126385Smlaier	u_int64_t		f;		/* fit time for upper-limit */
86126385Smlaier
87126385Smlaier	/* info helpful for debugging */
88126385Smlaier	u_int64_t		initvt;		/* init virtual time */
89126385Smlaier	u_int64_t		vtoff;		/* cl_vt_ipoff */
90126385Smlaier	u_int64_t		cvtmax;		/* cl_maxvt */
91126385Smlaier	u_int64_t		myf;		/* cl_myf */
92126385Smlaier	u_int64_t		cfmin;		/* cl_mincf */
93126385Smlaier	u_int64_t		cvtmin;		/* cl_mincvt */
94126385Smlaier	u_int64_t		myfadj;		/* cl_myfadj */
95126385Smlaier	u_int64_t		vtadj;		/* cl_vtadj */
96126385Smlaier	u_int64_t		cur_time;
97126385Smlaier	u_int32_t		machclk_freq;
98126385Smlaier
99126385Smlaier	u_int			qlength;
100126385Smlaier	u_int			qlimit;
101126385Smlaier	struct pktcntr		xmit_cnt;
102126385Smlaier	struct pktcntr		drop_cnt;
103126385Smlaier	u_int			period;
104126385Smlaier
105126385Smlaier	u_int			vtperiod;	/* vt period sequence no */
106126385Smlaier	u_int			parentperiod;	/* parent's vt period seqno */
107126385Smlaier	int			nactive;	/* number of active children */
108126385Smlaier
109126385Smlaier	/* red and rio related info */
110126385Smlaier	int			qtype;
111126385Smlaier	struct redstats		red[3];
112126385Smlaier};
113126385Smlaier
114126385Smlaier#ifdef ALTQ3_COMPAT
115126385Smlaierstruct hfsc_interface {
116126385Smlaier	char	hfsc_ifname[IFNAMSIZ];  /* interface name (e.g., fxp0) */
117126385Smlaier};
118126385Smlaier
119126385Smlaierstruct hfsc_attach {
120126385Smlaier	struct hfsc_interface	iface;
121126385Smlaier	u_int			bandwidth;  /* link bandwidth in bits/sec */
122126385Smlaier};
123126385Smlaier
124126385Smlaierstruct hfsc_add_class {
125126385Smlaier	struct hfsc_interface	iface;
126126385Smlaier	u_int32_t		parent_handle;
127126385Smlaier	struct service_curve	service_curve;
128126385Smlaier	int			qlimit;
129126385Smlaier	int			flags;
130126385Smlaier
131126385Smlaier	u_int32_t		class_handle;  /* return value */
132126385Smlaier};
133126385Smlaier
134126385Smlaierstruct hfsc_delete_class {
135126385Smlaier	struct hfsc_interface	iface;
136126385Smlaier	u_int32_t		class_handle;
137126385Smlaier};
138126385Smlaier
139126385Smlaierstruct hfsc_modify_class {
140126385Smlaier	struct hfsc_interface	iface;
141126385Smlaier	u_int32_t		class_handle;
142126385Smlaier	struct service_curve	service_curve;
143126385Smlaier	int			sctype;
144126385Smlaier};
145126385Smlaier
146126385Smlaierstruct hfsc_add_filter {
147126385Smlaier	struct hfsc_interface	iface;
148126385Smlaier	u_int32_t		class_handle;
149126385Smlaier	struct flow_filter	filter;
150126385Smlaier
151126385Smlaier	u_long			filter_handle;  /* return value */
152126385Smlaier};
153126385Smlaier
154126385Smlaierstruct hfsc_delete_filter {
155126385Smlaier	struct hfsc_interface	iface;
156126385Smlaier	u_long			filter_handle;
157126385Smlaier};
158126385Smlaier
159126385Smlaierstruct hfsc_class_stats {
160126385Smlaier	struct hfsc_interface	iface;
161126385Smlaier	int			nskip;		/* skip # of classes */
162126385Smlaier	int			nclasses;	/* # of class stats (WR) */
163126385Smlaier	u_int64_t		cur_time;	/* current time */
164126385Smlaier	u_int32_t		machclk_freq;	/* machine clock frequency */
165126385Smlaier	u_int			hif_classes;	/* # of classes in the tree */
166126385Smlaier	u_int			hif_packets;	/* # of packets in the tree */
167126385Smlaier	struct hfsc_classstats	*stats;		/* pointer to stats array */
168126385Smlaier};
169126385Smlaier
170126385Smlaier#define	HFSC_IF_ATTACH		_IOW('Q', 1, struct hfsc_attach)
171126385Smlaier#define	HFSC_IF_DETACH		_IOW('Q', 2, struct hfsc_interface)
172126385Smlaier#define	HFSC_ENABLE		_IOW('Q', 3, struct hfsc_interface)
173126385Smlaier#define	HFSC_DISABLE		_IOW('Q', 4, struct hfsc_interface)
174126385Smlaier#define	HFSC_CLEAR_HIERARCHY	_IOW('Q', 5, struct hfsc_interface)
175126385Smlaier#define	HFSC_ADD_CLASS		_IOWR('Q', 7, struct hfsc_add_class)
176126385Smlaier#define	HFSC_DEL_CLASS		_IOW('Q', 8, struct hfsc_delete_class)
177126385Smlaier#define	HFSC_MOD_CLASS		_IOW('Q', 9, struct hfsc_modify_class)
178126385Smlaier#define	HFSC_ADD_FILTER		_IOWR('Q', 10, struct hfsc_add_filter)
179126385Smlaier#define	HFSC_DEL_FILTER		_IOW('Q', 11, struct hfsc_delete_filter)
180126385Smlaier#define	HFSC_GETSTATS		_IOWR('Q', 12, struct hfsc_class_stats)
181126385Smlaier#endif /* ALTQ3_COMPAT */
182126385Smlaier
183126385Smlaier#ifdef _KERNEL
184126385Smlaier/*
185126385Smlaier * kernel internal service curve representation
186126385Smlaier *	coordinates are given by 64 bit unsigned integers.
187126385Smlaier *	x-axis: unit is clock count.  for the intel x86 architecture,
188126385Smlaier *		the raw Pentium TSC (Timestamp Counter) value is used.
189126385Smlaier *		virtual time is also calculated in this time scale.
190126385Smlaier *	y-axis: unit is byte.
191126385Smlaier *
192126385Smlaier *	the service curve parameters are converted to the internal
193126385Smlaier *	representation.
194126385Smlaier *	the slope values are scaled to avoid overflow.
195126385Smlaier *	the inverse slope values as well as the y-projection of the 1st
196126385Smlaier *	segment are kept in order to to avoid 64-bit divide operations
197126385Smlaier *	that are expensive on 32-bit architectures.
198126385Smlaier *
199126385Smlaier *  note: Intel Pentium TSC never wraps around in several thousands of years.
200126385Smlaier *	x-axis doesn't wrap around for 1089 years with 1GHz clock.
201126385Smlaier *      y-axis doesn't wrap around for 4358 years with 1Gbps bandwidth.
202126385Smlaier */
203126385Smlaier
204126385Smlaier/* kernel internal representation of a service curve */
205126385Smlaierstruct internal_sc {
206126385Smlaier	u_int64_t	sm1;	/* scaled slope of the 1st segment */
207126385Smlaier	u_int64_t	ism1;	/* scaled inverse-slope of the 1st segment */
208126385Smlaier	u_int64_t	dx;	/* the x-projection of the 1st segment */
209126385Smlaier	u_int64_t	dy;	/* the y-projection of the 1st segment */
210126385Smlaier	u_int64_t	sm2;	/* scaled slope of the 2nd segment */
211126385Smlaier	u_int64_t	ism2;	/* scaled inverse-slope of the 2nd segment */
212126385Smlaier};
213126385Smlaier
214126385Smlaier/* runtime service curve */
215126385Smlaierstruct runtime_sc {
216126385Smlaier	u_int64_t	x;	/* current starting position on x-axis */
217126385Smlaier	u_int64_t	y;	/* current starting position on x-axis */
218126385Smlaier	u_int64_t	sm1;	/* scaled slope of the 1st segment */
219126385Smlaier	u_int64_t	ism1;	/* scaled inverse-slope of the 1st segment */
220126385Smlaier	u_int64_t	dx;	/* the x-projection of the 1st segment */
221126385Smlaier	u_int64_t	dy;	/* the y-projection of the 1st segment */
222126385Smlaier	u_int64_t	sm2;	/* scaled slope of the 2nd segment */
223126385Smlaier	u_int64_t	ism2;	/* scaled inverse-slope of the 2nd segment */
224126385Smlaier};
225126385Smlaier
226126385Smlaier/* for TAILQ based ellist and actlist implementation */
227126385Smlaierstruct hfsc_class;
228126385Smlaiertypedef TAILQ_HEAD(_eligible, hfsc_class) ellist_t;
229126385Smlaiertypedef TAILQ_ENTRY(hfsc_class) elentry_t;
230126385Smlaiertypedef TAILQ_HEAD(_active, hfsc_class) actlist_t;
231126385Smlaiertypedef TAILQ_ENTRY(hfsc_class) actentry_t;
232126385Smlaier#define	ellist_first(s)		TAILQ_FIRST(s)
233126385Smlaier#define	actlist_first(s)	TAILQ_FIRST(s)
234126385Smlaier#define	actlist_last(s)		TAILQ_LAST(s, _active)
235126385Smlaier
236126385Smlaierstruct hfsc_class {
237126385Smlaier	u_int		cl_id;		/* class id (just for debug) */
238126385Smlaier	u_int32_t	cl_handle;	/* class handle */
239126385Smlaier	struct hfsc_if	*cl_hif;	/* back pointer to struct hfsc_if */
240126385Smlaier	int		cl_flags;	/* misc flags */
241126385Smlaier
242126385Smlaier	struct hfsc_class *cl_parent;	/* parent class */
243126385Smlaier	struct hfsc_class *cl_siblings;	/* sibling classes */
244126385Smlaier	struct hfsc_class *cl_children;	/* child classes */
245126385Smlaier
246126385Smlaier	class_queue_t	*cl_q;		/* class queue structure */
247126385Smlaier	struct red	*cl_red;	/* RED state */
248126385Smlaier	struct altq_pktattr *cl_pktattr; /* saved header used by ECN */
249126385Smlaier
250126385Smlaier	u_int64_t	cl_total;	/* total work in bytes */
251126385Smlaier	u_int64_t	cl_cumul;	/* cumulative work in bytes
252126385Smlaier					   done by real-time criteria */
253126385Smlaier	u_int64_t	cl_d;		/* deadline */
254126385Smlaier	u_int64_t	cl_e;		/* eligible time */
255126385Smlaier	u_int64_t	cl_vt;		/* virtual time */
256126385Smlaier	u_int64_t	cl_f;		/* time when this class will fit for
257126385Smlaier					   link-sharing, max(myf, cfmin) */
258126385Smlaier	u_int64_t	cl_myf;		/* my fit-time (as calculated from this
259126385Smlaier					   class's own upperlimit curve) */
260126385Smlaier	u_int64_t	cl_myfadj;	/* my fit-time adjustment
261126385Smlaier					   (to cancel history dependence) */
262126385Smlaier	u_int64_t	cl_cfmin;	/* earliest children's fit-time (used
263126385Smlaier					   with cl_myf to obtain cl_f) */
264126385Smlaier	u_int64_t	cl_cvtmin;	/* minimal virtual time among the
265126385Smlaier					   children fit for link-sharing
266126385Smlaier					   (monotonic within a period) */
267126385Smlaier	u_int64_t	cl_vtadj;	/* intra-period cumulative vt
268126385Smlaier					   adjustment */
269126385Smlaier	u_int64_t	cl_vtoff;	/* inter-period cumulative vt offset */
270126385Smlaier	u_int64_t	cl_cvtmax;	/* max child's vt in the last period */
271126385Smlaier
272126385Smlaier	u_int64_t	cl_initvt;	/* init virtual time (for debugging) */
273126385Smlaier
274126385Smlaier	struct internal_sc *cl_rsc;	/* internal real-time service curve */
275126385Smlaier	struct internal_sc *cl_fsc;	/* internal fair service curve */
276126385Smlaier	struct internal_sc *cl_usc;	/* internal upperlimit service curve */
277126385Smlaier	struct runtime_sc  cl_deadline;	/* deadline curve */
278126385Smlaier	struct runtime_sc  cl_eligible;	/* eligible curve */
279126385Smlaier	struct runtime_sc  cl_virtual;	/* virtual curve */
280126385Smlaier	struct runtime_sc  cl_ulimit;	/* upperlimit curve */
281126385Smlaier
282126385Smlaier	u_int		cl_vtperiod;	/* vt period sequence no */
283126385Smlaier	u_int		cl_parentperiod;  /* parent's vt period seqno */
284126385Smlaier	int		cl_nactive;	/* number of active children */
285126385Smlaier	actlist_t	*cl_actc;	/* active children list */
286126385Smlaier
287126385Smlaier	actentry_t	cl_actlist;	/* active children list entry */
288126385Smlaier	elentry_t	cl_ellist;	/* eligible list entry */
289126385Smlaier
290126385Smlaier	struct {
291126385Smlaier		struct pktcntr	xmit_cnt;
292126385Smlaier		struct pktcntr	drop_cnt;
293126385Smlaier		u_int period;
294126385Smlaier	} cl_stats;
295126385Smlaier};
296126385Smlaier
297126385Smlaier/*
298126385Smlaier * hfsc interface state
299126385Smlaier */
300126385Smlaierstruct hfsc_if {
301126385Smlaier	struct hfsc_if		*hif_next;	/* interface state list */
302126385Smlaier	struct ifaltq		*hif_ifq;	/* backpointer to ifaltq */
303126385Smlaier	struct hfsc_class	*hif_rootclass;		/* root class */
304126385Smlaier	struct hfsc_class	*hif_defaultclass;	/* default class */
305126385Smlaier	struct hfsc_class	*hif_class_tbl[HFSC_MAX_CLASSES];
306126385Smlaier	struct hfsc_class	*hif_pollcache;	/* cache for poll operation */
307126385Smlaier
308126385Smlaier	u_int	hif_classes;			/* # of classes in the tree */
309126385Smlaier	u_int	hif_packets;			/* # of packets in the tree */
310126385Smlaier	u_int	hif_classid;			/* class id sequence number */
311126385Smlaier
312126385Smlaier	ellist_t *hif_eligible;			/* eligible list */
313126385Smlaier
314126385Smlaier#ifdef ALTQ3_CLFIER_COMPAT
315126385Smlaier	struct acc_classifier	hif_classifier;
316126385Smlaier#endif
317126385Smlaier};
318126385Smlaier
319126385Smlaier#endif /* _KERNEL */
320126385Smlaier
321126385Smlaier#ifdef __cplusplus
322126385Smlaier}
323126385Smlaier#endif
324126385Smlaier
325126385Smlaier#endif /* _ALTQ_ALTQ_HFSC_H_ */
326