xref: /dragonfly/sys/net/ifq_var.h (revision 9db4b353)
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