2 * Copyright (c) 2005 The DragonFly Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
14 * 3. Neither the name of The DragonFly Project nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific, prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #ifndef _NET_IFQ_VAR_H_
33 #define _NET_IFQ_VAR_H_
37 #error "This file should not be included by userland programs."
42 #include <sys/systm.h>
44 #ifndef _SYS_THREAD2_H_
45 #include <sys/thread2.h>
47 #ifndef _SYS_SERIALIZE_H_
48 #include <sys/serialize.h>
53 #ifndef _NET_IF_VAR_H_
54 #include <net/if_var.h>
56 #ifndef _NET_ALTQ_IF_ALTQ_H_
57 #include <net/altq/if_altq.h>
63 * Support for "classic" ALTQ interfaces.
65 int ifq_classic_enqueue(struct ifaltq *, struct mbuf *,
66 struct altq_pktattr *);
67 struct mbuf *ifq_classic_dequeue(struct ifaltq *, struct mbuf *, int);
68 int ifq_classic_request(struct ifaltq *, int, void *);
69 void ifq_set_classic(struct ifaltq *);
71 void ifq_set_maxlen(struct ifaltq *, int);
74 * Dispatch a packet to an interface.
76 int ifq_dispatch(struct ifnet *, struct mbuf *,
77 struct altq_pktattr *);
82 ifq_is_enabled(struct ifaltq *_ifq)
84 return(_ifq->altq_flags & ALTQF_ENABLED);
88 ifq_is_attached(struct ifaltq *_ifq)
90 return(_ifq->altq_disc != NULL);
96 ifq_is_enabled(struct ifaltq *_ifq)
102 ifq_is_attached(struct ifaltq *_ifq)
110 ifq_is_ready(struct ifaltq *_ifq)
112 return(_ifq->altq_flags & ALTQF_READY);
116 ifq_set_ready(struct ifaltq *_ifq)
118 _ifq->altq_flags |= ALTQF_READY;
122 * ALTQ lock must be held
125 ifq_enqueue_locked(struct ifaltq *_ifq, struct mbuf *_m,
126 struct altq_pktattr *_pa)
129 if (!ifq_is_enabled(_ifq))
130 return ifq_classic_enqueue(_ifq, _m, _pa);
133 return _ifq->altq_enqueue(_ifq, _m, _pa);
137 ifq_enqueue(struct ifaltq *_ifq, struct mbuf *_m, struct altq_pktattr *_pa)
142 _error = ifq_enqueue_locked(_ifq, _m, _pa);
147 static __inline struct mbuf *
148 ifq_dequeue(struct ifaltq *_ifq, struct mbuf *_mpolled)
153 if (_ifq->altq_prepended != NULL) {
154 _m = _ifq->altq_prepended;
155 _ifq->altq_prepended = NULL;
156 KKASSERT(_ifq->ifq_len > 0);
163 if (_ifq->altq_tbr != NULL)
164 _m = tbr_dequeue(_ifq, _mpolled, ALTDQ_REMOVE);
165 else if (!ifq_is_enabled(_ifq))
166 _m = ifq_classic_dequeue(_ifq, _mpolled, ALTDQ_REMOVE);
169 _m = _ifq->altq_dequeue(_ifq, _mpolled, ALTDQ_REMOVE);
175 * ALTQ lock must be held
177 static __inline struct mbuf *
178 ifq_poll_locked(struct ifaltq *_ifq)
180 if (_ifq->altq_prepended != NULL)
181 return _ifq->altq_prepended;
184 if (_ifq->altq_tbr != NULL)
185 return tbr_dequeue(_ifq, NULL, ALTDQ_POLL);
186 else if (!ifq_is_enabled(_ifq))
187 return ifq_classic_dequeue(_ifq, NULL, ALTDQ_POLL);
190 return _ifq->altq_dequeue(_ifq, NULL, ALTDQ_POLL);
193 static __inline struct mbuf *
194 ifq_poll(struct ifaltq *_ifq)
199 _m = ifq_poll_locked(_ifq);
205 * ALTQ lock must be held
208 ifq_purge_locked(struct ifaltq *_ifq)
210 if (_ifq->altq_prepended != NULL) {
211 m_freem(_ifq->altq_prepended);
212 _ifq->altq_prepended = NULL;
213 KKASSERT(_ifq->ifq_len > 0);
218 if (!ifq_is_enabled(_ifq))
219 ifq_classic_request(_ifq, ALTRQ_PURGE, NULL);
222 _ifq->altq_request(_ifq, ALTRQ_PURGE, NULL);
226 ifq_purge(struct ifaltq *_ifq)
229 ifq_purge_locked(_ifq);
234 * ALTQ lock must be held
237 ifq_purge_all_locked(struct ifaltq *_ifq)
240 ifq_purge_locked(_ifq);
244 ifq_purge_all(struct ifaltq *_ifq)
247 ifq_purge_all_locked(_ifq);
252 ifq_classify(struct ifaltq *_ifq, struct mbuf *_m, uint8_t _af,
253 struct altq_pktattr *_pa)
257 if (ifq_is_enabled(_ifq)) {
259 _pa->pattr_hdr = mtod(_m, caddr_t);
260 if (_ifq->altq_flags & ALTQF_CLASSIFY)
261 _ifq->altq_classify(_ifq, _m, _pa);
268 ifq_prepend(struct ifaltq *_ifq, struct mbuf *_m)
271 KASSERT(_ifq->altq_prepended == NULL, ("pending prepended mbuf"));
272 _ifq->altq_prepended = _m;
278 * Interface TX serializer must be held
281 ifq_set_oactive(struct ifaltq *_ifq)
283 _ifq->altq_hw_oactive = 1;
287 * Interface TX serializer must be held
290 ifq_clr_oactive(struct ifaltq *_ifq)
292 _ifq->altq_hw_oactive = 0;
296 * Interface TX serializer must be held
299 ifq_is_oactive(const struct ifaltq *_ifq)
301 return _ifq->altq_hw_oactive;
305 * Hand a packet to an interface.
307 * Interface TX serializer must be held. If the interface TX
308 * serializer is not held yet, ifq_dispatch() should be used
309 * to get better performance.
312 ifq_handoff(struct ifnet *_ifp, struct mbuf *_m, struct altq_pktattr *_pa)
316 ASSERT_IFNET_SERIALIZED_TX(_ifp);
317 _error = ifq_enqueue(&_ifp->if_snd, _m, _pa);
319 _ifp->if_obytes += _m->m_pkthdr.len;
320 if (_m->m_flags & M_MCAST)
322 if (!ifq_is_oactive(&_ifp->if_snd))
323 (*_ifp->if_start)(_ifp);
329 ifq_is_empty(struct ifaltq *_ifq)
331 return(_ifq->ifq_len == 0);
335 * ALTQ lock must be held
338 ifq_data_ready(struct ifaltq *_ifq)
341 if (_ifq->altq_tbr != NULL)
342 return (ifq_poll_locked(_ifq) != NULL);
345 return !ifq_is_empty(_ifq);
349 #endif /* _NET_IFQ_VAR_H_ */