xref: /dragonfly/sys/net/altq/altq_classq.h (revision a3127495)
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_ */
175