diff options
author | jlemon <jlemon@FreeBSD.org> | 2003-03-04 23:19:55 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2003-03-04 23:19:55 +0000 |
commit | 04e28d5a816573d1300b4591306a8785d3ace29c (patch) | |
tree | f304f726e8973253d3e8a87e56119fec0276a61c | |
parent | 45fcac94f475f1d18d50dde4f72eb51ee4abddcc (diff) | |
download | FreeBSD-src-04e28d5a816573d1300b4591306a8785d3ace29c.zip FreeBSD-src-04e28d5a816573d1300b4591306a8785d3ace29c.tar.gz |
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
64 files changed, 667 insertions, 745 deletions
diff --git a/sys/conf/files b/sys/conf/files index 4b98441..6565cad 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -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 diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c index b7e66ff..800f392 100644 --- a/sys/contrib/ipfilter/netinet/ip_auth.c +++ b/sys/contrib/ipfilter/netinet/ip_auth.c @@ -442,10 +442,8 @@ fr_authioctlloop: # 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++; diff --git a/sys/dev/en/midway.c b/sys/dev/en/midway.c index ffcc6c9..6c2ba95 100644 --- a/sys/dev/en/midway.c +++ b/sys/dev/en/midway.c @@ -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); diff --git a/sys/dev/hea/eni_receive.c b/sys/dev/hea/eni_receive.c index 1ad4478..0fbf329 100644 --- a/sys/dev/hea/eni_receive.c +++ b/sys/dev/hea/eni_receive.c @@ -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 @@ next_buffer: } 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; } diff --git a/sys/dev/hfa/fore_receive.c b/sys/dev/hfa/fore_receive.c index 15ccf78..5cce110 100644 --- a/sys/dev/hfa/fore_receive.c +++ b/sys/dev/hfa/fore_receive.c @@ -479,9 +479,7 @@ retry: /* * 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; } diff --git a/sys/dev/iicbus/if_ic.c b/sys/dev/iicbus/if_ic.c index a6660b7..fa4f8aa 100644 --- a/sys/dev/iicbus/if_ic.c +++ b/sys/dev/iicbus/if_ic.c @@ -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: diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c index 5ba4dc3..7c3b2c5 100644 --- a/sys/dev/ppbus/if_plip.c +++ b/sys/dev/ppbus/if_plip.c @@ -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; diff --git a/sys/dev/usb/usb_ethersubr.c b/sys/dev/usb/usb_ethersubr.c index 4e8daf3..ce25fe9 100644 --- a/sys/dev/usb/usb_ethersubr.c +++ b/sys/dev/usb/usb_ethersubr.c @@ -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) diff --git a/sys/dev/usb/usb_ethersubr.h b/sys/dev/usb/usb_ethersubr.h index 29cdde5..c8a4010 100644 --- a/sys/dev/usb/usb_ethersubr.h +++ b/sys/dev/usb/usb_ethersubr.h @@ -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 *); diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c index 33033d2..dd82aba 100644 --- a/sys/i4b/driver/i4b_ipr.c +++ b/sys/i4b/driver/i4b_ipr.c @@ -879,7 +879,7 @@ error: 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++; diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index b772b94..248e4ea 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -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. */ diff --git a/sys/kern/kern_poll.c b/sys/kern/kern_poll.c index 0f3254e..aeb5f57 100644 --- a/sys/kern/kern_poll.c +++ b/sys/kern/kern_poll.c @@ -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; } } diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c index dda353a..a2d8a4d 100644 --- a/sys/net/if_arcsubr.c +++ b/sys/net/if_arcsubr.c @@ -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); } /* diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c index 78ab13c..782ed88 100644 --- a/sys/net/if_atmsubr.c +++ b/sys/net/if_atmsubr.c @@ -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); } /* diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c index e136a6a..86f73c1 100644 --- a/sys/net/if_ef.c +++ b/sys/net/if_ef.c @@ -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 diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index f3963e6..9d51e69 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -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 @@ post_stats: case ETHERTYPE_IP: if (ipflow_fastforward(m)) return; - schednetisr(NETISR_IP); - inq = &ipintrq; + isr = NETISR_IP; break; case ETHERTYPE_ARP: @@ -765,40 +762,34 @@ post_stats: 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 @@ post_stats: 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, diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index 280a041..372786a 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -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); } diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index fa31889..00b07e6 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -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: diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 1cb4463..ae761e8 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -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? */ diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c index 91fa8c6..a0411e8 100644 --- a/sys/net/if_iso88025subr.c +++ b/sys/net/if_iso88025subr.c @@ -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); } diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index c753fdc..3e0a8c5 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -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); } diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 564d324..bc26a26 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -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; diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 8a91b0b..1d3fa0b 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -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; } diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 2df21cf..1c1e972 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -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)); diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 1d84836..e8ed1ca 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -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 */ diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index e0b3c97..85c4cd3 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -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); } /* diff --git a/sys/net/netisr.c b/sys/net/netisr.c index cb7bc32..7211539 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -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 */ + +struct netisr { + netisr_t *ni_handler; + struct ifqueue *ni_queue; +} netisrs[32]; -void *net_ih; -volatile unsigned int netisr; -void (*netisrs[32])(void); +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) +{ + + KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), + ("bad isr %d", num)); + netisrs[num].ni_handler = handler; + netisrs[num].ni_queue = inq; +} + +void +netisr_unregister(int num) { + struct netisr *ni; + int s; - if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) { - printf("register_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] = handler; - return (0); } -int -unregister_netisr(int num) +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; - if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) { - printf("unregister_netisr: bad isr number: %d\n", num); - return (EINVAL); + 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); } - netisrs[num] = NULL; - return (0); } -#ifdef DEVICE_POLLING -void netisr_pollmore(void); -#endif +/* + * 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 - 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(); - } + const int polling = 1; +#else + const int polling = 0; #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"); } diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 452ad5c..a2e63de 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -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 diff --git a/sys/netatalk/aarp.c b/sys/netatalk/aarp.c index a22488a..f2598b9 100644 --- a/sys/netatalk/aarp.c +++ b/sys/netatalk/aarp.c @@ -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; diff --git a/sys/netatalk/at_extern.h b/sys/netatalk/at_extern.h index 7a6189c..8afdad1 100644 --- a/sys/netatalk/at_extern.h +++ b/sys/netatalk/at_extern.h @@ -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, diff --git a/sys/netatalk/at_var.h b/sys/netatalk/at_var.h index c4310aa..e047485 100644 --- a/sys/netatalk/at_var.h +++ b/sys/netatalk/at_var.h @@ -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_ */ diff --git a/sys/netatalk/ddp_input.c b/sys/netatalk/ddp_input.c index 6db107f..2f7ad83 100644 --- a/sys/netatalk/ddp_input.c +++ b/sys/netatalk/ddp_input.c @@ -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,77 +36,44 @@ 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(); - - IF_DEQUEUE( &atintrq2, m ); - - 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; - } + /* + * Phase 2 packet handling + */ + ddp_input(m, m->m_pkthdr.rcvif, NULL, 2); + return; +} - ifp = m->m_pkthdr.rcvif; +void +at1intr(struct mbuf *m) +{ + struct elaphdr *elhp, elh; - 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; -} - -static void -netisr_atalk_setup(void *dummy __unused) -{ - - register_netisr(NETISR_ATALK, atintr); + return; } -SYSINIT(atalk_setup, SI_SUB_CPU, SI_ORDER_ANY, netisr_atalk_setup, NULL); static void ddp_input( m, ifp, elh, phase ) diff --git a/sys/netatalk/ddp_pcb.c b/sys/netatalk/ddp_pcb.c index fa79cec..7e8eed8 100644 --- a/sys/netatalk/ddp_pcb.c +++ b/sys/netatalk/ddp_pcb.c @@ -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 diff --git a/sys/netatalk/ddp_usrreq.c b/sys/netatalk/ddp_usrreq.c index fa79cec..7e8eed8 100644 --- a/sys/netatalk/ddp_usrreq.c +++ b/sys/netatalk/ddp_usrreq.c @@ -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 diff --git a/sys/netatm/atm_device.c b/sys/netatm/atm_device.c index c85303e..cc2a2a8 100644 --- a/sys/netatm/atm_device.c +++ b/sys/netatm/atm_device.c @@ -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 diff --git a/sys/netatm/atm_subr.c b/sys/netatm/atm_subr.c index c76b245..cd78aaf 100644 --- a/sys/netatm/atm_subr.c +++ b/sys/netatm/atm_subr.c @@ -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,52 +540,38 @@ 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; - } + /* + * 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); + /* + * Call processing function + */ + (*func)(token, m); - /* - * Drain any deferred calls - */ - STACK_DRAIN(); - } + /* + * Drain any deferred calls + */ + STACK_DRAIN(); } - /* * Print a pdu buffer chain * diff --git a/sys/netatm/atm_var.h b/sys/netatm/atm_var.h index 839372c..022f2e3 100644 --- a/sys/netatm/atm_var.h +++ b/sys/netatm/atm_var.h @@ -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 */ diff --git a/sys/netatm/ipatm/ipatm_input.c b/sys/netatm/ipatm/ipatm_input.c index f26a9fb..5be25e0 100644 --- a/sys/netatm/ipatm/ipatm_input.c +++ b/sys/netatm/ipatm/ipatm_input.c @@ -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); } - diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 4c8dde3..efa0e03 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -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: diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 4068f25..efaee7f 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -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); } /* diff --git a/sys/netgraph/ng_ip_input.c b/sys/netgraph/ng_ip_input.c index eb8a74d..bb24c64 100644 --- a/sys/netgraph/ng_ip_input.c +++ b/sys/netgraph/ng_ip_input.c @@ -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; } diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index c463bf9..c02ba55 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -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_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 (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; - } + 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)) { + switch (ntohs(ar->ar_pro)) { #ifdef INET - case ETHERTYPE_IP: - in_arpinput(m); - continue; + case ETHERTYPE_IP: + in_arpinput(m); + return; #endif - } - m_freem(m); } + 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); diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h index 6b31758..1f7a2cd 100644 --- a/sys/netinet/if_ether.h +++ b/sys/netinet/if_ether.h @@ -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 *); diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 4ccc4cd..c3ff684 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -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[]; diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index a986b4a..89e0955 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -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); } /* diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index afac57c..44e4eda 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -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); } /* @@ -951,22 +948,6 @@ bad: } /* - * 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 * exists, then it is given as fp; otherwise have to make a chain. diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 3caba6b..8c7d890 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -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. */ } diff --git a/sys/netinet6/ah_input.c b/sys/netinet6/ah_input.c index 0afdfed..d7d3030 100644 --- a/sys/netinet6/ah_input.c +++ b/sys/netinet6/ah_input.c @@ -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 { /* diff --git a/sys/netinet6/esp_input.c b/sys/netinet6/esp_input.c index d8de60c..43f0a61 100644 --- a/sys/netinet6/esp_input.c +++ b/sys/netinet6/esp_input.c @@ -388,13 +388,12 @@ noreplaycheck: 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 @@ noreplaycheck: 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 { /* diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index fc2242a..35f9e5b 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -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; diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 1f37bae..bb46d35 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -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 diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 9edb73b..7ffdf1e 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -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 *)); diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c index 9ebb518..b0d5df0 100644 --- a/sys/netipsec/ipsec_input.c +++ b/sys/netipsec/ipsec_input.c @@ -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); diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c index 9d49a3e..11ec9b9 100644 --- a/sys/netipsec/xform_ipip.c +++ b/sys/netipsec/xform_ipip.c @@ -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); } } diff --git a/sys/netipx/ipx_if.h b/sys/netipx/ipx_if.h index 48a4d08..13bc607 100644 --- a/sys/netipx/ipx_if.h +++ b/sys/netipx/ipx_if.h @@ -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); diff --git a/sys/netipx/ipx_input.c b/sys/netipx/ipx_input.c index 3410a41..edb6c22 100644 --- a/sys/netipx/ipx_input.c +++ b/sys/netipx/ipx_input.c @@ -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 @@ next: 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 @@ next: if (ipx->ipx_pt == IPXPROTO_NETBIOS) { if (ipxnetbios) { ipx_output_type20(m); - goto next; + return; } else goto bad; } @@ -236,7 +225,7 @@ next: */ if (ipx->ipx_tc < IPX_MAXHOPS) { ipx_forward(m); - goto next; + return; } } /* @@ -251,7 +240,7 @@ next: if (ia == NULL) { ipx_forward(m); - goto next; + return; } } ours: @@ -266,20 +255,18 @@ ours: 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 diff --git a/sys/netipx/ipx_ip.c b/sys/netipx/ipx_ip.c index 6f5d74c..f9f82c0 100644 --- a/sys/netipx/ipx_ip.c +++ b/sys/netipx/ipx_ip.c @@ -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 diff --git a/sys/netipx/ipx_var.h b/sys/netipx/ipx_var.h index de67691..ff2045e 100644 --- a/sys/netipx/ipx_var.h +++ b/sys/netipx/ipx_var.h @@ -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); diff --git a/sys/netnatm/natm.c b/sys/netnatm/natm.c index e0535b6..2df3c22 100644 --- a/sys/netnatm/natm.c +++ b/sys/netnatm/natm.c @@ -698,21 +698,12 @@ done: */ 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 @@ next: 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... diff --git a/sys/netnatm/natm.h b/sys/netnatm/natm.h index b695006..aa4cf3c 100644 --- a/sys/netnatm/natm.h +++ b/sys/netnatm/natm.h @@ -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 diff --git a/sys/netnatm/natm_proto.c b/sys/netnatm/natm_proto.c index 6106026..10b78bb 100644 --- a/sys/netnatm/natm_proto.c +++ b/sys/netnatm/natm_proto.c @@ -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__) diff --git a/sys/netns/ns_if.h b/sys/netns/ns_if.h index 25e82d4..c80eebb 100644 --- a/sys/netns/ns_if.h +++ b/sys/netns/ns_if.h @@ -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 diff --git a/sys/netns/ns_input.c b/sys/netns/ns_input.c index 22abe02..9cf6f73 100644 --- a/sys/netns/ns_input.c +++ b/sys/netns/ns_input.c @@ -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 @@ next: else error = NS_ERR_BADSUM_T; ns_error(m, error, 0); - goto next; + return; } } /* @@ -196,7 +188,7 @@ next: */ if (idp->idp_tc < NS_MAXHOPS) { idp_forward(m); - goto next; + return; } } /* @@ -204,7 +196,7 @@ next: */ } 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 @@ next: 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] = { diff --git a/sys/netns/ns_ip.c b/sys/netns/ns_ip.c index 55d1a9f..ef898ce 100644 --- a/sys/netns/ns_ip.c +++ b/sys/netns/ns_ip.c @@ -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 */ |