The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/ifq.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1982, 1986, 1989, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    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 the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 4. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      From: @(#)if.h  8.1 (Berkeley) 6/10/93
   30  * $FreeBSD: releng/11.2/sys/net/ifq.h 331722 2018-03-29 02:50:57Z eadler $
   31  */
   32 
   33 #ifndef _NET_IFQ_H_
   34 #define _NET_IFQ_H_
   35 
   36 #ifdef _KERNEL
   37 #include <sys/mbuf.h>           /* ifqueue only? */
   38 #include <sys/buf_ring.h>
   39 #include <net/vnet.h>
   40 #endif /* _KERNEL */
   41 #include <sys/lock.h>           /* XXX */
   42 #include <sys/mutex.h>          /* struct ifqueue */
   43 
   44 /*
   45  * Couple of ugly extra definitions that are required since ifq.h
   46  * is splitted from if_var.h.
   47  */
   48 #define IF_DUNIT_NONE   -1
   49 
   50 #include <net/altq/if_altq.h>
   51 
   52 /*
   53  * Structure defining a queue for a network interface.
   54  */
   55 struct  ifqueue {
   56         struct  mbuf *ifq_head;
   57         struct  mbuf *ifq_tail;
   58         int     ifq_len;
   59         int     ifq_maxlen;
   60         struct  mtx ifq_mtx;
   61 };
   62 
   63 #ifdef _KERNEL
   64 /*
   65  * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
   66  * are queues of messages stored on ifqueue structures
   67  * (defined above).  Entries are added to and deleted from these structures
   68  * by these macros.
   69  */
   70 #define IF_LOCK(ifq)            mtx_lock(&(ifq)->ifq_mtx)
   71 #define IF_UNLOCK(ifq)          mtx_unlock(&(ifq)->ifq_mtx)
   72 #define IF_LOCK_ASSERT(ifq)     mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
   73 #define _IF_QFULL(ifq)          ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
   74 #define _IF_QLEN(ifq)           ((ifq)->ifq_len)
   75 
   76 #define _IF_ENQUEUE(ifq, m) do {                                \
   77         (m)->m_nextpkt = NULL;                                  \
   78         if ((ifq)->ifq_tail == NULL)                            \
   79                 (ifq)->ifq_head = m;                            \
   80         else                                                    \
   81                 (ifq)->ifq_tail->m_nextpkt = m;                 \
   82         (ifq)->ifq_tail = m;                                    \
   83         (ifq)->ifq_len++;                                       \
   84 } while (0)
   85 
   86 #define IF_ENQUEUE(ifq, m) do {                                 \
   87         IF_LOCK(ifq);                                           \
   88         _IF_ENQUEUE(ifq, m);                                    \
   89         IF_UNLOCK(ifq);                                         \
   90 } while (0)
   91 
   92 #define _IF_PREPEND(ifq, m) do {                                \
   93         (m)->m_nextpkt = (ifq)->ifq_head;                       \
   94         if ((ifq)->ifq_tail == NULL)                            \
   95                 (ifq)->ifq_tail = (m);                          \
   96         (ifq)->ifq_head = (m);                                  \
   97         (ifq)->ifq_len++;                                       \
   98 } while (0)
   99 
  100 #define IF_PREPEND(ifq, m) do {                                 \
  101         IF_LOCK(ifq);                                           \
  102         _IF_PREPEND(ifq, m);                                    \
  103         IF_UNLOCK(ifq);                                         \
  104 } while (0)
  105 
  106 #define _IF_DEQUEUE(ifq, m) do {                                \
  107         (m) = (ifq)->ifq_head;                                  \
  108         if (m) {                                                \
  109                 if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \
  110                         (ifq)->ifq_tail = NULL;                 \
  111                 (m)->m_nextpkt = NULL;                          \
  112                 (ifq)->ifq_len--;                               \
  113         }                                                       \
  114 } while (0)
  115 
  116 #define IF_DEQUEUE(ifq, m) do {                                 \
  117         IF_LOCK(ifq);                                           \
  118         _IF_DEQUEUE(ifq, m);                                    \
  119         IF_UNLOCK(ifq);                                         \
  120 } while (0)
  121 
  122 #define _IF_DEQUEUE_ALL(ifq, m) do {                            \
  123         (m) = (ifq)->ifq_head;                                  \
  124         (ifq)->ifq_head = (ifq)->ifq_tail = NULL;               \
  125         (ifq)->ifq_len = 0;                                     \
  126 } while (0)
  127 
  128 #define IF_DEQUEUE_ALL(ifq, m) do {                             \
  129         IF_LOCK(ifq);                                           \
  130         _IF_DEQUEUE_ALL(ifq, m);                                \
  131         IF_UNLOCK(ifq);                                         \
  132 } while (0)
  133 
  134 #define _IF_POLL(ifq, m)        ((m) = (ifq)->ifq_head)
  135 #define IF_POLL(ifq, m)         _IF_POLL(ifq, m)
  136 
  137 #define _IF_DRAIN(ifq) do {                                     \
  138         struct mbuf *m;                                         \
  139         for (;;) {                                              \
  140                 _IF_DEQUEUE(ifq, m);                            \
  141                 if (m == NULL)                                  \
  142                         break;                                  \
  143                 m_freem(m);                                     \
  144         }                                                       \
  145 } while (0)
  146 
  147 #define IF_DRAIN(ifq) do {                                      \
  148         IF_LOCK(ifq);                                           \
  149         _IF_DRAIN(ifq);                                         \
  150         IF_UNLOCK(ifq);                                         \
  151 } while(0)
  152 
  153 int     if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
  154             int adjust);
  155 #define IF_HANDOFF(ifq, m, ifp)                 \
  156         if_handoff((struct ifqueue *)ifq, m, ifp, 0)
  157 #define IF_HANDOFF_ADJ(ifq, m, ifp, adj)        \
  158         if_handoff((struct ifqueue *)ifq, m, ifp, adj)
  159 
  160 void    if_start(struct ifnet *);
  161 
  162 #define IFQ_ENQUEUE(ifq, m, err)                                        \
  163 do {                                                                    \
  164         IF_LOCK(ifq);                                                   \
  165         if (ALTQ_IS_ENABLED(ifq))                                       \
  166                 ALTQ_ENQUEUE(ifq, m, NULL, err);                        \
  167         else {                                                          \
  168                 if (_IF_QFULL(ifq)) {                                   \
  169                         m_freem(m);                                     \
  170                         (err) = ENOBUFS;                                \
  171                 } else {                                                \
  172                         _IF_ENQUEUE(ifq, m);                            \
  173                         (err) = 0;                                      \
  174                 }                                                       \
  175         }                                                               \
  176         IF_UNLOCK(ifq);                                                 \
  177 } while (0)
  178 
  179 #define IFQ_DEQUEUE_NOLOCK(ifq, m)                                      \
  180 do {                                                                    \
  181         if (TBR_IS_ENABLED(ifq))                                        \
  182                 (m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);               \
  183         else if (ALTQ_IS_ENABLED(ifq))                                  \
  184                 ALTQ_DEQUEUE(ifq, m);                                   \
  185         else                                                            \
  186                 _IF_DEQUEUE(ifq, m);                                    \
  187 } while (0)
  188 
  189 #define IFQ_DEQUEUE(ifq, m)                                             \
  190 do {                                                                    \
  191         IF_LOCK(ifq);                                                   \
  192         IFQ_DEQUEUE_NOLOCK(ifq, m);                                     \
  193         IF_UNLOCK(ifq);                                                 \
  194 } while (0)
  195 
  196 #define IFQ_POLL_NOLOCK(ifq, m)                                         \
  197 do {                                                                    \
  198         if (TBR_IS_ENABLED(ifq))                                        \
  199                 (m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);                 \
  200         else if (ALTQ_IS_ENABLED(ifq))                                  \
  201                 ALTQ_POLL(ifq, m);                                      \
  202         else                                                            \
  203                 _IF_POLL(ifq, m);                                       \
  204 } while (0)
  205 
  206 #define IFQ_POLL(ifq, m)                                                \
  207 do {                                                                    \
  208         IF_LOCK(ifq);                                                   \
  209         IFQ_POLL_NOLOCK(ifq, m);                                        \
  210         IF_UNLOCK(ifq);                                                 \
  211 } while (0)
  212 
  213 #define IFQ_PURGE_NOLOCK(ifq)                                           \
  214 do {                                                                    \
  215         if (ALTQ_IS_ENABLED(ifq)) {                                     \
  216                 ALTQ_PURGE(ifq);                                        \
  217         } else                                                          \
  218                 _IF_DRAIN(ifq);                                         \
  219 } while (0)
  220 
  221 #define IFQ_PURGE(ifq)                                                  \
  222 do {                                                                    \
  223         IF_LOCK(ifq);                                                   \
  224         IFQ_PURGE_NOLOCK(ifq);                                          \
  225         IF_UNLOCK(ifq);                                                 \
  226 } while (0)
  227 
  228 #define IFQ_SET_READY(ifq)                                              \
  229         do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
  230 
  231 #define IFQ_LOCK(ifq)                   IF_LOCK(ifq)
  232 #define IFQ_UNLOCK(ifq)                 IF_UNLOCK(ifq)
  233 #define IFQ_LOCK_ASSERT(ifq)            IF_LOCK_ASSERT(ifq)
  234 #define IFQ_IS_EMPTY(ifq)               ((ifq)->ifq_len == 0)
  235 #define IFQ_INC_LEN(ifq)                ((ifq)->ifq_len++)
  236 #define IFQ_DEC_LEN(ifq)                (--(ifq)->ifq_len)
  237 #define IFQ_SET_MAXLEN(ifq, len)        ((ifq)->ifq_maxlen = (len))
  238 
  239 /*
  240  * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
  241  * the handoff logic, as that flag is locked by the device driver.
  242  */
  243 #define IFQ_HANDOFF_ADJ(ifp, m, adj, err)                               \
  244 do {                                                                    \
  245         int len;                                                        \
  246         short mflags;                                                   \
  247                                                                         \
  248         len = (m)->m_pkthdr.len;                                        \
  249         mflags = (m)->m_flags;                                          \
  250         IFQ_ENQUEUE(&(ifp)->if_snd, m, err);                            \
  251         if ((err) == 0) {                                               \
  252                 if_inc_counter((ifp), IFCOUNTER_OBYTES, len + (adj));   \
  253                 if (mflags & M_MCAST)                                   \
  254                         if_inc_counter((ifp), IFCOUNTER_OMCASTS, 1);    \
  255                 if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)       \
  256                         if_start(ifp);                                  \
  257         } else                                                          \
  258                 if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1);            \
  259 } while (0)
  260 
  261 #define IFQ_HANDOFF(ifp, m, err)                                        \
  262         IFQ_HANDOFF_ADJ(ifp, m, 0, err)
  263 
  264 #define IFQ_DRV_DEQUEUE(ifq, m)                                         \
  265 do {                                                                    \
  266         (m) = (ifq)->ifq_drv_head;                                      \
  267         if (m) {                                                        \
  268                 if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)     \
  269                         (ifq)->ifq_drv_tail = NULL;                     \
  270                 (m)->m_nextpkt = NULL;                                  \
  271                 (ifq)->ifq_drv_len--;                                   \
  272         } else {                                                        \
  273                 IFQ_LOCK(ifq);                                          \
  274                 IFQ_DEQUEUE_NOLOCK(ifq, m);                             \
  275                 while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {    \
  276                         struct mbuf *m0;                                \
  277                         IFQ_DEQUEUE_NOLOCK(ifq, m0);                    \
  278                         if (m0 == NULL)                                 \
  279                                 break;                                  \
  280                         m0->m_nextpkt = NULL;                           \
  281                         if ((ifq)->ifq_drv_tail == NULL)                \
  282                                 (ifq)->ifq_drv_head = m0;               \
  283                         else                                            \
  284                                 (ifq)->ifq_drv_tail->m_nextpkt = m0;    \
  285                         (ifq)->ifq_drv_tail = m0;                       \
  286                         (ifq)->ifq_drv_len++;                           \
  287                 }                                                       \
  288                 IFQ_UNLOCK(ifq);                                        \
  289         }                                                               \
  290 } while (0)
  291 
  292 #define IFQ_DRV_PREPEND(ifq, m)                                         \
  293 do {                                                                    \
  294         (m)->m_nextpkt = (ifq)->ifq_drv_head;                           \
  295         if ((ifq)->ifq_drv_tail == NULL)                                \
  296                 (ifq)->ifq_drv_tail = (m);                              \
  297         (ifq)->ifq_drv_head = (m);                                      \
  298         (ifq)->ifq_drv_len++;                                           \
  299 } while (0)
  300 
  301 #define IFQ_DRV_IS_EMPTY(ifq)                                           \
  302         (((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
  303 
  304 #define IFQ_DRV_PURGE(ifq)                                              \
  305 do {                                                                    \
  306         struct mbuf *m, *n = (ifq)->ifq_drv_head;                       \
  307         while((m = n) != NULL) {                                        \
  308                 n = m->m_nextpkt;                                       \
  309                 m_freem(m);                                             \
  310         }                                                               \
  311         (ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;               \
  312         (ifq)->ifq_drv_len = 0;                                         \
  313         IFQ_PURGE(ifq);                                                 \
  314 } while (0)
  315 
  316 static __inline int
  317 drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
  318 {       
  319         int error = 0;
  320 
  321 #ifdef ALTQ
  322         if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
  323                 IFQ_ENQUEUE(&ifp->if_snd, m, error);
  324                 if (error)
  325                         if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1);
  326                 return (error);
  327         }
  328 #endif
  329         error = buf_ring_enqueue(br, m);
  330         if (error)
  331                 m_freem(m);
  332 
  333         return (error);
  334 }
  335 
  336 static __inline void
  337 drbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *new)
  338 {
  339         /*
  340          * The top of the list needs to be swapped 
  341          * for this one.
  342          */
  343 #ifdef ALTQ
  344         if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
  345                 /* 
  346                  * Peek in altq case dequeued it
  347                  * so put it back.
  348                  */
  349                 IFQ_DRV_PREPEND(&ifp->if_snd, new);
  350                 return;
  351         }
  352 #endif
  353         buf_ring_putback_sc(br, new);
  354 }
  355 
  356 static __inline struct mbuf *
  357 drbr_peek(struct ifnet *ifp, struct buf_ring *br)
  358 {
  359 #ifdef ALTQ
  360         struct mbuf *m;
  361         if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
  362                 /* 
  363                  * Pull it off like a dequeue
  364                  * since drbr_advance() does nothing
  365                  * for altq and drbr_putback() will
  366                  * use the old prepend function.
  367                  */
  368                 IFQ_DEQUEUE(&ifp->if_snd, m);
  369                 return (m);
  370         }
  371 #endif
  372         return(buf_ring_peek_clear_sc(br));
  373 }
  374 
  375 static __inline void
  376 drbr_flush(struct ifnet *ifp, struct buf_ring *br)
  377 {
  378         struct mbuf *m;
  379 
  380 #ifdef ALTQ
  381         if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
  382                 IFQ_PURGE(&ifp->if_snd);
  383 #endif  
  384         while ((m = buf_ring_dequeue_sc(br)) != NULL)
  385                 m_freem(m);
  386 }
  387 
  388 static __inline void
  389 drbr_free(struct buf_ring *br, struct malloc_type *type)
  390 {
  391 
  392         drbr_flush(NULL, br);
  393         buf_ring_free(br, type);
  394 }
  395 
  396 static __inline struct mbuf *
  397 drbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
  398 {
  399 #ifdef ALTQ
  400         struct mbuf *m;
  401 
  402         if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {     
  403                 IFQ_DEQUEUE(&ifp->if_snd, m);
  404                 return (m);
  405         }
  406 #endif
  407         return (buf_ring_dequeue_sc(br));
  408 }
  409 
  410 static __inline void
  411 drbr_advance(struct ifnet *ifp, struct buf_ring *br)
  412 {
  413 #ifdef ALTQ
  414         /* Nothing to do here since peek dequeues in altq case */
  415         if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
  416                 return;
  417 #endif
  418         return (buf_ring_advance_sc(br));
  419 }
  420 
  421 
  422 static __inline struct mbuf *
  423 drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
  424     int (*func) (struct mbuf *, void *), void *arg) 
  425 {
  426         struct mbuf *m;
  427 #ifdef ALTQ
  428         if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
  429                 IFQ_LOCK(&ifp->if_snd);
  430                 IFQ_POLL_NOLOCK(&ifp->if_snd, m);
  431                 if (m != NULL && func(m, arg) == 0) {
  432                         IFQ_UNLOCK(&ifp->if_snd);
  433                         return (NULL);
  434                 }
  435                 IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
  436                 IFQ_UNLOCK(&ifp->if_snd);
  437                 return (m);
  438         }
  439 #endif
  440         m = buf_ring_peek(br);
  441         if (m == NULL || func(m, arg) == 0)
  442                 return (NULL);
  443 
  444         return (buf_ring_dequeue_sc(br));
  445 }
  446 
  447 static __inline int
  448 drbr_empty(struct ifnet *ifp, struct buf_ring *br)
  449 {
  450 #ifdef ALTQ
  451         if (ALTQ_IS_ENABLED(&ifp->if_snd))
  452                 return (IFQ_IS_EMPTY(&ifp->if_snd));
  453 #endif
  454         return (buf_ring_empty(br));
  455 }
  456 
  457 static __inline int
  458 drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
  459 {
  460 #ifdef ALTQ
  461         if (ALTQ_IS_ENABLED(&ifp->if_snd))
  462                 return (1);
  463 #endif
  464         return (!buf_ring_empty(br));
  465 }
  466 
  467 static __inline int
  468 drbr_inuse(struct ifnet *ifp, struct buf_ring *br)
  469 {
  470 #ifdef ALTQ
  471         if (ALTQ_IS_ENABLED(&ifp->if_snd))
  472                 return (ifp->if_snd.ifq_len);
  473 #endif
  474         return (buf_ring_count(br));
  475 }
  476 
  477 extern  int ifqmaxlen;
  478 
  479 void    if_qflush(struct ifnet *);
  480 void    ifq_init(struct ifaltq *, struct ifnet *ifp);
  481 void    ifq_delete(struct ifaltq *);
  482 
  483 #endif /* _KERNEL */
  484 #endif /* !_NET_IFQ_H_ */

Cache object: bde5c18714de56830d7a1c3c19177650


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.