diff --git a/sys/arch/acorn32/podulebus/if_ie.c b/sys/arch/acorn32/podulebus/if_ie.c
index be6f4db..8bb02ec 100644
--- a/sys/arch/acorn32/podulebus/if_ie.c
+++ b/sys/arch/acorn32/podulebus/if_ie.c
@@ -1282,7 +1282,7 @@ ie_read_frame(struct ie_softc *sc, int num)
 
     bpf_mtap(ifp, m);
 
-    (*ifp->if_input)(ifp, m);
+    if_input(ifp, m);
 }
 
 void
diff --git a/sys/arch/amiga/dev/if_es.c b/sys/arch/amiga/dev/if_es.c
index 94a6a22..8269a3b 100644
--- a/sys/arch/amiga/dev/if_es.c
+++ b/sys/arch/amiga/dev/if_es.c
@@ -721,7 +721,7 @@ esrint(struct es_softc *sc)
 	 * the raw packet to bpf.
 	 */
 	bpf_mtap(ifp, top);
-	(*ifp->if_input)(ifp, top);
+	if_input(ifp, top);
 #ifdef ESDEBUG
 	if (--sc->sc_smcbusy) {
 		printf("%s: esintr busy on exit\n", device_xname(sc->sc_dev));
diff --git a/sys/arch/amiga/dev/if_qn.c b/sys/arch/amiga/dev/if_qn.c
index 5c79072..2150cd3 100644
--- a/sys/arch/amiga/dev/if_qn.c
+++ b/sys/arch/amiga/dev/if_qn.c
@@ -585,7 +585,7 @@ qn_get_packet(struct qn_softc *sc, u_short len)
 	/* Tap off BPF listeners */
 	bpf_mtap(ifp, head);
 
-	(*ifp->if_input)(ifp, head);
+	if_input(ifp, head);
 	return;
 
 bad:
diff --git a/sys/arch/arm/allwinner/awin_eth.c b/sys/arch/arm/allwinner/awin_eth.c
index bf66172..536cb4d 100644
--- a/sys/arch/arm/allwinner/awin_eth.c
+++ b/sys/arch/arm/allwinner/awin_eth.c
@@ -422,7 +422,7 @@ awin_eth_if_input(struct awin_eth_softc *sc, struct mbuf *m)
 {
 	struct ifnet * const ifp = &sc->sc_ec.ec_if;
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 static void
diff --git a/sys/arch/arm/at91/at91emac.c b/sys/arch/arm/at91/at91emac.c
index c76a21c..687b534 100644
--- a/sys/arch/arm/at91/at91emac.c
+++ b/sys/arch/arm/at91/at91emac.c
@@ -284,7 +284,7 @@ emac_intr(void *arg)
 					sc->rxq[bi].m->m_len = fl;
 				bpf_mtap(ifp, sc->rxq[bi].m);
 				DPRINTFN(2,("received %u bytes packet\n", fl));
-                                (*ifp->if_input)(ifp, sc->rxq[bi].m);
+                                if_input(ifp, sc->rxq[bi].m);
 				if (mtod(m, intptr_t) & 3) {
 					m_adj(m, mtod(m, intptr_t) & 3);
 				}
diff --git a/sys/arch/arm/broadcom/bcm53xx_eth.c b/sys/arch/arm/broadcom/bcm53xx_eth.c
index 7a924cd..4c50385 100644
--- a/sys/arch/arm/broadcom/bcm53xx_eth.c
+++ b/sys/arch/arm/broadcom/bcm53xx_eth.c
@@ -401,8 +401,9 @@ bcmeth_ccb_attach(device_t parent, device_t self, void *aux)
 	/*
 	 * Attach the interface.
 	 */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, sc->sc_enaddr);
+	if_register(ifp);
 
 #ifdef BCMETH_COUNTERS
 	evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR,
@@ -1020,12 +1021,12 @@ bcmeth_rx_input(
 	 */
 #ifdef BCMETH_MPSAFE
 	mutex_exit(sc->sc_lock);
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	mutex_enter(sc->sc_lock);
 #else
 	int s = splnet();
 	bpf_mtap(ifp, m);
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	splx(s);
 #endif
 }
diff --git a/sys/arch/arm/ep93xx/epe.c b/sys/arch/arm/ep93xx/epe.c
index 997ebf7..3072ada 100644
--- a/sys/arch/arm/ep93xx/epe.c
+++ b/sys/arch/arm/ep93xx/epe.c
@@ -231,7 +231,7 @@ begin:
 				sc->rxq[bi].m->m_pkthdr.len = 
 					sc->rxq[bi].m->m_len = fl;
 				bpf_mtap(ifp, sc->rxq[bi].m);
-                                (*ifp->if_input)(ifp, sc->rxq[bi].m);
+                                if_input(ifp, sc->rxq[bi].m);
 				sc->rxq[bi].m = m;
 				bus_dmamap_load(sc->sc_dmat, 
 					sc->rxq[bi].m_dmamap, 
diff --git a/sys/arch/arm/gemini/gemini_gmac.c b/sys/arch/arm/gemini/gemini_gmac.c
index 8a46bfa..10a0c19 100644
--- a/sys/arch/arm/gemini/gemini_gmac.c
+++ b/sys/arch/arm/gemini/gemini_gmac.c
@@ -856,7 +856,7 @@ gmac_hwqueue_rxconsume(gmac_hwqueue_t *hwq, const gmac_desc_t *d)
 		m->m_data += 2;
 		KASSERT(m_length(m) == m->m_pkthdr.len);
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		break;
 	default:
 		ifp->if_ierrors++;
diff --git a/sys/arch/arm/gemini/if_gpn.c b/sys/arch/arm/gemini/if_gpn.c
index 71c12a6..a08352d 100644
--- a/sys/arch/arm/gemini/if_gpn.c
+++ b/sys/arch/arm/gemini/if_gpn.c
@@ -307,7 +307,7 @@ gpn_process_data(struct gpn_softc *sc, const ipm_gpn_desc_t *gd)
 		printf("%s: rx len=%d crc=%#x\n", ifp->if_xname,
 		    m->m_pkthdr.len, m_crc32_le(m));
 #endif
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 out:
diff --git a/sys/arch/arm/imx/if_enet.c b/sys/arch/arm/imx/if_enet.c
index d62b2da..1e52e3a 100644
--- a/sys/arch/arm/imx/if_enet.c
+++ b/sys/arch/arm/imx/if_enet.c
@@ -755,7 +755,7 @@ enet_rx_intr(void *arg)
 				/* Pass this up to any BPF listeners */
 				bpf_mtap(ifp, m0);
 
-				(*ifp->if_input)(ifp, m0);
+				if_input(ifp, m0);
 			}
 
 			m0 = NULL;
diff --git a/sys/arch/arm/omap/if_cpsw.c b/sys/arch/arm/omap/if_cpsw.c
index 6b6ae90..2287ebc 100644
--- a/sys/arch/arm/omap/if_cpsw.c
+++ b/sys/arch/arm/omap/if_cpsw.c
@@ -1170,7 +1170,7 @@ cpsw_rxintr(void *arg)
 
 		bpf_mtap(ifp, m);
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 next:
 		sc->sc_rxhead = RXDESC_NEXT(sc->sc_rxhead);
diff --git a/sys/arch/arm/omap/omapl1x_emac.c b/sys/arch/arm/omap/omapl1x_emac.c
index 9af7e54..4a23332 100644
--- a/sys/arch/arm/omap/omapl1x_emac.c
+++ b/sys/arch/arm/omap/omapl1x_emac.c
@@ -658,7 +658,7 @@ emac_rx_desc_process (struct emac_softc *sc, struct emac_channel *chan)
 	ifp->if_ipackets++;
 
 	bpf_mtap(ifp, mb);
-	(*ifp->if_input)(ifp, mb);
+	if_input(ifp, mb);
 
 	entry->m = NULL;
 
diff --git a/sys/arch/arm/rockchip/rockchip_emac.c b/sys/arch/arm/rockchip/rockchip_emac.c
index c4dfd77..cffa42f 100644
--- a/sys/arch/arm/rockchip/rockchip_emac.c
+++ b/sys/arch/arm/rockchip/rockchip_emac.c
@@ -879,7 +879,7 @@ rkemac_rxintr(struct rkemac_softc *sc)
 
 		bpf_mtap(ifp, m);
 		ifp->if_ipackets++;
-		ifp->if_input(ifp, m);
+		if_input(ifp, m);
 
 skip:
 		bus_dmamap_sync(sc->sc_dmat, rd->rd_map, 0,
diff --git a/sys/arch/arm/xscale/ixp425_if_npe.c b/sys/arch/arm/xscale/ixp425_if_npe.c
index 0edcf35..84a0b71 100644
--- a/sys/arch/arm/xscale/ixp425_if_npe.c
+++ b/sys/arch/arm/xscale/ixp425_if_npe.c
@@ -1055,7 +1055,7 @@ npe_rxdone(int qid, void *arg)
 			 * Tap off here if there is a bpf listener.
 			 */
 			bpf_mtap(ifp, mrx);
-			ifp->if_input(ifp, mrx);
+			if_input(ifp, mrx);
 		} else {
 fail:
 			/* discard frame and re-use mbuf */
diff --git a/sys/arch/emips/ebus/if_le_ebus.c b/sys/arch/emips/ebus/if_le_ebus.c
index 8e37c36..947bdb0 100644
--- a/sys/arch/emips/ebus/if_le_ebus.c
+++ b/sys/arch/emips/ebus/if_le_ebus.c
@@ -768,7 +768,7 @@ enic_rint(struct enic_softc *sc, uint32_t saf, paddr_t phys)
 		bpf_mtap(ifp, m);
 
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 
 	/* Need to refill now */
 	enic_refill(sc);
diff --git a/sys/arch/evbppc/virtex/dev/if_temac.c b/sys/arch/evbppc/virtex/dev/if_temac.c
index 7f65ce3..b61dae5 100644
--- a/sys/arch/evbppc/virtex/dev/if_temac.c
+++ b/sys/arch/evbppc/virtex/dev/if_temac.c
@@ -1211,7 +1211,7 @@ temac_rxreap(struct temac_softc *sc)
 		bpf_mtap(ifp, m);
 
 		ifp->if_ipackets++;
-		(ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		/* Refresh descriptor, bail out if we're out of buffers. */
 		if (temac_rxalloc(sc, tail, 1) != 0) {
diff --git a/sys/arch/mac68k/dev/if_mc.c b/sys/arch/mac68k/dev/if_mc.c
index 04d4933..240308a 100644
--- a/sys/arch/mac68k/dev/if_mc.c
+++ b/sys/arch/mac68k/dev/if_mc.c
@@ -585,7 +585,7 @@ mace_read(struct mc_softc *sc, void *pkt, int len)
 	bpf_mtap(ifp, m);
 
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/arch/mac68k/nubus/if_netdock_nubus.c b/sys/arch/mac68k/nubus/if_netdock_nubus.c
index 3d0940a..f409666 100644
--- a/sys/arch/mac68k/nubus/if_netdock_nubus.c
+++ b/sys/arch/mac68k/nubus/if_netdock_nubus.c
@@ -766,7 +766,7 @@ netdock_read(struct netdock_softc *sc, int len)
 
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 
 	return (1);
 }
diff --git a/sys/arch/macppc/dev/am79c950.c b/sys/arch/macppc/dev/am79c950.c
index 20195c3..cc24c3d 100644
--- a/sys/arch/macppc/dev/am79c950.c
+++ b/sys/arch/macppc/dev/am79c950.c
@@ -597,7 +597,7 @@ mace_read(struct mc_softc *sc, uint8_t *pkt, int len)
 	bpf_mtap(ifp, m); 
 
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/arch/macppc/dev/if_bm.c b/sys/arch/macppc/dev/if_bm.c
index 8973260..b915695 100644
--- a/sys/arch/macppc/dev/if_bm.c
+++ b/sys/arch/macppc/dev/if_bm.c
@@ -502,7 +502,7 @@ bmac_rint(void *v)
 		 * If so, hand off the raw packet to BPF.
 		 */
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		ifp->if_ipackets++;
 
 next:
diff --git a/sys/arch/macppc/dev/if_gm.c b/sys/arch/macppc/dev/if_gm.c
index d9fc859..2701f6c 100644
--- a/sys/arch/macppc/dev/if_gm.c
+++ b/sys/arch/macppc/dev/if_gm.c
@@ -382,7 +382,7 @@ gmac_rint(struct gmac_softc *sc)
 		 * If so, hand off the raw packet to BPF.
 		 */
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		ifp->if_ipackets++;
 
 next:
diff --git a/sys/arch/mips/adm5120/dev/if_admsw.c b/sys/arch/mips/adm5120/dev/if_admsw.c
index 2ed507b..df46260 100644
--- a/sys/arch/mips/adm5120/dev/if_admsw.c
+++ b/sys/arch/mips/adm5120/dev/if_admsw.c
@@ -1002,7 +1002,7 @@ admsw_rxintr(struct admsw_softc *sc, int high)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		ifp->if_ipackets++;
 	}
 #ifdef ADMSW_EVENT_COUNTERS
diff --git a/sys/arch/mips/alchemy/dev/if_aumac.c b/sys/arch/mips/alchemy/dev/if_aumac.c
index 0bc885c..cc6b123 100644
--- a/sys/arch/mips/alchemy/dev/if_aumac.c
+++ b/sys/arch/mips/alchemy/dev/if_aumac.c
@@ -719,7 +719,7 @@ aumac_rxintr(struct aumac_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		ifp->if_ipackets++;
 	}
 	if (pkts)
diff --git a/sys/arch/mips/atheros/dev/if_ae.c b/sys/arch/mips/atheros/dev/if_ae.c
index 93e7453..3e02216 100644
--- a/sys/arch/mips/atheros/dev/if_ae.c
+++ b/sys/arch/mips/atheros/dev/if_ae.c
@@ -1139,7 +1139,7 @@ ae_rxintr(struct ae_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/arch/mips/cavium/dev/if_cnmac.c b/sys/arch/mips/cavium/dev/if_cnmac.c
index e0b6474..c7824e3 100644
--- a/sys/arch/mips/cavium/dev/if_cnmac.c
+++ b/sys/arch/mips/cavium/dev/if_cnmac.c
@@ -1489,7 +1489,7 @@ octeon_eth_recv(struct octeon_eth_softc *sc, uint64_t *work)
 		octeon_eth_send_queue_flush_sync(sc);
 	/* XXX XXX XXX */
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 
 	return 0;
 
@@ -1826,7 +1826,7 @@ octeon_eth_sysctl_verify(SYSCTLFN_ARGS)
 					octeon_eth_mii_statchg(ifp);
 					/* octeon_gmx_set_filter(sc->sc_gmx_port); */
 				}
-				ifp->if_input = ether_input;
+				if_input= ether_input;
 			}
 			else {
 				if (!ISSET(ifp->if_flags, IFF_PROMISC)) {
@@ -1834,7 +1834,7 @@ octeon_eth_sysctl_verify(SYSCTLFN_ARGS)
 					octeon_eth_mii_statchg(ifp);
 					/* octeon_gmx_set_filter(sc->sc_gmx_port); */
 				}
-				ifp->if_input = octeon_eth_recv_redir;
+				if_input= octeon_eth_recv_redir;
 			}
 		}
 		splx(s);
diff --git a/sys/arch/mips/ralink/ralink_eth.c b/sys/arch/mips/ralink/ralink_eth.c
index d328e8a..245e571 100644
--- a/sys/arch/mips/ralink/ralink_eth.c
+++ b/sys/arch/mips/ralink/ralink_eth.c
@@ -1490,7 +1490,7 @@ ralink_eth_rxintr(ralink_eth_softc_t *sc)
 
 		/* Pass it on. */
 		sc->sc_evcnt_input.ev_count++;
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		fe_write(sc, RA_FE_PDMA_RX0_CPU_IDX, rx_cpu_idx);
 	}
diff --git a/sys/arch/mips/sibyte/dev/sbmac.c b/sys/arch/mips/sibyte/dev/sbmac.c
index ee8c946..4ce905c 100644
--- a/sys/arch/mips/sibyte/dev/sbmac.c
+++ b/sys/arch/mips/sibyte/dev/sbmac.c
@@ -938,7 +938,7 @@ sbdma_rx_process(struct sbmac_softc *sc, sbmacdma_t *d)
 			/*
 			 * Pass the buffer to the kernel
 			 */
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 		} else {
 			/*
 			 * Packet was mangled somehow.  Just drop it and
diff --git a/sys/arch/newsmips/apbus/if_sn.c b/sys/arch/newsmips/apbus/if_sn.c
index 1a03d7d..2f9ee54 100644
--- a/sys/arch/newsmips/apbus/if_sn.c
+++ b/sys/arch/newsmips/apbus/if_sn.c
@@ -1059,7 +1059,7 @@ sonic_read(struct sn_softc *sc, void *pkt, int len)
 		return 0;
 	/* Pass the packet to any BPF listeners. */
 	bpf_mtap(ifp, m);
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	return 1;
 }
 
diff --git a/sys/arch/next68k/dev/mb8795.c b/sys/arch/next68k/dev/mb8795.c
index 34f19fa..a2c54d3 100644
--- a/sys/arch/next68k/dev/mb8795.c
+++ b/sys/arch/next68k/dev/mb8795.c
@@ -328,7 +328,7 @@ mb8795_rint(struct mb8795_softc *sc)
 			ifp->if_ipackets++;
 
 			/* Pass the packet up. */
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 
 			s = spldma();
 
diff --git a/sys/arch/playstation2/dev/if_smap.c b/sys/arch/playstation2/dev/if_smap.c
index 8f496ad..0bf16bb 100644
--- a/sys/arch/playstation2/dev/if_smap.c
+++ b/sys/arch/playstation2/dev/if_smap.c
@@ -410,7 +410,7 @@ smap_rxeof(void *arg)
 		if (m != NULL) {
 			if (ifp->if_bpf)
 				bpf_mtap(ifp->if_bpf, m);
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 		}
 	}
 	sc->rx_done_index = i;
diff --git a/sys/arch/powerpc/booke/dev/pq3etsec.c b/sys/arch/powerpc/booke/dev/pq3etsec.c
index 00117d8..39fa7d6 100644
--- a/sys/arch/powerpc/booke/dev/pq3etsec.c
+++ b/sys/arch/powerpc/booke/dev/pq3etsec.c
@@ -1577,7 +1577,7 @@ pq3etsec_rx_input(
 	 */
 	int s = splnet();
 	bpf_mtap(ifp, m);
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	splx(s);
 }
 
diff --git a/sys/arch/powerpc/ibm4xx/dev/if_emac.c b/sys/arch/powerpc/ibm4xx/dev/if_emac.c
index 7b3c85a..5df1ab2 100644
--- a/sys/arch/powerpc/ibm4xx/dev/if_emac.c
+++ b/sys/arch/powerpc/ibm4xx/dev/if_emac.c
@@ -1676,7 +1676,7 @@ emac_rxeob_intr(void *arg)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/arch/sgimips/hpc/if_sq.c b/sys/arch/sgimips/hpc/if_sq.c
index cf3b7eb..080e816 100644
--- a/sys/arch/sgimips/hpc/if_sq.c
+++ b/sys/arch/sgimips/hpc/if_sq.c
@@ -1022,7 +1022,7 @@ sq_rxintr(struct sq_softc *sc)
 		    device_xname(sc->sc_dev), i, framelen));
 
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 
diff --git a/sys/arch/sgimips/mace/if_mec.c b/sys/arch/sgimips/mace/if_mec.c
index 6b606c8..4064785 100644
--- a/sys/arch/sgimips/mace/if_mec.c
+++ b/sys/arch/sgimips/mace/if_mec.c
@@ -1739,7 +1739,7 @@ mec_rxintr(struct mec_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* update RX pointer */
diff --git a/sys/arch/sun2/dev/if_ec.c b/sys/arch/sun2/dev/if_ec.c
index f9e539a..6017c64 100644
--- a/sys/arch/sun2/dev/if_ec.c
+++ b/sys/arch/sun2/dev/if_ec.c
@@ -532,7 +532,7 @@ ec_recv(struct ec_softc *sc, int intbit)
 		bpf_mtap(ifp, m0);
 
 		/* Pass the packet up. */
-		(*ifp->if_input)(ifp, m0);
+		if_input(ifp, m0);
 
 	} else {
 		/* Something went wrong. */
diff --git a/sys/arch/sun3/dev/if_ie.c b/sys/arch/sun3/dev/if_ie.c
index f4e48eb..ea8c67e 100644
--- a/sys/arch/sun3/dev/if_ie.c
+++ b/sys/arch/sun3/dev/if_ie.c
@@ -996,7 +996,7 @@ ie_readframe(struct ie_softc *sc, int num)
 	/*
 	 * Finally pass this packet up to higher layers.
 	 */
-	(*sc->sc_if.if_input)(&sc->sc_if, m);
+	if_input(&sc->sc_if, m);
 	sc->sc_if.if_ipackets++;
 }
 
diff --git a/sys/arch/usermode/dev/if_veth.c b/sys/arch/usermode/dev/if_veth.c
index 328162d..a8948b1 100644
--- a/sys/arch/usermode/dev/if_veth.c
+++ b/sys/arch/usermode/dev/if_veth.c
@@ -137,8 +137,9 @@ veth_attach(device_t parent, device_t self, void *opaque)
 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
 	IFQ_SET_READY(&ifq->if_snd);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, sc->sc_eaddr);
+	if_register(ifp);
 
 	ifmedia_init(&sc->sc_ifmedia, 0,
 	    veth_ifmedia_change,
@@ -236,7 +237,7 @@ veth_softrx(void *priv)
 		bpf_mtap(ifp, m);
 
 		s = splnet();
-		ifp->if_input(ifp, m);
+		if_input(ifp, m);
 		splx(s);
 	}
 }
diff --git a/sys/arch/x86/pci/if_vmx.c b/sys/arch/x86/pci/if_vmx.c
index 4c70818..850b62f9 100644
--- a/sys/arch/x86/pci/if_vmx.c
+++ b/sys/arch/x86/pci/if_vmx.c
@@ -767,7 +767,7 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
 
 		bpf_mtap(ifp, m);
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 skip_buffer:
 #ifdef VMXNET3_STAT
diff --git a/sys/arch/xen/xen/if_xennet_xenbus.c b/sys/arch/xen/xen/if_xennet_xenbus.c
index 5de13bc..b7daca8 100644
--- a/sys/arch/xen/xen/if_xennet_xenbus.c
+++ b/sys/arch/xen/xen/if_xennet_xenbus.c
@@ -1107,7 +1107,7 @@ again:
 		ifp->if_ipackets++;
 
 		/* Pass the packet up. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 	xen_rmb();
 	sc->sc_rx_ring.rsp_cons = i;
diff --git a/sys/arch/xen/xen/xennetback_xenbus.c b/sys/arch/xen/xen/xennetback_xenbus.c
index a284e02..0885d2c 100644
--- a/sys/arch/xen/xen/xennetback_xenbus.c
+++ b/sys/arch/xen/xen/xennetback_xenbus.c
@@ -891,7 +891,7 @@ so always copy for now.
 		ifp->if_ipackets++;
 		
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 	xen_rmb(); /* be sure to read the request before updating pointer */
 	xneti->xni_txring.req_cons = req_cons;
diff --git a/sys/dev/bi/if_ni.c b/sys/dev/bi/if_ni.c
index 8aadca6..2836b68 100644
--- a/sys/dev/bi/if_ni.c
+++ b/sys/dev/bi/if_ni.c
@@ -618,7 +618,7 @@ niintr(void *arg)
 				break; /* Out of mbufs */
 
 			bpf_mtap(ifp, m);
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 			break;
 
 		case BVP_DGRAM:
diff --git a/sys/dev/cadence/if_cemac.c b/sys/dev/cadence/if_cemac.c
index a3988f8..13e27a2 100644
--- a/sys/dev/cadence/if_cemac.c
+++ b/sys/dev/cadence/if_cemac.c
@@ -358,7 +358,7 @@ cemac_intr(void *arg)
 				sc->rxq[bi].m->m_pkthdr.csum_flags = csum;
 				bpf_mtap(ifp, sc->rxq[bi].m);
 				DPRINTFN(2,("received %u bytes packet\n", fl));
-                                (*ifp->if_input)(ifp, sc->rxq[bi].m);
+                                if_input(ifp, sc->rxq[bi].m);
 				if (mtod(m, intptr_t) & 3)
 					m_adj(m, mtod(m, intptr_t) & 3);
 				sc->rxq[bi].m = m;
diff --git a/sys/dev/ic/aic6915.c b/sys/dev/ic/aic6915.c
index 205625b..0cc2152 100644
--- a/sys/dev/ic/aic6915.c
+++ b/sys/dev/ic/aic6915.c
@@ -791,7 +791,7 @@ sf_rxintr(struct sf_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the chip's pointers. */
diff --git a/sys/dev/ic/cs89x0.c b/sys/dev/ic/cs89x0.c
index 1e7576f..4a74b19 100644
--- a/sys/dev/ic/cs89x0.c
+++ b/sys/dev/ic/cs89x0.c
@@ -1665,7 +1665,7 @@ cs_ether_input(struct cs_softc *sc, struct mbuf *m)
 	bpf_mtap(ifp, m);
 
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 void
diff --git a/sys/dev/ic/dm9000.c b/sys/dev/ic/dm9000.c
index 386741c..b688d4b 100644
--- a/sys/dev/ic/dm9000.c
+++ b/sys/dev/ic/dm9000.c
@@ -827,7 +827,7 @@ dme_receive(struct dme_softc *sc, struct ifnet *ifp)
 				if (ifp->if_bpf)
 					bpf_mtap(ifp, m);
 				ifp->if_ipackets++;
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			}
 
 		} else if (ready != 0x00) {
diff --git a/sys/dev/ic/dp8390.c b/sys/dev/ic/dp8390.c
index e8a1126..9ac92a2 100644
--- a/sys/dev/ic/dp8390.c
+++ b/sys/dev/ic/dp8390.c
@@ -947,7 +947,7 @@ dp8390_read(struct dp8390_softc *sc, int buf, u_short len)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 
diff --git a/sys/dev/ic/dp83932.c b/sys/dev/ic/dp83932.c
index 3333e16..f511869 100644
--- a/sys/dev/ic/dp83932.c
+++ b/sys/dev/ic/dp83932.c
@@ -843,7 +843,7 @@ sonic_rxintr(struct sonic_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/ic/dwc_gmac.c b/sys/dev/ic/dwc_gmac.c
index cce240f..358ecc7 100644
--- a/sys/dev/ic/dwc_gmac.c
+++ b/sys/dev/ic/dwc_gmac.c
@@ -1127,7 +1127,7 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
 
 		bpf_mtap(ifp, m);
 		ifp->if_ipackets++;
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 skip:
 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
diff --git a/sys/dev/ic/elink3.c b/sys/dev/ic/elink3.c
index c8a2194..ea14a4a 100644
--- a/sys/dev/ic/elink3.c
+++ b/sys/dev/ic/elink3.c
@@ -1496,7 +1496,7 @@ again:
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 
 	/*
 	 * In periods of high traffic we can actually receive enough
diff --git a/sys/dev/ic/elinkxl.c b/sys/dev/ic/elinkxl.c
index 9dd2d0b..7130201 100644
--- a/sys/dev/ic/elinkxl.c
+++ b/sys/dev/ic/elinkxl.c
@@ -1393,7 +1393,7 @@ ex_intr(void *arg)
 					    M_CSUM_TCP_UDP_BAD;
 			}
 		}
-					(*ifp->if_input)(ifp, m);
+					if_input(ifp, m);
 				}
 				goto rcvloop;
 			}
diff --git a/sys/dev/ic/gem.c b/sys/dev/ic/gem.c
index b59ff38..423a3a4 100644
--- a/sys/dev/ic/gem.c
+++ b/sys/dev/ic/gem.c
@@ -1940,7 +1940,7 @@ swcsum:
 			m->m_pkthdr.csum_flags = 0;
 #endif
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	if (progress) {
diff --git a/sys/dev/ic/hme.c b/sys/dev/ic/hme.c
index cac2652..6ba8fe0 100644
--- a/sys/dev/ic/hme.c
+++ b/sys/dev/ic/hme.c
@@ -885,7 +885,7 @@ hme_read(struct hme_softc *sc, int ix, uint32_t flags)
 	bpf_mtap(ifp, m);
 
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 void
diff --git a/sys/dev/ic/i82557.c b/sys/dev/ic/i82557.c
index cb8bdef..ba110b3 100644
--- a/sys/dev/ic/i82557.c
+++ b/sys/dev/ic/i82557.c
@@ -1458,7 +1458,7 @@ fxp_rxintr(struct fxp_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/ic/i82586.c b/sys/dev/ic/i82586.c
index 69ea76f..cb1252f 100644
--- a/sys/dev/ic/i82586.c
+++ b/sys/dev/ic/i82586.c
@@ -1039,7 +1039,7 @@ ie_readframe(
 	/*
 	 * Finally pass this packet up to higher layers.
 	 */
-	(*sc->sc_ethercom.ec_if.if_input)(&sc->sc_ethercom.ec_if, m);
+	if_input(&sc->sc_ethercom.ec_if, m);
 	sc->sc_ethercom.ec_if.if_ipackets++;
 	return (0);
 }
diff --git a/sys/dev/ic/i82596.c b/sys/dev/ic/i82596.c
index d6bed02..776ecb2 100644
--- a/sys/dev/ic/i82596.c
+++ b/sys/dev/ic/i82596.c
@@ -281,7 +281,7 @@ iee_intr(void *intarg)
 		bus_dmamap_sync(sc->sc_dmat, rx_map, 0,
 		    rx_map->dm_mapsize, BUS_DMASYNC_PREREAD);
 		bpf_mtap(ifp, rx_mbuf);
-		(*ifp->if_input)(ifp, rx_mbuf);
+		if_input(ifp, rx_mbuf);
 		ifp->if_ipackets++;
 		sc->sc_rx_mbuf[sc->sc_rx_done] = new_mbuf;
 		rbd->rbd_count = 0;
diff --git a/sys/dev/ic/lan9118.c b/sys/dev/ic/lan9118.c
index 62e4ba5..4ca065c 100644
--- a/sys/dev/ic/lan9118.c
+++ b/sys/dev/ic/lan9118.c
@@ -1002,7 +1002,7 @@ dropit:
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/ic/lance.c b/sys/dev/ic/lance.c
index ee015f1..2bb24c1 100644
--- a/sys/dev/ic/lance.c
+++ b/sys/dev/ic/lance.c
@@ -479,7 +479,7 @@ lance_read(struct lance_softc *sc, int boff, int len)
 	bpf_mtap(ifp, m);
 
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 #undef	ifp
diff --git a/sys/dev/ic/lemac.c b/sys/dev/ic/lemac.c
index d419963..7a49291 100644
--- a/sys/dev/ic/lemac.c
+++ b/sys/dev/ic/lemac.c
@@ -317,7 +317,7 @@ lemac_input(
     }
     m->m_pkthdr.len = m->m_len = length;
     m->m_pkthdr.rcvif = &sc->sc_if;
-    (*sc->sc_if.if_input)(&sc->sc_if, m);
+    if_input(&sc->sc_if, m);
 }
 
 static void
diff --git a/sys/dev/ic/mb86950.c b/sys/dev/ic/mb86950.c
index 6738190..8765142 100644
--- a/sys/dev/ic/mb86950.c
+++ b/sys/dev/ic/mb86950.c
@@ -908,7 +908,7 @@ mb86950_get_fifo(struct mb86950_softc *sc, u_int len)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	return (0);
 }
 
diff --git a/sys/dev/ic/mb86960.c b/sys/dev/ic/mb86960.c
index 327591d..0aaaef6 100644
--- a/sys/dev/ic/mb86960.c
+++ b/sys/dev/ic/mb86960.c
@@ -1336,7 +1336,7 @@ mb86960_get_packet(struct mb86960_softc *sc, u_int len)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	return 1;
 }
 
diff --git a/sys/dev/ic/mtd803.c b/sys/dev/ic/mtd803.c
index 23618e4..47491e8 100644
--- a/sys/dev/ic/mtd803.c
+++ b/sys/dev/ic/mtd803.c
@@ -681,7 +681,7 @@ mtd_rxirq(struct mtd_softc *sc)
 
 		bpf_mtap(ifp, m);
 		/* Pass the packet up */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	return 1;
diff --git a/sys/dev/ic/pdq_ifsubr.c b/sys/dev/ic/pdq_ifsubr.c
index 3a32b91..d0323a0 100644
--- a/sys/dev/ic/pdq_ifsubr.c
+++ b/sys/dev/ic/pdq_ifsubr.c
@@ -249,7 +249,7 @@ pdq_os_receive_pdu(
     }
 
     m->m_pkthdr.rcvif = &sc->sc_if;
-    (*sc->sc_if.if_input)(&sc->sc_if, m);
+    if_input(&sc->sc_if, m);
 }
 
 void
diff --git a/sys/dev/ic/rrunner.c b/sys/dev/ic/rrunner.c
index 7fdf97a..ebcb728 100644
--- a/sys/dev/ic/rrunner.c
+++ b/sys/dev/ic/rrunner.c
@@ -2377,7 +2377,7 @@ esh_read_snap_ring(struct esh_softc *sc, u_int16_t consumer, int error)
 				} else {
 					m = m_pullup(m,
 					    sizeof(struct hippi_header));
-					(*ifp->if_input)(ifp, m);
+					if_input(ifp, m);
 				}
 			} else {
 				ifp->if_ierrors++;
diff --git a/sys/dev/ic/rtl8169.c b/sys/dev/ic/rtl8169.c
index 372d340..4af51a3 100644
--- a/sys/dev/ic/rtl8169.c
+++ b/sys/dev/ic/rtl8169.c
@@ -1358,7 +1358,7 @@ re_rxeof(struct rtk_softc *sc)
 			     continue);
 		}
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	sc->re_ldata.re_rx_prodidx = i;
diff --git a/sys/dev/ic/rtl81x9.c b/sys/dev/ic/rtl81x9.c
index d5b532b..7725298 100644
--- a/sys/dev/ic/rtl81x9.c
+++ b/sys/dev/ic/rtl81x9.c
@@ -1077,7 +1077,7 @@ rtk_rxeof(struct rtk_softc *sc)
 
 		bpf_mtap(ifp, m);
 		/* pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/ic/seeq8005.c b/sys/dev/ic/seeq8005.c
index 917658f..a800cab 100644
--- a/sys/dev/ic/seeq8005.c
+++ b/sys/dev/ic/seeq8005.c
@@ -1252,7 +1252,7 @@ ea_read(struct seeq8005_softc *sc, int addr, int len)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/dev/ic/sgec.c b/sys/dev/ic/sgec.c
index 81ba463..4c1fb9f 100644
--- a/sys/dev/ic/sgec.c
+++ b/sys/dev/ic/sgec.c
@@ -466,7 +466,7 @@ sgec_intr(struct ze_softc *sc)
 				m->m_pkthdr.len = m->m_len =
 				    len - ETHER_CRC_LEN;
 				bpf_mtap(ifp, m);
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			}
 		}
 	}
diff --git a/sys/dev/ic/smc83c170.c b/sys/dev/ic/smc83c170.c
index 588d8b5..71a04c3 100644
--- a/sys/dev/ic/smc83c170.c
+++ b/sys/dev/ic/smc83c170.c
@@ -714,7 +714,7 @@ epic_intr(void *arg)
 			bpf_mtap(ifp, m);
 
 			/* Pass it on. */
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 			ifp->if_ipackets++;
 		}
 
diff --git a/sys/dev/ic/smc90cx6.c b/sys/dev/ic/smc90cx6.c
index 559d5f5..5ed9121 100644
--- a/sys/dev/ic/smc90cx6.c
+++ b/sys/dev/ic/smc90cx6.c
@@ -598,7 +598,7 @@ bah_srint(void *vsc)
 
 	bpf_mtap(ifp, head);
 
-	(*sc->sc_arccom.ac_if.if_input)(&sc->sc_arccom.ac_if, head);
+	if_input(&sc->sc_arccom.ac_if, head);
 
 	head = NULL;
 	ifp->if_ipackets++;
diff --git a/sys/dev/ic/smc91cxx.c b/sys/dev/ic/smc91cxx.c
index 7af74ca..4c0c0e2 100644
--- a/sys/dev/ic/smc91cxx.c
+++ b/sys/dev/ic/smc91cxx.c
@@ -1243,7 +1243,7 @@ smc91cxx_read(struct smc91cxx_softc *sc)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 
  out:
 	/*
diff --git a/sys/dev/ic/tropic.c b/sys/dev/ic/tropic.c
index 2fb6d21..55570ad 100644
--- a/sys/dev/ic/tropic.c
+++ b/sys/dev/ic/tropic.c
@@ -1251,7 +1251,7 @@ tr_rint(struct tr_softc *sc)
 		++ifp->if_ipackets;
 
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/ic/tulip.c b/sys/dev/ic/tulip.c
index 3ea9fec..a3543ed 100644
--- a/sys/dev/ic/tulip.c
+++ b/sys/dev/ic/tulip.c
@@ -1397,7 +1397,7 @@ tlp_rxintr(struct tulip_softc *sc)
 		}
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 1cb7fe6..1a3be07 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -1048,7 +1048,7 @@ ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt)
 
 			bpf_mtap(ifp, m0);
 
-			(*ifp->if_input)(ifp, m0);
+			if_input(ifp, m0);
 		}
 	}
 
diff --git a/sys/dev/isa/if_eg.c b/sys/dev/isa/if_eg.c
index b1420b9..c6a1d17 100644
--- a/sys/dev/isa/if_eg.c
+++ b/sys/dev/isa/if_eg.c
@@ -730,7 +730,7 @@ egread(struct eg_softc *sc, void *buf, int len)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/dev/isa/if_el.c b/sys/dev/isa/if_el.c
index c0f9469..f2c3c5a 100644
--- a/sys/dev/isa/if_el.c
+++ b/sys/dev/isa/if_el.c
@@ -591,7 +591,7 @@ elread(struct el_softc *sc, int len)
 	 */
 	bpf_mtap(ifp, m);
 
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/dev/isa/if_iy.c b/sys/dev/isa/if_iy.c
index d7aa89a..acf1374 100644
--- a/sys/dev/isa/if_iy.c
+++ b/sys/dev/isa/if_iy.c
@@ -1046,7 +1046,7 @@ iyget(struct iy_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh, int rxle
 
 
 	bpf_mtap(ifp, top);
-	(*ifp->if_input)(ifp, top);
+	if_input(ifp, top);
 	return;
 
 dropped:
diff --git a/sys/dev/marvell/if_gfe.c b/sys/dev/marvell/if_gfe.c
index ecf7602..a8f15bb 100644
--- a/sys/dev/marvell/if_gfe.c
+++ b/sys/dev/marvell/if_gfe.c
@@ -955,7 +955,7 @@ gfe_rx_get(struct gfe_softc *sc, enum gfe_rxprio rxprio)
 		    (eh->ether_dhost[0] & 1) != 0 ||
 		    memcmp(eh->ether_dhost, CLLADDR(ifp->if_sadl),
 							ETHER_ADDR_LEN) == 0) {
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 			m = NULL;
 			GE_DPRINTF(sc, (">"));
 		} else {
diff --git a/sys/dev/marvell/if_mvgbe.c b/sys/dev/marvell/if_mvgbe.c
index b18c126..1e2d97e 100644
--- a/sys/dev/marvell/if_mvgbe.c
+++ b/sys/dev/marvell/if_mvgbe.c
@@ -2085,7 +2085,7 @@ mvgbe_rxeof(struct mvgbe_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/marvell/if_mvxpe.c b/sys/dev/marvell/if_mvxpe.c
index e1ba655..a9d3a28 100644
--- a/sys/dev/marvell/if_mvxpe.c
+++ b/sys/dev/marvell/if_mvxpe.c
@@ -2448,7 +2448,7 @@ mvxpe_rx_queue(struct mvxpe_softc *sc, int q, int npkt)
 		mvxpe_rx_set_csumflag(ifp, r, m);
 		ifp->if_ipackets++;
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		chunk = NULL; /* the BM chunk goes to networking stack now */
 rx_done:
 		if (chunk) {
diff --git a/sys/dev/ofw/ofnet.c b/sys/dev/ofw/ofnet.c
index 829cfcd..06d2235 100644
--- a/sys/dev/ofw/ofnet.c
+++ b/sys/dev/ofw/ofnet.c
@@ -263,7 +263,7 @@ ofnet_read(struct ofnet_softc *of)
 
 		bpf_mtap(ifp, m);
 		ifp->if_ipackets++;
-		(*ifp->if_input)(ifp, head);
+		if_input(ifp, head);
 	}
 	splx(s);
 }
diff --git a/sys/dev/pci/cxgb/cxgb_sge.c b/sys/dev/pci/cxgb/cxgb_sge.c
index 53ad9b7..3482ecb 100644
--- a/sys/dev/pci/cxgb/cxgb_sge.c
+++ b/sys/dev/pci/cxgb/cxgb_sge.c
@@ -2176,7 +2176,7 @@ t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
      */
     m_adj(m, sizeof(*cpl) + ethpad);
 
-    (*ifp->if_input)(ifp, m);
+    if_input(ifp, m);
 }
 
 /**
diff --git a/sys/dev/pci/if_age.c b/sys/dev/pci/if_age.c
index b9fa768..b950c17 100644
--- a/sys/dev/pci/if_age.c
+++ b/sys/dev/pci/if_age.c
@@ -1505,7 +1505,7 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
 
 			bpf_mtap(ifp, m);
 			/* Pass it on. */
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 
 			/* Reset mbuf chains. */
 			AGE_RXCHAIN_RESET(sc);
diff --git a/sys/dev/pci/if_alc.c b/sys/dev/pci/if_alc.c
index 5886d9a..4135386 100644
--- a/sys/dev/pci/if_alc.c
+++ b/sys/dev/pci/if_alc.c
@@ -2596,7 +2596,7 @@ alc_rxeof(struct alc_softc *sc, struct rx_rdesc *rrd)
 			bpf_mtap(ifp, m);
 
 			/* Pass it on. */
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 		}
 	}
 	/* Reset mbuf chains. */
diff --git a/sys/dev/pci/if_ale.c b/sys/dev/pci/if_ale.c
index c8bbc36..90c42ee 100644
--- a/sys/dev/pci/if_ale.c
+++ b/sys/dev/pci/if_ale.c
@@ -1548,7 +1548,7 @@ ale_rxeof(struct ale_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it to upper layer. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		ale_rx_update_page(sc, &rx_page, length, &prod);
 	}
diff --git a/sys/dev/pci/if_bce.c b/sys/dev/pci/if_bce.c
index b127ced..9f07de1 100644
--- a/sys/dev/pci/if_bce.c
+++ b/sys/dev/pci/if_bce.c
@@ -815,7 +815,7 @@ bce_rxintr(struct bce_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input) (ifp, m);
+		if_input (ifp, m);
 
 		/* re-check current in case it changed */
 		curr = (bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index 81908f1..c59eda5 100644
--- a/sys/dev/pci/if_bge.c
+++ b/sys/dev/pci/if_bge.c
@@ -4574,7 +4574,7 @@ bge_rxeof(struct bge_softc *sc)
 			VLAN_INPUT_TAG(ifp, m, cur_rx->bge_vlan_tag, continue);
 		}
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	sc->bge_rx_saved_considx = rx_cons;
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index 5b79dfe..74e4f5f 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -4647,7 +4647,7 @@ bnx_rx_intr(struct bnx_softc *sc)
 			ifp->if_ipackets++;
 			DBPRINT(sc, BNX_VERBOSE_RECV,
 			    "%s(): Passing received frame up.\n", __func__);
-			(*ifp->if_input)(ifp, m);
+			if_input(ifp, m);
 			DBRUNIF(1, sc->rx_mbuf_alloc--);
 
 		}
diff --git a/sys/dev/pci/if_cas.c b/sys/dev/pci/if_cas.c
index ec4c78f..37ced60 100644
--- a/sys/dev/pci/if_cas.c
+++ b/sys/dev/pci/if_cas.c
@@ -1303,7 +1303,7 @@ cas_rint(struct cas_softc *sc)
 
 				ifp->if_ipackets++;
 				m->m_pkthdr.csum_flags = 0;
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			} else
 				ifp->if_ierrors++;
 		}
@@ -1336,7 +1336,7 @@ cas_rint(struct cas_softc *sc)
 
 				ifp->if_ipackets++;
 				m->m_pkthdr.csum_flags = 0;
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			} else
 				ifp->if_ierrors++;
 		}
diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c
index 6a229b5..f916419 100644
--- a/sys/dev/pci/if_de.c
+++ b/sys/dev/pci/if_de.c
@@ -3750,7 +3750,7 @@ tulip_rx_intr(
 		ms->m_pkthdr.len = total_len;
 		ms->m_pkthdr.rcvif = ifp;
 #if defined(__NetBSD__)
-		(*ifp->if_input)(ifp, ms);
+		if_input(ifp, ms);
 #else
 		m_adj(ms, sizeof(struct ether_header));
 		ether_input(ifp, &eh, ms);
@@ -3764,7 +3764,7 @@ tulip_rx_intr(
 		m0->m_len = m0->m_pkthdr.len = total_len;
 		m0->m_pkthdr.rcvif = ifp;
 #if defined(__NetBSD__)
-		(*ifp->if_input)(ifp, m0);
+		if_input(ifp, m0);
 #else
 		m_adj(m0, sizeof(struct ether_header));
 		ether_input(ifp, &eh, m0);
diff --git a/sys/dev/pci/if_dge.c b/sys/dev/pci/if_dge.c
index 66ef831..570b935 100644
--- a/sys/dev/pci/if_dge.c
+++ b/sys/dev/pci/if_dge.c
@@ -1763,7 +1763,7 @@ dge_rxintr(struct dge_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/pci/if_et.c b/sys/dev/pci/if_et.c
index 208359e..35efae3 100644
--- a/sys/dev/pci/if_et.c
+++ b/sys/dev/pci/if_et.c
@@ -1759,7 +1759,7 @@ et_rxeof(struct et_softc *sc)
 				bpf_mtap(ifp, m);
 
 				ifp->if_ipackets++;
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			}
 		} else {
 			ifp->if_ierrors++;
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 12c60bb..15e5033 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -6832,6 +6832,8 @@ iwm_attach(device_t parent, device_t self, void *aux)
 	ether_ifattach(ifp, ic->ic_myaddr);	/* XXX */
 #endif
 	if_register(ifp);
+	/* XXX should provide its own softint handler */
+	ifp->if_percpuq = if_percpuq_create(if_percpuq_softint, ifp);
 
 	callout_init(&sc->sc_calib_to, 0);
 	callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c
index d5e7514..d4045ce 100644
--- a/sys/dev/pci/if_jme.c
+++ b/sys/dev/pci/if_jme.c
@@ -1213,7 +1213,7 @@ jme_intr_rx(jme_softc_t *sc) {
 			VLAN_INPUT_TAG(ifp, mhead,
 			    (flags & JME_RD_VLAN_MASK), continue);
 		}
-		(*ifp->if_input)(ifp, mhead);
+		if_input(ifp, mhead);
 	}
 	if (ipackets)
 		rnd_add_uint32(&sc->rnd_source, ipackets);
diff --git a/sys/dev/pci/if_kse.c b/sys/dev/pci/if_kse.c
index e25f61d..05bf539 100644
--- a/sys/dev/pci/if_kse.c
+++ b/sys/dev/pci/if_kse.c
@@ -1200,7 +1200,7 @@ rxintr(struct kse_softc *sc)
 				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
 		}
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 #ifdef KSEDIAGNOSTIC
 		if (kse_monitor_rxintr > 0) {
 			printf("m stat %x data %p len %d\n",
diff --git a/sys/dev/pci/if_lii.c b/sys/dev/pci/if_lii.c
index f494b6e..3a68627 100644
--- a/sys/dev/pci/if_lii.c
+++ b/sys/dev/pci/if_lii.c
@@ -1001,7 +1001,7 @@ lii_rxintr(struct lii_softc *sc)
 
 		bpf_mtap(ifp, m);
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	AT_WRITE_4(sc, ATL2_MB_RXD_RD_IDX, sc->sc_rxcur);
diff --git a/sys/dev/pci/if_lmc.c b/sys/dev/pci/if_lmc.c
index a2e67c0..1caa300 100644
--- a/sys/dev/pci/if_lmc.c
+++ b/sys/dev/pci/if_lmc.c
@@ -3510,7 +3510,7 @@ ifnet_setup(struct ifnet *ifp)
   ifp->if_flags    = IFF_POINTOPOINT;
   ifp->if_flags   |= IFF_SIMPLEX;
   ifp->if_flags   |= IFF_NOARP;
-  ifp->if_input    = ifnet_input;
+  ifp->_if_input    = ifnet_input;
   ifp->if_output   = ifnet_output;
   ifp->if_start    = ifnet_start;
   ifp->if_ioctl    = ifnet_ioctl;
diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c
index 92e4d76..237668f 100644
--- a/sys/dev/pci/if_msk.c
+++ b/sys/dev/pci/if_msk.c
@@ -1751,7 +1751,7 @@ msk_rxeof(struct sk_if_softc *sc_if, u_int16_t len, u_int32_t rxstat)
 	bpf_mtap(ifp, m);
 
 	/* pass it on. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 void
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c
index 6c17241..817aa9a 100644
--- a/sys/dev/pci/if_nfe.c
+++ b/sys/dev/pci/if_nfe.c
@@ -946,7 +946,7 @@ mbufcopied:
 		}
 		bpf_mtap(ifp, m);
 		ifp->if_ipackets++;
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 skip1:
 		/* update mapping address in h/w descriptor */
diff --git a/sys/dev/pci/if_pcn.c b/sys/dev/pci/if_pcn.c
index 55bf8e7..3bdc599 100644
--- a/sys/dev/pci/if_pcn.c
+++ b/sys/dev/pci/if_pcn.c
@@ -1551,7 +1551,7 @@ pcn_rxintr(struct pcn_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		ifp->if_ipackets++;
 	}
 
diff --git a/sys/dev/pci/if_rtwn.c b/sys/dev/pci/if_rtwn.c
index 99c7d46..6f61bac 100644
--- a/sys/dev/pci/if_rtwn.c
+++ b/sys/dev/pci/if_rtwn.c
@@ -358,6 +358,8 @@ rtwn_attach(device_t parent, device_t self, void *aux)
 	if_initialize(ifp);
 	ieee80211_ifattach(ic);
 	if_register(ifp);
+	/* XXX should provide its own softint handler */
+	ifp->if_percpuq = if_percpuq_create(if_percpuq_softint, ifp);
 
 	/* override default methods */
 	ic->ic_newassoc = rtwn_newassoc;
diff --git a/sys/dev/pci/if_sip.c b/sys/dev/pci/if_sip.c
index 4d9d5bd..5752c79 100644
--- a/sys/dev/pci/if_sip.c
+++ b/sys/dev/pci/if_sip.c
@@ -2242,7 +2242,7 @@ gsip_rxintr(struct sip_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
@@ -2409,7 +2409,7 @@ sip_rxintr(struct sip_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c
index dc93aac..2f3e424 100644
--- a/sys/dev/pci/if_sk.c
+++ b/sys/dev/pci/if_sk.c
@@ -2117,7 +2117,7 @@ sk_rxeof(struct sk_if_softc *sc_if)
 
 		bpf_mtap(ifp, m);
 		/* pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/pci/if_ste.c b/sys/dev/pci/if_ste.c
index b6053c0..34e9e13 100644
--- a/sys/dev/pci/if_ste.c
+++ b/sys/dev/pci/if_ste.c
@@ -1050,7 +1050,7 @@ ste_rxintr(struct ste_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/pci/if_stge.c b/sys/dev/pci/if_stge.c
index a8cd774..6cce8b9 100644
--- a/sys/dev/pci/if_stge.c
+++ b/sys/dev/pci/if_stge.c
@@ -1377,7 +1377,7 @@ stge_rxintr(struct stge_softc *sc)
 		}
 #endif
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/pci/if_ti.c b/sys/dev/pci/if_ti.c
index d4c5ef2..4912d8a 100644
--- a/sys/dev/pci/if_ti.c
+++ b/sys/dev/pci/if_ti.c
@@ -2030,7 +2030,7 @@ ti_rxeof(struct ti_softc *sc)
 			    continue);
 		}
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Only necessary on the Tigon 1. */
diff --git a/sys/dev/pci/if_tl.c b/sys/dev/pci/if_tl.c
index bf5036c..a9dfb1b 100644
--- a/sys/dev/pci/if_tl.c
+++ b/sys/dev/pci/if_tl.c
@@ -1078,7 +1078,7 @@ tl_intr(void *v)
 				}
 #endif
 				bpf_mtap(ifp, m);
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			}
 		}
 		bus_dmamap_sync(sc->tl_dmatag, sc->Rx_dmamap, 0,
diff --git a/sys/dev/pci/if_txp.c b/sys/dev/pci/if_txp.c
index b259ff9..bf560e3 100644
--- a/sys/dev/pci/if_txp.c
+++ b/sys/dev/pci/if_txp.c
@@ -751,7 +751,7 @@ txp_rx_reclaim(struct txp_softc *sc, struct txp_rx_ring *r, struct txp_dma_alloc
 			    continue);
 		}
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 next:
 		bus_dmamap_sync(sc->sc_dmat, dma->dma_map,
diff --git a/sys/dev/pci/if_vge.c b/sys/dev/pci/if_vge.c
index 3c4da7e..f23f785 100644
--- a/sys/dev/pci/if_vge.c
+++ b/sys/dev/pci/if_vge.c
@@ -1373,7 +1373,7 @@ vge_rxeof(struct vge_softc *sc)
 		 */
 		bpf_mtap(ifp, m);
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		lim++;
 		if (lim == VGE_NRXDESC)
diff --git a/sys/dev/pci/if_vioif.c b/sys/dev/pci/if_vioif.c
index 6f60c5c..8f1fa30 100644
--- a/sys/dev/pci/if_vioif.c
+++ b/sys/dev/pci/if_vioif.c
@@ -1038,7 +1038,7 @@ vioif_rx_deq_locked(struct vioif_softc *sc)
 		bpf_mtap(ifp, m);
 
 		VIOIF_RX_UNLOCK(sc);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		VIOIF_RX_LOCK(sc);
 
 		if (sc->sc_stopping)
diff --git a/sys/dev/pci/if_vr.c b/sys/dev/pci/if_vr.c
index 06ec081..0d1ad42 100644
--- a/sys/dev/pci/if_vr.c
+++ b/sys/dev/pci/if_vr.c
@@ -788,7 +788,7 @@ vr_rxeof(struct vr_softc *sc)
 		 */
 		bpf_mtap(ifp, m);
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	/* Update the receive pointer. */
diff --git a/sys/dev/pci/if_vte.c b/sys/dev/pci/if_vte.c
index f0f1293..8db52291 100644
--- a/sys/dev/pci/if_vte.c
+++ b/sys/dev/pci/if_vte.c
@@ -1131,7 +1131,7 @@ vte_rxeof(struct vte_softc *sc)
 		m->m_pkthdr.rcvif = ifp;
 		ifp->if_ipackets++;
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 
 	if (prog > 0) {
diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c
index 4124859..6a19ffe 100644
--- a/sys/dev/pci/if_wm.c
+++ b/sys/dev/pci/if_wm.c
@@ -7121,7 +7121,7 @@ wm_rxeof(struct wm_rxqueue *rxq)
 		bpf_mtap(ifp, m);
 
 		/* Pass it on. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		WM_RX_LOCK(rxq);
 
diff --git a/sys/dev/pci/if_xge.c b/sys/dev/pci/if_xge.c
index ffd22b3..798528c 100644
--- a/sys/dev/pci/if_xge.c
+++ b/sys/dev/pci/if_xge.c
@@ -808,7 +808,7 @@ xge_intr(void *pv)
 
 		bpf_mtap(ifp, m);
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		if (++sc->sc_nextrx == NRXREAL)
 			sc->sc_nextrx = 0;
diff --git a/sys/dev/pci/ixgbe/ixgbe.c b/sys/dev/pci/ixgbe/ixgbe.c
index a389453..a93cc94 100644
--- a/sys/dev/pci/ixgbe/ixgbe.c
+++ b/sys/dev/pci/ixgbe/ixgbe.c
@@ -1650,7 +1650,12 @@ ixgbe_legacy_irq(void *arg)
 	}
 
 	if ((ifp->if_flags & IFF_RUNNING) != 0) {
+#ifdef __NetBSD__
+		/* Don't run ixgbe_rxeof in interrupt context */
+		more = true;
+#else
 		more = ixgbe_rxeof(que);
+#endif
 
 		IXGBE_TX_LOCK(txr);
 		ixgbe_txeof(txr);
@@ -1712,7 +1717,12 @@ ixgbe_msix_que(void *arg)
 	ixgbe_disable_queue(adapter, que->msix);
 	++que->irqs;
 
+#ifdef __NetBSD__
+	/* Don't run ixgbe_rxeof in interrupt context */
+	more = true;
+#else
 	more = ixgbe_rxeof(que);
+#endif
 
 	IXGBE_TX_LOCK(txr);
 	ixgbe_txeof(txr);
@@ -4812,7 +4822,7 @@ ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype
 	s = splnet();
 	/* Pass this up to any BPF listeners. */
 	bpf_mtap(ifp, m);
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	splx(s);
 
 	IXGBE_RX_LOCK(rxr);
diff --git a/sys/dev/pci/ixgbe/ixv.c b/sys/dev/pci/ixgbe/ixv.c
index 32d86b0..7dc5641 100644
--- a/sys/dev/pci/ixgbe/ixv.c
+++ b/sys/dev/pci/ixgbe/ixv.c
@@ -3372,7 +3372,7 @@ ixv_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype)
 	s = splnet();
 	/* Pass this up to any BPF listeners. */
 	bpf_mtap(ifp, m);
-        (*ifp->if_input)(ifp, m);
+        if_input(ifp, m);
 	splx(s);
 
 	IXV_RX_LOCK(rxr);
diff --git a/sys/dev/pcmcia/if_cnw.c b/sys/dev/pcmcia/if_cnw.c
index 4bfaf09..bf54ff7 100644
--- a/sys/dev/pcmcia/if_cnw.c
+++ b/sys/dev/pcmcia/if_cnw.c
@@ -856,7 +856,7 @@ cnw_recv(struct cnw_softc *sc)
 		bpf_mtap(ifp, m);
 
 		/* Pass the packet up. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 }
 
diff --git a/sys/dev/pcmcia/if_malo_pcmcia.c b/sys/dev/pcmcia/if_malo_pcmcia.c
index f9fb417..d3b4c93 100644
--- a/sys/dev/pcmcia/if_malo_pcmcia.c
+++ b/sys/dev/pcmcia/if_malo_pcmcia.c
@@ -1013,7 +1013,7 @@ cmalo_rx(struct malo_softc *sc)
 
 	/* push the frame up to the network stack if not in monitor mode */
 	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 		ifp->if_ipackets++;
 	}
 }
diff --git a/sys/dev/pcmcia/if_ray.c b/sys/dev/pcmcia/if_ray.c
index 98f844c..ed62d07 100644
--- a/sys/dev/pcmcia/if_ray.c
+++ b/sys/dev/pcmcia/if_ray.c
@@ -1517,7 +1517,7 @@ done:
 	bpf_mtap(ifp, m);
 	/* XXX doesn't appear to be included m->m_flags |= M_HASFCS; */
 	ifp->if_ipackets++;
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/dev/pcmcia/if_xi.c b/sys/dev/pcmcia/if_xi.c
index 7df0635..0df3f0d 100644
--- a/sys/dev/pcmcia/if_xi.c
+++ b/sys/dev/pcmcia/if_xi.c
@@ -475,7 +475,7 @@ xi_get(struct xi_softc *sc)
 
 	bpf_mtap(ifp, top);
 
-	(*ifp->if_input)(ifp, top);
+	if_input(ifp, top);
 	return (recvcount);
 }
 
diff --git a/sys/dev/qbus/if_de.c b/sys/dev/qbus/if_de.c
index eef778e..49ad29f 100644
--- a/sys/dev/qbus/if_de.c
+++ b/sys/dev/qbus/if_de.c
@@ -557,7 +557,7 @@ derecv(struct de_softc *sc)
 		}
 		bpf_mtap(ifp, m);
 
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 		/* hang the receive buffer again */
 next:		rp->r_lenerr = 0;
diff --git a/sys/dev/qbus/if_il.c b/sys/dev/qbus/if_il.c
index c9c9faf..fdf3a5f 100644
--- a/sys/dev/qbus/if_il.c
+++ b/sys/dev/qbus/if_il.c
@@ -533,7 +533,7 @@ ilrint(void *arg)
 
 	/* Shave off status hdr */
 	m_adj(m, 4);
-	(*sc->sc_if.if_input)(&sc->sc_if, m);
+	if_input(&sc->sc_if, m);
 setup:
 	/*
 	 * Reset for next packet if possible.
diff --git a/sys/dev/qbus/if_qe.c b/sys/dev/qbus/if_qe.c
index 4ebb9ee..2ecae27 100644
--- a/sys/dev/qbus/if_qe.c
+++ b/sys/dev/qbus/if_qe.c
@@ -597,7 +597,7 @@ qeintr(void *arg)
 				sc->sc_nextrx = 0;
 			bpf_mtap(ifp, m);
 			if ((status1 & QE_ESETUP) == 0)
-				(*ifp->if_input)(ifp, m);
+				if_input(ifp, m);
 			else
 				m_freem(m);
 		}
diff --git a/sys/dev/qbus/if_qt.c b/sys/dev/qbus/if_qt.c
index 83f2b74..5e749a1 100644
--- a/sys/dev/qbus/if_qt.c
+++ b/sys/dev/qbus/if_qt.c
@@ -586,7 +586,7 @@ qtrint(struct qt_softc *sc)
 			goto rnext;
 		}
 		bpf_mtap(ifp, m);
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 rnext:
 		--sc->nrcv;
 		rp->rmd3 = 0;
diff --git a/sys/dev/sbus/be.c b/sys/dev/sbus/be.c
index 7241ca6..e81c0f2 100644
--- a/sys/dev/sbus/be.c
+++ b/sys/dev/sbus/be.c
@@ -574,7 +574,7 @@ be_read(struct be_softc *sc, int idx, int len)
 	 */
 	bpf_mtap(ifp, m);
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/dev/sbus/qe.c b/sys/dev/sbus/qe.c
index 24d1c5a..2bee6fe 100644
--- a/sys/dev/sbus/qe.c
+++ b/sys/dev/sbus/qe.c
@@ -429,7 +429,7 @@ qe_read(struct qe_softc *sc, int idx, int len)
 	 */
 	bpf_mtap(ifp, m);
 	/* Pass the packet up. */
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/dev/scsipi/if_se.c b/sys/dev/scsipi/if_se.c
index 707b90d..f5db75e 100644
--- a/sys/dev/scsipi/if_se.c
+++ b/sys/dev/scsipi/if_se.c
@@ -359,8 +359,9 @@ seattach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, myaddr);
+	if_register(ifp);
 }
 
 
@@ -674,7 +675,7 @@ se_read(struct se_softc *sc, char *data, int datalen)
 		bpf_mtap(ifp, m);
 
 		/* Pass the packet up. */
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 
 	next_packet:
 		data += len;
diff --git a/sys/dev/usb/if_atu.c b/sys/dev/usb/if_atu.c
index 91912f7..4a806d7 100644
--- a/sys/dev/usb/if_atu.c
+++ b/sys/dev/usb/if_atu.c
@@ -1452,8 +1452,9 @@ atu_complete_attach(struct atu_softc *sc)
 	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Call MI attach routine. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 
 	sc->sc_newstate = ic->ic_newstate;
 	ic->ic_newstate = atu_newstate;
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c
index 9d9343a..c8ff1d1 100644
--- a/sys/dev/usb/if_aue.c
+++ b/sys/dev/usb/if_aue.c
@@ -856,8 +856,9 @@ aue_attach(device_t parent, device_t self, void *aux)
 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 	rnd_attach_source(&sc->rnd_source, device_xname(sc->aue_dev),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
 
@@ -1173,7 +1174,7 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 	DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->aue_dev),
 		    __func__, m->m_len));
-	(*(ifp)->if_input)((ifp), (m));
+	if_input((ifp), (m));
  done1:
 	splx(s);
 
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c
index 13f2029..3ee9fbf 100644
--- a/sys/dev/usb/if_axe.c
+++ b/sys/dev/usb/if_axe.c
@@ -840,8 +840,9 @@ axe_attach(device_t parent, device_t self, void *aux)
 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 	rnd_attach_source(&sc->rnd_source, device_xname(sc->axe_dev),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
 
@@ -1095,7 +1096,7 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 		DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->axe_dev),
 		    __func__, m->m_len));
-		(*(ifp)->if_input)((ifp), (m));
+		if_input((ifp), (m));
 
 		splx(s);
 
diff --git a/sys/dev/usb/if_axen.c b/sys/dev/usb/if_axen.c
index 3ccd7bf..110f35e 100644
--- a/sys/dev/usb/if_axen.c
+++ b/sys/dev/usb/if_axen.c
@@ -791,8 +791,9 @@ axen_attach(device_t parent, device_t self, void *aux)
 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 	rnd_attach_source(&sc->rnd_source, device_xname(sc->axen_dev),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
 
@@ -1112,7 +1113,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 		/* push the packet up */
 		s = splnet();
 		bpf_mtap(ifp, m);
-		(*(ifp)->if_input)((ifp), (m));
+		if_input((ifp), (m));
 		splx(s);
 
 nextpkt:
diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c
index 52067ab..b45edaf 100644
--- a/sys/dev/usb/if_cdce.c
+++ b/sys/dev/usb/if_cdce.c
@@ -285,8 +285,9 @@ cdce_attach(device_t parent, device_t self, void *aux)
 
 	IFQ_SET_READY(&ifp->if_snd);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 
 	sc->cdce_attached = 1;
 	splx(s);
@@ -722,7 +723,7 @@ cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 	bpf_mtap(ifp, m);
 
-	(*(ifp)->if_input)((ifp), (m));
+	if_input((ifp), (m));
 
 done1:
 	splx(s);
diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c
index bfe0b05..7142b88 100644
--- a/sys/dev/usb/if_cue.c
+++ b/sys/dev/usb/if_cue.c
@@ -547,8 +547,9 @@ cue_attach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 	rnd_attach_source(&sc->rnd_source, device_xname(sc->cue_dev),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
 
@@ -798,7 +799,7 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 	DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->cue_dev),
 		    __func__, m->m_len));
-	(*(ifp)->if_input)((ifp), (m));
+	if_input((ifp), (m));
  done1:
 	splx(s);
 
diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c
index b69c0d3..946b805 100644
--- a/sys/dev/usb/if_kue.c
+++ b/sys/dev/usb/if_kue.c
@@ -504,8 +504,9 @@ kue_attach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
+	if_register(ifp);
 	rnd_attach_source(&sc->rnd_source, device_xname(sc->kue_dev),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
 
@@ -723,7 +724,7 @@ kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 	DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->kue_dev),
 		    __func__, m->m_len));
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 
 	splx(s);
 
diff --git a/sys/dev/usb/if_otus.c b/sys/dev/usb/if_otus.c
index 8ce517f..f95f618 100644
--- a/sys/dev/usb/if_otus.c
+++ b/sys/dev/usb/if_otus.c
@@ -850,9 +850,9 @@ otus_attachhook(device_t arg)
 	IFQ_SET_READY(&ifp->if_snd);
 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
 
-	if_attach(ifp);
-
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 
 	ic->ic_node_alloc = otus_node_alloc;
 	ic->ic_newassoc   = otus_newassoc;
diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c
index 49158c4..30f6830 100644
--- a/sys/dev/usb/if_rum.c
+++ b/sys/dev/usb/if_rum.c
@@ -457,8 +457,9 @@ rum_attach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 	ic->ic_newassoc = rum_newassoc;
 
 	/* override state transition machine */
diff --git a/sys/dev/usb/if_run.c b/sys/dev/usb/if_run.c
index d3f3bcb..fc77bfa 100644
--- a/sys/dev/usb/if_run.c
+++ b/sys/dev/usb/if_run.c
@@ -632,8 +632,9 @@ run_attach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 	ic->ic_node_alloc = run_node_alloc;
 	ic->ic_newassoc = run_newassoc;
 	ic->ic_updateslot = run_updateslot;
diff --git a/sys/dev/usb/if_smsc.c b/sys/dev/usb/if_smsc.c
index 48cbf1b..63cb924 100644
--- a/sys/dev/usb/if_smsc.c
+++ b/sys/dev/usb/if_smsc.c
@@ -1113,8 +1113,9 @@ smsc_attach(device_t parent, device_t self, void *aux)
 	} else
 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, sc->sc_enaddr);
+	if_register(ifp);
 
 	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
@@ -1410,7 +1411,7 @@ smsc_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 		/* push the packet up */
 		s = splnet();
 		bpf_mtap(ifp, m);
-		ifp->if_input(ifp, m);
+		if_input(ifp, m);
 		splx(s);
 	}
 
diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c
index 455481a..8c46689 100644
--- a/sys/dev/usb/if_udav.c
+++ b/sys/dev/usb/if_udav.c
@@ -315,8 +315,9 @@ udav_attach(device_t parent, device_t self, void *aux)
 
 skipmii:
 	/* attach the interface */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 
 	rnd_attach_source(&sc->rnd_source, device_xname(self),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
@@ -1203,7 +1204,7 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 	DPRINTF(("%s: %s: deliver %d\n", device_xname(sc->sc_dev),
 		 __func__, m->m_len));
-	(*(ifp)->if_input)((ifp), (m));
+	if_input((ifp), (m));
 
  done1:
 	splx(s);
diff --git a/sys/dev/usb/if_upgt.c b/sys/dev/usb/if_upgt.c
index 957f18a..00c7c66 100644
--- a/sys/dev/usb/if_upgt.c
+++ b/sys/dev/usb/if_upgt.c
@@ -449,8 +449,9 @@ upgt_attach_hook(device_t arg)
 	IFQ_SET_READY(&ifp->if_snd);
 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 	ic->ic_newassoc = upgt_newassoc;
 
 	sc->sc_newstate = ic->ic_newstate;
diff --git a/sys/dev/usb/if_upl.c b/sys/dev/usb/if_upl.c
index 82095cd..f659b61 100644
--- a/sys/dev/usb/if_upl.c
+++ b/sys/dev/usb/if_upl.c
@@ -300,13 +300,14 @@ upl_attach(device_t parent, device_t self, void *aux)
 	ifp->if_addrlen = 0;
 	ifp->if_hdrlen = 0;
 	ifp->if_output = upl_output;
-	ifp->if_input = upl_input;
+	ifp->_if_input = upl_input;
 	ifp->if_baudrate = 12000000;
 	ifp->if_dlt = DLT_RAW;
 	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Attach the interface. */
-	if_attach(ifp);
+	if_initialize(ifp);
+	if_register(ifp);
 	if_alloc_sadl(ifp);
 
 	bpf_attach(ifp, DLT_RAW, 0);
@@ -546,7 +547,7 @@ upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 	DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev),
 		    __func__, m->m_len));
 
-	(*(ifp)->if_input)((ifp), (m));
+	if_input((ifp), (m));
 
  done1:
 	splx(s);
diff --git a/sys/dev/usb/if_ural.c b/sys/dev/usb/if_ural.c
index be57979..1476a31 100644
--- a/sys/dev/usb/if_ural.c
+++ b/sys/dev/usb/if_ural.c
@@ -499,8 +499,9 @@ ural_attach(device_t parent, device_t self, void *aux)
 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
 	}
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 	ic->ic_reset = ural_reset;
 
 	/* override state transition machine */
diff --git a/sys/dev/usb/if_url.c b/sys/dev/usb/if_url.c
index 0d3d41a..57eae41 100644
--- a/sys/dev/usb/if_url.c
+++ b/sys/dev/usb/if_url.c
@@ -311,8 +311,9 @@ url_attach(device_t parent, device_t self, void *aux)
 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
 	/* attach the interface */
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 
 	rnd_attach_source(&sc->rnd_source, device_xname(self),
 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
@@ -1065,7 +1066,7 @@ url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
 	DPRINTF(("%s: %s: deliver %d\n", device_xname(sc->sc_dev),
 		 __func__, m->m_len));
-	(*(ifp)->if_input)((ifp), (m));
+	if_input((ifp), (m));
 
  done1:
 	splx(s);
diff --git a/sys/dev/usb/if_urndis.c b/sys/dev/usb/if_urndis.c
index 1ae2f74..5880bcb 100644
--- a/sys/dev/usb/if_urndis.c
+++ b/sys/dev/usb/if_urndis.c
@@ -874,7 +874,7 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, uint32_t len)
 
 			bpf_mtap(ifp, m);
 
-			(*(ifp)->if_input)((ifp), (m));
+			if_input((ifp), (m));
 		}
 		splx(s);
 
@@ -1490,8 +1490,9 @@ urndis_attach(device_t parent, device_t self, void *aux)
 		return;
 	}
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, eaddr);
+	if_register(ifp);
 	sc->sc_attached = 1;
 
 	splx(s);
diff --git a/sys/dev/usb/if_urtw.c b/sys/dev/usb/if_urtw.c
index e6b1136..9a71ac4 100644
--- a/sys/dev/usb/if_urtw.c
+++ b/sys/dev/usb/if_urtw.c
@@ -729,8 +729,9 @@ urtw_attach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 	memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 
 	/* override state transition machine */
 	sc->sc_newstate = ic->ic_newstate;
diff --git a/sys/dev/usb/if_urtwn.c b/sys/dev/usb/if_urtwn.c
index 2294a92..75cb9b0 100644
--- a/sys/dev/usb/if_urtwn.c
+++ b/sys/dev/usb/if_urtwn.c
@@ -439,8 +439,9 @@ urtwn_attach(device_t parent, device_t self, void *aux)
 	IFQ_SET_READY(&ifp->if_snd);
 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 
 	/* override default methods */
 	ic->ic_newassoc = urtwn_newassoc;
diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c
index 913dd41..36072b6 100644
--- a/sys/dev/usb/if_zyd.c
+++ b/sys/dev/usb/if_zyd.c
@@ -426,8 +426,9 @@ zyd_complete_attach(struct zyd_softc *sc)
 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
 	}
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ieee80211_ifattach(ic);
+	if_register(ifp);
 	ic->ic_node_alloc = zyd_node_alloc;
 	ic->ic_newassoc = zyd_newassoc;
 
diff --git a/sys/net/agr/if_agr.c b/sys/net/agr/if_agr.c
index 5210867..4524715 100644
--- a/sys/net/agr/if_agr.c
+++ b/sys/net/agr/if_agr.c
@@ -158,7 +158,7 @@ agr_input(struct ifnet *ifp_port, struct mbuf *m)
 #endif
 
 	bpf_mtap(ifp, m);
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 }
 
 /*
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 825894c..a3af562 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -720,7 +720,7 @@ bpf_write(struct file *fp, off_t *offp, struct uio *uio,
 
 	if (mc != NULL) {
 		if (error == 0)
-			(*ifp->if_input)(ifp, mc);
+			if_input(ifp, mc);
 		else
 			m_freem(mc);
 	}
diff --git a/sys/net/if.c b/sys/net/if.c
index 56e3d98..dfd622f 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -117,6 +117,7 @@ __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.322 2016/01/21 15:41:29 riastradh Exp $");
 #include <sys/kauth.h>
 #include <sys/kmem.h>
 #include <sys/xcall.h>
+#include <sys/cpu.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -648,6 +649,67 @@ if_register(ifnet_t *ifp)
 	TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list);
 }
 
+static void
+if_percpuq_init_ifq(void *p, void *arg __unused, struct cpu_info *ci __unused)
+{
+	struct ifqueue *const ifq = p;
+
+	memset(ifq, 0, sizeof(*ifq));
+	ifq->ifq_maxlen = IFQ_MAXLEN;
+}
+
+struct if_percpuq *
+if_percpuq_create(void (*sih)(void *), void *arg)
+{
+	struct if_percpuq *ipq;
+
+	ipq = kmem_zalloc(sizeof(*ipq), KM_SLEEP);
+	if (ipq == NULL)
+		panic("kmem_zalloc failed");
+
+	ipq->ipq_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,
+	    sih, arg);
+	ipq->ipq_ifqs = percpu_alloc(sizeof(struct ifqueue));
+	percpu_foreach(ipq->ipq_ifqs, &if_percpuq_init_ifq, NULL);
+
+	return ipq;
+}
+
+void
+if_percpuq_softint(void *arg)
+{
+	struct ifnet *ifp = arg;
+	struct mbuf *m;
+	struct ifqueue *ifq;
+	int s;
+
+	s = splnet();
+	ifq = percpu_getref(ifp->if_percpuq->ipq_ifqs);
+	while (!IF_IS_EMPTY(ifq)) {
+		IF_DEQUEUE(ifq, m);
+		ifp->_if_input(ifp, m);
+	}
+	percpu_putref(ifp->if_percpuq->ipq_ifqs);
+	splx(s);
+}
+
+static void
+if_percpuq_purge_ifq(void *p, void *arg __unused, struct cpu_info *ci __unused)
+{
+	struct ifqueue *const ifq = p;
+
+	IF_PURGE(ifq);
+}
+
+void
+if_percpuq_destroy(struct if_percpuq *ipq)
+{
+
+	percpu_foreach(ipq->ipq_ifqs, &if_percpuq_purge_ifq, NULL);
+	percpu_free(ipq->ipq_ifqs, sizeof(struct ifqueue));
+	softint_disestablish(ipq->ipq_si);
+}
+
 /*
  * Deprecated. Use if_initialize and if_register instead.
  * See the above comment of if_initialize.
@@ -656,6 +718,7 @@ void
 if_attach(ifnet_t *ifp)
 {
 	if_initialize(ifp);
+	ifp->if_percpuq = if_percpuq_create(if_percpuq_softint, ifp);
 	if_register(ifp);
 }
 
@@ -702,7 +765,7 @@ if_deactivate(struct ifnet *ifp)
 	s = splnet();
 
 	ifp->if_output	 = if_nulloutput;
-	ifp->if_input	 = if_nullinput;
+	ifp->_if_input	 = if_nullinput;
 	ifp->if_start	 = if_nullstart;
 	ifp->if_ioctl	 = if_nullioctl;
 	ifp->if_init	 = if_nullinit;
@@ -925,6 +988,14 @@ again:
 	xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
 	xc_wait(xc);
 
+	if (ifp->if_percpuq != NULL) {
+		struct if_percpuq *ipq = ifp->if_percpuq;
+
+		percpu_foreach(ipq->ipq_ifqs, &if_percpuq_purge_ifq, NULL);
+		percpu_free(ipq->ipq_ifqs, sizeof(struct ifqueue));
+		softint_disestablish(ipq->ipq_si);
+	}
+
 	splx(s);
 }
 
@@ -2441,6 +2512,42 @@ if_mcast_op(ifnet_t *ifp, const unsigned long cmd, const struct sockaddr *sa)
 	return rc;
 }
 
+void
+if_percpuq_enqueue(struct if_percpuq *ipq, struct mbuf *m)
+{
+	struct ifqueue *ifq = percpu_getref(ipq->ipq_ifqs);
+
+	if (IF_QFULL(ifq)) {
+		IF_DROP(ifq);
+		m_freem(m);
+		return;
+	}
+	IF_ENQUEUE(ifq, m);
+	percpu_putref(ipq->ipq_ifqs);
+
+	softint_schedule(ipq->ipq_si);
+}
+
+/*
+ * The common interface input routine that is called by device drivers.
+ * We ensure that the upper layer routines, e.g., ether_input and bridge_input,
+ * aren't run in hardware interrupt context.
+ */
+void
+if_input(struct ifnet *ifp, struct mbuf *m)
+{
+
+	if (ifp->if_percpuq) {
+		KASSERT(cpu_intr_p());
+
+		if_percpuq_enqueue(ifp->if_percpuq, m);
+	} else {
+		KASSERT(!cpu_intr_p());
+
+		ifp->_if_input(ifp, m);
+	}
+}
+
 static void
 sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
     struct ifaltq *ifq)
diff --git a/sys/net/if.h b/sys/net/if.h
index f8051e4..5f2e185 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -85,6 +85,7 @@
 #include <net/pfil.h>
 #ifdef _KERNEL
 #include <net/pktqueue.h>
+#include <sys/intr.h>
 #endif
 
 /*
@@ -252,6 +253,11 @@ struct bridge_iflist;
 struct callout;
 struct krwlock;
 
+struct if_percpuq {
+	void		*ipq_si;
+	struct percpu	*ipq_ifqs;	/* struct ifqueue */
+};
+
 typedef struct ifnet {
 	void	*if_softc;		/* lower-level data for this if */
 	TAILQ_ENTRY(ifnet) if_list;	/* all struct ifnets are chained */
@@ -271,7 +277,7 @@ typedef struct ifnet {
 	int	(*if_output)		/* output routine (enqueue) */
 		    (struct ifnet *, struct mbuf *, const struct sockaddr *,
 		     struct rtentry *);
-	void	(*if_input)		/* input routine (from h/w driver) */
+	void	(*_if_input)		/* input routine (from h/w driver) */
 		    (struct ifnet *, struct mbuf *);
 	void	(*if_start)		/* initiate output routine */
 		    (struct ifnet *);
@@ -351,12 +357,13 @@ typedef struct ifnet {
 	struct ifnet_lock *if_ioctl_lock;
 #ifdef _KERNEL /* XXX kvm(3) */
 	struct callout *if_slowtimo_ch;
-#endif
 #ifdef GATEWAY
 	struct kmutex	*if_afdata_lock;
 #else
 	struct krwlock	*if_afdata_lock;
 #endif
+	struct if_percpuq	*if_percpuq; /* We should remove it in the future */
+#endif
 } ifnet_t;
  
 #define	if_mtu		if_data.ifi_mtu
@@ -947,6 +954,14 @@ int	if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
 int	if_flags_set(struct ifnet *, const short);
 int	if_clone_list(int, char *, int *);
 
+void	if_input(struct ifnet *, struct mbuf *);
+
+struct if_percpuq *
+	if_percpuq_create(void (*)(void *), void *);
+void	if_percpuq_destroy(struct if_percpuq *);
+void	if_percpuq_enqueue(struct if_percpuq *, struct mbuf *);
+void	if_percpuq_softint(void *);
+
 void ifa_insert(struct ifnet *, struct ifaddr *);
 void ifa_remove(struct ifnet *, struct ifaddr *);
 
diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c
index 9e0d422..5f83863 100644
--- a/sys/net/if_atmsubr.c
+++ b/sys/net/if_atmsubr.c
@@ -257,7 +257,7 @@ atm_input(struct ifnet *ifp, struct atm_pseudohdr *ah, struct mbuf *m,
 	switch (etype) {
 #ifdef INET
 	case ETHERTYPE_IP:
-#ifdef GATEWAY
+#if 0	/* XXX re-enable once atm_input runs in softint */
 		if (ipflow_fastforward(m))
 			return;
 #endif
@@ -266,7 +266,7 @@ atm_input(struct ifnet *ifp, struct atm_pseudohdr *ah, struct mbuf *m,
 #endif /* INET */
 #ifdef INET6
 	case ETHERTYPE_IPV6:
-#ifdef GATEWAY
+#if 0	/* XXX re-enable once atm_input runs in softint */
 		if (ip6flow_fastforward(&m))
 			return;
 #endif
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index f51edd3..a0cb2ca 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -453,7 +453,8 @@ bridge_clone_create(struct if_clone *ifc, int unit)
 
 	bridge_sysctl_fwdq_setup(&ifp->if_sysctl_log, sc);
 
-	if_attach(ifp);
+	if_initialize(ifp);
+	if_register(ifp);
 
 	if_alloc_sadl(ifp);
 
@@ -834,7 +835,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
 
 	KASSERT(BRIDGE_LOCKED(sc));
 
-	ifs->if_input = ether_input;
+	ifs->_if_input = ether_input;
 	ifs->if_bridge = NULL;
 	ifs->if_bridgeif = NULL;
 
@@ -882,7 +883,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 	if (ifs->if_bridge != NULL)
 		return (EBUSY);
 
-	if (ifs->if_input != ether_input)
+	if (ifs->_if_input != ether_input)
 		return EINVAL;
 
 	/* FIXME: doesn't work with non-IFF_SIMPLEX interfaces */
@@ -919,7 +920,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 	ifs->if_bridge = sc;
 	ifs->if_bridgeif = bif;
 	LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
-	ifs->if_input = bridge_input;
+	ifs->_if_input = bridge_input;
 
 	BRIDGE_UNLOCK(sc);
 
@@ -1887,6 +1888,8 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
 	struct bridge_iflist *bif;
 	struct ether_header *eh;
 
+	KASSERT(!cpu_intr_p());
+
 	if (__predict_false(sc == NULL) ||
 	    (sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 		ether_input(ifp, m);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 67e2cf1..d527904 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -88,6 +88,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.215 2015/11/19 16:23:54 christos
 #include <sys/device.h>
 #include <sys/rnd.h>
 #include <sys/rndsource.h>
+#include <sys/cpu.h>
 
 #include <net/if.h>
 #include <net/netisr.h>
@@ -539,6 +540,8 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
 	struct llc *l;
 #endif
 
+	KASSERT(!cpu_intr_p());
+
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		m_freem(m);
 		return;
@@ -932,7 +935,7 @@ ether_ifattach(struct ifnet *ifp, const uint8_t *lla)
 	ifp->if_dlt = DLT_EN10MB;
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_output = ether_output;
-	ifp->if_input = ether_input;
+	ifp->_if_input = ether_input;
 	if (ifp->if_baudrate == 0)
 		ifp->if_baudrate = IF_Mbps(10);		/* just a default */
 
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index f128d91..24b8248 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -597,7 +597,7 @@ fddi_ifattach(struct ifnet *ifp, void *lla)
 	ifp->if_dlt = DLT_FDDI;
 	ifp->if_mtu = FDDIMTU;
 	ifp->if_output = fddi_output;
-	ifp->if_input = fddi_input;
+	ifp->_if_input = fddi_input;
 	ifp->if_baudrate = IF_Mbps(100);
 #ifdef IFF_NOTRAILERS
 	ifp->if_flags |= IFF_NOTRAILERS;
diff --git a/sys/net/if_hippisubr.c b/sys/net/if_hippisubr.c
index 9c5709d..955f0af 100644
--- a/sys/net/if_hippisubr.c
+++ b/sys/net/if_hippisubr.c
@@ -288,7 +288,7 @@ hippi_ifattach(struct ifnet *ifp, void *lla)
 	ifp->if_dlt = DLT_HIPPI;
 	ifp->if_mtu = HIPPIMTU;
 	ifp->if_output = hippi_output;
-	ifp->if_input = hippi_input;
+	ifp->_if_input = hippi_input;
 	ifp->if_baudrate = IF_Mbps(800);	/* XXX double-check */
 
 	if_set_sadl(ifp, lla, 6, true);
diff --git a/sys/net/if_mpls.c b/sys/net/if_mpls.c
index 944621a..2d2b93f 100644
--- a/sys/net/if_mpls.c
+++ b/sys/net/if_mpls.c
@@ -132,7 +132,7 @@ mpls_clone_create(struct if_clone *ifc, int unit)
 	sc->sc_if.if_dlt = DLT_NULL;
 	sc->sc_if.if_mtu = 1500;
 	sc->sc_if.if_flags = 0;
-	sc->sc_if.if_input = mpls_input;
+	sc->sc_if._if_input = mpls_input;
 	sc->sc_if.if_output = mpls_output;
 	sc->sc_if.if_ioctl = mpls_ioctl;
 
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index c7a6aa9..7d9a56a 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -1061,7 +1061,7 @@ tap_dev_write(int unit, struct uio *uio, int flags)
 
 	bpf_mtap(ifp, m);
 	s = splnet();
-	(*ifp->if_input)(ifp, m);
+	if_input(ifp, m);
 	splx(s);
 
 	return (0);
diff --git a/sys/net/if_tokensubr.c b/sys/net/if_tokensubr.c
index f413070..883f534 100644
--- a/sys/net/if_tokensubr.c
+++ b/sys/net/if_tokensubr.c
@@ -501,7 +501,7 @@ token_ifattach(struct ifnet *ifp, void *lla)
 	ifp->if_dlt = DLT_IEEE802;
 	ifp->if_mtu = ISO88025_MTU;
 	ifp->if_output = token_output;
-	ifp->if_input = token_input;
+	ifp->_if_input = token_input;
 	ifp->if_broadcastaddr = tokenbroadcastaddr;
 #ifdef IFF_NOTRAILERS
 	ifp->if_flags |= IFF_NOTRAILERS;
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 9ffaf1e..11d687f 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -240,8 +240,9 @@ vlan_clone_create(struct if_clone *ifc, int unit)
 	ifp->if_ioctl = vlan_ioctl;
 	IFQ_SET_READY(&ifp->if_snd);
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	vlan_reset_linkname(ifp);
+	if_register(ifp);
 
 	return (0);
 }
@@ -907,5 +908,5 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
 	bpf_mtap(&ifv->ifv_if, m);
 
 	m->m_flags &= ~M_PROMISC;
-	ifv->ifv_if.if_input(&ifv->ifv_if, m);
+	if_input(&ifv->ifv_if, m);
 }
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index c4f6796..f39387c 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -766,7 +766,7 @@ ieee80211_deliver_data(struct ieee80211com *ic,
 			/* XXX goto err? */
 			VLAN_INPUT_TAG(ifp, m, ni->ni_vlan, goto out);
 		}
-		(*ifp->if_input)(ifp, m);
+		if_input(ifp, m);
 	}
 	return;
   out:
diff --git a/sys/netinet/ip_etherip.c b/sys/netinet/ip_etherip.c
index 5e444f2..05f8765 100644
--- a/sys/netinet/ip_etherip.c
+++ b/sys/netinet/ip_etherip.c
@@ -259,7 +259,7 @@ ip_etherip_input(struct mbuf *m, ...)
 	ifp->if_ipackets++;
 
 	s = splnet();
-	(ifp->if_input)(ifp, m);
+	ifp->_if_input(ifp, m);
 	splx(s);
 
 	return;
diff --git a/sys/netinet6/ip6_etherip.c b/sys/netinet6/ip6_etherip.c
index a06d301..60d85ba 100644
--- a/sys/netinet6/ip6_etherip.c
+++ b/sys/netinet6/ip6_etherip.c
@@ -264,7 +264,7 @@ ip6_etherip_input(struct mbuf **mp, int *offp, int proto)
 	ifp->if_ipackets++;
 
 	s = splnet();
-	(ifp->if_input)(ifp, m);
+	ifp->_if_input(ifp, m);
 	splx(s);
 
 	return IPPROTO_DONE;
diff --git a/sys/rump/net/lib/libshmif/if_shmem.c b/sys/rump/net/lib/libshmif/if_shmem.c
index 01d867e..2af2503 100644
--- a/sys/rump/net/lib/libshmif/if_shmem.c
+++ b/sys/rump/net/lib/libshmif/if_shmem.c
@@ -187,8 +187,9 @@ allocif(int unit, struct shmif_sc **scp)
 	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
 	cv_init(&sc->sc_cv, "shmifcv");
 
-	if_attach(ifp);
+	if_initialize(ifp);
 	ether_ifattach(ifp, enaddr);
+	if_register(ifp);
 
 	aprint_verbose("shmif%d: Ethernet address %s\n",
 	    unit, ether_sprintf(enaddr));
@@ -766,7 +767,7 @@ shmif_rcv(void *arg)
 			ifp->if_ipackets++;
 			KERNEL_LOCK(1, NULL);
 			bpf_mtap(ifp, m);
-			ifp->if_input(ifp, m);
+			if_input(ifp, m);
 			KERNEL_UNLOCK_ONE(NULL);
 			m = NULL;
 		}
diff --git a/sys/rump/net/lib/libvirtif/if_virt.c b/sys/rump/net/lib/libvirtif/if_virt.c
index fd8f34c..d867436 100644
--- a/sys/rump/net/lib/libvirtif/if_virt.c
+++ b/sys/rump/net/lib/libvirtif/if_virt.c
@@ -121,7 +121,8 @@ virtif_clone(struct if_clone *ifc, int num)
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_dlt = DLT_EN10MB;
 
-	if_attach(ifp);
+	if_initialize(ifp);
+	if_register(ifp);
 
 #ifndef RUMP_VIF_LINKSTR
 	/*
@@ -377,7 +378,7 @@ VIF_DELIVERPKT(struct virtif_sc *sc, struct iovec *iov, size_t iovlen)
 		m->m_pkthdr.rcvif = ifp;
 		KERNEL_LOCK(1, NULL);
 		bpf_mtap(ifp, m);
-		ifp->if_input(ifp, m);
+		if_input(ifp, m);
 		KERNEL_UNLOCK_LAST(NULL);
 	} else {
 		m_freem(m);