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 /sys/netinet | |
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
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/if_ether.c | 73 | ||||
-rw-r--r-- | sys/netinet/if_ether.h | 1 | ||||
-rw-r--r-- | sys/netinet/in_var.h | 1 | ||||
-rw-r--r-- | sys/netinet/ip_gre.c | 33 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 23 | ||||
-rw-r--r-- | sys/netinet/ip_mroute.c | 7 |
6 files changed, 46 insertions, 92 deletions
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. */ } |