14d723e5aSJoerg Sonnenberger /*- 24d723e5aSJoerg Sonnenberger * Copyright (c) 2005 The DragonFly Project. All rights reserved. 34d723e5aSJoerg Sonnenberger * 44d723e5aSJoerg Sonnenberger * Redistribution and use in source and binary forms, with or without 54d723e5aSJoerg Sonnenberger * modification, are permitted provided that the following conditions 64d723e5aSJoerg Sonnenberger * are met: 74d723e5aSJoerg Sonnenberger * 84d723e5aSJoerg Sonnenberger * 1. Redistributions of source code must retain the above copyright 94d723e5aSJoerg Sonnenberger * notice, this list of conditions and the following disclaimer. 104d723e5aSJoerg Sonnenberger * 2. Redistributions in binary form must reproduce the above copyright 114d723e5aSJoerg Sonnenberger * notice, this list of conditions and the following disclaimer in 124d723e5aSJoerg Sonnenberger * the documentation and/or other materials provided with the 134d723e5aSJoerg Sonnenberger * distribution. 144d723e5aSJoerg Sonnenberger * 3. Neither the name of The DragonFly Project nor the names of its 154d723e5aSJoerg Sonnenberger * contributors may be used to endorse or promote products derived 164d723e5aSJoerg Sonnenberger * from this software without specific, prior written permission. 174d723e5aSJoerg Sonnenberger * 184d723e5aSJoerg Sonnenberger * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 194d723e5aSJoerg Sonnenberger * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 204d723e5aSJoerg Sonnenberger * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 214d723e5aSJoerg Sonnenberger * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 224d723e5aSJoerg Sonnenberger * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 234d723e5aSJoerg Sonnenberger * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 244d723e5aSJoerg Sonnenberger * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 254d723e5aSJoerg Sonnenberger * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 264d723e5aSJoerg Sonnenberger * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 274d723e5aSJoerg Sonnenberger * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 284d723e5aSJoerg Sonnenberger * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 294d723e5aSJoerg Sonnenberger * SUCH DAMAGE. 304d723e5aSJoerg Sonnenberger * 31*9db4b353SSepherosa Ziehau * $DragonFly: src/sys/net/ifq_var.h,v 1.10 2008/05/14 11:59:23 sephe Exp $ 324d723e5aSJoerg Sonnenberger */ 3378195a76SMatthew Dillon /* 3478195a76SMatthew Dillon * NOTE ON MPSAFE access. Routines which manipulate the packet queue must 3578195a76SMatthew Dillon * be called within a critical section to interlock subsystems based on 3678195a76SMatthew Dillon * the MP lock, and must be holding the interface serializer to interlock 3778195a76SMatthew Dillon * MPSAFE subsystems. Once all subsystems are made MPSAFE, the critical 3878195a76SMatthew Dillon * section will no longer be required. 3978195a76SMatthew Dillon */ 4078195a76SMatthew Dillon 411bd40720SMatthew Dillon #ifndef _NET_IFQ_VAR_H_ 421bd40720SMatthew Dillon #define _NET_IFQ_VAR_H_ 434d723e5aSJoerg Sonnenberger 4403d6a592SMatthew Dillon #ifndef _KERNEL 4503d6a592SMatthew Dillon 4603d6a592SMatthew Dillon #error "This file should not be included by userland programs." 4703d6a592SMatthew Dillon 4803d6a592SMatthew Dillon #else 4903d6a592SMatthew Dillon 5003d6a592SMatthew Dillon #ifndef _SYS_SYSTM_H_ 511bd40720SMatthew Dillon #include <sys/systm.h> 521bd40720SMatthew Dillon #endif 531bd40720SMatthew Dillon #ifndef _SYS_THREAD2_H_ 544986965bSJoerg Sonnenberger #include <sys/thread2.h> 551bd40720SMatthew Dillon #endif 561bd40720SMatthew Dillon #ifndef _SYS_SERIALIZE_H_ 571bd40720SMatthew Dillon #include <sys/serialize.h> 581bd40720SMatthew Dillon #endif 591bd40720SMatthew Dillon #ifndef _SYS_MBUF_H_ 601bd40720SMatthew Dillon #include <sys/mbuf.h> 611bd40720SMatthew Dillon #endif 621bd40720SMatthew Dillon #ifndef _NET_IF_VAR_H_ 631bd40720SMatthew Dillon #include <net/if_var.h> 641bd40720SMatthew Dillon #endif 651bd40720SMatthew Dillon #ifndef _NET_ALTQ_IF_ALTQ_H_ 661bd40720SMatthew Dillon #include <net/altq/if_altq.h> 671bd40720SMatthew Dillon #endif 681bd40720SMatthew Dillon 691bd40720SMatthew Dillon struct ifaltq; 704986965bSJoerg Sonnenberger 71*9db4b353SSepherosa Ziehau /* 72*9db4b353SSepherosa Ziehau * Support for non-ALTQ interfaces. 73*9db4b353SSepherosa Ziehau */ 74*9db4b353SSepherosa Ziehau int ifq_classic_enqueue(struct ifaltq *, struct mbuf *, 75*9db4b353SSepherosa Ziehau struct altq_pktattr *); 76*9db4b353SSepherosa Ziehau struct mbuf *ifq_classic_dequeue(struct ifaltq *, struct mbuf *, int); 77*9db4b353SSepherosa Ziehau int ifq_classic_request(struct ifaltq *, int, void *); 78*9db4b353SSepherosa Ziehau void ifq_set_classic(struct ifaltq *); 79*9db4b353SSepherosa Ziehau 80*9db4b353SSepherosa Ziehau int ifq_dispatch(struct ifnet *, struct mbuf *, 81*9db4b353SSepherosa Ziehau struct altq_pktattr *); 82*9db4b353SSepherosa Ziehau 834d723e5aSJoerg Sonnenberger #ifdef ALTQ 844d723e5aSJoerg Sonnenberger static __inline int 854d723e5aSJoerg Sonnenberger ifq_is_enabled(struct ifaltq *_ifq) 864d723e5aSJoerg Sonnenberger { 874d723e5aSJoerg Sonnenberger return(_ifq->altq_flags & ALTQF_ENABLED); 884d723e5aSJoerg Sonnenberger } 894d723e5aSJoerg Sonnenberger 904d723e5aSJoerg Sonnenberger static __inline int 914d723e5aSJoerg Sonnenberger ifq_is_attached(struct ifaltq *_ifq) 924d723e5aSJoerg Sonnenberger { 934d723e5aSJoerg Sonnenberger return(_ifq->altq_disc != NULL); 944d723e5aSJoerg Sonnenberger } 954d723e5aSJoerg Sonnenberger #else 964d723e5aSJoerg Sonnenberger static __inline int 974d723e5aSJoerg Sonnenberger ifq_is_enabled(struct ifaltq *_ifq) 984d723e5aSJoerg Sonnenberger { 994d723e5aSJoerg Sonnenberger return(0); 1004d723e5aSJoerg Sonnenberger } 1014d723e5aSJoerg Sonnenberger 1024d723e5aSJoerg Sonnenberger static __inline int 1034d723e5aSJoerg Sonnenberger ifq_is_attached(struct ifaltq *_ifq) 1044d723e5aSJoerg Sonnenberger { 1054d723e5aSJoerg Sonnenberger return(0); 1064d723e5aSJoerg Sonnenberger } 1074d723e5aSJoerg Sonnenberger #endif 1084d723e5aSJoerg Sonnenberger 10978195a76SMatthew Dillon /* 11078195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 11178195a76SMatthew Dillon */ 1124d723e5aSJoerg Sonnenberger static __inline int 1134d723e5aSJoerg Sonnenberger ifq_is_ready(struct ifaltq *_ifq) 1144d723e5aSJoerg Sonnenberger { 1154d723e5aSJoerg Sonnenberger return(_ifq->altq_flags & ALTQF_READY); 1164d723e5aSJoerg Sonnenberger } 1174d723e5aSJoerg Sonnenberger 11878195a76SMatthew Dillon /* 11978195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 12078195a76SMatthew Dillon */ 1214d723e5aSJoerg Sonnenberger static __inline void 1224d723e5aSJoerg Sonnenberger ifq_set_ready(struct ifaltq *_ifq) 1234d723e5aSJoerg Sonnenberger { 1244d723e5aSJoerg Sonnenberger _ifq->altq_flags |= ALTQF_READY; 1254d723e5aSJoerg Sonnenberger } 1264d723e5aSJoerg Sonnenberger 12778195a76SMatthew Dillon /* 12878195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 12978195a76SMatthew Dillon */ 1304d723e5aSJoerg Sonnenberger static __inline int 131*9db4b353SSepherosa Ziehau ifq_enqueue_locked(struct ifaltq *_ifq, struct mbuf *_m, 132*9db4b353SSepherosa Ziehau struct altq_pktattr *_pa) 133*9db4b353SSepherosa Ziehau { 134*9db4b353SSepherosa Ziehau #ifdef ALTQ 135*9db4b353SSepherosa Ziehau if (!ifq_is_enabled(_ifq)) 136*9db4b353SSepherosa Ziehau return ifq_classic_enqueue(_ifq, _m, _pa); 137*9db4b353SSepherosa Ziehau else 138*9db4b353SSepherosa Ziehau #endif 139*9db4b353SSepherosa Ziehau return _ifq->altq_enqueue(_ifq, _m, _pa); 140*9db4b353SSepherosa Ziehau } 141*9db4b353SSepherosa Ziehau 142*9db4b353SSepherosa Ziehau static __inline int 1434d723e5aSJoerg Sonnenberger ifq_enqueue(struct ifaltq *_ifq, struct mbuf *_m, struct altq_pktattr *_pa) 1444d723e5aSJoerg Sonnenberger { 145*9db4b353SSepherosa Ziehau int _error; 146*9db4b353SSepherosa Ziehau 147*9db4b353SSepherosa Ziehau ALTQ_LOCK(_ifq); 148*9db4b353SSepherosa Ziehau _error = ifq_enqueue_locked(_ifq, _m, _pa); 149*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 150*9db4b353SSepherosa Ziehau return _error; 1514d723e5aSJoerg Sonnenberger } 1524d723e5aSJoerg Sonnenberger 15378195a76SMatthew Dillon /* 15478195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 15578195a76SMatthew Dillon */ 1564d723e5aSJoerg Sonnenberger static __inline struct mbuf * 157d2c71fa0SMatthew Dillon ifq_dequeue(struct ifaltq *_ifq, struct mbuf *_mpolled) 1584d723e5aSJoerg Sonnenberger { 159*9db4b353SSepherosa Ziehau struct mbuf *_m; 160*9db4b353SSepherosa Ziehau 161*9db4b353SSepherosa Ziehau ALTQ_LOCK(_ifq); 162*9db4b353SSepherosa Ziehau if (_ifq->altq_prepended != NULL) { 163*9db4b353SSepherosa Ziehau _m = _ifq->altq_prepended; 164*9db4b353SSepherosa Ziehau _ifq->altq_prepended = NULL; 165*9db4b353SSepherosa Ziehau KKASSERT(_ifq->ifq_len > 0); 166*9db4b353SSepherosa Ziehau _ifq->ifq_len--; 167*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 168*9db4b353SSepherosa Ziehau return _m; 169*9db4b353SSepherosa Ziehau } 170*9db4b353SSepherosa Ziehau 1714d723e5aSJoerg Sonnenberger #ifdef ALTQ 1724d723e5aSJoerg Sonnenberger if (_ifq->altq_tbr != NULL) 173*9db4b353SSepherosa Ziehau _m = tbr_dequeue(_ifq, _mpolled, ALTDQ_REMOVE); 174*9db4b353SSepherosa Ziehau else if (!ifq_is_enabled(_ifq)) 175*9db4b353SSepherosa Ziehau _m = ifq_classic_dequeue(_ifq, _mpolled, ALTDQ_REMOVE); 176*9db4b353SSepherosa Ziehau else 1774d723e5aSJoerg Sonnenberger #endif 178*9db4b353SSepherosa Ziehau _m = _ifq->altq_dequeue(_ifq, _mpolled, ALTDQ_REMOVE); 179*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 180*9db4b353SSepherosa Ziehau return _m; 1814d723e5aSJoerg Sonnenberger } 1824d723e5aSJoerg Sonnenberger 18378195a76SMatthew Dillon /* 18478195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 18578195a76SMatthew Dillon */ 1864d723e5aSJoerg Sonnenberger static __inline struct mbuf * 187*9db4b353SSepherosa Ziehau ifq_poll_locked(struct ifaltq *_ifq) 1884d723e5aSJoerg Sonnenberger { 189*9db4b353SSepherosa Ziehau if (_ifq->altq_prepended != NULL) 190*9db4b353SSepherosa Ziehau return _ifq->altq_prepended; 191*9db4b353SSepherosa Ziehau 1924d723e5aSJoerg Sonnenberger #ifdef ALTQ 1934d723e5aSJoerg Sonnenberger if (_ifq->altq_tbr != NULL) 194*9db4b353SSepherosa Ziehau return tbr_dequeue(_ifq, NULL, ALTDQ_POLL); 195*9db4b353SSepherosa Ziehau else if (!ifq_is_enabled(_ifq)) 196*9db4b353SSepherosa Ziehau return ifq_classic_dequeue(_ifq, NULL, ALTDQ_POLL); 197*9db4b353SSepherosa Ziehau else 1984d723e5aSJoerg Sonnenberger #endif 199*9db4b353SSepherosa Ziehau return _ifq->altq_dequeue(_ifq, NULL, ALTDQ_POLL); 200*9db4b353SSepherosa Ziehau } 201*9db4b353SSepherosa Ziehau 202*9db4b353SSepherosa Ziehau static __inline struct mbuf * 203*9db4b353SSepherosa Ziehau ifq_poll(struct ifaltq *_ifq) 204*9db4b353SSepherosa Ziehau { 205*9db4b353SSepherosa Ziehau struct mbuf *_m; 206*9db4b353SSepherosa Ziehau 207*9db4b353SSepherosa Ziehau ALTQ_LOCK(_ifq); 208*9db4b353SSepherosa Ziehau _m = ifq_poll_locked(_ifq); 209*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 210*9db4b353SSepherosa Ziehau return _m; 2114d723e5aSJoerg Sonnenberger } 2124d723e5aSJoerg Sonnenberger 21378195a76SMatthew Dillon /* 21478195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 21578195a76SMatthew Dillon */ 2164d723e5aSJoerg Sonnenberger static __inline void 217*9db4b353SSepherosa Ziehau ifq_purge_locked(struct ifaltq *_ifq) 218*9db4b353SSepherosa Ziehau { 219*9db4b353SSepherosa Ziehau if (_ifq->altq_prepended != NULL) { 220*9db4b353SSepherosa Ziehau m_freem(_ifq->altq_prepended); 221*9db4b353SSepherosa Ziehau _ifq->altq_prepended = NULL; 222*9db4b353SSepherosa Ziehau KKASSERT(_ifq->ifq_len > 0); 223*9db4b353SSepherosa Ziehau _ifq->ifq_len--; 224*9db4b353SSepherosa Ziehau } 225*9db4b353SSepherosa Ziehau 226*9db4b353SSepherosa Ziehau #ifdef ALTQ 227*9db4b353SSepherosa Ziehau if (!ifq_is_enabled(_ifq)) 228*9db4b353SSepherosa Ziehau ifq_classic_request(_ifq, ALTRQ_PURGE, NULL); 229*9db4b353SSepherosa Ziehau else 230*9db4b353SSepherosa Ziehau #endif 231*9db4b353SSepherosa Ziehau _ifq->altq_request(_ifq, ALTRQ_PURGE, NULL); 232*9db4b353SSepherosa Ziehau } 233*9db4b353SSepherosa Ziehau 234*9db4b353SSepherosa Ziehau static __inline void 2354d723e5aSJoerg Sonnenberger ifq_purge(struct ifaltq *_ifq) 2364d723e5aSJoerg Sonnenberger { 237*9db4b353SSepherosa Ziehau ALTQ_LOCK(_ifq); 238*9db4b353SSepherosa Ziehau ifq_purge_locked(_ifq); 239*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 2404d723e5aSJoerg Sonnenberger } 2414d723e5aSJoerg Sonnenberger 24278195a76SMatthew Dillon /* 24378195a76SMatthew Dillon * WARNING: Should only be called in an MPSAFE manner. 24478195a76SMatthew Dillon */ 2454d723e5aSJoerg Sonnenberger static __inline void 2464d723e5aSJoerg Sonnenberger ifq_classify(struct ifaltq *_ifq, struct mbuf *_m, uint8_t _af, 2474d723e5aSJoerg Sonnenberger struct altq_pktattr *_pa) 2484d723e5aSJoerg Sonnenberger { 249*9db4b353SSepherosa Ziehau #ifdef ALTQ 250*9db4b353SSepherosa Ziehau ALTQ_LOCK(_ifq); 251*9db4b353SSepherosa Ziehau if (ifq_is_enabled(_ifq)) { 2524d723e5aSJoerg Sonnenberger _pa->pattr_af = _af; 2534d723e5aSJoerg Sonnenberger _pa->pattr_hdr = mtod(_m, caddr_t); 2544d723e5aSJoerg Sonnenberger if (_ifq->altq_flags & ALTQF_CLASSIFY) 255*9db4b353SSepherosa Ziehau _ifq->altq_classify(_ifq, _m, _pa); 256*9db4b353SSepherosa Ziehau } 257*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 258*9db4b353SSepherosa Ziehau #endif 259*9db4b353SSepherosa Ziehau } 260*9db4b353SSepherosa Ziehau 261*9db4b353SSepherosa Ziehau static __inline void 262*9db4b353SSepherosa Ziehau ifq_prepend(struct ifaltq *_ifq, struct mbuf *_m) 263*9db4b353SSepherosa Ziehau { 264*9db4b353SSepherosa Ziehau ALTQ_LOCK(_ifq); 265*9db4b353SSepherosa Ziehau KASSERT(_ifq->altq_prepended == NULL, ("pending prepended mbuf\n")); 266*9db4b353SSepherosa Ziehau _ifq->altq_prepended = _m; 267*9db4b353SSepherosa Ziehau _ifq->ifq_len++; 268*9db4b353SSepherosa Ziehau ALTQ_UNLOCK(_ifq); 2694d723e5aSJoerg Sonnenberger } 2704d723e5aSJoerg Sonnenberger 27178195a76SMatthew Dillon /* 27278195a76SMatthew Dillon * Hand a packet to an interface. 27378195a76SMatthew Dillon * 27478195a76SMatthew Dillon * For subsystems protected by the MP lock, access to the queue is protected 27578195a76SMatthew Dillon * by a critical section. 27678195a76SMatthew Dillon * 27778195a76SMatthew Dillon * For MPSAFE subsystems and drivers, access to the queue is protected by 27878195a76SMatthew Dillon * the ifnet serializer. 27978195a76SMatthew Dillon */ 2804d723e5aSJoerg Sonnenberger static __inline int 2814d723e5aSJoerg Sonnenberger ifq_handoff(struct ifnet *_ifp, struct mbuf *_m, struct altq_pktattr *_pa) 2824d723e5aSJoerg Sonnenberger { 2834986965bSJoerg Sonnenberger int _error; 2844d723e5aSJoerg Sonnenberger 28578195a76SMatthew Dillon ASSERT_SERIALIZED(_ifp->if_serializer); 2864d723e5aSJoerg Sonnenberger _error = ifq_enqueue(&_ifp->if_snd, _m, _pa); 2874d723e5aSJoerg Sonnenberger if (_error == 0) { 2884d723e5aSJoerg Sonnenberger _ifp->if_obytes += _m->m_pkthdr.len; 2894d723e5aSJoerg Sonnenberger if (_m->m_flags & M_MCAST) 2904d723e5aSJoerg Sonnenberger _ifp->if_omcasts++; 2914d723e5aSJoerg Sonnenberger if ((_ifp->if_flags & IFF_OACTIVE) == 0) 2924d723e5aSJoerg Sonnenberger (*_ifp->if_start)(_ifp); 2934d723e5aSJoerg Sonnenberger } 2944d723e5aSJoerg Sonnenberger return(_error); 2954d723e5aSJoerg Sonnenberger } 2964d723e5aSJoerg Sonnenberger 2974d723e5aSJoerg Sonnenberger static __inline int 2984d723e5aSJoerg Sonnenberger ifq_is_empty(struct ifaltq *_ifq) 2994d723e5aSJoerg Sonnenberger { 3004d723e5aSJoerg Sonnenberger return(_ifq->ifq_len == 0); 3014d723e5aSJoerg Sonnenberger } 3024d723e5aSJoerg Sonnenberger 3034d723e5aSJoerg Sonnenberger static __inline void 3044d723e5aSJoerg Sonnenberger ifq_set_maxlen(struct ifaltq *_ifq, int _len) 3054d723e5aSJoerg Sonnenberger { 3064d723e5aSJoerg Sonnenberger _ifq->ifq_maxlen = _len; 3074d723e5aSJoerg Sonnenberger } 3084d723e5aSJoerg Sonnenberger 309*9db4b353SSepherosa Ziehau static __inline int 310*9db4b353SSepherosa Ziehau ifq_data_ready(struct ifaltq *_ifq) 311*9db4b353SSepherosa Ziehau { 312*9db4b353SSepherosa Ziehau #ifdef ALTQ 313*9db4b353SSepherosa Ziehau if (_ifq->altq_tbr != NULL) 314*9db4b353SSepherosa Ziehau return (ifq_poll_locked(_ifq) != NULL); 315*9db4b353SSepherosa Ziehau else 316*9db4b353SSepherosa Ziehau #endif 317*9db4b353SSepherosa Ziehau return !ifq_is_empty(_ifq); 318*9db4b353SSepherosa Ziehau } 319b2f93efeSJoerg Sonnenberger 32003d6a592SMatthew Dillon #endif /* _KERNEL */ 32103d6a592SMatthew Dillon #endif /* _NET_IFQ_VAR_H_ */ 322