Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.434 diff -u -p -r1.434 if.c --- net/if.c 10 Jun 2016 20:33:29 -0000 1.434 +++ net/if.c 11 Jul 2016 12:02:42 -0000 @@ -824,6 +826,10 @@ if_netisr(void *unused) atomic_clearbits_int(&netisr, n); +#if NETHER > 0 + if (n & (1 << NETISR_ARP)) + arpintr(); +#endif if (n & (1 << NETISR_IP)) ipintr(); #ifdef INET6 Index: net/netisr.h =================================================================== RCS file: /cvs/src/sys/net/netisr.h,v retrieving revision 1.45 diff -u -p -r1.45 netisr.h --- net/netisr.h 3 May 2016 14:52:39 -0000 1.45 +++ net/netisr.h 11 Jul 2016 12:02:42 -0000 @@ -53,6 +53,7 @@ #define NETISR_IP 2 /* same as AF_INET */ #define NETISR_TX 3 /* for if_snd processing */ #define NETISR_PFSYNC 5 /* for pfsync "immediate" tx */ +#define NETISR_ARP 18 /* same as AF_LINK */ #define NETISR_IPV6 24 /* same as AF_INET6 */ #define NETISR_ISDN 26 /* same as AF_E164 */ #define NETISR_PPP 28 /* for PPP processing */ @@ -68,6 +69,7 @@ extern int netisr; /* scheduling bits for network */ extern struct task if_input_task_locked; +void arpintr(void); void ipintr(void); void ip6intr(void); void pppintr(void); Index: netinet/if_ether.c =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.c,v retrieving revision 1.216 diff -u -p -r1.216 if_ether.c --- netinet/if_ether.c 28 Jun 2016 17:18:24 -0000 1.216 +++ netinet/if_ether.c 11 Jul 2016 12:02:42 -0000 @@ -86,6 +86,8 @@ void in_revarpinput(struct ifnet *, stru int arpcache(struct ifnet *, struct ether_arp *, struct rtentry *); void arpreply(struct ifnet *, struct mbuf *, struct in_addr *, uint8_t *); +struct niqueue arpinq = NIQUEUE_INITIALIZER(50, NETISR_ARP); + LIST_HEAD(, llinfo_arp) arp_list; struct pool arp_pool; /* pool for llinfo_arp structures */ int arp_maxtries = 5; @@ -438,7 +440,28 @@ arpinput(struct ifnet *ifp, struct mbuf if (m->m_len < len && (m = m_pullup(m, len)) == NULL) return; - in_arpinput(ifp, m); + niq_enqueue(&arpinq, m); +} + +void +arpintr(void) +{ + struct mbuf_list ml; + struct mbuf *m; + struct ifnet *ifp; + + niq_delist(&arpinq, &ml); + + while ((m = ml_dequeue(&ml)) != NULL) { + ifp = if_get(m->m_pkthdr.ph_ifidx); + + if (ifp != NULL) + in_arpinput(ifp, m); + else + m_freem(m); + + if_put(ifp); + } } /* @@ -788,7 +811,7 @@ in_revarpinput(struct ifnet *ifp, struct switch (op) { case ARPOP_REQUEST: case ARPOP_REPLY: /* per RFC */ - in_arpinput(ifp, m); + niq_enqueue(&arpinq, m); return; case ARPOP_REVREPLY: break;