]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/altq/altq_rmclass.h
sysctl(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / sys / net / altq / altq_rmclass.h
1 /*-
2  * Copyright (c) 1991-1997 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the Network Research
16  *      Group at Lawrence Berkeley Laboratory.
17  * 4. Neither the name of the University nor of the Laboratory may be used
18  *    to endorse or promote products derived from this software without
19  *    specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * $KAME: altq_rmclass.h,v 1.10 2003/08/20 23:30:23 itojun Exp $
34  * $FreeBSD$
35  */
36
37 #ifndef _ALTQ_ALTQ_RMCLASS_H_
38 #define _ALTQ_ALTQ_RMCLASS_H_
39
40 #include <net/altq/altq_classq.h>
41
42 /* #pragma ident "@(#)rm_class.h  1.20     97/10/23 SMI" */
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 #define RM_MAXPRIO      8       /* Max priority */
49
50 #ifdef _KERNEL
51
52 typedef struct mbuf             mbuf_t;
53 typedef struct rm_ifdat         rm_ifdat_t;
54 typedef struct rm_class         rm_class_t;
55
56 struct red;
57
58 /*
59  * Macros for dealing with time values.  We assume all times are
60  * 'timevals'.  `microtime' is used to get the best available clock
61  * resolution.  If `microtime' *doesn't* return a value that's about
62  * ten times smaller than the average packet time on the fastest
63  * link that will use these routines, a slightly different clock
64  * scheme than this one should be used.
65  * (Bias due to truncation error in this scheme will overestimate utilization
66  * and discriminate against high bandwidth classes.  To remove this bias an
67  * integrator needs to be added.  The simplest integrator uses a history of
68  * 10 * avg.packet.time / min.tick.time packet completion entries.  This is
69  * straight forward to add but we don't want to pay the extra memory
70  * traffic to maintain it if it's not necessary (occasionally a vendor
71  * accidentally builds a workstation with a decent clock - e.g., Sun & HP).)
72  */
73
74 #define RM_GETTIME(now) microtime(&now)
75
76 #define TV_LT(a, b) (((a)->tv_sec < (b)->tv_sec) ||  \
77         (((a)->tv_usec < (b)->tv_usec) && ((a)->tv_sec <= (b)->tv_sec)))
78
79 #define TV_DELTA(a, b, delta) { \
80         int     xxs;    \
81                                                         \
82         delta = (a)->tv_usec - (b)->tv_usec; \
83         if ((xxs = (a)->tv_sec - (b)->tv_sec)) { \
84                 switch (xxs) { \
85                 default: \
86                         /* if (xxs < 0) \
87                                 printf("rm_class: bogus time values\n"); */ \
88                         delta = 0; \
89                         /* fall through */ \
90                 case 2: \
91                         delta += 1000000; \
92                         /* fall through */ \
93                 case 1: \
94                         delta += 1000000; \
95                         break; \
96                 } \
97         } \
98 }
99
100 #define TV_ADD_DELTA(a, delta, res) { \
101         int xxus = (a)->tv_usec + (delta); \
102         \
103         (res)->tv_sec = (a)->tv_sec; \
104         while (xxus >= 1000000) { \
105                 ++((res)->tv_sec); \
106                 xxus -= 1000000; \
107         } \
108         (res)->tv_usec = xxus; \
109 }
110
111 #define RM_TIMEOUT      2       /* 1 Clock tick. */
112
113 #if 1
114 #define RM_MAXQUEUED    1       /* this isn't used in ALTQ/CBQ */
115 #else
116 #define RM_MAXQUEUED    16      /* Max number of packets downstream of CBQ */
117 #endif
118 #define RM_MAXQUEUE     64      /* Max queue length */
119 #define RM_FILTER_GAIN  5       /* log2 of gain, e.g., 5 => 31/32 */
120 #define RM_POWER        (1 << RM_FILTER_GAIN)
121 #define RM_MAXDEPTH     32
122 #define RM_NS_PER_SEC   (1000000000)
123
124 typedef struct _rm_class_stats_ {
125         u_int           handle;
126         u_int           depth;
127
128         struct pktcntr  xmit_cnt;       /* packets sent in this class */
129         struct pktcntr  drop_cnt;       /* dropped packets */
130         u_int           over;           /* # times went over limit */
131         u_int           borrows;        /* # times tried to borrow */
132         u_int           overactions;    /* # times invoked overlimit action */
133         u_int           delays;         /* # times invoked delay actions */
134 } rm_class_stats_t;
135
136 /*
137  * CBQ Class state structure
138  */
139 struct rm_class {
140         class_queue_t   *q_;            /* Queue of packets */
141         rm_ifdat_t      *ifdat_;
142         int             pri_;           /* Class priority. */
143         int             depth_;         /* Class depth */
144         u_int           ns_per_byte_;   /* NanoSeconds per byte. */
145         u_int           maxrate_;       /* Bytes per second for this class. */
146         u_int           allotment_;     /* Fraction of link bandwidth. */
147         u_int           w_allotment_;   /* Weighted allotment for WRR */
148         int             bytes_alloc_;   /* Allocation for round of WRR */
149
150         int             avgidle_;
151         int             maxidle_;
152         int             minidle_;
153         int             offtime_;
154         int             sleeping_;      /* != 0 if delaying */
155         int             qthresh_;       /* Queue threshold for formal link sharing */
156         int             leaf_;          /* Note whether leaf class or not.*/
157
158         rm_class_t      *children_;     /* Children of this class */
159         rm_class_t      *next_;         /* Next pointer, used if child */
160
161         rm_class_t      *peer_;         /* Peer class */
162         rm_class_t      *borrow_;       /* Borrow class */
163         rm_class_t      *parent_;       /* Parent class */
164
165         void    (*overlimit)(struct rm_class *, struct rm_class *);
166         void    (*drop)(struct rm_class *);       /* Class drop action. */
167
168         union {
169                 struct red      *red_;          /* RED state pointer */
170                 struct codel    *codel_;        /* codel state pointer */
171         } cl_aqm_;
172 #define red_            cl_aqm_.red_
173 #define codel_          cl_aqm_.codel_
174         struct altq_pktattr *pktattr_;  /* saved hdr used by RED/ECN */
175         int             flags_;
176
177         int             last_pkttime_;  /* saved pkt_time */
178         struct timeval  undertime_;     /* time can next send */
179         struct timeval  last_;          /* time last packet sent */
180         struct timeval  overtime_;
181         struct callout  callout_;       /* for timeout() calls */
182
183         rm_class_stats_t stats_;        /* Class Statistics */
184 };
185
186 /*
187  * CBQ Interface state
188  */
189 struct rm_ifdat {
190         int             queued_;        /* # pkts queued downstream */
191         int             efficient_;     /* Link Efficiency bit */
192         int             wrr_;           /* Enable Weighted Round-Robin */
193         u_long          ns_per_byte_;   /* Link byte speed. */
194         int             maxqueued_;     /* Max packets to queue */
195         int             maxpkt_;        /* Max packet size. */
196         int             qi_;            /* In/out pointers for downstream */
197         int             qo_;            /* packets */
198
199         /*
200          * Active class state and WRR state.
201          */
202         rm_class_t      *active_[RM_MAXPRIO];   /* Active cl's in each pri */
203         int             na_[RM_MAXPRIO];        /* # of active cl's in a pri */
204         int             num_[RM_MAXPRIO];       /* # of cl's per pri */
205         int             alloc_[RM_MAXPRIO];     /* Byte Allocation */
206         u_long          M_[RM_MAXPRIO];         /* WRR weights. */
207
208         /*
209          * Network Interface/Solaris Queue state pointer.
210          */
211         struct ifaltq   *ifq_;
212         rm_class_t      *default_;      /* Default Pkt class, BE */
213         rm_class_t      *root_;         /* Root Link class. */
214         rm_class_t      *ctl_;          /* Control Traffic class. */
215         void            (*restart)(struct ifaltq *);    /* Restart routine. */
216
217         /*
218          * Current packet downstream packet state and dynamic state.
219          */
220         rm_class_t      *borrowed_[RM_MAXQUEUED]; /* Class borrowed last */
221         rm_class_t      *class_[RM_MAXQUEUED];  /* class sending */
222         int             curlen_[RM_MAXQUEUED];  /* Current pktlen */
223         struct timeval  now_[RM_MAXQUEUED];     /* Current packet time. */
224         int             is_overlimit_[RM_MAXQUEUED];/* Current packet time. */
225
226         int             cutoff_;        /* Cut-off depth for borrowing */
227
228         struct timeval  ifnow_;         /* expected xmit completion time */
229 #if 1 /* ALTQ4PPP */
230         int             maxiftime_;     /* max delay inside interface */
231 #endif
232         rm_class_t      *pollcache_;    /* cached rm_class by poll operation */
233 };
234
235 /* flags for rmc_init and rmc_newclass */
236 /* class flags; must be the same as class flags in altq_cbq.h */
237 #define RMCF_RED                0x0001
238 #define RMCF_ECN                0x0002
239 #define RMCF_RIO                0x0004
240 #define RMCF_FLOWVALVE          0x0008  /* use flowvalve (aka penalty-box) */
241 #define RMCF_CLEARDSCP          0x0010  /* clear diffserv codepoint */
242 #define RMCF_CODEL              0x0040
243
244 /* flags for rmc_init */
245 #define RMCF_WRR                0x0100
246 #define RMCF_EFFICIENT          0x0200
247
248 #define is_a_parent_class(cl)   ((cl)->children_ != NULL)
249
250 extern rm_class_t *rmc_newclass(int, struct rm_ifdat *, u_int,
251                                 void (*)(struct rm_class *, struct rm_class *),
252                                 int, struct rm_class *, struct rm_class *,
253                                 u_int, int, u_int, int, int);
254 extern void     rmc_delete_class(struct rm_ifdat *, struct rm_class *);
255 extern int      rmc_modclass(struct rm_class *, u_int, int,
256                              u_int, int, u_int, int);
257 extern void     rmc_init(struct ifaltq *, struct rm_ifdat *, u_int,
258                          void (*)(struct ifaltq *),
259                          int, int, u_int, int, u_int, int);
260 extern int      rmc_queue_packet(struct rm_class *, mbuf_t *);
261 extern mbuf_t   *rmc_dequeue_next(struct rm_ifdat *, int);
262 extern void     rmc_update_class_util(struct rm_ifdat *);
263 extern void     rmc_delay_action(struct rm_class *, struct rm_class *);
264 extern void     rmc_dropall(struct rm_class *);
265 extern int      rmc_get_weight(struct rm_ifdat *, int);
266
267 #endif /* _KERNEL */
268
269 #ifdef __cplusplus
270 }
271 #endif
272
273 #endif /* _ALTQ_ALTQ_RMCLASS_H_ */