1*1bfa548bSJustin Hibbits /*- 2*1bfa548bSJustin Hibbits * SPDX-License-Identifier: BSD-3-Clause 3*1bfa548bSJustin Hibbits * 4*1bfa548bSJustin Hibbits * Copyright (c) 1982, 1986, 1989, 1993 5*1bfa548bSJustin Hibbits * The Regents of the University of California. All rights reserved. 6*1bfa548bSJustin Hibbits * 7*1bfa548bSJustin Hibbits * Redistribution and use in source and binary forms, with or without 8*1bfa548bSJustin Hibbits * modification, are permitted provided that the following conditions 9*1bfa548bSJustin Hibbits * are met: 10*1bfa548bSJustin Hibbits * 1. Redistributions of source code must retain the above copyright 11*1bfa548bSJustin Hibbits * notice, this list of conditions and the following disclaimer. 12*1bfa548bSJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright 13*1bfa548bSJustin Hibbits * notice, this list of conditions and the following disclaimer in the 14*1bfa548bSJustin Hibbits * documentation and/or other materials provided with the distribution. 15*1bfa548bSJustin Hibbits * 3. Neither the name of the University nor the names of its contributors 16*1bfa548bSJustin Hibbits * may be used to endorse or promote products derived from this software 17*1bfa548bSJustin Hibbits * without specific prior written permission. 18*1bfa548bSJustin Hibbits * 19*1bfa548bSJustin Hibbits * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20*1bfa548bSJustin Hibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21*1bfa548bSJustin Hibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22*1bfa548bSJustin Hibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23*1bfa548bSJustin Hibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24*1bfa548bSJustin Hibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25*1bfa548bSJustin Hibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26*1bfa548bSJustin Hibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27*1bfa548bSJustin Hibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28*1bfa548bSJustin Hibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29*1bfa548bSJustin Hibbits * SUCH DAMAGE. 30*1bfa548bSJustin Hibbits * 31*1bfa548bSJustin Hibbits * From: @(#)if.h 8.1 (Berkeley) 6/10/93 32*1bfa548bSJustin Hibbits */ 33*1bfa548bSJustin Hibbits 34*1bfa548bSJustin Hibbits #include <sys/param.h> 35*1bfa548bSJustin Hibbits #include <sys/socket.h> 36*1bfa548bSJustin Hibbits 37*1bfa548bSJustin Hibbits #ifndef ALTQ 38*1bfa548bSJustin Hibbits #define ALTQ /* Needed for ifq.h prototypes only. */ 39*1bfa548bSJustin Hibbits #endif 40*1bfa548bSJustin Hibbits 41*1bfa548bSJustin Hibbits #include <net/if.h> 42*1bfa548bSJustin Hibbits #include <net/if_var.h> 43*1bfa548bSJustin Hibbits #include <net/ifq.h> 44*1bfa548bSJustin Hibbits 45*1bfa548bSJustin Hibbits int 46*1bfa548bSJustin Hibbits drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m) 47*1bfa548bSJustin Hibbits { 48*1bfa548bSJustin Hibbits int error = 0; 49*1bfa548bSJustin Hibbits 50*1bfa548bSJustin Hibbits if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 51*1bfa548bSJustin Hibbits IFQ_ENQUEUE(&ifp->if_snd, m, error); 52*1bfa548bSJustin Hibbits if (error) 53*1bfa548bSJustin Hibbits if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1); 54*1bfa548bSJustin Hibbits return (error); 55*1bfa548bSJustin Hibbits } 56*1bfa548bSJustin Hibbits error = buf_ring_enqueue(br, m); 57*1bfa548bSJustin Hibbits if (error) 58*1bfa548bSJustin Hibbits m_freem(m); 59*1bfa548bSJustin Hibbits 60*1bfa548bSJustin Hibbits return (error); 61*1bfa548bSJustin Hibbits } 62*1bfa548bSJustin Hibbits 63*1bfa548bSJustin Hibbits void 64*1bfa548bSJustin Hibbits drbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m_new) 65*1bfa548bSJustin Hibbits { 66*1bfa548bSJustin Hibbits /* 67*1bfa548bSJustin Hibbits * The top of the list needs to be swapped 68*1bfa548bSJustin Hibbits * for this one. 69*1bfa548bSJustin Hibbits */ 70*1bfa548bSJustin Hibbits if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 71*1bfa548bSJustin Hibbits /* 72*1bfa548bSJustin Hibbits * Peek in altq case dequeued it 73*1bfa548bSJustin Hibbits * so put it back. 74*1bfa548bSJustin Hibbits */ 75*1bfa548bSJustin Hibbits IFQ_DRV_PREPEND(&ifp->if_snd, m_new); 76*1bfa548bSJustin Hibbits return; 77*1bfa548bSJustin Hibbits } 78*1bfa548bSJustin Hibbits buf_ring_putback_sc(br, m_new); 79*1bfa548bSJustin Hibbits } 80*1bfa548bSJustin Hibbits 81*1bfa548bSJustin Hibbits struct mbuf * 82*1bfa548bSJustin Hibbits drbr_peek(struct ifnet *ifp, struct buf_ring *br) 83*1bfa548bSJustin Hibbits { 84*1bfa548bSJustin Hibbits struct mbuf *m; 85*1bfa548bSJustin Hibbits if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 86*1bfa548bSJustin Hibbits /* 87*1bfa548bSJustin Hibbits * Pull it off like a dequeue 88*1bfa548bSJustin Hibbits * since drbr_advance() does nothing 89*1bfa548bSJustin Hibbits * for altq and drbr_putback() will 90*1bfa548bSJustin Hibbits * use the old prepend function. 91*1bfa548bSJustin Hibbits */ 92*1bfa548bSJustin Hibbits IFQ_DEQUEUE(&ifp->if_snd, m); 93*1bfa548bSJustin Hibbits return (m); 94*1bfa548bSJustin Hibbits } 95*1bfa548bSJustin Hibbits return ((struct mbuf *)buf_ring_peek_clear_sc(br)); 96*1bfa548bSJustin Hibbits } 97*1bfa548bSJustin Hibbits 98*1bfa548bSJustin Hibbits void 99*1bfa548bSJustin Hibbits drbr_flush(struct ifnet *ifp, struct buf_ring *br) 100*1bfa548bSJustin Hibbits { 101*1bfa548bSJustin Hibbits struct mbuf *m; 102*1bfa548bSJustin Hibbits 103*1bfa548bSJustin Hibbits if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) 104*1bfa548bSJustin Hibbits IFQ_PURGE(&ifp->if_snd); 105*1bfa548bSJustin Hibbits while ((m = (struct mbuf *)buf_ring_dequeue_sc(br)) != NULL) 106*1bfa548bSJustin Hibbits m_freem(m); 107*1bfa548bSJustin Hibbits } 108*1bfa548bSJustin Hibbits 109*1bfa548bSJustin Hibbits struct mbuf * 110*1bfa548bSJustin Hibbits drbr_dequeue(struct ifnet *ifp, struct buf_ring *br) 111*1bfa548bSJustin Hibbits { 112*1bfa548bSJustin Hibbits struct mbuf *m; 113*1bfa548bSJustin Hibbits 114*1bfa548bSJustin Hibbits if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 115*1bfa548bSJustin Hibbits IFQ_DEQUEUE(&ifp->if_snd, m); 116*1bfa548bSJustin Hibbits return (m); 117*1bfa548bSJustin Hibbits } 118*1bfa548bSJustin Hibbits return ((struct mbuf *)buf_ring_dequeue_sc(br)); 119*1bfa548bSJustin Hibbits } 120*1bfa548bSJustin Hibbits 121*1bfa548bSJustin Hibbits void 122*1bfa548bSJustin Hibbits drbr_advance(struct ifnet *ifp, struct buf_ring *br) 123*1bfa548bSJustin Hibbits { 124*1bfa548bSJustin Hibbits /* Nothing to do here since peek dequeues in altq case */ 125*1bfa548bSJustin Hibbits if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) 126*1bfa548bSJustin Hibbits return; 127*1bfa548bSJustin Hibbits return (buf_ring_advance_sc(br)); 128*1bfa548bSJustin Hibbits } 129*1bfa548bSJustin Hibbits 130*1bfa548bSJustin Hibbits struct mbuf * 131*1bfa548bSJustin Hibbits drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br, 132*1bfa548bSJustin Hibbits int (*func) (struct mbuf *, void *), void *arg) 133*1bfa548bSJustin Hibbits { 134*1bfa548bSJustin Hibbits struct mbuf *m; 135*1bfa548bSJustin Hibbits if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 136*1bfa548bSJustin Hibbits IFQ_LOCK(&ifp->if_snd); 137*1bfa548bSJustin Hibbits IFQ_POLL_NOLOCK(&ifp->if_snd, m); 138*1bfa548bSJustin Hibbits if (m != NULL && func(m, arg) == 0) { 139*1bfa548bSJustin Hibbits IFQ_UNLOCK(&ifp->if_snd); 140*1bfa548bSJustin Hibbits return (NULL); 141*1bfa548bSJustin Hibbits } 142*1bfa548bSJustin Hibbits IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m); 143*1bfa548bSJustin Hibbits IFQ_UNLOCK(&ifp->if_snd); 144*1bfa548bSJustin Hibbits return (m); 145*1bfa548bSJustin Hibbits } 146*1bfa548bSJustin Hibbits m = (struct mbuf *)buf_ring_peek(br); 147*1bfa548bSJustin Hibbits if (m == NULL || func(m, arg) == 0) 148*1bfa548bSJustin Hibbits return (NULL); 149*1bfa548bSJustin Hibbits 150*1bfa548bSJustin Hibbits return ((struct mbuf *)buf_ring_dequeue_sc(br)); 151*1bfa548bSJustin Hibbits } 152*1bfa548bSJustin Hibbits 153*1bfa548bSJustin Hibbits int 154*1bfa548bSJustin Hibbits drbr_empty(struct ifnet *ifp, struct buf_ring *br) 155*1bfa548bSJustin Hibbits { 156*1bfa548bSJustin Hibbits if (ALTQ_IS_ENABLED(&ifp->if_snd)) 157*1bfa548bSJustin Hibbits return (IFQ_IS_EMPTY(&ifp->if_snd)); 158*1bfa548bSJustin Hibbits return (buf_ring_empty(br)); 159*1bfa548bSJustin Hibbits } 160*1bfa548bSJustin Hibbits 161*1bfa548bSJustin Hibbits int 162*1bfa548bSJustin Hibbits drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br) 163*1bfa548bSJustin Hibbits { 164*1bfa548bSJustin Hibbits if (ALTQ_IS_ENABLED(&ifp->if_snd)) 165*1bfa548bSJustin Hibbits return (1); 166*1bfa548bSJustin Hibbits return (!buf_ring_empty(br)); 167*1bfa548bSJustin Hibbits } 168*1bfa548bSJustin Hibbits 169*1bfa548bSJustin Hibbits int 170*1bfa548bSJustin Hibbits drbr_inuse(struct ifnet *ifp, struct buf_ring *br) 171*1bfa548bSJustin Hibbits { 172*1bfa548bSJustin Hibbits if (ALTQ_IS_ENABLED(&ifp->if_snd)) 173*1bfa548bSJustin Hibbits return (ifp->if_snd.ifq_len); 174*1bfa548bSJustin Hibbits return (buf_ring_count(br)); 175*1bfa548bSJustin Hibbits } 176*1bfa548bSJustin Hibbits 177