Add ALTQ support. This is used for testing/debugging ALTQ only. It

is triggered only on loopback interfaces, and not simplex interfaces
(which also use looutput()).
This commit is contained in:
thorpej 2000-12-18 19:18:33 +00:00
parent 66539b9373
commit db9fd3e536

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_loop.c,v 1.31 2000/12/12 18:00:27 thorpej Exp $ */
/* $NetBSD: if_loop.c,v 1.32 2000/12/18 19:18:33 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -139,6 +139,8 @@
struct ifnet loif[NLOOP];
void lostart(struct ifnet *);
void
loopattach(n)
int n;
@ -154,9 +156,11 @@ loopattach(n)
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
ifp->if_ioctl = loioctl;
ifp->if_output = looutput;
ifp->if_start = lostart;
ifp->if_type = IFT_LOOP;
ifp->if_hdrlen = 0;
ifp->if_addrlen = 0;
IFQ_SET_READY(&ifp->if_snd);
if_attach(ifp);
#if NBPFILTER > 0
bpfattach(ifp, DLT_NULL, sizeof(u_int));
@ -258,6 +262,36 @@ looutput(ifp, m, dst, rt)
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
#ifdef ALTQ
/*
* ALTQ on the loopback interface is just for debugging. It's
* used only for loopback interfaces, not for a simplex interface.
*/
if ((ALTQ_IS_ENABLED(&ifp->if_snd) || TBR_IS_ENABLED(&ifp->if_snd)) &&
ifp->if_start == lostart) {
struct altq_pktattr pktattr;
int error;
/*
* If the queueing discipline needs packet classification,
* do it before prepending the link headers.
*/
IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
M_PREPEND(m, sizeof(uint32_t), M_DONTWAIT);
if (m == NULL)
return (ENOBUFS);
*(mtod(m, uint32_t *)) = dst->sa_family;
s = splimp();
IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error);
(*ifp->if_start)(ifp);
splx(s);
return (error);
}
#endif /* ALTQ */
switch (dst->sa_family) {
#ifdef INET
@ -318,6 +352,83 @@ looutput(ifp, m, dst, rt)
return (0);
}
#ifdef ALTQ
void
lostart(struct ifnet *ifp)
{
struct ifqueue *ifq;
struct mbuf *m;
uint32_t af;
int s, isr;
for (;;) {
IFQ_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
return;
af = *(mtod(m, uint32_t *));
m_adj(m, sizeof(uint32_t));
switch (af) {
#ifdef INET
case AF_INET:
ifq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
m->m_flags |= M_LOOP;
ifq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
#ifdef IPX
case AF_IPX:
ifq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
#ifdef NS
case AF_NS:
ifq = &nsintrq;
isr = NETISR_NS;
break;
#endif
#ifdef ISO
case AF_ISO:
ifq = &clnlintrq;
isr = NETISR_ISO;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
ifq = &atintrq2;
isr = NETISR_ATALK;
break;
#endif
default:
printf("%s: can't handle af%d\n", ifp->if_xname, af);
m_freem(m);
return;
}
s = splimp();
if (IF_QFULL(ifq)) {
IF_DROP(ifq);
splx(s);
m_freem(m);
return;
}
IF_ENQUEUE(ifq, m);
schednetisr(isr);
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
splx(s);
}
}
#endif /* ALTQ */
/* ARGSUSED */
void
lortrequest(cmd, rt, sa)