summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2003-03-04 23:19:55 +0000
committerjlemon <jlemon@FreeBSD.org>2003-03-04 23:19:55 +0000
commit04e28d5a816573d1300b4591306a8785d3ace29c (patch)
treef304f726e8973253d3e8a87e56119fec0276a61c /sys/net
parent45fcac94f475f1d18d50dde4f72eb51ee4abddcc (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_arcsubr.c23
-rw-r--r--sys/net/if_atmsubr.c14
-rw-r--r--sys/net/if_ef.c95
-rw-r--r--sys/net/if_ethersubr.c90
-rw-r--r--sys/net/if_faith.c6
-rw-r--r--sys/net/if_fddisubr.c52
-rw-r--r--sys/net/if_gif.c9
-rw-r--r--sys/net/if_iso88025subr.c21
-rw-r--r--sys/net/if_loop.c11
-rw-r--r--sys/net/if_ppp.c27
-rw-r--r--sys/net/if_sl.c5
-rw-r--r--sys/net/if_spppsubr.c46
-rw-r--r--sys/net/if_stf.c12
-rw-r--r--sys/net/if_tun.c51
-rw-r--r--sys/net/netisr.c245
-rw-r--r--sys/net/netisr.h32
16 files changed, 412 insertions, 327 deletions
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
OpenPOWER on IntegriCloud