ipfw3_nat: move func prototype into header
[dragonfly.git] / sys / net / altq / altq_classq.h
1 /*      $KAME: altq_classq.h,v 1.6 2003/01/07 07:33:38 kjc Exp $        */
2 /*      $DragonFly: src/sys/net/altq/altq_classq.h,v 1.2 2006/09/03 18:52:29 dillon Exp $ */
3
4 /*
5  * Copyright (c) 1991-1997 Regents of the University of California.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the Network Research
19  *      Group at Lawrence Berkeley Laboratory.
20  * 4. Neither the name of the University nor of the Laboratory may be used
21  *    to endorse or promote products derived from this software without
22  *    specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 /*
37  * class queue definitions extracted from rm_class.h.
38  */
39 #ifndef _ALTQ_ALTQ_CLASSQ_H_
40 #define _ALTQ_ALTQ_CLASSQ_H_
41
42 #include <net/altq/if_classq.h>
43
44 /*
45  * Packet Queue types: RED or DROPHEAD.
46  */
47 #define Q_DROPHEAD      0x00
48 #define Q_RED           0x01
49 #define Q_RIO           0x02
50 #define Q_DROPTAIL      0x03
51
52 #ifdef _KERNEL
53
54 /*
55  * Packet Queue structures and macros to manipulate them.
56  */
57 struct _class_queue_ {
58         struct if_classq que_;
59         int     qlen_;          /* Queue length (in number of packets) */
60         int     qlim_;          /* Queue limit (in number of packets*) */
61         int     qtype_;         /* Queue type */
62 };
63
64 typedef struct _class_queue_    class_queue_t;
65
66 #define qtype(q)        (q)->qtype_             /* Get queue type */
67 #define qlimit(q)       (q)->qlim_              /* Max packets to be queued */
68 #define qlen(q)         (q)->qlen_              /* Current queue length. */
69 #define qtail(q)        classq_tail(&(q)->que_) /* Tail of the queue */
70 #define qhead(q)        classq_head(&(q)->que_)
71
72 #define qempty(q)       ((q)->qlen_ == 0)       /* Is the queue empty?? */
73 #define q_is_red(q)     ((q)->qtype_ == Q_RED)  /* Is the queue a red queue */
74 #define q_is_rio(q)     ((q)->qtype_ == Q_RIO)  /* Is the queue a rio queue */
75 #define q_is_red_or_rio(q)      ((q)->qtype_ == Q_RED || (q)->qtype_ == Q_RIO)
76
77 static __inline void
78 _addq(class_queue_t *q, struct mbuf *m)
79 {
80         classq_add(&q->que_, m);
81         qlen(q)++;
82 }
83
84 static __inline struct mbuf *
85 _getq(class_queue_t *q)
86 {
87         struct mbuf *m;
88
89         m = classq_get(&q->que_);
90         if (m != NULL)
91                 qlen(q)--;
92         return (m);
93 }
94
95 /* drop a packet at the tail of the queue */
96 static __inline struct mbuf *
97 _getq_tail(class_queue_t *q)
98 {
99         struct mbuf *m, *m0, *prev;
100
101         if ((m = m0 = qtail(q)) == NULL)
102                 return NULL;
103         do {
104                 prev = m0;
105                 m0 = m0->m_nextpkt;
106         } while (m0 != m);
107         prev->m_nextpkt = m->m_nextpkt;
108         if (prev == m)
109                 qtail(q) = NULL;
110         else
111                 qtail(q) = prev;
112         qlen(q)--;
113         m->m_nextpkt = NULL;
114         return (m);
115 }
116
117 /* randomly select a packet in the queue */
118 static __inline struct mbuf *
119 _getq_random(class_queue_t *q)
120 {
121         struct mbuf *m;
122         int i, n;
123
124         if ((m = qtail(q)) == NULL)
125                 return NULL;
126         if (m->m_nextpkt == m)
127                 qtail(q) = NULL;
128         else {
129                 struct mbuf *prev = NULL;
130
131                 n = krandom() % qlen(q) + 1;
132                 for (i = 0; i < n; i++) {
133                         prev = m;
134                         m = m->m_nextpkt;
135                 }
136                 prev->m_nextpkt = m->m_nextpkt;
137                 if (m == qtail(q))
138                         qtail(q) = prev;
139         }
140         qlen(q)--;
141         m->m_nextpkt = NULL;
142         return (m);
143 }
144
145 static __inline void
146 _removeq(class_queue_t *q, struct mbuf *m)
147 {
148         struct mbuf *m0, *prev;
149
150         m0 = qtail(q);
151         do {
152                 prev = m0;
153                 m0 = m0->m_nextpkt;
154         } while (m0 != m);
155         prev->m_nextpkt = m->m_nextpkt;
156         if (prev == m)
157                 qtail(q) = NULL;
158         else if (qtail(q) == m)
159                 qtail(q) = prev;
160         qlen(q)--;
161 }
162
163 static __inline void
164 _flushq(class_queue_t *q)
165 {
166         struct mbuf *m;
167
168         while ((m = _getq(q)) != NULL)
169                 m_freem(m);
170 }
171
172 #endif /* _KERNEL */
173
174 #endif /* _ALTQ_ALTQ_CLASSQ_H_ */