Now that in_arpinput() only uses the routing table, if_get()/if_put()
and carp_iamatch being already mpsafe we can kill the ARP input queue.
This moves the ARP input path processing from the softnet interrupt
context (under KERNEL_LOCK) to the sofnettask (without KERNEL_LOCK).
ok?
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.231
diff -u -p -r1.231 if_ethersubr.c
--- net/if_ethersubr.c 2 Dec 2015 08:47:00 -0000 1.231
+++ net/if_ethersubr.c 4 Dec 2015 10:42:14 -0000
@@ -372,14 +372,14 @@ decapsulate:
case ETHERTYPE_ARP:
if (ifp->if_flags & IFF_NOARP)
goto dropanyway;
- inq = &arpintrq;
- break;
+ arpinput(m);
+ return (1);
case ETHERTYPE_REVARP:
if (ifp->if_flags & IFF_NOARP)
goto dropanyway;
- inq = &rarpintrq;
- break;
+ revarpinput(m);
+ return (1);
#ifdef INET6
/*
Index: net/netisr.c
===================================================================
RCS file: /cvs/src/sys/net/netisr.c,v
retrieving revision 1.8
diff -u -p -r1.8 netisr.c
--- net/netisr.c 3 Dec 2015 12:22:51 -0000 1.8
+++ net/netisr.c 4 Dec 2015 10:43:35 -0000
@@ -20,7 +20,6 @@
#include <machine/intr.h>
-#include "ether.h"
#include "ppp.h"
#include "bridge.h"
#include "pppoe.h"
@@ -39,10 +38,6 @@ netintr(void *unused) /* ARGSUSED */
while ((n = netisr) != 0) {
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.43
diff -u -p -r1.43 netisr.h
--- net/netisr.h 3 Dec 2015 12:27:33 -0000 1.43
+++ net/netisr.h 4 Dec 2015 10:44:01 -0000
@@ -53,7 +53,6 @@
#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 */
@@ -64,7 +63,6 @@
#ifdef _KERNEL
extern int netisr; /* scheduling bits for network */
-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.197
diff -u -p -r1.197 if_ether.c
--- netinet/if_ether.c 2 Dec 2015 22:02:18 -0000 1.197
+++ netinet/if_ether.c 4 Dec 2015 10:44:17 -0000
@@ -88,14 +88,10 @@ void arptfree(struct rtentry *);
void arptimer(void *);
struct rtentry *arplookup(u_int32_t, int, int, u_int);
void in_arpinput(struct mbuf *);
-void revarpinput(struct mbuf *);
void in_revarpinput(struct mbuf *);
LIST_HEAD(, llinfo_arp) arp_list;
struct pool arp_pool; /* pool for llinfo_arp structures */
-/* XXX hate magic numbers */
-struct niqueue arpintrq = NIQUEUE_INITIALIZER(50, NETISR_ARP);
-struct niqueue rarpintrq = NIQUEUE_INITIALIZER(50, NETISR_ARP);
int arp_inuse, arp_allocated;
int arp_maxtries = 5;
int arpinit_done;
@@ -426,43 +422,40 @@ bad:
* then the protocol-specific routine is called.
*/
void
-arpintr(void)
+arpinput(struct mbuf *m)
{
- struct mbuf *m;
struct arphdr *ar;
int len;
- while ((m = niq_dequeue(&arpintrq)) != NULL) {
#ifdef DIAGNOSTIC
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("arpintr");
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("%s", __func__);
#endif
- len = sizeof(struct arphdr);
- if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
- continue;
-
- ar = mtod(m, struct arphdr *);
- if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) {
- m_freem(m);
- continue;
- }
+ len = sizeof(struct arphdr);
+ if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
+ return;
- len += 2 * (ar->ar_hln + ar->ar_pln);
- if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
- continue;
-
- switch (ntohs(ar->ar_pro)) {
- case ETHERTYPE_IP:
- case ETHERTYPE_IPTRAILERS:
- in_arpinput(m);
- continue;
- }
+ ar = mtod(m, struct arphdr *);
+ if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) {
m_freem(m);
+ return;
}
- while ((m = niq_dequeue(&rarpintrq)) != NULL)
- revarpinput(m);
+ len += 2 * (ar->ar_hln + ar->ar_pln);
+ if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
+ return;
+
+ switch (ntohs(ar->ar_pro)) {
+ case ETHERTYPE_IP:
+ case ETHERTYPE_IPTRAILERS:
+ in_arpinput(m);
+ return;
+ default:
+ break;
+ }
+
+ m_freem(m);
}
/*
Index: netinet/if_ether.h
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.h,v
retrieving revision 1.64
diff -u -p -r1.64 if_ether.h
--- netinet/if_ether.h 24 Nov 2015 15:27:46 -0000 1.64
+++ netinet/if_ether.h 4 Dec 2015 10:42:32 -0000
@@ -182,11 +182,20 @@ extern u_int8_t etherbroadcastaddr[ETHER
extern u_int8_t etheranyaddr[ETHER_ADDR_LEN];
extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
-extern struct niqueue arpintrq;
-extern struct niqueue rarpintrq;
+#ifdef NFSCLIENT
+extern unsigned int revarp_ifidx;
+#endif /* NFSCLIENT */
+
+void revarpinput(struct mbuf *);
+void revarprequest(struct ifnet *);
+int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
+int revarpwhoami(struct in_addr *, struct ifnet *);
+
+void arpinput(struct mbuf *);
+void arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *);
void arpwhohas(struct arpcom *, struct in_addr *);
-void arpintr(void);
+int arpproxy(struct in_addr, unsigned int);
int arpresolve(struct ifnet *, struct rtentry *, struct mbuf *,
struct sockaddr *, u_char *);
void arp_rtrequest(struct ifnet *, int, struct rtentry *);
@@ -261,17 +270,6 @@ do {
\
(step).e_enm = LIST_FIRST(&(ac)->ac_multiaddrs); \
ETHER_NEXT_MULTI((step), (enm)); \
} while (/* CONSTCOND */ 0)
-
-#ifdef NFSCLIENT
-extern unsigned int revarp_ifidx;
-#endif /* NFSCLIENT */
-
-void arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *);
-int arpproxy(struct in_addr, unsigned int);
-void revarprequest(struct ifnet *);
-int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
-int revarpwhoami(struct in_addr *, struct ifnet *);
-int db_show_arptab(void);
u_int32_t ether_crc32_le_update(u_int32_t crc, const u_int8_t *, size_t);
u_int32_t ether_crc32_be_update(u_int32_t crc, const u_int8_t *, size_t);