/*-1* Copyright (c) 1991-1997 Regents of the University of California.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. All advertising materials mentioning features or use of this software13* must display the following acknowledgement:14* This product includes software developed by the Network Research15* Group at Lawrence Berkeley Laboratory.16* 4. Neither the name of the University nor of the Laboratory may be used17* to endorse or promote products derived from this software without18* specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*32* $KAME: altq_classq.h,v 1.6 2003/01/07 07:33:38 kjc Exp $33*/34/*35* class queue definitions extracted from rm_class.h.36*/37#ifndef _ALTQ_ALTQ_CLASSQ_H_38#define _ALTQ_ALTQ_CLASSQ_H_3940#ifdef __cplusplus41extern "C" {42#endif4344/*45* Packet Queue types: RED or DROPHEAD.46*/47#define Q_DROPHEAD 0x0048#define Q_RED 0x0149#define Q_RIO 0x0250#define Q_DROPTAIL 0x0351#define Q_CODEL 0x045253#ifdef _KERNEL5455/*56* Packet Queue structures and macros to manipulate them.57*/58struct _class_queue_ {59struct mbuf *tail_; /* Tail of packet queue */60int qlen_; /* Queue length (in number of packets) */61int qlim_; /* Queue limit (in number of packets*) */62int qsize_; /* Queue size (in number of bytes*) */63int qtype_; /* Queue type */64};6566typedef struct _class_queue_ class_queue_t;6768#define qtype(q) (q)->qtype_ /* Get queue type */69#define qlimit(q) (q)->qlim_ /* Max packets to be queued */70#define qlen(q) (q)->qlen_ /* Current queue length. */71#define qsize(q) (q)->qsize_ /* Current queue size. */72#define qtail(q) (q)->tail_ /* Tail of the queue */73#define qhead(q) ((q)->tail_ ? (q)->tail_->m_nextpkt : NULL)7475#define qempty(q) ((q)->qlen_ == 0) /* Is the queue empty?? */76#define q_is_codel(q) ((q)->qtype_ == Q_CODEL) /* Is the queue a codel queue */77#define q_is_red(q) ((q)->qtype_ == Q_RED) /* Is the queue a red queue */78#define q_is_rio(q) ((q)->qtype_ == Q_RIO) /* Is the queue a rio queue */79#define q_is_red_or_rio(q) ((q)->qtype_ == Q_RED || (q)->qtype_ == Q_RIO)8081#if !defined(__GNUC__) || defined(ALTQ_DEBUG)8283extern void _addq(class_queue_t *, struct mbuf *);84extern struct mbuf *_getq(class_queue_t *);85extern struct mbuf *_getq_tail(class_queue_t *);86extern struct mbuf *_getq_random(class_queue_t *);87extern void _removeq(class_queue_t *, struct mbuf *);88extern void _flushq(class_queue_t *);8990#else /* __GNUC__ && !ALTQ_DEBUG */91/*92* inlined versions93*/94static __inline void95_addq(class_queue_t *q, struct mbuf *m)96{97struct mbuf *m0;9899if ((m0 = qtail(q)) != NULL)100m->m_nextpkt = m0->m_nextpkt;101else102m0 = m;103m0->m_nextpkt = m;104qtail(q) = m;105qlen(q)++;106qsize(q) += m_pktlen(m);107}108109static __inline struct mbuf *110_getq(class_queue_t *q)111{112struct mbuf *m, *m0;113114if ((m = qtail(q)) == NULL)115return (NULL);116if ((m0 = m->m_nextpkt) != m)117m->m_nextpkt = m0->m_nextpkt;118else119qtail(q) = NULL;120qlen(q)--;121qsize(q) -= m_pktlen(m0);122m0->m_nextpkt = NULL;123return (m0);124}125126/* drop a packet at the tail of the queue */127static __inline struct mbuf *128_getq_tail(class_queue_t *q)129{130struct mbuf *m, *m0, *prev;131132if ((m = m0 = qtail(q)) == NULL)133return NULL;134do {135prev = m0;136m0 = m0->m_nextpkt;137} while (m0 != m);138prev->m_nextpkt = m->m_nextpkt;139if (prev == m)140qtail(q) = NULL;141else142qtail(q) = prev;143qlen(q)--;144m->m_nextpkt = NULL;145return (m);146}147148/* randomly select a packet in the queue */149static __inline struct mbuf *150_getq_random(class_queue_t *q)151{152struct mbuf *m;153int i, n;154155if ((m = qtail(q)) == NULL)156return NULL;157if (m->m_nextpkt == m)158qtail(q) = NULL;159else {160struct mbuf *prev = NULL;161162n = random() % qlen(q) + 1;163for (i = 0; i < n; i++) {164prev = m;165m = m->m_nextpkt;166}167prev->m_nextpkt = m->m_nextpkt;168if (m == qtail(q))169qtail(q) = prev;170}171qlen(q)--;172m->m_nextpkt = NULL;173return (m);174}175176static __inline void177_removeq(class_queue_t *q, struct mbuf *m)178{179struct mbuf *m0, *prev;180181m0 = qtail(q);182do {183prev = m0;184m0 = m0->m_nextpkt;185} while (m0 != m);186prev->m_nextpkt = m->m_nextpkt;187if (prev == m)188qtail(q) = NULL;189else if (qtail(q) == m)190qtail(q) = prev;191qlen(q)--;192}193194static __inline void195_flushq(class_queue_t *q)196{197struct mbuf *m;198199while ((m = _getq(q)) != NULL)200m_freem(m);201}202203#endif /* __GNUC__ && !ALTQ_DEBUG */204205#endif /* _KERNEL */206207#ifdef __cplusplus208}209#endif210211#endif /* _ALTQ_ALTQ_CLASSQ_H_ */212213214