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