Update netisr handling; Each SWI now registers its queue, and all queue

drain routines are done by swi_net, which allows for better queue control
at some future point.  Packets may also be directly dispatched to a netisr
instead of queued, this may be of interest at some installations, but
currently defaults to off.

Reviewed by: hsu, silby, jayanth, sam
Sponsored by: DARPA, NAI Labs
This commit is contained in:
Jonathan Lemon 2003-03-04 23:19:55 +00:00
parent c141c242ac
commit 1cafed3941
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=111888
64 changed files with 674 additions and 752 deletions

View File

@ -1172,7 +1172,6 @@ net/if_stf.c optional stf
net/if_tun.c optional tun
net/if_tap.c optional tap
net/if_vlan.c optional vlan
net/intrq.c standard
net/net_osdep.c standard
net/netisr.c standard
net/ppp_deflate.c optional ppp_deflate

View File

@ -442,10 +442,8 @@ int cmd;
# if SOLARIS
error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0;
# else /* SOLARIS */
if (! IF_HANDOFF(&ipintrq, m, NULL))
if (! netisr_queue(NETISR_IP, m))
error = ENOBUFS;
else
schednetisr(NETISR_IP);
# endif /* SOLARIS */
if (error)
fr_authstats.fas_quefail++;

View File

@ -3314,7 +3314,9 @@ int unit, level;
printf(" %d cells trashed due almost full buffer\n", sc->ttrash);
printf(" %d rx mbuf allocation failures\n", sc->rxmbufout);
#ifdef NATM
#if 0
printf(" %d drops at natmintrq\n", natmintrq.ifq_drops);
#endif
#ifdef NATM_STAT
printf(" natmintr so_rcv: ok/drop cnt: %d/%d, ok/drop bytes: %d/%d\n",
natm_sookcnt, natm_sodropcnt, natm_sookbytes, natm_sodropbytes);

View File

@ -680,7 +680,6 @@ eni_recv_drain ( eup )
u_long DMA_Rdptr;
u_long dma_wrp;
u_long start, stop;
int que = 0;
int s;
s = splimp();
@ -802,9 +801,7 @@ eni_recv_drain ( eup )
/*
* Schedule callback
*/
if (IF_HANDOFF(&atm_intrq, m, NULL)) {
que++;
} else {
if (! netisr_queue(NETISR_ATM, m)) {
eup->eu_stats.eni_st_drv.drv_rv_intrq++;
eup->eu_pif.pif_ierrors++;
#ifdef DO_LOG
@ -827,13 +824,6 @@ eni_recv_drain ( eup )
}
finish:
(void) splx(s);
/*
* If we found any completed buffers, schedule a call into
* the kernel to process the atm_intrq.
*/
if ( que )
schednetisr(NETISR_ATM);
return;
}

View File

@ -479,9 +479,7 @@ fore_recv_drain(fup)
/*
* Schedule callback
*/
if (IF_HANDOFF(&atm_intrq, mhead, NULL)) {
schednetisr(NETISR_ATM);
} else {
if (! netisr_queue(NETISR_ATM, mhead)) {
fup->fu_stats->st_drv.drv_rv_ifull++;
goto free_ent;
}

View File

@ -314,10 +314,8 @@ icintr (device_t dev, int event, char *ptr)
top = m_devget(sc->ic_ifbuf + ICHDRLEN, len, 0, &sc->ic_if, 0);
if (top) {
if (IF_HANDOFF(&ipintrq, top, NULL))
schednetisr(NETISR_IP);
}
if (top)
netisr_dispatch(NETISR_IP, top);
break;
err:

View File

@ -520,11 +520,7 @@ lp_intr (void *arg)
if (top) {
if (sc->sc_if.if_bpf)
lptap(&sc->sc_if, top);
if (! IF_HANDOFF(&ipintrq, top, NULL)) {
lprintf("DROP");
} else {
schednetisr(NETISR_IP);
}
netisr_queue(NETISR_IP, top);
}
goto done;
}
@ -569,11 +565,7 @@ lp_intr (void *arg)
if (top) {
if (sc->sc_if.if_bpf)
lptap(&sc->sc_if, top);
if (! IF_HANDOFF(&ipintrq, top, NULL)) {
lprintf("DROP");
} else {
schednetisr(NETISR_IP);
}
netisr_queue(NETISR_IP, top);
}
}
goto done;

View File

@ -78,7 +78,7 @@ Static int mtx_inited = 0;
Static void usbintr (void);
Static void usbintr()
Static void usbintr(void)
{
struct mbuf *m;
struct usb_qdat *q;
@ -118,7 +118,7 @@ void usb_register_netisr()
{
if (mtx_inited)
return;
register_netisr(NETISR_USB, usbintr);
netisr_register(NETISR_USB, (netisr_t *)usbintr, NULL);
mtx_init(&usbq_tx.ifq_mtx, "usbq_tx_mtx", NULL, MTX_DEF);
mtx_init(&usbq_rx.ifq_mtx, "usbq_rx_mtx", NULL, MTX_DEF);
mtx_inited++;
@ -126,7 +126,7 @@ void usb_register_netisr()
}
/*
* Must be called at splusp() (actually splbio()). This should be
* Must be called at splusb() (actually splbio()). This should be
* the case when called from a transfer callback routine.
*/
void usb_ether_input(m)

View File

@ -35,10 +35,6 @@
#ifndef _USB_ETHERSUBR_H_
#define _USB_ETHERSUBR_H_
#ifndef NETISR_USB
#define NETISR_USB 25
#endif
struct usb_qdat {
struct ifnet *ifp;
void (*if_rxstart) (struct ifnet *);

View File

@ -879,7 +879,7 @@ ipr_rx_data_rdy(int unit)
BPF_MTAP(&sc->sc_if, &mm);
}
if(! IF_HANDOFF(&ipintrq, m, NULL))
if(! netisr_queue(NETISR_IP, m))
{
NDBGL4(L4_IPRDBG, "ipr%d: ipintrq full!", unit);
sc->sc_if.if_ierrors++;

View File

@ -70,7 +70,6 @@
#endif
#ifdef DEVICE_POLLING
extern void init_device_poll(void);
extern void hardclock_device_poll(void);
#endif /* DEVICE_POLLING */
@ -137,9 +136,6 @@ initclocks(dummy)
*/
cpu_initclocks();
#ifdef DEVICE_POLLING
init_device_poll();
#endif
/*
* Compute profhz/stathz, and fix profhz if needed.
*/

View File

@ -47,9 +47,8 @@
#endif
static void netisr_poll(void); /* the two netisr handlers */
void netisr_pollmore(void);
static void netisr_pollmore(void);
void init_device_poll(void); /* init routine */
void hardclock_device_poll(void); /* hook from hardclock */
void ether_poll(int); /* polling while in trap */
@ -183,14 +182,15 @@ struct pollrec {
static struct pollrec pr[POLL_LIST_LEN];
/*
* register relevant netisr. Called from kern_clock.c:
*/
void
static void
init_device_poll(void)
{
register_netisr(NETISR_POLL, netisr_poll);
netisr_register(NETISR_POLL, (netisr_t *)netisr_poll, NULL);
netisr_register(NETISR_POLLMORE, (netisr_t *)netisr_pollmore, NULL);
}
SYSINIT(device_poll, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, init_device_poll, NULL)
/*
* Hook from hardclock. Tries to schedule a netisr, but keeps track
@ -236,7 +236,7 @@ hardclock_device_poll(void)
if (phase != 0)
suspect++;
phase = 1;
schednetisr(NETISR_POLL);
schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE);
phase = 2;
}
if (pending_polls++ > 0)
@ -289,9 +289,9 @@ netisr_pollmore()
phase = 5;
if (residual_burst > 0) {
schednetisr(NETISR_POLL);
schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE);
/* will run immediately on return, followed by netisrs */
return ;
return;
}
/* here we can account time spent in netisr's in this tick */
microuptime(&t);
@ -318,7 +318,7 @@ netisr_pollmore()
poll_burst -= (poll_burst / 8);
if (poll_burst < 1)
poll_burst = 1;
schednetisr(NETISR_POLL);
schednetisrbits(1 << NETISR_POLL | 1 << NETISR_POLLMORE);
phase = 6;
}
}

View File

@ -507,7 +507,7 @@ arc_input(ifp, m)
struct mbuf *m;
{
struct arc_header *ah;
struct ifqueue *inq;
int isr;
u_int8_t atype;
if ((ifp->if_flags & IFF_UP) == 0) {
@ -545,16 +545,14 @@ arc_input(ifp, m)
m_adj(m, ARC_HDRNEWLEN);
if (ipflow_fastforward(m))
return;
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
case ARCTYPE_IP_OLD:
m_adj(m, ARC_HDRLEN);
if (ipflow_fastforward(m))
return;
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
case ARCTYPE_ARP:
@ -564,8 +562,7 @@ arc_input(ifp, m)
return;
}
m_adj(m, ARC_HDRNEWLEN);
schednetisr(NETISR_ARP);
inq = &arpintrq;
isr = NETISR_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
mtod(m, struct arphdr *)->ar_pro = htons(ETHERTYPE_IP);
#endif
@ -578,8 +575,7 @@ arc_input(ifp, m)
return;
}
m_adj(m, ARC_HDRLEN);
schednetisr(NETISR_ARP);
inq = &arpintrq;
isr = NETISR_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
mtod(m, struct arphdr *)->ar_pro = htons(ETHERTYPE_IP);
#endif
@ -588,23 +584,20 @@ arc_input(ifp, m)
#ifdef INET6
case ARCTYPE_INET6:
m_adj(m, ARC_HDRNEWLEN);
schednetisr(NETISR_IPV6);
inq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
#ifdef IPX
case ARCTYPE_IPX:
m_adj(m, ARC_HDRNEWLEN);
schednetisr(NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
default:
m_freem(m);
return;
}
IF_HANDOFF(inq, m, NULL);
netisr_dispatch(isr, m);
}
/*

View File

@ -212,7 +212,7 @@ atm_input(ifp, ah, m, rxhand)
struct mbuf *m;
void *rxhand;
{
struct ifqueue *inq;
int isr;
u_int16_t etype = ETHERTYPE_IP; /* default */
int s;
@ -231,8 +231,7 @@ atm_input(ifp, ah, m, rxhand)
s = splimp(); /* in case 2 atm cards @ diff lvls */
npcb->npcb_inq++; /* count # in queue */
splx(s);
schednetisr(NETISR_NATM);
inq = &natmintrq;
isr = NETISR_NATM;
m->m_pkthdr.rcvif = rxhand; /* XXX: overload */
#else
printf("atm_input: NATM detected but not configured in kernel\n");
@ -267,14 +266,12 @@ atm_input(ifp, ah, m, rxhand)
switch (etype) {
#ifdef INET
case ETHERTYPE_IP:
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
schednetisr(NETISR_IPV6);
inq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
default:
@ -282,8 +279,7 @@ atm_input(ifp, ah, m, rxhand)
return;
}
}
(void) IF_HANDOFF(inq, m, NULL);
netisr_dispatch(isr, m);
}
/*

View File

@ -240,70 +240,74 @@ ef_start(struct ifnet *ifp)
* parameter passing but simplify the code
*/
static int __inline
ef_inputEII(struct mbuf *m, struct ether_header *eh,
u_short ether_type, struct ifqueue **inq)
ef_inputEII(struct mbuf *m, struct ether_header *eh, u_short ether_type)
{
int isr;
switch(ether_type) {
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr(NETISR_IPX);
*inq = &ipxintrq;
case ETHERTYPE_IPX:
isr = NETISR_IPX;
break;
#endif
#ifdef INET
case ETHERTYPE_IP:
case ETHERTYPE_IP:
if (ipflow_fastforward(m))
return 1;
schednetisr(NETISR_IP);
*inq = &ipintrq;
return (0);
isr = NETISR_IP;
break;
case ETHERTYPE_ARP:
schednetisr(NETISR_ARP);
*inq = &arpintrq;
case ETHERTYPE_ARP:
isr = NETISR_ARP;
break;
#endif
default:
return EPROTONOSUPPORT;
default:
return (EPROTONOSUPPORT);
}
return 0;
netisr_dispatch(isr, m);
return (0);
}
static int __inline
ef_inputSNAP(struct mbuf *m, struct ether_header *eh, struct llc* l,
u_short ether_type, struct ifqueue **inq)
u_short ether_type)
{
int isr;
switch(ether_type) {
#ifdef IPX
case ETHERTYPE_IPX:
case ETHERTYPE_IPX:
m_adj(m, 8);
schednetisr(NETISR_IPX);
*inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
default:
return EPROTONOSUPPORT;
default:
return (EPROTONOSUPPORT);
}
return 0;
netisr_dispatch(isr, m);
return (0);
}
static int __inline
ef_input8022(struct mbuf *m, struct ether_header *eh, struct llc* l,
u_short ether_type, struct ifqueue **inq)
u_short ether_type)
{
int isr;
switch(ether_type) {
#ifdef IPX
case 0xe0:
case 0xe0:
m_adj(m, 3);
schednetisr(NETISR_IPX);
*inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
default:
return EPROTONOSUPPORT;
default:
return (EPROTONOSUPPORT);
}
return 0;
netisr_dispatch(isr, m);
return (0);
}
/*
* Called from ether_input()
*/
@ -312,11 +316,11 @@ ef_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
{
u_short ether_type;
int ft = -1;
struct ifqueue *inq;
struct efnet *efp;
struct ifnet *eifp;
struct llc *l;
struct ef_link *efl;
int isr;
ether_type = ntohs(eh->ether_type);
if (ether_type < ETHERMTU) {
@ -377,35 +381,28 @@ ef_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
/*
* Now we ready to adjust mbufs and pass them to protocol intr's
*/
inq = NULL;
switch(ft) {
case ETHER_FT_EII:
if (ef_inputEII(m, eh, ether_type, &inq) != 0)
return EPROTONOSUPPORT;
case ETHER_FT_EII:
return (ef_inputEII(m, eh, ether_type));
break;
#ifdef IPX
case ETHER_FT_8023: /* only IPX can be here */
schednetisr(NETISR_IPX);
inq = &ipxintrq;
case ETHER_FT_8023: /* only IPX can be here */
isr = NETISR_IPX;
break;
#endif
case ETHER_FT_SNAP:
if (ef_inputSNAP(m, eh, l, ether_type, &inq) != 0)
return EPROTONOSUPPORT;
case ETHER_FT_SNAP:
return (ef_inputSNAP(m, eh, l, ether_type));
break;
case ETHER_FT_8022:
if (ef_input8022(m, eh, l, ether_type, &inq) != 0)
return EPROTONOSUPPORT;
case ETHER_FT_8022:
return (ef_input8022(m, eh, l, ether_type));
break;
}
if (inq == NULL) {
default:
EFDEBUG("No support for frame %d and proto %04x\n",
ft, ether_type);
return EPROTONOSUPPORT;
return (EPROTONOSUPPORT);
}
(void) IF_HANDOFF(inq, m, NULL);
return 0;
netisr_dispatch(isr, m);
return (0);
}
static int

View File

@ -259,9 +259,7 @@ ether_output(ifp, m, dst, rt0)
*/
if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){
m->m_pkthdr.rcvif = ifp;
inq = &nsintrq;
if (IF_HANDOFF(inq, m, NULL))
schednetisr(NETISR_NS);
netisr_queue(NETISR_NS, m);
return (error);
}
if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){
@ -645,7 +643,7 @@ void
ether_demux(struct ifnet *ifp, struct mbuf *m)
{
struct ether_header *eh;
struct ifqueue *inq;
int isr;
u_short ether_type;
#if defined(NETATALK)
struct llc *l;
@ -755,8 +753,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
case ETHERTYPE_IP:
if (ipflow_fastforward(m))
return;
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
case ETHERTYPE_ARP:
@ -765,40 +762,34 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
m_freem(m);
return;
}
schednetisr(NETISR_ARP);
inq = &arpintrq;
isr = NETISR_ARP;
break;
#endif
#ifdef IPX
case ETHERTYPE_IPX:
if (ef_inputp && ef_inputp(ifp, eh, m) == 0)
return;
schednetisr(NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
schednetisr(NETISR_IPV6);
inq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
#ifdef NS
case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
schednetisr(NETISR_NS);
inq = &nsintrq;
isr = NETISR_NS;
break;
#endif /* NS */
#ifdef NETATALK
case ETHERTYPE_AT:
schednetisr(NETISR_ATALK);
inq = &atintrq1;
break;
case ETHERTYPE_AARP:
/* probably this should be done with a NETISR as well */
aarpinput(IFP2AC(ifp), m); /* XXX */
return;
case ETHERTYPE_AT:
isr = NETISR_ATALK1;
break;
case ETHERTYPE_AARP:
isr = NETISR_AARP;
break;
#endif /* NETATALK */
default:
#ifdef IPX
@ -809,59 +800,44 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
checksum = mtod(m, ushort *);
/* Novell 802.3 */
if ((ether_type <= ETHERMTU) &&
((*checksum == 0xffff) || (*checksum == 0xE0E0))){
if(*checksum == 0xE0E0) {
((*checksum == 0xffff) || (*checksum == 0xE0E0))) {
if (*checksum == 0xE0E0) {
m->m_pkthdr.len -= 3;
m->m_len -= 3;
m->m_data += 3;
}
schednetisr(NETISR_NS);
inq = &nsintrq;
break;
isr = NETISR_NS;
break;
}
#endif /* NS */
#if defined(NETATALK)
if (ether_type > ETHERMTU)
goto discard;
l = mtod(m, struct llc *);
switch (l->llc_dsap) {
case LLC_SNAP_LSAP:
switch (l->llc_control) {
case LLC_UI:
if (l->llc_ssap != LLC_SNAP_LSAP)
goto discard;
if (l->llc_dsap == LLC_SNAP_LSAP &&
l->llc_ssap == LLC_SNAP_LSAP &&
l->llc_control == LLC_UI) {
if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
inq = &atintrq2;
m_adj( m, LLC_SNAPFRAMELEN);
schednetisr(NETISR_ATALK);
break;
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
m_adj(m, LLC_SNAPFRAMELEN);
isr = NETISR_ATALK2;
break;
}
if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
m_adj( m, LLC_SNAPFRAMELEN);
aarpinput(IFP2AC(ifp), m); /* XXX */
return;
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
m_adj(m, LLC_SNAPFRAMELEN);
isr = NETISR_AARP;
break;
}
default:
goto discard;
}
break;
default:
goto discard;
}
#else /* NETATALK */
goto discard;
#endif /* NETATALK */
goto discard;
}
(void) IF_HANDOFF(inq, m, NULL);
netisr_dispatch(isr, m);
return;
discard:
/*
* Packet is to be discarded. If netgraph is present,

View File

@ -202,7 +202,6 @@ faithoutput(ifp, m, dst, rt)
struct rtentry *rt;
{
int isr;
struct ifqueue *ifq = 0;
if ((m->m_flags & M_PKTHDR) == 0)
panic("faithoutput no HDR");
@ -243,13 +242,11 @@ faithoutput(ifp, m, dst, rt)
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
ifq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
ifq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
@ -263,8 +260,7 @@ faithoutput(ifp, m, dst, rt)
m->m_pkthdr.rcvif = ifp;
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
(void) IF_HANDOFF(ifq, m, NULL);
schednetisr(isr);
netisr_dispatch(isr, m);
return (0);
}

View File

@ -345,7 +345,7 @@ fddi_input(ifp, m)
struct ifnet *ifp;
struct mbuf *m;
{
struct ifqueue *inq;
int isr;
struct llc *l;
struct fddi_header *fh;
@ -418,20 +418,19 @@ fddi_input(ifp, m)
}
#ifdef NETATALK
if (Bcmp(&(l->llc_snap.org_code)[0], at_org_code,
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
inq = &atintrq2;
m_adj(m, LLC_SNAPFRAMELEN);
schednetisr(NETISR_ATALK);
break;
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
isr = NETISR_ATALK2;
m_adj(m, LLC_SNAPFRAMELEN);
break;
}
if (Bcmp(&(l->llc_snap.org_code)[0], aarp_org_code,
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
m_adj(m, LLC_SNAPFRAMELEN);
aarpinput(IFP2AC(ifp), m); /* XXX */
return;
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
m_adj(m, LLC_SNAPFRAMELEN);
isr = NETISR_AARP;
break;
}
#endif /* NETATALK */
if (l->llc_snap.org_code[0] != 0 ||
@ -449,50 +448,42 @@ fddi_input(ifp, m)
case ETHERTYPE_IP:
if (ipflow_fastforward(m))
return;
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
case ETHERTYPE_ARP:
if (ifp->if_flags & IFF_NOARP)
goto dropanyway;
schednetisr(NETISR_ARP);
inq = &arpintrq;
isr = NETISR_ARP;
break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
schednetisr(NETISR_IPV6);
inq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr(NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
#ifdef NS
case ETHERTYPE_NS:
schednetisr(NETISR_NS);
inq = &nsintrq;
isr = NETISR_NS;
break;
#endif
#ifdef DECNET
case ETHERTYPE_DECNET:
schednetisr(NETISR_DECNET);
inq = &decnetintrq;
isr = NETISR_DECNET;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_AT:
schednetisr(NETISR_ATALK);
inq = &atintrq1;
isr = NETISR_ATALK1;
break;
case ETHERTYPE_AARP:
/* probably this should be done with a NETISR as well */
aarpinput(IFP2AC(ifp), m); /* XXX */
return;
isr = NETISR_AARP;
break;
#endif /* NETATALK */
default:
/* printf("fddi_input: unknown protocol 0x%x\n", type); */
@ -507,8 +498,7 @@ fddi_input(ifp, m)
ifp->if_noproto++;
goto dropanyway;
}
(void) IF_HANDOFF(inq, m, NULL);
netisr_dispatch(isr, m);
return;
dropanyway:

View File

@ -405,7 +405,6 @@ gif_input(m, af, ifp)
struct ifnet *ifp;
{
int isr;
struct ifqueue *ifq = NULL;
if (ifp == NULL) {
/* just in case */
@ -457,13 +456,11 @@ gif_input(m, af, ifp)
switch (af) {
#ifdef INET
case AF_INET:
ifq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
ifq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
@ -477,11 +474,7 @@ gif_input(m, af, ifp)
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
(void) IF_HANDOFF(ifq, m, NULL);
/* we need schednetisr since the address family may change */
schednetisr(isr);
return;
netisr_dispatch(isr, m);
}
/* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */

View File

@ -393,7 +393,7 @@ iso88025_input(ifp, th, m)
struct iso88025_header *th;
struct mbuf *m;
{
struct ifqueue *inq;
int isr;
struct llc *l;
if ((ifp->if_flags & IFF_UP) == 0) {
@ -425,8 +425,7 @@ iso88025_input(ifp, th, m)
th->iso88025_shost[0] &= ~(TR_RII);
m_adj(m, 3);
schednetisr(NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif /* IPX */
case LLC_SNAP_LSAP: {
@ -448,30 +447,26 @@ iso88025_input(ifp, th, m)
th->iso88025_shost[0] &= ~(TR_RII);
if (ipflow_fastforward(m))
return;
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
case ETHERTYPE_ARP:
if (ifp->if_flags & IFF_NOARP)
goto dropanyway;
schednetisr(NETISR_ARP);
inq = &arpintrq;
isr = NETISR_ARP;
break;
#endif /* INET */
#ifdef IPX_SNAP /* XXX: Not supported! */
case ETHERTYPE_IPX:
th->iso88025_shost[0] &= ~(TR_RII);
schednetisr(NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif /* IPX_SNAP */
#ifdef NOT_YET
#ifdef INET6
case ETHERTYPE_IPV6:
th->iso88025_shost[0] &= ~(TR_RII);
schednetisr(NETISR_IPV6);
inq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif /* INET6 */
#endif /* NOT_YET */
@ -543,7 +538,5 @@ iso88025_input(ifp, th, m)
m_freem(m);
return;
}
if (! IF_HANDOFF(inq, m, NULL))
printf("iso88025_input: Packet dropped (Queue full).\n");
netisr_dispatch(isr, m);
}

View File

@ -281,7 +281,6 @@ if_simloop(ifp, m, af, hlen)
int hlen;
{
int isr;
struct ifqueue *inq = 0;
KASSERT((m->m_flags & M_PKTHDR) != 0, ("if_simloop: no HDR"));
m->m_pkthdr.rcvif = ifp;
@ -336,33 +335,28 @@ if_simloop(ifp, m, af, hlen)
switch (af) {
#ifdef INET
case AF_INET:
inq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
m->m_flags |= M_LOOP;
inq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
#ifdef IPX
case AF_IPX:
inq = &ipxintrq;
isr = NETISR_IPX;
break;
#endif
#ifdef NS
case AF_NS:
inq = &nsintrq;
isr = NETISR_NS;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
inq = &atintrq2;
isr = NETISR_ATALK;
isr = NETISR_ATALK2;
break;
#endif
default:
@ -372,8 +366,7 @@ if_simloop(ifp, m, af, hlen)
}
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
(void) IF_HANDOFF(inq, m, NULL);
schednetisr(isr);
netisr_dispatch(isr, m);
return (0);
}

View File

@ -245,7 +245,7 @@ ppp_modevent(module_t mod, int type, void *data)
case MOD_LOAD:
if_clone_attach(&ppp_cloner);
register_netisr(NETISR_PPP, pppintr);
netisr_register(NETISR_PPP, (netisr_t *)pppintr, NULL);
/*
* XXX layering violation - if_ppp can work over any lower
* level transport that cares to attach to it.
@ -256,7 +256,7 @@ ppp_modevent(module_t mod, int type, void *data)
/* XXX: layering violation */
pppasyncdetach();
unregister_netisr(NETISR_PPP);
netisr_unregister(NETISR_PPP);
if_clone_detach(&ppp_cloner);
@ -1305,7 +1305,7 @@ ppp_inproc(sc, m)
struct mbuf *m;
{
struct ifnet *ifp = &sc->sc_if;
struct ifqueue *inq;
int isr;
int s, ilen = 0, xlen, proto, rv;
u_char *cp, adrs, ctrl;
struct mbuf *mp, *dmp = NULL;
@ -1520,7 +1520,7 @@ ppp_inproc(sc, m)
/* See if bpf wants to look at the packet. */
BPF_MTAP(&sc->sc_if, m);
rv = 0;
isr = -1;
switch (proto) {
#ifdef INET
case PPP_IP:
@ -1538,8 +1538,7 @@ ppp_inproc(sc, m)
m->m_len -= PPP_HDRLEN;
if (ipflow_fastforward(m))
return;
schednetisr(NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef IPX
@ -1556,8 +1555,7 @@ ppp_inproc(sc, m)
m->m_pkthdr.len -= PPP_HDRLEN;
m->m_data += PPP_HDRLEN;
m->m_len -= PPP_HDRLEN;
schednetisr(NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
sc->sc_last_recv = time_second; /* update time of last pkt rcvd */
break;
#endif
@ -1566,15 +1564,14 @@ ppp_inproc(sc, m)
/*
* Some other protocol - place on input queue for read().
*/
inq = &sc->sc_inq;
rv = 1;
break;
}
/*
* Put the packet on the appropriate input queue.
*/
if (! IF_HANDOFF(inq, m, NULL)) {
if (isr == -1)
rv = IF_HANDOFF(&sc->sc_inq, m, NULL);
else
rv = netisr_queue(isr, m);
if (rv) {
if (sc->sc_flags & SC_DEBUG)
if_printf(ifp, "input queue full\n");
ifp->if_iqdrops++;
@ -1584,7 +1581,7 @@ ppp_inproc(sc, m)
ifp->if_ibytes += ilen;
getmicrotime(&ifp->if_lastchange);
if (rv)
if (isr == -1)
(*sc->sc_ctlp)(sc);
return;

View File

@ -968,12 +968,9 @@ slinput(c, tp)
m_freem(m);
goto newpack;
}
if (! IF_HANDOFF(&ipintrq, m, NULL)) {
if (! netisr_queue(NETISR_IP, m)) {
sc->sc_if.if_ierrors++;
sc->sc_if.if_iqdrops++;
} else {
schednetisr(NETISR_IP);
}
goto newpack;
}

View File

@ -514,7 +514,7 @@ void
sppp_input(struct ifnet *ifp, struct mbuf *m)
{
struct ppp_header *h;
struct ifqueue *inq = 0;
int isr = -1;
struct sppp *sp = (struct sppp *)ifp;
u_char *iphdr;
int hlen, vjlen, do_account = 0;
@ -591,8 +591,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
return;
case PPP_IP:
if (sp->state[IDX_IPCP] == STATE_OPENED) {
schednetisr (NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
}
do_account++;
break;
@ -622,9 +621,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
if (m == NULL)
goto drop2;
bcopy(iphdr, mtod(m, u_char *), hlen);
schednetisr (NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
}
do_account++;
break;
@ -641,8 +638,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
SPP_ARGS(ifp));
goto drop;
}
schednetisr (NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
}
do_account++;
break;
@ -655,30 +651,24 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
return;
case PPP_IPV6:
if (sp->state[IDX_IPV6CP] == STATE_OPENED) {
schednetisr (NETISR_IPV6);
inq = &ip6intrq;
}
if (sp->state[IDX_IPV6CP] == STATE_OPENED)
isr = NETISR_IPV6;
do_account++;
break;
#endif
#ifdef IPX
case PPP_IPX:
/* IPX IPXCP not implemented yet */
if (sp->pp_phase == PHASE_NETWORK) {
schednetisr (NETISR_IPX);
inq = &ipxintrq;
}
if (sp->pp_phase == PHASE_NETWORK)
isr = NETISR_IPX;
do_account++;
break;
#endif
#ifdef NS
case PPP_XNS:
/* XNS IDPCP not implemented yet */
if (sp->pp_phase == PHASE_NETWORK) {
schednetisr (NETISR_NS);
inq = &nsintrq;
}
if (sp->pp_phase == PHASE_NETWORK)
isr = NETISR_NS;
do_account++;
break;
#endif
@ -706,29 +696,25 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
return;
#ifdef INET
case ETHERTYPE_IP:
schednetisr (NETISR_IP);
inq = &ipintrq;
isr = NETISR_IP;
do_account++;
break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
schednetisr (NETISR_IPV6);
inq = &ip6intrq;
isr = NETISR_IPV6;
do_account++;
break;
#endif
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr (NETISR_IPX);
inq = &ipxintrq;
isr = NETISR_IPX;
do_account++;
break;
#endif
#ifdef NS
case ETHERTYPE_NS:
schednetisr (NETISR_NS);
inq = &nsintrq;
isr = NETISR_NS;
do_account++;
break;
#endif
@ -745,11 +731,11 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
goto drop;
}
if (! (ifp->if_flags & IFF_UP) || ! inq)
if (! (ifp->if_flags & IFF_UP) || isr == -1)
goto drop;
/* Check queue. */
if (! IF_HANDOFF(inq, m, NULL)) {
if (! netisr_queue(isr, m)) {
if (debug)
log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n",
SPP_ARGS(ifp));

View File

@ -614,8 +614,6 @@ in_stf_input(m, off)
struct ip *ip;
struct ip6_hdr *ip6;
u_int8_t otos, itos;
int len, isr;
struct ifqueue *ifq = NULL;
struct ifnet *ifp;
proto = mtod(m, struct ip *)->ip_p;
@ -708,15 +706,9 @@ in_stf_input(m, off)
* See net/if_gif.c for possible issues with packet processing
* reorder due to extra queueing.
*/
ifq = &ip6intrq;
isr = NETISR_IPV6;
len = m->m_pkthdr.len;
if (! IF_HANDOFF(ifq, m, NULL))
return;
schednetisr(isr);
ifp->if_ipackets++;
ifp->if_ibytes += len;
ifp->if_ibytes += m->m_pkthdr.len;
netisr_dispatch(NETISR_IPV6, m);
}
/* ARGSUSED */

View File

@ -39,12 +39,13 @@
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <machine/bus.h> /* XXX Shouldn't really be required ! */
#include <sys/random.h>
#include <sys/rman.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/intrq.h>
#ifdef INET
#include <netinet/in.h>
#endif
@ -693,6 +694,7 @@ tunwrite(dev_t dev, struct uio *uio, int flag)
struct mbuf *top, **mp, *m;
int error=0, tlen, mlen;
uint32_t family;
int isr;
TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
@ -787,10 +789,53 @@ tunwrite(dev_t dev, struct uio *uio, int flag)
} else
family = AF_INET;
switch (family) {
#ifdef INET
case AF_INET:
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
isr = NETISR_IPV6;
break;
#endif
#ifdef IPX
case AF_IPX:
isr = NETISR_IPX;
break;
#endif
#ifdef NS
case AF_NS:
isr = NETISR_NS;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
isr = NETISR_ATALK2;
break;
#endif
#ifdef NATM
case AF_NATM:
isr = NETISR_NATM;
break;
#endif
#ifdef ATM_CORE
case AF_ATM:
isr = NETISR_ATM;
break;
#endif
default:
m_freem(m);
return (EAFNOSUPPORT);
}
/* First chunk of an mbuf contains good junk */
if (harvest.point_to_point)
random_harvest(m, 16, 3, 0, RANDOM_NET);
ifp->if_ibytes += top->m_pkthdr.len;
ifp->if_ipackets++;
return (family_enqueue(family, top));
netisr_dispatch(isr, top);
return (0);
}
/*

View File

@ -1,4 +1,5 @@
/*
/*-
* Copyright (c) 2001,2002,2003 Jonathan Lemon <jlemon@FreeBSD.org>
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
* All rights reserved.
*
@ -6,40 +7,61 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/proc.h>
#include <sys/rtprio.h>
#include <sys/systm.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/random.h>
#include <sys/resourcevar.h>
#include <sys/sysctl.h>
#include <sys/unistd.h>
#include <machine/atomic.h>
#include <machine/cpu.h>
#include <machine/stdarg.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/netisr.h>
static void swi_net(void *);
volatile unsigned int netisr; /* scheduling bits for network */
void *net_ih;
volatile unsigned int netisr;
void (*netisrs[32])(void);
struct netisr {
netisr_t *ni_handler;
struct ifqueue *ni_queue;
} netisrs[32];
static struct mtx netisr_mtx;
static void *net_ih;
void
legacy_setsoftnet(void)
@ -47,69 +69,176 @@ legacy_setsoftnet(void)
swi_sched(net_ih, 0);
}
int
register_netisr(int num, netisr_t *handler)
void
netisr_register(int num, netisr_t *handler, struct ifqueue *inq)
{
if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) {
printf("register_netisr: bad isr number: %d\n", num);
return (EINVAL);
}
netisrs[num] = handler;
return (0);
KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
("bad isr %d", num));
netisrs[num].ni_handler = handler;
netisrs[num].ni_queue = inq;
}
int
unregister_netisr(int num)
void
netisr_unregister(int num)
{
struct netisr *ni;
int s;
if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) {
printf("unregister_netisr: bad isr number: %d\n", num);
return (EINVAL);
KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
("bad isr %d", num));
ni = &netisrs[num];
ni->ni_handler = NULL;
if (ni->ni_queue != NULL) {
s = splimp();
IF_DRAIN(ni->ni_queue);
splx(s);
}
netisrs[num] = NULL;
return (0);
}
#ifdef DEVICE_POLLING
void netisr_pollmore(void);
#endif
struct isrstat {
int isrs_count; /* dispatch count */
int isrs_directed; /* ...successfully dispatched */
int isrs_deferred; /* ...queued instead */
int isrs_bypassed; /* bypassed queued packets */
int isrs_queued; /* intentionally queueued */
int isrs_swi_count; /* swi_net handlers called */
};
static struct isrstat isrstat;
SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW, 0, "netisr counters");
static int netisr_enable = 0;
SYSCTL_INT(_net_isr, OID_AUTO, enable, CTLFLAG_RW,
&netisr_enable, 0, "enable direct dispatch");
SYSCTL_INT(_net_isr, OID_AUTO, count, CTLFLAG_RD,
&isrstat.isrs_count, 0, "");
SYSCTL_INT(_net_isr, OID_AUTO, directed, CTLFLAG_RD,
&isrstat.isrs_directed, 0, "");
SYSCTL_INT(_net_isr, OID_AUTO, deferred, CTLFLAG_RD,
&isrstat.isrs_deferred, 0, "");
SYSCTL_INT(_net_isr, OID_AUTO, bypassed, CTLFLAG_RD,
&isrstat.isrs_bypassed, 0, "");
SYSCTL_INT(_net_isr, OID_AUTO, queued, CTLFLAG_RD,
&isrstat.isrs_queued, 0, "");
SYSCTL_INT(_net_isr, OID_AUTO, swi_count, CTLFLAG_RD,
&isrstat.isrs_swi_count, 0, "");
/*
* Call the netisr directly instead of queueing the packet, if possible.
*
* Ideally, the permissibility of calling the routine would be determined
* by checking if splnet() was asserted at the time the device interrupt
* occurred; if so, this indicates that someone is in the network stack.
*
* However, bus_setup_intr uses INTR_TYPE_NET, which sets splnet before
* calling the interrupt handler, so the previous mask is unavailable.
* Approximate this by checking intr_nesting_level instead; if any SWI
* handlers are running, the packet is queued instead.
*/
void
netisr_dispatch(int num, struct mbuf *m)
{
struct netisr *ni;
isrstat.isrs_count++;
KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
("bad isr %d", num));
ni = &netisrs[num];
KASSERT(ni->ni_queue != NULL, ("no queue for isr %d", num));
if (netisr_enable && mtx_trylock(&netisr_mtx)) {
isrstat.isrs_directed++;
/*
* One slight problem here is that packets might bypass
* each other in the stack, if an earlier one happened
* to get stuck in the queue.
*
* we can either:
* a. drain the queue before handling this packet,
* b. fallback to queueing the packet,
* c. sweep the issue under the rug and ignore it.
*
* Currently, we do c), and keep a rough event counter.
*/
if (_IF_QLEN(ni->ni_queue) > 0)
isrstat.isrs_bypassed++;
ni->ni_handler(m);
mtx_unlock(&netisr_mtx);
} else {
isrstat.isrs_deferred++;
if (IF_HANDOFF(ni->ni_queue, m, NULL))
schednetisr(num);
}
}
/*
* Same as above, but always queue.
* This is either used in places where we are not confident that
* direct dispatch is possible, or where queueing is required.
*/
int
netisr_queue(int num, struct mbuf *m)
{
struct netisr *ni;
KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
("bad isr %d", num));
ni = &netisrs[num];
KASSERT(ni->ni_queue != NULL, ("no queue for isr %d", num));
isrstat.isrs_queued++;
if (!IF_HANDOFF(ni->ni_queue, m, NULL))
return (0);
schednetisr(num);
return (1);
}
static void
swi_net(void *dummy)
{
struct netisr *ni;
struct mbuf *m;
u_int bits;
int i;
#ifdef DEVICE_POLLING
const int polling = 1;
#else
const int polling = 0;
#endif
#ifdef DEVICE_POLLING
for (;;) {
int pollmore;
#endif
bits = atomic_readandclear_int(&netisr);
#ifdef DEVICE_POLLING
if (bits == 0)
return;
pollmore = bits & (1 << NETISR_POLL);
#endif
while ((i = ffs(bits)) != 0) {
i--;
if (netisrs[i] != NULL)
netisrs[i]();
else
printf("swi_net: unregistered isr number: %d.\n", i);
bits &= ~(1 << i);
}
#ifdef DEVICE_POLLING
if (pollmore)
netisr_pollmore();
}
#endif
mtx_lock(&netisr_mtx);
do {
bits = atomic_readandclear_int(&netisr);
if (bits == 0)
break;
while ((i = ffs(bits)) != 0) {
isrstat.isrs_swi_count++;
i--;
bits &= ~(1 << i);
ni = &netisrs[i];
if (ni->ni_handler == NULL) {
printf("swi_net: unregistered isr %d.\n", i);
continue;
}
if (ni->ni_queue == NULL)
ni->ni_handler(NULL);
else
for (;;) {
IF_DEQUEUE(ni->ni_queue, m);
if (m == NULL)
break;
ni->ni_handler(m);
}
}
} while (polling);
mtx_unlock(&netisr_mtx);
}
static void
start_netisr(void *dummy)
{
mtx_init(&netisr_mtx, "netisr lock", NULL, MTX_DEF);
if (swi_add(NULL, "net", swi_net, NULL, SWI_NET, 0, &net_ih))
panic("start_netisr");
}

View File

@ -55,15 +55,18 @@
#define NETISR_POLL 0 /* polling callback, must be first */
#define NETISR_IP 2 /* same as AF_INET */
#define NETISR_NS 6 /* same as AF_NS */
#define NETISR_ATALK 16 /* same as AF_APPLETALK */
#define NETISR_AARP 15 /* Appletalk ARP */
#define NETISR_ATALK2 16 /* Appletalk phase 2 */
#define NETISR_ATALK1 17 /* Appletalk phase 1 */
#define NETISR_ARP 18 /* same as AF_LINK */
#define NETISR_IPX 23 /* same as AF_IPX */
#define NETISR_USB 25 /* USB soft interrupt */
#define NETISR_PPP 27 /* PPP soft interrupt */
#define NETISR_IPV6 28 /* same as AF_INET6 */
#define NETISR_NATM 29 /* same as AF_NATM */
#define NETISR_ATM 30 /* same as AF_ATM */
#define NETISR_NETGRAPH 31 /* same as AF_NETGRAPH */
#define NETISR_PPP 26 /* PPP soft interrupt */
#define NETISR_IPV6 27
#define NETISR_NATM 28
#define NETISR_ATM 29
#define NETISR_NETGRAPH 30
#define NETISR_POLLMORE 31 /* polling callback, must be last */
#ifndef LOCORE
@ -72,16 +75,25 @@
void legacy_setsoftnet(void);
extern volatile unsigned int netisr; /* scheduling bits for network */
extern void (*netisrs[32])(void);
#define schednetisr(anisr) do { \
atomic_set_rel_int(&netisr, 1 << (anisr)); \
legacy_setsoftnet(); \
} while (0)
/* used to atomically schedule multiple netisrs */
#define schednetisrbits(isrbits) do { \
atomic_set_rel_int(&netisr, isrbits); \
legacy_setsoftnet(); \
} while (0)
typedef void netisr_t(void);
struct ifqueue;
struct mbuf;
int register_netisr(int, netisr_t *);
int unregister_netisr(int);
typedef void netisr_t (struct mbuf *);
void netisr_dispatch(int, struct mbuf *);
int netisr_queue(int, struct mbuf *);
void netisr_register(int, netisr_t *, struct ifqueue *);
void netisr_unregister(int);
#endif
#endif

View File

@ -258,12 +258,13 @@ aarpresolve( ac, m, destsat, desten )
}
void
aarpinput( ac, m )
struct arpcom *ac;
aarpintr( m )
struct mbuf *m;
{
struct arphdr *ar;
struct arpcom *ac;
ac = (struct arpcom *)m->m_pkthdr.rcvif;
if ( ac->ac_if.if_flags & IFF_NOARP )
goto out;

View File

@ -10,7 +10,6 @@ extern int aarpresolve (struct arpcom *,
struct mbuf *,
struct sockaddr_at *,
u_char *);
extern void aarpinput (struct arpcom *, struct mbuf *);
extern int at_broadcast (struct sockaddr_at *);
#endif
@ -22,6 +21,9 @@ struct ifnet;
struct thread;
struct socket;
extern void aarpintr (struct mbuf *);
extern void at1intr (struct mbuf *);
extern void at2intr (struct mbuf *);
extern void aarp_clean (void);
extern int at_control (struct socket *so,
u_long cmd,

View File

@ -61,7 +61,6 @@ struct at_aliasreq {
#ifdef _KERNEL
extern struct at_ifaddr *at_ifaddr;
extern struct ifqueue atintrq1, atintrq2;
#endif
#endif /* _NETATALK_AT_VAR_H_ */

View File

@ -18,8 +18,6 @@
#include <sys/sx.h>
#include <sys/systm.h>
#include <net/if.h>
#include <net/intrq.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netatalk/at.h>
@ -38,78 +36,45 @@ static void ddp_input(struct mbuf *, struct ifnet *, struct elaphdr *, int);
/*
* Could probably merge these two code segments a little better...
*/
static void
atintr( void )
void
at2intr(struct mbuf *m)
{
struct elaphdr *elhp, elh;
struct ifnet *ifp;
struct mbuf *m;
int s;
/*
* First pull off all the phase 2 packets.
*/
for (;;) {
s = splimp();
/*
* Phase 2 packet handling
*/
ddp_input(m, m->m_pkthdr.rcvif, NULL, 2);
return;
}
IF_DEQUEUE( &atintrq2, m );
void
at1intr(struct mbuf *m)
{
struct elaphdr *elhp, elh;
splx( s );
if ( m == 0 ) { /* no more queued packets */
break;
}
ifp = m->m_pkthdr.rcvif;
ddp_input( m, ifp, (struct elaphdr *)NULL, 2 );
}
/*
* Then pull off all the phase 1 packets.
*/
for (;;) {
s = splimp();
IF_DEQUEUE( &atintrq1, m );
splx( s );
if ( m == 0 ) { /* no more queued packets */
break;
}
ifp = m->m_pkthdr.rcvif;
if ( m->m_len < SZ_ELAPHDR &&
(( m = m_pullup( m, SZ_ELAPHDR )) == 0 )) {
ddpstat.ddps_tooshort++;
continue;
/*
* Phase 1 packet handling
*/
if (m->m_len < SZ_ELAPHDR && ((m = m_pullup(m, SZ_ELAPHDR)) == 0)) {
ddpstat.ddps_tooshort++;
return;
}
/*
* this seems a little dubios, but I don't know phase 1 so leave it.
* This seems a little dubious, but I don't know phase 1 so leave it.
*/
elhp = mtod( m, struct elaphdr *);
m_adj( m, SZ_ELAPHDR );
elhp = mtod(m, struct elaphdr *);
m_adj(m, SZ_ELAPHDR);
if ( elhp->el_type == ELAP_DDPEXTEND ) {
ddp_input( m, ifp, (struct elaphdr *)NULL, 1 );
if (elhp->el_type == ELAP_DDPEXTEND) {
ddp_input(m, m->m_pkthdr.rcvif, NULL, 1);
} else {
bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR );
ddp_input( m, ifp, &elh, 1 );
bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR);
ddp_input(m, m->m_pkthdr.rcvif, &elh, 1);
}
}
return;
return;
}
static void
netisr_atalk_setup(void *dummy __unused)
{
register_netisr(NETISR_ATALK, atintr);
}
SYSINIT(atalk_setup, SI_SUB_CPU, SI_ORDER_ANY, netisr_atalk_setup, NULL);
static void
ddp_input( m, ifp, elh, phase )
struct mbuf *m;

View File

@ -14,7 +14,7 @@
#include <sys/protosw.h>
#include <net/if.h>
#include <net/route.h>
#include <net/intrq.h>
#include <net/netisr.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
@ -35,6 +35,7 @@ struct ddpcb *ddpcb = NULL;
static u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
static u_long ddp_recvspace = 10 * ( 587 + sizeof( struct sockaddr_at ));
static struct ifqueue atintrq1, atintrq2, aarpintrq;
static int
ddp_attach(struct socket *so, int proto, struct thread *td)
@ -542,16 +543,19 @@ at_setsockaddr(struct socket *so, struct sockaddr **nam)
return(0);
}
void
ddp_init(void )
ddp_init(void)
{
atintrq1.ifq_maxlen = IFQ_MAXLEN;
atintrq2.ifq_maxlen = IFQ_MAXLEN;
atintrq1_present = 1;
atintrq2_present = 1;
mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
atintrq1.ifq_maxlen = IFQ_MAXLEN;
atintrq2.ifq_maxlen = IFQ_MAXLEN;
aarpintrq.ifq_maxlen = IFQ_MAXLEN;
mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF);
netisr_register(NETISR_ATALK1, at1intr, &atintrq1);
netisr_register(NETISR_ATALK2, at2intr, &atintrq2);
netisr_register(NETISR_AARP, aarpintr, &aarpintrq);
}
#if 0

View File

@ -14,7 +14,7 @@
#include <sys/protosw.h>
#include <net/if.h>
#include <net/route.h>
#include <net/intrq.h>
#include <net/netisr.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
@ -35,6 +35,7 @@ struct ddpcb *ddpcb = NULL;
static u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
static u_long ddp_recvspace = 10 * ( 587 + sizeof( struct sockaddr_at ));
static struct ifqueue atintrq1, atintrq2, aarpintrq;
static int
ddp_attach(struct socket *so, int proto, struct thread *td)
@ -542,16 +543,19 @@ at_setsockaddr(struct socket *so, struct sockaddr **nam)
return(0);
}
void
ddp_init(void )
ddp_init(void)
{
atintrq1.ifq_maxlen = IFQ_MAXLEN;
atintrq2.ifq_maxlen = IFQ_MAXLEN;
atintrq1_present = 1;
atintrq2_present = 1;
mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
atintrq1.ifq_maxlen = IFQ_MAXLEN;
atintrq2.ifq_maxlen = IFQ_MAXLEN;
aarpintrq.ifq_maxlen = IFQ_MAXLEN;
mtx_init(&atintrq1.ifq_mtx, "at1_inq", NULL, MTX_DEF);
mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF);
mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF);
netisr_register(NETISR_ATALK1, at1intr, &atintrq1);
netisr_register(NETISR_ATALK2, at2intr, &atintrq2);
netisr_register(NETISR_AARP, aarpintr, &aarpintrq);
}
#if 0

View File

@ -99,6 +99,7 @@ static struct t_atm_cause atm_dev_cause = {
{0, 0, 0, 0}
};
extern struct ifqueue atm_intrq;
/*
* ATM Device Stack Instantiation

View File

@ -45,7 +45,6 @@
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/intrq.h>
#include <netatm/port.h>
#include <netatm/queue.h>
#include <netatm/atm.h>
@ -77,6 +76,7 @@ int atm_dev_print = 0;
int atm_print_data = 0;
int atm_version = ATM_VERSION;
struct timeval atm_debugtime = {0, 0};
struct ifqueue atm_intrq;
uma_zone_t atm_attributes_zone;
@ -84,6 +84,7 @@ uma_zone_t atm_attributes_zone;
* Local functions
*/
static KTimeout_ret atm_timexp(void *);
static void atm_intr(struct mbuf *);
/*
* Local variables
@ -115,10 +116,6 @@ atm_initialize()
return;
atm_init = 1;
atm_intrq.ifq_maxlen = ATM_INTRQ_MAX;
mtx_init(&atm_intrq.ifq_mtx, "atm_inq", NULL, MTX_DEF);
atmintrq_present = 1;
atm_attributes_zone = uma_zcreate("atm attributes",
sizeof(Atm_attributes), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
@ -132,7 +129,9 @@ atm_initialize()
panic("atm_initialize: unable to create stackq zone");
uma_zone_set_max(atm_stackq_zone, 10);
register_netisr(NETISR_ATM, atm_intr);
atm_intrq.ifq_maxlen = ATM_INTRQ_MAX;
mtx_init(&atm_intrq.ifq_mtx, "atm_inq", NULL, MTX_DEF);
netisr_register(NETISR_ATM, atm_intr, &atm_intrq);
/*
* Initialize subsystems
@ -541,51 +540,37 @@ atm_stack_drain()
* none
*
*/
void
atm_intr()
static void
atm_intr(struct mbuf *m)
{
KBuffer *m;
caddr_t cp;
atm_intr_func_t func;
void *token;
int s;
for (; ; ) {
/*
* Get next buffer from queue
*/
s = splimp();
IF_DEQUEUE(&atm_intrq, m);
(void) splx(s);
if (m == NULL)
break;
/*
* Get function to call and token value
*/
KB_DATASTART(m, cp, caddr_t);
func = *(atm_intr_func_t *)cp;
cp += sizeof(func);
token = *(void **)cp;
KB_HEADADJ(m, -(sizeof(func) + sizeof(token)));
if (KB_LEN(m) == 0) {
KBuffer *m1;
KB_UNLINKHEAD(m, m1);
m = m1;
}
/*
* Call processing function
*/
(*func)(token, m);
/*
* Drain any deferred calls
*/
STACK_DRAIN();
/*
* Get function to call and token value
*/
KB_DATASTART(m, cp, caddr_t);
func = *(atm_intr_func_t *)cp;
cp += sizeof(func);
token = *(void **)cp;
KB_HEADADJ(m, -(sizeof(func) + sizeof(token)));
if (KB_LEN(m) == 0) {
KBuffer *m1;
KB_UNLINKHEAD(m, m1);
m = m1;
}
}
/*
* Call processing function
*/
(*func)(token, m);
/*
* Drain any deferred calls
*/
STACK_DRAIN();
}
/*
* Print a pdu buffer chain

View File

@ -59,7 +59,6 @@ extern struct atm_ncm *atm_netconv_head;
extern Atm_endpoint *atm_endpoints[];
extern struct stackq_entry *atm_stackq_head;
extern struct stackq_entry *atm_stackq_tail;
extern struct ifqueue atm_intrq;
extern struct atm_sock_stat atm_sock_stat;
extern int atm_init;
extern int atm_version;
@ -173,7 +172,6 @@ int atm_untimeout(struct atm_time *);
int atm_stack_enq(int, void (*)(int, void *, intptr_t, intptr_t),
void *, Atm_connvc *, intptr_t, intptr_t);
void atm_stack_drain(void);
void atm_intr(void);
void atm_pdu_print(KBuffer *, char *);
#endif /* _KERNEL */
#endif /* _NETATM_ATM_VAR_H */

View File

@ -162,9 +162,6 @@ ipatm_ipinput(inp, m)
* just call IP directly to avoid the extra unnecessary
* kernel scheduling.
*/
if (! IF_HANDOFF(&ipintrq, m, NULL))
return (1);
schednetisr ( NETISR_IP );
netisr_dispatch(NETISR_IP, m);
return (0);
}

View File

@ -2987,7 +2987,7 @@ ngb_mod_event(module_t mod, int event, void *data)
mtx_init(&ng_idhash_mtx, "netgraph idhash mutex", NULL, 0);
mtx_init(&ngq_mtx, "netgraph netisr mutex", NULL, 0);
s = splimp();
error = register_netisr(NETISR_NETGRAPH, ngintr);
netisr_register(NETISR_NETGRAPH, (netisr_t *)ngintr, NULL);
splx(s);
break;
case MOD_UNLOAD:

View File

@ -1,4 +1,3 @@
/*
* ng_iface.c
*
@ -58,6 +57,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/random.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <sys/syslog.h>
@ -65,8 +65,8 @@
#include <net/if.h>
#include <net/if_types.h>
#include <net/intrq.h>
#include <net/bpf.h>
#include <net/netisr.h>
#include <netinet/in.h>
@ -729,6 +729,7 @@ ng_iface_rcvdata(hook_p hook, item_p item)
const iffam_p iffam = get_iffam_from_hook(priv, hook);
struct ifnet *const ifp = priv->ifp;
struct mbuf *m;
int isr;
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
@ -753,7 +754,51 @@ ng_iface_rcvdata(hook_p hook, item_p item)
ng_iface_bpftap(ifp, m, iffam->family);
/* Send packet */
return family_enqueue(iffam->family, m);
switch (iffam->family) {
#ifdef INET
case AF_INET:
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
isr = NETISR_IPV6;
break;
#endif
#ifdef IPX
case AF_IPX:
isr = NETISR_IPX;
break;
#endif
#ifdef NS
case AF_NS:
isr = NETISR_NS;
break;
#endif
#ifdef NETATALK
case AF_APPLETALK:
isr = NETISR_ATALK2;
break;
#endif
#ifdef NATM
case AF_NATM:
isr = NETISR_NATM;
break;
#endif
#ifdef ATM_CORE
case AF_ATM:
isr = NETISR_ATM;
break;
#endif
default:
m_freem(m);
return (EAFNOSUPPORT);
}
/* First chunk of an mbuf contains good junk */
if (harvest.point_to_point)
random_harvest(m, 16, 3, 0, RANDOM_NET);
netisr_dispatch(isr, m);
return (0);
}
/*

View File

@ -125,8 +125,7 @@ ngipi_rcvdata(hook_p hook, item_p item)
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
schednetisr(NETISR_IP);
(void) IF_HANDOFF(&ipintrq, m, NULL);
netisr_dispatch(NETISR_IP, m);
return 0;
}

View File

@ -104,7 +104,7 @@ struct llinfo_arp {
static LIST_HEAD(, llinfo_arp) llinfo_arp;
struct ifqueue arpintrq;
static struct ifqueue arpintrq;
static int arp_inuse, arp_allocated, arpinit_done;
static int arp_maxtries = 5;
@ -122,7 +122,7 @@ static void arp_init(void);
static void arp_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
static void arprequest(struct ifnet *,
struct in_addr *, struct in_addr *, u_char *);
static void arpintr(void);
static void arpintr(struct mbuf *);
static void arptfree(struct llinfo_arp *);
static void arptimer(void *);
static struct llinfo_arp
@ -497,56 +497,45 @@ arpresolve(ifp, rt, m, dst, desten, rt0)
* then the protocol-specific routine is called.
*/
static void
arpintr()
arpintr(struct mbuf *m)
{
register struct mbuf *m;
register struct arphdr *ar;
int s;
struct arphdr *ar;
if (!arpinit_done) {
arpinit_done = 1;
timeout(arptimer, (caddr_t)0, hz);
}
while (arpintrq.ifq_head) {
s = splimp();
IF_DEQUEUE(&arpintrq, m);
splx(s);
if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
panic("arpintr");
if (m->m_len < sizeof(struct arphdr) &&
((m = m_pullup(m, sizeof(struct arphdr))) == NULL)) {
log(LOG_ERR, "arp: runt packet -- m_pullup failed\n");
continue;
}
ar = mtod(m, struct arphdr *);
if (ntohs(ar->ar_hrd) != ARPHRD_ETHER
&& ntohs(ar->ar_hrd) != ARPHRD_IEEE802
&& ntohs(ar->ar_hrd) != ARPHRD_ARCNET) {
log(LOG_ERR,
"arp: unknown hardware address format (0x%2D)\n",
(unsigned char *)&ar->ar_hrd, "");
m_freem(m);
continue;
}
if (m->m_pkthdr.len < arphdr_len(ar) &&
(m = m_pullup(m, arphdr_len(ar))) == NULL) {
log(LOG_ERR, "arp: runt packet\n");
m_freem(m);
continue;
}
switch (ntohs(ar->ar_pro)) {
#ifdef INET
case ETHERTYPE_IP:
in_arpinput(m);
continue;
#endif
}
m_freem(m);
if (m->m_len < sizeof(struct arphdr) &&
((m = m_pullup(m, sizeof(struct arphdr))) == NULL)) {
log(LOG_ERR, "arp: runt packet -- m_pullup failed\n");
return;
}
ar = mtod(m, struct arphdr *);
if (ntohs(ar->ar_hrd) != ARPHRD_ETHER &&
ntohs(ar->ar_hrd) != ARPHRD_IEEE802 &&
ntohs(ar->ar_hrd) != ARPHRD_ARCNET) {
log(LOG_ERR, "arp: unknown hardware address format (0x%2D)\n",
(unsigned char *)&ar->ar_hrd, "");
m_freem(m);
return;
}
if (m->m_pkthdr.len < arphdr_len(ar) &&
(m = m_pullup(m, arphdr_len(ar))) == NULL) {
log(LOG_ERR, "arp: runt packet\n");
m_freem(m);
return;
}
switch (ntohs(ar->ar_pro)) {
#ifdef INET
case ETHERTYPE_IP:
in_arpinput(m);
return;
#endif
}
m_freem(m);
}
#ifdef INET
@ -958,7 +947,7 @@ arp_init(void)
arpintrq.ifq_maxlen = 50;
mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF);
LIST_INIT(&llinfo_arp);
register_netisr(NETISR_ARP, arpintr);
netisr_register(NETISR_ARP, arpintr, &arpintrq);
}
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);

View File

@ -112,7 +112,6 @@ struct sockaddr_inarp {
#ifdef _KERNEL
extern u_char ether_ipmulticast_min[ETHER_ADDR_LEN];
extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
extern struct ifqueue arpintrq;
int arpresolve(struct ifnet *, struct rtentry *, struct mbuf *,
struct sockaddr *, u_char *, struct rtentry *);

View File

@ -83,7 +83,6 @@ struct in_aliasreq {
#ifdef _KERNEL
extern struct ifqueue ipintrq; /* ip packet input queue */
extern struct in_addr zeroin_addr;
extern u_char inetctlerrmap[];

View File

@ -146,8 +146,7 @@ static int
gre_input2(struct mbuf *m ,int hlen, u_char proto)
{
struct greip *gip = mtod(m, struct greip *);
int s;
struct ifqueue *ifq;
int isr;
struct gre_softc *sc;
u_short flags;
@ -180,18 +179,16 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto)
switch (ntohs(gip->gi_ptype)) { /* ethertypes */
case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */
case WCCP_PROTOCOL_TYPE: /* we are in ip_input */
ifq = &ipintrq;
isr = NETISR_IP;
break;
#ifdef NS
case ETHERTYPE_NS:
ifq = &nsintrq;
schednetisr(NETISR_NS);
isr = NETISR_NS;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_ATALK:
ifq = &atintrq1;
schednetisr(NETISR_ATALK);
isr = NETISR_ATALK1;
break;
#endif
case ETHERTYPE_IPV6:
@ -222,14 +219,7 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto)
m->m_pkthdr.rcvif = &sc->sc_if;
s = splnet(); /* possible */
if (_IF_QFULL(ifq)) {
_IF_DROP(ifq);
m_freem(m);
} else {
IF_ENQUEUE(ifq,m);
}
splx(s);
netisr_dispatch(isr, m);
return(1); /* packet is done, no further processing needed */
}
@ -252,9 +242,8 @@ gre_mobile_input(m, va_alist)
{
struct ip *ip = mtod(m, struct ip *);
struct mobip_h *mip = mtod(m, struct mobip_h *);
struct ifqueue *ifq;
struct gre_softc *sc;
int hlen,s;
int hlen;
va_list ap;
u_char osrc = 0;
int msiz;
@ -317,15 +306,7 @@ gre_mobile_input(m, va_alist)
m->m_pkthdr.rcvif = &sc->sc_if;
ifq = &ipintrq;
s = splnet(); /* possible */
if (_IF_QFULL(ifq)) {
_IF_DROP(ifq);
m_freem(m);
} else {
IF_ENQUEUE(ifq,m);
}
splx(s);
netisr_dispatch(NETISR_IP, m);
}
/*

View File

@ -65,7 +65,6 @@
#include <net/if_dl.h>
#include <net/route.h>
#include <net/netisr.h>
#include <net/intrq.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@ -156,6 +155,7 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, check_interface, CTLFLAG_RW,
static int ipprintfs = 0;
#endif
static struct ifqueue ipintrq;
static int ipqmaxlen = IFQ_MAXLEN;
extern struct domain inetdomain;
@ -233,7 +233,6 @@ static void ip_forward(struct mbuf *m, int srcrt,
static void ip_freef(struct ipqhead *, struct ipq *);
static struct mbuf *ip_reass(struct mbuf *, struct ipqhead *,
struct ipq *, u_int32_t *, u_int16_t *);
static void ipintr(void);
/*
* IP initialization: fill in IP protocol switch table.
@ -269,9 +268,7 @@ ip_init()
#endif
ipintrq.ifq_maxlen = ipqmaxlen;
mtx_init(&ipintrq.ifq_mtx, "ip_inq", NULL, MTX_DEF);
ipintrq_present = 1;
register_netisr(NETISR_IP, ipintr);
netisr_register(NETISR_IP, ip_input, &ipintrq);
}
/*
@ -950,22 +947,6 @@ DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
m_freem(m);
}
/*
* IP software interrupt routine - to go away sometime soon
*/
static void
ipintr(void)
{
struct mbuf *m;
while (1) {
IF_DEQUEUE(&ipintrq, m);
if (m == 0)
return;
ip_input(m);
}
}
/*
* Take incoming datagram fragment and try to reassemble it into
* whole datagram. If a chain for reassembly of this datagram already

View File

@ -33,6 +33,7 @@
#include <sys/systm.h>
#include <sys/time.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/igmp.h>
@ -554,13 +555,17 @@ mroute_encap_input(struct mbuf *m, int off)
m->m_pkthdr.rcvif = last_encap_vif->v_ifp;
(void) IF_HANDOFF(&ipintrq, m, NULL);
netisr_queue(NETISR_IP, m);
/*
* normally we would need a "schednetisr(NETISR_IP)"
* here but we were called by ip_input and it is going
* to loop back & try to dequeue the packet we just
* queued as soon as we return so we avoid the
* unnecessary software interrrupt.
*
* XXX
* This no longer holds - we may have direct-dispatched the packet,
* or there may be a queue processing limit.
*/
}

View File

@ -454,13 +454,12 @@ ah4_input(m, off)
goto fail;
}
if (! IF_HANDOFF(&ipintrq, m, NULL)) {
if (! netisr_queue(NETISR_IP, m)) {
ipsecstat.in_inval++;
m = NULL;
goto fail;
}
m = NULL;
schednetisr(NETISR_IP); /* can be skipped but to make sure */
nxt = IPPROTO_DONE;
} else {
/*
@ -852,13 +851,12 @@ ah6_input(mp, offp, proto)
goto fail;
}
if (! IF_HANDOFF(&ip6intrq, m, NULL)) {
if (! netisr_queue(NETISR_IPV6, m)) {
ipsec6stat.in_inval++;
m = NULL;
goto fail;
}
m = NULL;
schednetisr(NETISR_IPV6); /* can be skipped but to make sure */
nxt = IPPROTO_DONE;
} else {
/*

View File

@ -388,13 +388,12 @@ esp4_input(m, off)
goto bad;
}
if (! IF_HANDOFF(&ipintrq, m, NULL)) {
if (! netisr_queue(NETISR_IP, m)) {
ipsecstat.in_inval++;
m = NULL;
goto bad;
}
m = NULL;
schednetisr(NETISR_IP); /* can be skipped but to make sure */
nxt = IPPROTO_DONE;
} else {
/*
@ -750,13 +749,12 @@ esp6_input(mp, offp, proto)
goto bad;
}
if (! IF_HANDOFF(&ip6intrq, m, NULL)) {
if (! netisr_queue(NETISR_IPV6, m)) {
ipsec6stat.in_inval++;
m = NULL;
goto bad;
}
m = NULL;
schednetisr(NETISR_IPV6); /* can be skipped but to make sure */
nxt = IPPROTO_DONE;
} else {
/*

View File

@ -460,7 +460,6 @@ do { \
} \
} while (0)
extern struct ifqueue ip6intrq; /* IP6 packet input queue */
extern struct in6_addr zeroin6_addr;
extern u_char inet6ctlerrmap[];
extern unsigned long in6_maxmtu;

View File

@ -90,7 +90,6 @@
#include <net/if_dl.h>
#include <net/route.h>
#include <net/netisr.h>
#include <net/intrq.h>
#ifdef PFIL_HOOKS
#include <net/pfil.h>
#endif
@ -132,6 +131,7 @@
extern struct domain inet6domain;
u_char ip6_protox[IPPROTO_MAX];
static struct ifqueue ip6intrq;
static int ip6qmaxlen = IFQ_MAXLEN;
struct in6_ifaddr *in6_ifaddr;
@ -186,8 +186,7 @@ ip6_init()
ip6_protox[pr->pr_protocol] = pr - inet6sw;
ip6intrq.ifq_maxlen = ip6qmaxlen;
mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", NULL, MTX_DEF);
ip6intrq_present = 1;
register_netisr(NETISR_IPV6, ip6intr);
netisr_register(NETISR_IPV6, ip6_input, &ip6intrq);
nd6_init();
frag6_init();
/*
@ -230,25 +229,6 @@ ip6_init2(dummy)
/* This must be after route_init(), which is now SI_ORDER_THIRD */
SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL);
/*
* IP6 input interrupt handling. Just pass the packet to ip6_input.
*/
void
ip6intr()
{
int s;
struct mbuf *m;
for (;;) {
s = splimp();
IF_DEQUEUE(&ip6intrq, m);
splx(s);
if (m == 0)
return;
ip6_input(m);
}
}
extern struct route_in6 ip6_forward_rt;
void

View File

@ -294,7 +294,6 @@ int icmp6_ctloutput __P((struct socket *, struct sockopt *sopt));
struct in6_ifaddr;
void ip6_init __P((void));
void ip6intr __P((void));
void ip6_input __P((struct mbuf *));
struct in6_ifaddr *ip6_getdstifaddr __P((struct mbuf *));
void ip6_freepcbopts __P((struct ip6_pktopts *));

View File

@ -396,7 +396,7 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
/*
* Re-dispatch via software interrupt.
*/
if (!IF_HANDOFF(&ipintrq, m, NULL)) {
if (!netisr_queue(NETISR_IP, m)) {
IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull,
ipcompstat.ipcomps_qfull);
@ -404,7 +404,6 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
"proto %u packet dropped\n", sproto));
return ENOBUFS;
}
schednetisr(NETISR_IP);
return 0;
bad:
m_freem(m);

View File

@ -165,7 +165,6 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
register struct sockaddr_in *sin;
register struct ifnet *ifp;
register struct ifaddr *ifa;
struct ifqueue *ifq = NULL;
struct ip *ipo;
#ifdef INET6
register struct sockaddr_in6 *sin6;
@ -368,13 +367,11 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
switch (v >> 4) {
#ifdef INET
case 4:
ifq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case 6:
ifq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
@ -382,12 +379,9 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
panic("ipip_input: should never reach here");
}
if (!IF_HANDOFF(ifq, m, NULL)) {
if (!netisr_queue(isr, m)) {
ipipstat.ipips_qfull++;
DPRINTF(("ipip_input: packet dropped because of full queue\n"));
} else {
schednetisr(isr);
}
}

View File

@ -88,7 +88,6 @@ struct ipxip_req {
#endif
#ifdef _KERNEL
extern struct ifqueue ipxintrq; /* IPX input packet queue */
extern struct ipx_ifaddr *ipx_ifaddr;
struct ipx_ifaddr *ipx_iaonnetof(struct ipx_addr *dst);

View File

@ -48,7 +48,6 @@
#include <net/if.h>
#include <net/route.h>
#include <net/netisr.h>
#include <net/intrq.h>
#include <netipx/ipx.h>
#include <netipx/spx.h>
@ -87,12 +86,14 @@ struct ipxpcb ipxpcb;
struct ipxpcb ipxrawpcb;
static int ipxqmaxlen = IFQ_MAXLEN;
static struct ifqueue ipxintrq;
long ipx_pexseq;
static int ipx_do_route(struct ipx_addr *src, struct route *ro);
static void ipx_undo_route(struct route *ro);
static void ipx_forward(struct mbuf *m);
static void ipxintr(struct mbuf *m);
/*
* IPX initialization.
@ -105,9 +106,6 @@ ipx_init()
ipx_broadhost = *(union ipx_host *)allones;
read_random(&ipx_pexseq, sizeof ipx_pexseq);
ipxintrq.ifq_maxlen = ipxqmaxlen;
mtx_init(&ipxintrq.ifq_mtx, "ipx_inq", NULL, MTX_DEF);
ipxintrq_present = 1;
ipxpcb.ipxp_next = ipxpcb.ipxp_prev = &ipxpcb;
ipxrawpcb.ipxp_next = ipxrawpcb.ipxp_prev = &ipxrawpcb;
@ -118,31 +116,22 @@ ipx_init()
ipx_hostmask.sipx_addr.x_net = ipx_broadnet;
ipx_hostmask.sipx_addr.x_host = ipx_broadhost;
register_netisr(NETISR_IPX, ipxintr);
ipxintrq.ifq_maxlen = ipxqmaxlen;
mtx_init(&ipxintrq.ifq_mtx, "ipx_inq", NULL, MTX_DEF);
netisr_register(NETISR_IPX, ipxintr, &ipxintrq);
}
/*
* IPX input routine. Pass to next level.
*/
void
ipxintr()
static void
ipxintr(struct mbuf *m)
{
register struct ipx *ipx;
register struct mbuf *m;
register struct ipxpcb *ipxp;
struct ipx_ifaddr *ia;
int len, s;
int len;
next:
/*
* Get next datagram off input queue and get IPX header
* in first mbuf.
*/
s = splimp();
IF_DEQUEUE(&ipxintrq, m);
splx(s);
if (m == NULL)
return;
/*
* If no IPX addresses have been set yet but the interfaces
* are receiving, can't do anything with incoming packets yet.
@ -155,7 +144,7 @@ ipxintr()
if ((m->m_flags & M_EXT || m->m_len < sizeof(struct ipx)) &&
(m = m_pullup(m, sizeof(struct ipx))) == 0) {
ipxstat.ipxs_toosmall++;
goto next;
return;
}
/*
@ -201,7 +190,7 @@ ipxintr()
if (ipx->ipx_pt == IPXPROTO_NETBIOS) {
if (ipxnetbios) {
ipx_output_type20(m);
goto next;
return;
} else
goto bad;
}
@ -236,7 +225,7 @@ ipxintr()
*/
if (ipx->ipx_tc < IPX_MAXHOPS) {
ipx_forward(m);
goto next;
return;
}
}
/*
@ -251,7 +240,7 @@ ipxintr()
if (ia == NULL) {
ipx_forward(m);
goto next;
return;
}
}
ours:
@ -266,20 +255,18 @@ ipxintr()
ipxstat.ipxs_delivered++;
if ((ipxp->ipxp_flags & IPXP_ALL_PACKETS) == 0)
switch (ipx->ipx_pt) {
case IPXPROTO_SPX:
spx_input(m, ipxp);
goto next;
case IPXPROTO_SPX:
spx_input(m, ipxp);
return;
}
ipx_input(m, ipxp);
} else
goto bad;
goto next;
return;
bad:
m_freem(m);
goto next;
}
void

View File

@ -168,7 +168,6 @@ ipxip_input(m, hlen)
{
register struct ip *ip;
register struct ipx *ipx;
register struct ifqueue *ifq = &ipxintrq;
int len, s;
if (ipxip_hold_input) {
@ -224,9 +223,7 @@ ipxip_input(m, hlen)
/*
* Deliver to IPX
*/
if (IF_HANDOFF(ifq, m, NULL))
schednetisr(NETISR_IPX);
return;
netisr_dispatch(NETISR_IPX, m);
}
static int

View File

@ -95,7 +95,6 @@ int ipx_ctloutput(struct socket *so, struct sockopt *sopt);
void ipx_drop(struct ipxpcb *ipxp, int errno);
void ipx_init(void);
void ipx_input(struct mbuf *m, struct ipxpcb *ipxp);
void ipxintr(void);
int ipx_outputfl(struct mbuf *m0, struct route *ro, int flags);
int ipx_output_type20(struct mbuf *);
int ipx_peeraddr(struct socket *so, struct sockaddr **nam);

View File

@ -698,21 +698,12 @@ struct proc *p;
*/
void
natmintr()
natmintr(struct mbuf *m)
{
int s;
struct mbuf *m;
struct socket *so;
struct natmpcb *npcb;
next:
s = splimp();
IF_DEQUEUE(&natmintrq, m);
splx(s);
if (m == NULL)
return;
#ifdef DIAGNOSTIC
if ((m->m_flags & M_PKTHDR) == 0)
panic("natmintr no HDR");
@ -729,12 +720,12 @@ natmintr()
m_freem(m);
if (npcb->npcb_inq == 0)
FREE(npcb, M_PCB); /* done! */
goto next;
return;
}
if (npcb->npcb_flags & NPCB_FREE) {
m_freem(m); /* drop */
goto next;
return;
}
#ifdef NEED_TO_RESTORE_IFP
@ -760,21 +751,8 @@ m->m_pkthdr.rcvif = NULL; /* null it out to be safe */
#endif
m_freem(m);
}
goto next;
}
#if defined(__FreeBSD__)
static void
netisr_natm_setup(void *dummy __unused)
{
register_netisr(NETISR_NATM, natmintr);
}
SYSINIT(natm_setup, SI_SUB_CPU, SI_ORDER_ANY, netisr_natm_setup, NULL);
#endif
/*
* natm0_sysctl: not used, but here in case we want to add something
* later...

View File

@ -111,7 +111,6 @@ LIST_HEAD(npcblist, natmpcb);
/* global data structures */
extern struct npcblist natm_pcbs; /* global list of pcbs */
extern struct ifqueue natmintrq; /* natm packet input queue */
#define NATM_STAT
#ifdef NATM_STAT
extern u_int natm_sodropcnt,
@ -153,6 +152,6 @@ int natm_usrreq(struct socket *, int, struct mbuf *,
#endif
int natm0_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int natm5_sysctl(int *, u_int, void *, size_t *, void *, size_t);
void natmintr(void);
void natmintr(struct mbuf *);
#endif

View File

@ -46,7 +46,7 @@
#include <sys/domain.h>
#include <net/if.h>
#include <net/intrq.h>
#include <net/netisr.h>
#include <netinet/in.h>
@ -107,6 +107,7 @@ static struct domain natmdomain =
0, 0, 0};
static int natmqmaxlen = IFQ_MAXLEN; /* max # of packets on queue */
static struct ifqueue natmintrq;
#ifdef NATM_STAT
u_int natm_sodropcnt = 0; /* # mbufs dropped due to full sb */
u_int natm_sodropbytes = 0; /* # of bytes dropped */
@ -122,8 +123,7 @@ static void natm_init()
bzero(&natmintrq, sizeof(natmintrq));
natmintrq.ifq_maxlen = natmqmaxlen;
mtx_init(&natmintrq.ifq_mtx, "natm_inq", NULL, MTX_DEF);
natmintrq_present = 1;
netisr_register(NETISR_NATM, natmintr, &natmintrq);
}
#if defined(__FreeBSD__)

View File

@ -82,8 +82,7 @@ struct nsip_req {
#ifdef _KERNEL
extern struct ns_ifaddr *ns_ifaddr;
struct ns_ifaddr *ns_iaonnetof(void);
void nsintr(void);
extern struct ifqueue nsintrq; /* XNS input packet queue */
void nsintr(struct mbuf *);
#endif
#endif

View File

@ -50,7 +50,6 @@
#include <net/route.h>
#include <net/raw_cb.h>
#include <net/netisr.h>
#include <net/intrq.h>
#include <netns/ns.h>
#include <netns/ns_if.h>
@ -71,6 +70,7 @@ struct sockaddr_ns ns_netmask, ns_hostmask;
static u_short allones[] = {-1, -1, -1};
static struct ifqueue nsintrq;
struct nspcb nspcb;
struct nspcb nsrawpcb;
@ -87,16 +87,15 @@ ns_init()
ns_broadnet = * (union ns_net *) allones;
nspcb.nsp_next = nspcb.nsp_prev = &nspcb;
nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb;
nsintrq.ifq_maxlen = nsqmaxlen;
mtx_init(&nsintrq.ifq_mtx, "ns_inq", NULL, MTX_DEF);
nsintrq_present = 1;
ns_pexseq = time.tv_usec;
ns_netmask.sns_len = 6;
ns_netmask.sns_addr.x_net = ns_broadnet;
ns_hostmask.sns_len = 12;
ns_hostmask.sns_addr.x_net = ns_broadnet;
ns_hostmask.sns_addr.x_host = ns_broadhost;
register_netisr(NETISR_NS, nsintr);
nsintrq.ifq_maxlen = nsqmaxlen;
mtx_init(&nsintrq.ifq_mtx, "ns_inq", NULL, MTX_DEF);
netisr_register(NETISR_NS, nsintr, &nsintrq);
}
/*
@ -105,30 +104,23 @@ ns_init()
int nsintr_getpck = 0;
int nsintr_swtch = 0;
void
nsintr(void)
nsintr(struct mbuf *m)
{
register struct idp *idp;
register struct mbuf *m;
register struct nspcb *nsp;
register int i;
int len, s, error;
char oddpacketp;
next:
/*
* Get next datagram off input queue and get IDP header
* in first mbuf.
*/
s = splimp();
IF_DEQUEUE(&nsintrq, m);
splx(s);
nsintr_getpck++;
if (m == 0)
return;
if ((m->m_flags & M_EXT || m->m_len < sizeof (struct idp)) &&
(m = m_pullup(m, sizeof (struct idp))) == 0) {
idpstat.idps_toosmall++;
goto next;
return;
}
/*
@ -173,7 +165,7 @@ nsintr(void)
else
error = NS_ERR_BADSUM_T;
ns_error(m, error, 0);
goto next;
return;
}
}
/*
@ -196,7 +188,7 @@ nsintr(void)
*/
if (idp->idp_tc < NS_MAXHOPS) {
idp_forward(m);
goto next;
return;
}
}
/*
@ -204,7 +196,7 @@ nsintr(void)
*/
} else if (!ns_hosteqnh(ns_thishost,idp->idp_dna.x_host)) {
idp_forward(m);
goto next;
return;
}
/*
* Locate pcb for datagram.
@ -223,21 +215,21 @@ nsintr(void)
case NSPROTO_SPP:
spp_input(m, nsp);
goto next;
return;
case NSPROTO_ERROR:
ns_err_input(m);
goto next;
return;
}
idp_input(m, nsp);
} else {
ns_error(m, NS_ERR_NOSOCK, 0);
}
goto next;
return;
bad:
m_freem(m);
goto next;
return;
}
u_char nsctlerrmap[PRC_NCMDS] = {

View File

@ -161,7 +161,6 @@ idpip_input(m, ifp)
{
register struct ip *ip;
register struct idp *idp;
register struct ifqueue *ifq = &nsintrq;
int len, s;
if (nsip_hold_input) {
@ -220,9 +219,7 @@ idpip_input(m, ifp)
/*
* Deliver to NS
*/
if (IF_HANDOFF(ifq, m, NULL))
schednetisr(NETISR_NS);
return;
netisr_dispatch(NETISR_NS, m);
}
/* ARGSUSED */