diff --git a/sys/dev/acpica5/acpi_cpu_pstate.c b/sys/dev/acpica5/acpi_cpu_pstate.c
index 5e436c8..7ba69ad 100644
--- a/sys/dev/acpica5/acpi_cpu_pstate.c
+++ b/sys/dev/acpica5/acpi_cpu_pstate.c
@@ -939,7 +939,7 @@ acpi_pst_check_csr(struct acpi_pst_softc *sc)
 	if (acpi_pst_md == NULL)
 		return 0;
 
-	netmsg_init(&msg.nmsg, &curthread->td_msgport,
+	netmsg_init(&msg.nmsg, NULL, &curthread->td_msgport,
 		    MSGF_MPSAFE | MSGF_PRIORITY,
 		    acpi_pst_check_csr_handler);
 	msg.ctrl = &sc->pst_creg;
@@ -965,7 +965,7 @@ acpi_pst_check_pstates(struct acpi_pst_softc *sc)
 	if (acpi_pst_md == NULL)
 		return 0;
 
-	netmsg_init(&nmsg, &curthread->td_msgport,
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
 		    MSGF_MPSAFE | MSGF_PRIORITY,
 		    acpi_pst_check_pstates_handler);
 
@@ -990,7 +990,7 @@ acpi_pst_init(struct acpi_pst_softc *sc)
 	if (acpi_pst_md == NULL)
 		return 0;
 
-	netmsg_init(&msg.nmsg, &curthread->td_msgport,
+	netmsg_init(&msg.nmsg, NULL, &curthread->td_msgport,
 		    MSGF_MPSAFE | MSGF_PRIORITY, acpi_pst_init_handler);
 	msg.ctrl = &sc->pst_creg;
 	msg.status = &sc->pst_sreg;
@@ -1021,7 +1021,7 @@ acpi_pst_set_pstate(struct acpi_pst_softc *sc, const struct acpi_pstate *pstate)
 			      pstate->st_freq);
 	}
 
-	netmsg_init(&msg.nmsg, &curthread->td_msgport,
+	netmsg_init(&msg.nmsg, NULL, &curthread->td_msgport,
 		    MSGF_MPSAFE | MSGF_PRIORITY,
 		    acpi_pst_set_pstate_handler);
 	msg.nmsg.nm_lmsg.u.ms_resultp = __DECONST(void *, pstate);
@@ -1051,7 +1051,7 @@ acpi_pst_get_pstate(struct acpi_pst_softc *sc)
 	if (acpi_pst_md == NULL)
 		return 0;
 
-	netmsg_init(&msg.nmsg, &curthread->td_msgport,
+	netmsg_init(&msg.nmsg, NULL, &curthread->td_msgport,
 		    MSGF_MPSAFE | MSGF_PRIORITY,
 		    acpi_pst_get_pstate_handler);
 	msg.status = &sc->pst_sreg;
diff --git a/sys/dev/netif/iwl/if_iwl.c b/sys/dev/netif/iwl/if_iwl.c
index 847f9b3..7049c7f 100644
--- a/sys/dev/netif/iwl/if_iwl.c
+++ b/sys/dev/netif/iwl/if_iwl.c
@@ -534,7 +534,7 @@ void
 iwlmsg_init(struct iwlmsg *msg, struct lwkt_port *rport, netisr_fn_t dispatch,
 	    void *sc)
 {
-	netmsg_init(&msg->iwlm_nmsg, rport, 0, dispatch);
+	netmsg_init(&msg->iwlm_nmsg, NULL, rport, 0, dispatch);
 	msg->iwlm_softc = sc;
 }
 
diff --git a/sys/kern/kern_poll.c b/sys/kern/kern_poll.c
index d4371c0..1504b37 100644
--- a/sys/kern/kern_poll.c
+++ b/sys/kern/kern_poll.c
@@ -257,14 +257,14 @@ init_device_poll_pcpu(int cpuid)
 	pctx->poll_cpuid = cpuid;
 	poll_reset_state(pctx);
 
-	netmsg_init(&pctx->poll_netmsg, &netisr_adone_rport, MSGF_MPSAFE,
-		    netisr_poll);
+	netmsg_init(&pctx->poll_netmsg, NULL, &netisr_adone_rport,
+		    MSGF_MPSAFE, netisr_poll);
 #ifdef INVARIANTS
 	pctx->poll_netmsg.nm_lmsg.u.ms_resultp = pctx;
 #endif
 
-	netmsg_init(&pctx->poll_more_netmsg, &netisr_adone_rport, MSGF_MPSAFE,
-		    netisr_pollmore);
+	netmsg_init(&pctx->poll_more_netmsg, NULL, &netisr_adone_rport,
+		    MSGF_MPSAFE, netisr_pollmore);
 #ifdef INVARIANTS
 	pctx->poll_more_netmsg.nm_lmsg.u.ms_resultp = pctx;
 #endif
@@ -341,8 +341,8 @@ sysctl_pollhz(SYSCTL_HANDLER_ARGS)
 	else if (phz > DEVICE_POLLING_FREQ_MAX)
 		phz = DEVICE_POLLING_FREQ_MAX;
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE,
-		    poll_sysctl_pollhz);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_sysctl_pollhz);
 	msg.nm_lmsg.u.ms_result = phz;
 
 	port = cpu_portfn(pctx->poll_cpuid);
@@ -366,8 +366,8 @@ sysctl_polling(SYSCTL_HANDLER_ARGS)
 	if (error || req->newptr == NULL)
 		return error;
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE,
-		    poll_sysctl_polling);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_sysctl_polling);
 	msg.nm_lmsg.u.ms_result = enabled;
 
 	port = cpu_portfn(pctx->poll_cpuid);
@@ -389,8 +389,8 @@ sysctl_regfrac(SYSCTL_HANDLER_ARGS)
 	if (error || req->newptr == NULL)
 		return error;
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE,
-		    poll_sysctl_regfrac);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_sysctl_regfrac);
 	msg.nm_lmsg.u.ms_result = reg_frac;
 
 	port = cpu_portfn(pctx->poll_cpuid);
@@ -416,8 +416,8 @@ sysctl_burstmax(SYSCTL_HANDLER_ARGS)
 	else if (burst_max > MAX_POLL_BURST_MAX)
 		burst_max = MAX_POLL_BURST_MAX;
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE,
-		    poll_sysctl_burstmax);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_sysctl_burstmax);
 	msg.nm_lmsg.u.ms_result = burst_max;
 
 	port = cpu_portfn(pctx->poll_cpuid);
@@ -439,8 +439,8 @@ sysctl_eachburst(SYSCTL_HANDLER_ARGS)
 	if (error || req->newptr == NULL)
 		return error;
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE,
-		    poll_sysctl_eachburst);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_sysctl_eachburst);
 	msg.nm_lmsg.u.ms_result = each_burst;
 
 	port = cpu_portfn(pctx->poll_cpuid);
@@ -766,7 +766,8 @@ ether_pollcpu_register(struct ifnet *ifp, int cpuid)
 		ifp->if_poll(ifp, POLL_REGISTER, 0);
 	ifnet_deserialize_all(ifp);
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE, poll_register);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_register);
 	msg.nm_lmsg.u.ms_resultp = ifp;
 
 	port = cpu_portfn(cpuid);
@@ -859,7 +860,8 @@ ether_poll_deregister(struct ifnet *ifp)
 	ifp->if_poll_cpuid = -1;
 	ifnet_deserialize_all(ifp);
 
-	netmsg_init(&msg, &curthread->td_msgport, MSGF_MPSAFE, poll_deregister);
+	netmsg_init(&msg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, poll_deregister);
 	msg.nm_lmsg.u.ms_resultp = ifp;
 
 	port = cpu_portfn(cpuid);
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index 91ebfae..6351326 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -486,6 +486,9 @@ callout_stop(struct callout *c)
  * Prepare a callout structure for use by callout_reset() and/or 
  * callout_stop().  The MP version of this routine requires that the callback
  * function installed by callout_reset() be MP safe.
+ *
+ * The init functions can be called from any cpu and do not have to be
+ * called from the cpu that the timer will eventually run on.
  */
 void
 callout_init(struct callout *c)
diff --git a/sys/kern/uipc_msg.c b/sys/kern/uipc_msg.c
index c117e38..0340daf 100644
--- a/sys/kern/uipc_msg.c
+++ b/sys/kern/uipc_msg.c
@@ -59,15 +59,12 @@ void
 so_pru_abort(struct socket *so)
 {
 	struct netmsg_pru_abort msg;
-	lwkt_port_t port;
 
 	KKASSERT(so->so_state & SS_ABORTING);
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport,
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
 		    0, netmsg_pru_abort);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort;
-	msg.nm_so = so;
-	(void)lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	(void)lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 }
 
 /*
@@ -80,16 +77,13 @@ void
 so_pru_aborta(struct socket *so)
 {
 	struct netmsg_pru_abort *msg;
-	lwkt_port_t port;
 
 	KKASSERT(so->so_state & SS_ABORTING);
 	msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_WAITOK | M_ZERO);
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT);
-	netmsg_init(&msg->nm_netmsg, &netisr_afree_rport,
+	netmsg_init(&msg->nm_netmsg, so, &netisr_afree_rport,
 		    0, netmsg_pru_abort);
 	msg->nm_prufn = so->so_proto->pr_usrreqs->pru_abort;
-	msg->nm_so = so;
-	lwkt_sendmsg(port, &msg->nm_netmsg.nm_lmsg);
+	lwkt_sendmsg(so->so_port, &msg->nm_netmsg.nm_lmsg);
 }
 
 /*
@@ -113,15 +107,12 @@ so_pru_accept(struct socket *so, struct sockaddr **nam)
 #ifdef notdef
 	int error;
 	struct netmsg_pru_accept msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ACCEPT);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_accept);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_accept);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept;
-	msg.nm_so = so;
 	msg.nm_nam = nam;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 #endif
 }
@@ -131,35 +122,34 @@ so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
 {
 	int error;
 	struct netmsg_pru_attach msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(NULL, NULL, NULL, PRU_ATTACH);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_attach);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_attach);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach;
-	msg.nm_so = so;
 	msg.nm_proto = proto;
 	msg.nm_ai = ai;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
+/*
+ * NOTE: If the target port changes the bind operation will deal with it.
+ */
 int
 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
 	int error;
 	struct netmsg_pru_bind msg;
-	lwkt_port_t port;
 
-	/* Send mesg to thread for new address. */
-	port = so->so_proto->pr_mport(NULL, nam, NULL, PRU_BIND);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_bind);
+#if 0
+	port = so->so_proto->pr_mport(NULL, nam, NULL);
+#endif
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_bind);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind;
-	msg.nm_so = so;
 	msg.nm_nam = nam;
 	msg.nm_td = td;		/* used only for prison_ip() XXX JH */
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -168,16 +158,13 @@ so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
 	int error;
 	struct netmsg_pru_connect msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, nam, NULL, PRU_CONNECT);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_connect);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_connect);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect;
-	msg.nm_so = so;
 	msg.nm_nam = nam;
 	msg.nm_td = td;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -186,38 +173,33 @@ so_pru_connect2(struct socket *so1, struct socket *so2)
 {
 	int error;
 	struct netmsg_pru_connect2 msg;
-	lwkt_port_t port;
 
-	port = so1->so_proto->pr_mport(so1, NULL, NULL, PRU_CONNECT2);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_connect2);
+	netmsg_init(&msg.nm_netmsg, so1, &curthread->td_msgport,
+		    0, netmsg_pru_connect2);
 	msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2;
 	msg.nm_so1 = so1;
 	msg.nm_so2 = so2;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so1->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
 int
 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
 {
-	return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp,
-	    curthread));
+	return ((*so->so_proto->pr_usrreqs->pru_control)(
+			so, cmd, data, ifp, curthread));
 #ifdef gag	/* does copyin and copyout deep inside stack XXX JH */
 	int error;
 	struct netmsg_pru_control msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CONTROL);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_control);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_control);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control;
-	msg.nm_so = so;
 	msg.nm_cmd = cmd;
 	msg.nm_data = data;
 	msg.nm_ifp = ifp;
 	msg.nm_td = td;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 #endif
 }
@@ -227,14 +209,11 @@ so_pru_detach(struct socket *so)
 {
 	int error;
 	struct netmsg_pru_detach msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DETACH);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_detach);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_detach);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach;
-	msg.nm_so = so;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -243,14 +222,11 @@ so_pru_disconnect(struct socket *so)
 {
 	int error;
 	struct netmsg_pru_disconnect msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DISCONNECT);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_disconnect);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_disconnect);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect;
-	msg.nm_so = so;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -259,15 +235,12 @@ so_pru_listen(struct socket *so, struct thread *td)
 {
 	int error;
 	struct netmsg_pru_listen msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_LISTEN);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_listen);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_listen);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen;
-	msg.nm_so = so;
 	msg.nm_td = td;		/* used only for prison_ip() XXX JH */
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -276,15 +249,12 @@ so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
 {
 	int error;
 	struct netmsg_pru_peeraddr msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_PEERADDR);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_peeraddr);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_peeraddr);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr;
-	msg.nm_so = so;
 	msg.nm_nam = nam;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -293,15 +263,12 @@ so_pru_rcvd(struct socket *so, int flags)
 {
 	int error;
 	struct netmsg_pru_rcvd msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVD);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_rcvd);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_rcvd);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd;
-	msg.nm_so = so;
 	msg.nm_flags = flags;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -310,37 +277,38 @@ so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
 {
 	int error;
 	struct netmsg_pru_rcvoob msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVOOB);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_rcvoob);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_rcvoob);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob;
-	msg.nm_so = so;
 	msg.nm_m = m;
 	msg.nm_flags = flags;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
+/*
+ * NOTE: so_pru_send() is the only code which uses pr_mport() now.
+ *
+ * NOTE: If the target port changes the implied connect will deal with it.
+ */
 int
-so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
-    struct mbuf *control, struct thread *td)
+so_pru_send(struct socket *so, int flags, struct mbuf *m,
+	    struct sockaddr *addr, struct mbuf *control, struct thread *td)
 {
 	int error;
 	struct netmsg_pru_send msg;
 	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, addr, &m, PRU_SEND);
+	port = so->so_proto->pr_mport(so, addr, &m);
 	if (port == NULL) {
 		KKASSERT(m == NULL);
 		return EINVAL;
 	}
 
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_send);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_send);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send;
-	msg.nm_so = so;
 	msg.nm_flags = flags;
 	msg.nm_m = m;
 	msg.nm_addr = addr;
@@ -358,15 +326,12 @@ so_pru_sense(struct socket *so, struct stat *sb)
 {
 	int error;
 	struct netmsg_pru_sense msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SENSE);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_sense);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_sense);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense;
-	msg.nm_so = so;
 	msg.nm_stat = sb;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -375,14 +340,11 @@ so_pru_shutdown(struct socket *so)
 {
 	int error;
 	struct netmsg_pru_shutdown msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SHUTDOWN);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_shutdown);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_shutdown);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown;
-	msg.nm_so = so;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -391,15 +353,12 @@ so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
 {
 	int error;
 	struct netmsg_pru_sockaddr msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOCKADDR);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_sockaddr);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_sockaddr);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr;
-	msg.nm_so = so;
 	msg.nm_nam = nam;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -408,17 +367,14 @@ so_pru_sopoll(struct socket *so, int events, struct ucred *cred)
 {
 	int error;
 	struct netmsg_pru_sopoll msg;
-	lwkt_port_t port;
 
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOPOLL);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_sopoll);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_sopoll);
 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll;
-	msg.nm_so = so;
 	msg.nm_events = events;
 	msg.nm_cred = cred;
 	msg.nm_td = curthread;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -426,18 +382,15 @@ int
 so_pru_ctloutput(struct socket *so, struct sockopt *sopt)
 {
 	struct netmsg_pru_ctloutput msg;
-	lwkt_port_t port;
 	int error;
 
 	KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
-	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CTLOUTPUT);
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_ctloutput);
+	netmsg_init(&msg.nm_netmsg, so, &curthread->td_msgport,
+		    0, netmsg_pru_ctloutput);
 	/* TBD: move pr_ctloutput to pr_usrreqs */
 	msg.nm_prufn = so->so_proto->pr_ctloutput;
-	msg.nm_so = so;
 	msg.nm_sopt = sopt;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, 0);
 	return (error);
 }
 
@@ -463,8 +416,8 @@ so_pru_ctlinput(struct protosw *pr, int cmd, struct sockaddr *arg, void *extra)
 	port = pr->pr_ctlport(cmd, arg, extra);
 	if (port == NULL)
 		return;
-	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-		    netmsg_pru_ctlinput);
+	netmsg_init(&msg.nm_netmsg, NULL, &curthread->td_msgport,
+		    0, netmsg_pru_ctlinput);
 	msg.nm_prufn = pr->pr_ctlinput;
 	msg.nm_cmd = cmd;
 	msg.nm_arg = arg;
@@ -486,7 +439,7 @@ void
 netmsg_pru_abort(netmsg_t msg)
 {
 	struct netmsg_pru_abort *nm = (void *)msg;
-	struct socket *so = nm->nm_so;
+	struct socket *so = msg->nm_so;
 	int error;
 
 	KKASSERT(so->so_state & SS_ABORTING);
@@ -503,7 +456,7 @@ netmsg_pru_accept(netmsg_t msg)
 {
 	struct netmsg_pru_accept *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_nam));
 }
 #endif
 
@@ -513,7 +466,7 @@ netmsg_pru_attach(netmsg_t msg)
 	struct netmsg_pru_attach *nm = (void *)msg;
 
 	lwkt_replymsg(&msg->nm_lmsg,
-		      nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai));
+		      nm->nm_prufn(msg->nm_so, nm->nm_proto, nm->nm_ai));
 }
 
 void
@@ -522,7 +475,7 @@ netmsg_pru_bind(netmsg_t msg)
 	struct netmsg_pru_bind *nm = (void *)msg;
 
 	lwkt_replymsg(&msg->nm_lmsg,
-		      nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td));
+		      nm->nm_prufn(msg->nm_so, nm->nm_nam, nm->nm_td));
 }
 
 void
@@ -531,7 +484,7 @@ netmsg_pru_connect(netmsg_t msg)
 	struct netmsg_pru_connect *nm = (void *)msg;
 
 	lwkt_replymsg(&msg->nm_lmsg,
-		      nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td));
+		      nm->nm_prufn(msg->nm_so, nm->nm_nam, nm->nm_td));
 }
 
 void
@@ -548,7 +501,7 @@ netmsg_pru_control(netmsg_t msg)
 	struct netmsg_pru_control *nm = (void *)msg;
 	int error;
 
-	error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
+	error = nm->nm_prufn(msg->nm_so, nm->nm_cmd, nm->nm_data,
 				nm->nm_ifp, nm->nm_td);
 	lwkt_replymsg(&msg->nm_lmsg, error);
 }
@@ -558,7 +511,7 @@ netmsg_pru_detach(netmsg_t msg)
 {
 	struct netmsg_pru_detach *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so));
 }
 
 void
@@ -566,7 +519,7 @@ netmsg_pru_disconnect(netmsg_t msg)
 {
 	struct netmsg_pru_disconnect *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so));
 }
 
 void
@@ -574,7 +527,7 @@ netmsg_pru_listen(netmsg_t msg)
 {
 	struct netmsg_pru_listen *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_td));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_td));
 }
 
 void
@@ -582,7 +535,7 @@ netmsg_pru_peeraddr(netmsg_t msg)
 {
 	struct netmsg_pru_peeraddr *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_nam));
 }
 
 void
@@ -590,7 +543,7 @@ netmsg_pru_rcvd(netmsg_t msg)
 {
 	struct netmsg_pru_rcvd *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_flags));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_flags));
 }
 
 void
@@ -599,7 +552,7 @@ netmsg_pru_rcvoob(netmsg_t msg)
 	struct netmsg_pru_rcvoob *nm = (void *)msg;
 
 	lwkt_replymsg(&msg->nm_lmsg,
-		      nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags));
+		      nm->nm_prufn(msg->nm_so, nm->nm_m, nm->nm_flags));
 }
 
 void
@@ -608,7 +561,7 @@ netmsg_pru_send(netmsg_t msg)
 	struct netmsg_pru_send *nm = (void *)msg;
 	int error;
 
-	error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
+	error = nm->nm_prufn(msg->nm_so, nm->nm_flags, nm->nm_m,
 				nm->nm_addr, nm->nm_control, nm->nm_td);
 	lwkt_replymsg(&msg->nm_lmsg, error);
 }
@@ -618,7 +571,7 @@ netmsg_pru_sense(netmsg_t msg)
 {
 	struct netmsg_pru_sense *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_stat));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_stat));
 }
 
 void
@@ -626,7 +579,7 @@ netmsg_pru_shutdown(netmsg_t msg)
 {
 	struct netmsg_pru_shutdown *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so));
 }
 
 void
@@ -634,7 +587,7 @@ netmsg_pru_sockaddr(netmsg_t msg)
 {
 	struct netmsg_pru_sockaddr *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_nam));
 }
 
 void
@@ -643,7 +596,7 @@ netmsg_pru_sopoll(netmsg_t msg)
 	struct netmsg_pru_sopoll *nm = (void *)msg;
 	int error;
 
-	error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td);
+	error = nm->nm_prufn(msg->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td);
 	lwkt_replymsg(&msg->nm_lmsg, error);
 }
 
@@ -652,7 +605,7 @@ netmsg_pru_ctloutput(netmsg_t msg)
 {
 	struct netmsg_pru_ctloutput *nm = (void *)msg;
 
-	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_sopt));
+	lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(msg->nm_so, nm->nm_sopt));
 }
 
 void
@@ -718,8 +671,8 @@ netmsg_so_notify_doabort(lwkt_msg_t lmsg)
 	struct netmsg_so_notify_abort msg;
 
 	if ((lmsg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) {
-		netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-			    netmsg_so_notify_abort);
+		netmsg_init(&msg.nm_netmsg, NULL, &curthread->td_msgport,
+			    0, netmsg_so_notify_abort);
 		msg.nm_notifymsg = (void *)lmsg;
 		lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg, 0);
 	}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 3f91b79..900172e 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -189,6 +189,14 @@ socreate(int dom, struct socket **aso, int type,
 	if (so == 0)
 		return (ENOBUFS);
 
+	/*
+	 * Set a default port for protocol processing.  No action will occur
+	 * on the socket on this port until an inpcb is attached to it and
+	 * is able to match incoming packets, or until the socket becomes
+	 * available to userland.
+	 */
+	so->so_port = cpu0_soport(so, NULL, NULL);
+
 	TAILQ_INIT(&so->so_incomp);
 	TAILQ_INIT(&so->so_comp);
 	so->so_type = type;
@@ -197,6 +205,7 @@ socreate(int dom, struct socket **aso, int type,
 	ai.sb_rlimit = &p->p_rlimit[RLIMIT_SBSIZE];
 	ai.p_ucred = p->p_ucred;
 	ai.fd_rdir = p->p_fd->fd_rdir;
+
 	/*
 	 * Auto-sizing of socket buffers is managed by the protocols and
 	 * the appropriate flags must be set in the pru_attach function.
@@ -207,6 +216,7 @@ socreate(int dom, struct socket **aso, int type,
 		sofree(so);
 		return (error);
 	}
+
 	*aso = so;
 	return (0);
 }
@@ -530,6 +540,7 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
 		resid = uio->uio_resid;
 	else
 		resid = (size_t)top->m_pkthdr.len;
+
 	/*
 	 * WARNING!  resid is unsigned, space and len are signed.  space
 	 * 	     can wind up negative if the sockbuf is overcommitted.
@@ -555,6 +566,7 @@ restart:
 	error = ssb_lock(&so->so_snd, SBLOCKWAIT(flags));
 	if (error)
 		goto out;
+
 	do {
 		crit_enter();
 		if (so->so_state & SS_CANTSENDMORE)
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index c2020b2..c0918a3 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -218,6 +218,17 @@ soisdisconnected(struct socket *so)
 }
 
 /*
+ * Set or change the message port a socket receives commands on.
+ *
+ * XXX
+ */
+void
+sosetport(struct socket *so, lwkt_port_t port)
+{
+	so->so_port = port;
+}
+
+/*
  * When an attempt at a new connection is noted on a socket
  * which accepts connections, sonewconn is called.  If the
  * connection is possible (subject to space constraints, etc.)
@@ -255,6 +266,7 @@ sonewconn(struct socket *head, int connstatus)
 		sodealloc(so);
 		return (NULL);
 	}
+	KKASSERT(so->so_port != NULL);
 	so->so_rcv.ssb_lowat = head->so_rcv.ssb_lowat;
 	so->so_snd.ssb_lowat = head->so_snd.ssb_lowat;
 	so->so_rcv.ssb_timeo = head->so_rcv.ssb_timeo;
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 295b00c..c53f728 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -255,7 +255,6 @@ kern_accept(int s, int fflags, struct sockaddr **name, int *namelen, int *res)
 	struct sockaddr *sa;
 	struct socket *head, *so;
 	struct netmsg_so_notify msg;
-	lwkt_port_t port;
 	int fd;
 	u_int fflag;		/* type must match fp->f_flag */
 	int error, tmp;
@@ -287,16 +286,13 @@ kern_accept(int s, int fflags, struct sockaddr **name, int *namelen, int *res)
 		fflags = lfp->f_flag;
 
 	/* optimize for uniprocessor case later XXX JH */
-	port = head->so_proto->pr_mport(head, NULL, NULL, PRU_PRED);
-	netmsg_init_abortable(&msg.nm_netmsg, &curthread->td_msgport,
-			      0,
-			      netmsg_so_notify,
-			      netmsg_so_notify_doabort);
+	netmsg_init_abortable(&msg.nm_netmsg, head, &curthread->td_msgport,
+			      0, netmsg_so_notify, netmsg_so_notify_doabort);
 	msg.nm_predicate = soaccept_predicate;
 	msg.nm_fflags = fflags;
 	msg.nm_so = head;
 	msg.nm_etype = NM_REVENT;
-	error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, PCATCH);
+	error = lwkt_domsg(head->so_port, &msg.nm_netmsg.nm_lmsg, PCATCH);
 	if (error)
 		goto done;
 
@@ -483,10 +479,8 @@ kern_connect(int s, int fflags, struct sockaddr *sa)
 	}
 	if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
 		struct netmsg_so_notify msg;
-		lwkt_port_t port;
 
-		port = so->so_proto->pr_mport(so, sa, NULL, PRU_PRED);
-		netmsg_init_abortable(&msg.nm_netmsg, 
+		netmsg_init_abortable(&msg.nm_netmsg, so,
 				      &curthread->td_msgport,
 				      0,
 				      netmsg_so_notify,
@@ -494,7 +488,7 @@ kern_connect(int s, int fflags, struct sockaddr *sa)
 		msg.nm_predicate = soconnected_predicate;
 		msg.nm_so = so;
 		msg.nm_etype = NM_REVENT;
-		error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, PCATCH);
+		error = lwkt_domsg(so->so_port, &msg.nm_netmsg.nm_lmsg, PCATCH);
 		if (error == EINTR || error == ERESTART)
 			interrupted = 1;
 	}
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 45479a7..9170df4 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -583,6 +583,7 @@ unp_attach(struct socket *so, struct pru_attach_info *ai)
 	LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
 			 : &unp_shead, unp, unp_link);
 	so->so_pcb = (caddr_t)unp;
+	so->so_port = sync_soport(so, NULL, NULL);
 	return (0);
 }
 
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index b85999b..2924a28 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -576,8 +576,8 @@ bpfwrite(struct dev_write_args *ap)
 	if (d->bd_hdrcmplt)
 		dst.sa_family = pseudo_AF_HDRCMPLT;
 
-	netmsg_init(&bmsg.nm_netmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    bpf_output_dispatch);
+	netmsg_init(&bmsg.nm_netmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, bpf_output_dispatch);
 	bmsg.nm_mbuf = m;
 	bmsg.nm_ifp = ifp;
 	bmsg.nm_dst = &dst;
diff --git a/sys/net/bridge/if_bridge.c b/sys/net/bridge/if_bridge.c
index b677715..6cd2fa1 100644
--- a/sys/net/bridge/if_bridge.c
+++ b/sys/net/bridge/if_bridge.c
@@ -653,12 +653,12 @@ bridge_clone_create(struct if_clone *ifc, int unit)
 	bridge_rtable_init(sc);
 
 	callout_init(&sc->sc_brcallout);
-	netmsg_init(&sc->sc_brtimemsg, &netisr_adone_rport,
+	netmsg_init(&sc->sc_brtimemsg, NULL, &netisr_adone_rport,
 		    MSGF_DROPABLE, bridge_timer_handler);
 	sc->sc_brtimemsg.nm_lmsg.u.ms_resultp = sc;
 
 	callout_init(&sc->sc_bstpcallout);
-	netmsg_init(&sc->sc_bstptimemsg, &netisr_adone_rport,
+	netmsg_init(&sc->sc_bstptimemsg, NULL, &netisr_adone_rport,
 		    MSGF_DROPABLE, bstp_tick_handler);
 	sc->sc_bstptimemsg.nm_lmsg.u.ms_resultp = sc;
 
@@ -746,7 +746,8 @@ bridge_clone_destroy(struct ifnet *ifp)
 
 	ifnet_deserialize_all(ifp);
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, bridge_delete_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_delete_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = sc;
 	lwkt_domsg(BRIDGE_CFGPORT, lmsg, 0);
@@ -1782,7 +1783,8 @@ bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
 	struct lwkt_msg *lmsg;
 	struct netmsg nmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, bridge_ifdetach_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_ifdetach_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = ifp;
 
@@ -1823,8 +1825,8 @@ bridge_enqueue(struct ifnet *dst_ifp, struct mbuf *m)
 	struct netmsg_packet *nmp;
 
 	nmp = &m->m_hdr.mh_netmsg;
-	netmsg_init(&nmp->nm_netmsg, &netisr_apanic_rport, 0,
-		    bridge_enqueue_handler);
+	netmsg_init(&nmp->nm_netmsg, NULL, &netisr_apanic_rport,
+		    0, bridge_enqueue_handler);
 	nmp->nm_packet = m;
 	nmp->nm_netmsg.nm_lmsg.u.ms_resultp = dst_ifp;
 
@@ -2516,8 +2518,8 @@ bridge_rtmsg_sync(struct bridge_softc *sc)
 
 	ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0,
-		    bridge_rtmsg_sync_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_rtmsg_sync_handler);
 	ifnet_domsg(&nmsg.nm_lmsg, 0);
 }
 
@@ -2640,8 +2642,8 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
 		if (brmsg == NULL)
 			return ENOMEM;
 
-		netmsg_init(&brmsg->br_nmsg, &netisr_afree_rport, 0,
-			    bridge_rtinstall_handler);
+		netmsg_init(&brmsg->br_nmsg, NULL, &netisr_afree_rport,
+			    0, bridge_rtinstall_handler);
 		memcpy(brmsg->br_dst, dst, ETHER_ADDR_LEN);
 		brmsg->br_dst_if = dst_if;
 		brmsg->br_flags = flags;
@@ -2665,8 +2667,8 @@ bridge_rtsaddr(struct bridge_softc *sc, const uint8_t *dst,
 
 	ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
 
-	netmsg_init(&brmsg.br_nmsg, &curthread->td_msgport, 0,
-		    bridge_rtinstall_handler);
+	netmsg_init(&brmsg.br_nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_rtinstall_handler);
 	memcpy(brmsg.br_dst, dst, ETHER_ADDR_LEN);
 	brmsg.br_dst_if = dst_if;
 	brmsg.br_flags = flags;
@@ -2712,7 +2714,8 @@ bridge_rtreap(struct bridge_softc *sc)
 
 	ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, bridge_rtreap_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_rtreap_handler);
 	nmsg.nm_lmsg.u.ms_resultp = sc;
 
 	ifnet_domsg(&nmsg.nm_lmsg, 0);
@@ -2725,7 +2728,8 @@ bridge_rtreap_async(struct bridge_softc *sc)
 
 	nmsg = kmalloc(sizeof(*nmsg), M_LWKTMSG, M_WAITOK);
 
-	netmsg_init(nmsg, &netisr_afree_rport, 0, bridge_rtreap_handler);
+	netmsg_init(nmsg, NULL, &netisr_afree_rport,
+		    0, bridge_rtreap_handler);
 	nmsg->nm_lmsg.u.ms_resultp = sc;
 
 	ifnet_sendmsg(&nmsg->nm_lmsg, 0);
@@ -3692,7 +3696,8 @@ bridge_control(struct bridge_softc *sc, u_long cmd,
 	bzero(&bc_msg, sizeof(bc_msg));
 	nmsg = &bc_msg.bc_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, bridge_control_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_control_dispatch);
 	bc_msg.bc_func = bc_func;
 	bc_msg.bc_sc = sc;
 	bc_msg.bc_arg = bc_arg;
@@ -3731,8 +3736,8 @@ bridge_add_bif(struct bridge_softc *sc, struct bridge_ifinfo *bif_info,
 
 	ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
 
-	netmsg_init(&amsg.br_nmsg, &curthread->td_msgport, 0,
-		    bridge_add_bif_handler);
+	netmsg_init(&amsg.br_nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_add_bif_handler);
 	amsg.br_softc = sc;
 	amsg.br_bif_info = bif_info;
 	amsg.br_bif_ifp = ifp;
@@ -3774,8 +3779,8 @@ bridge_del_bif(struct bridge_softc *sc, struct bridge_ifinfo *bif_info,
 
 	ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
 
-	netmsg_init(&dmsg.br_nmsg, &curthread->td_msgport, 0,
-		    bridge_del_bif_handler);
+	netmsg_init(&dmsg.br_nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_del_bif_handler);
 	dmsg.br_softc = sc;
 	dmsg.br_bif_info = bif_info;
 	dmsg.br_bif_list = saved_bifs;
@@ -3812,8 +3817,8 @@ bridge_set_bifflags(struct bridge_softc *sc, struct bridge_ifinfo *bif_info,
 
 	ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
 
-	netmsg_init(&smsg.br_nmsg, &curthread->td_msgport, 0,
-		    bridge_set_bifflags_handler);
+	netmsg_init(&smsg.br_nmsg, NULL, &curthread->td_msgport,
+		    0, bridge_set_bifflags_handler);
 	smsg.br_softc = sc;
 	smsg.br_bif_info = bif_info;
 	smsg.br_bif_flags = bif_flags;
diff --git a/sys/net/dummynet/ip_dummynet.c b/sys/net/dummynet/ip_dummynet.c
index 9e80e76..86df63d 100644
--- a/sys/net/dummynet/ip_dummynet.c
+++ b/sys/net/dummynet/ip_dummynet.c
@@ -1939,7 +1939,8 @@ ip_dn_init_dispatch(struct netmsg *msg)
     ip_dn_ctl_ptr = dummynet_ctl;
     ip_dn_io_ptr = dummynet_io;
 
-    netmsg_init(&dn_netmsg, &netisr_adone_rport, 0, dummynet);
+    netmsg_init(&dn_netmsg, NULL, &netisr_adone_rport,
+		0, dummynet);
     systimer_init_periodic_nq(&dn_clock, dummynet_clock, NULL, dn_hz);
 
 back:
@@ -1958,7 +1959,8 @@ ip_dn_init(void)
 	ip_dn_cpu = 0;
     }
 
-    netmsg_init(&smsg, &curthread->td_msgport, 0, ip_dn_init_dispatch);
+    netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		0, ip_dn_init_dispatch);
     lwkt_domsg(cpu_portfn(ip_dn_cpu), &smsg.nm_lmsg, 0);
     return smsg.nm_lmsg.ms_error;
 }
@@ -1987,7 +1989,8 @@ ip_dn_stop(void)
 {
     struct netmsg smsg;
 
-    netmsg_init(&smsg, &curthread->td_msgport, 0, ip_dn_stop_dispatch);
+    netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		0, ip_dn_stop_dispatch);
     lwkt_domsg(cpu_portfn(ip_dn_cpu), &smsg.nm_lmsg, 0);
 
     netmsg_service_sync();
diff --git a/sys/net/dummynet/ip_dummynet_glue.c b/sys/net/dummynet/ip_dummynet_glue.c
index a2cdd6a..214ae09 100644
--- a/sys/net/dummynet/ip_dummynet_glue.c
+++ b/sys/net/dummynet/ip_dummynet_glue.c
@@ -90,8 +90,8 @@ ip_dn_queue(struct mbuf *m)
 		("mbuf is not tagged for dummynet!\n"));
 
 	nmp = &m->m_hdr.mh_netmsg;
-	netmsg_init(&nmp->nm_netmsg, &netisr_apanic_rport, 0,
-		    ip_dn_dispatch);
+	netmsg_init(&nmp->nm_netmsg, NULL, &netisr_apanic_rport,
+		    0, ip_dn_dispatch);
 	nmp->nm_packet = m;
 
 	port = cpu_portfn(ip_dn_cpu);
@@ -109,8 +109,8 @@ ip_dn_packet_free(struct dn_pkt *pkt)
 		("mbuf is not tagged for dummynet!\n"));
 
 	nmp = &m->m_hdr.mh_netmsg;
-	netmsg_init(&nmp->nm_netmsg, &netisr_apanic_rport, 0,
-		    ip_dn_freepkt_dispatch);
+	netmsg_init(&nmp->nm_netmsg, NULL, &netisr_apanic_rport,
+		    0, ip_dn_freepkt_dispatch);
 	nmp->nm_packet = m;
 
 	lwkt_sendmsg(pkt->msgport, &nmp->nm_netmsg.nm_lmsg);
@@ -145,7 +145,8 @@ ip_dn_packet_redispatch(struct dn_pkt *pkt)
 		("mbuf is not tagged for dummynet!\n"));
 
 	nmp = &m->m_hdr.mh_netmsg;
-	netmsg_init(&nmp->nm_netmsg, &netisr_apanic_rport, 0, dispatch);
+	netmsg_init(&nmp->nm_netmsg, NULL, &netisr_apanic_rport,
+		    0, dispatch);
 	nmp->nm_packet = m;
 
 	lwkt_sendmsg(pkt->msgport, &nmp->nm_netmsg.nm_lmsg);
@@ -468,7 +469,8 @@ ip_dn_sockopt_flush(struct sockopt *sopt)
 	bzero(&dn_sopt, sizeof(dn_sopt));
 	dn_sopt.dn_sopt_name = sopt->sopt_name;
 
-	netmsg_init(&smsg, &curthread->td_msgport, 0, ip_dn_sockopt_dispatch);
+	netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		    0, ip_dn_sockopt_dispatch);
 	smsg.nm_lmsg.u.ms_resultp = &dn_sopt;
 	lwkt_domsg(cpu_portfn(ip_dn_cpu), &smsg.nm_lmsg, 0);
 
@@ -485,7 +487,8 @@ ip_dn_sockopt_get(struct sockopt *sopt)
 	bzero(&dn_sopt, sizeof(dn_sopt));
 	dn_sopt.dn_sopt_name = sopt->sopt_name;
 
-	netmsg_init(&smsg, &curthread->td_msgport, 0, ip_dn_sockopt_dispatch);
+	netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		    0, ip_dn_sockopt_dispatch);
 	smsg.nm_lmsg.u.ms_resultp = &dn_sopt;
 	lwkt_domsg(cpu_portfn(ip_dn_cpu), &smsg.nm_lmsg, 0);
 
@@ -519,7 +522,8 @@ ip_dn_sockopt_config(struct sockopt *sopt)
 	dn_sopt.dn_sopt_arg = &tmp_ioc_pipe;
 	dn_sopt.dn_sopt_arglen = sizeof(tmp_ioc_pipe);
 
-	netmsg_init(&smsg, &curthread->td_msgport, 0, ip_dn_sockopt_dispatch);
+	netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		    0, ip_dn_sockopt_dispatch);
 	smsg.nm_lmsg.u.ms_resultp = &dn_sopt;
 	lwkt_domsg(cpu_portfn(ip_dn_cpu), &smsg.nm_lmsg, 0);
 
diff --git a/sys/net/if.c b/sys/net/if.c
index 34c8ab7..fbda1cc 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -514,8 +514,8 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer)
 	ifp->if_start_nmsg = kmalloc(ncpus * sizeof(struct netmsg),
 				     M_LWKTMSG, M_WAITOK);
 	for (i = 0; i < ncpus; ++i) {
-		netmsg_init(&ifp->if_start_nmsg[i], &netisr_adone_rport, 0,
-			    if_start_dispatch);
+		netmsg_init(&ifp->if_start_nmsg[i], NULL, &netisr_adone_rport,
+			    0, if_start_dispatch);
 		ifp->if_start_nmsg[i].nm_lmsg.u.ms_resultp = ifp;
 	}
 
@@ -2324,8 +2324,8 @@ ifa_iflink(struct ifaddr *ifa, struct ifnet *ifp, int tail)
 {
 	struct netmsg_ifaddr msg;
 
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
-		    ifa_iflink_dispatch);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, ifa_iflink_dispatch);
 	msg.ifa = ifa;
 	msg.ifp = ifp;
 	msg.tail = tail;
@@ -2362,8 +2362,8 @@ ifa_ifunlink(struct ifaddr *ifa, struct ifnet *ifp)
 {
 	struct netmsg_ifaddr msg;
 
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
-		    ifa_ifunlink_dispatch);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, ifa_ifunlink_dispatch);
 	msg.ifa = ifa;
 	msg.ifp = ifp;
 
@@ -2384,8 +2384,8 @@ ifa_destroy(struct ifaddr *ifa)
 {
 	struct netmsg_ifaddr msg;
 
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
-		    ifa_destroy_dispatch);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, ifa_destroy_dispatch);
 	msg.ifa = ifa;
 
 	ifa_domsg(&msg.netmsg.nm_lmsg, 0);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index e06242f..c26e452 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1536,8 +1536,8 @@ ether_init_netpacket(int num, struct mbuf *m)
 	struct netmsg_packet *pmsg;
 
 	pmsg = &m->m_hdr.mh_netmsg;
-	netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, MSGF_MPSAFE,
-		    ether_input_handler);
+	netmsg_init(&pmsg->nm_netmsg, NULL, &netisr_apanic_rport,
+		    MSGF_MPSAFE, ether_input_handler);
 	pmsg->nm_packet = m;
 	pmsg->nm_netmsg.nm_lmsg.u.ms_result = num;
 }
diff --git a/sys/net/if_poll.c b/sys/net/if_poll.c
index e56689d..817ee75 100644
--- a/sys/net/if_poll.c
+++ b/sys/net/if_poll.c
@@ -374,8 +374,8 @@ ifpoll_register(struct ifnet *ifp)
 
 	ifnet_deserialize_all(ifp);
 
-	netmsg_init(&nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    ifpoll_register_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, ifpoll_register_handler);
 	nmsg.nm_lmsg.u.ms_resultp = &info;
 
 	error = ifnet_domsg(&nmsg.nm_lmsg, 0);
@@ -407,8 +407,8 @@ ifpoll_deregister(struct ifnet *ifp)
 
 	ifnet_deserialize_all(ifp);
 
-	netmsg_init(&nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    ifpoll_deregister_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, ifpoll_deregister_handler);
 	nmsg.nm_lmsg.u.ms_resultp = ifp;
 
 	error = ifnet_domsg(&nmsg.nm_lmsg, 0);
@@ -503,8 +503,8 @@ stpoll_init(void)
 			&st_ctx->poll_handlers, 0,
 			"Number of registered status poll handlers");
 
-	netmsg_init(&st_ctx->poll_netmsg, &netisr_adone_rport, MSGF_MPSAFE,
-		    stpoll_handler);
+	netmsg_init(&st_ctx->poll_netmsg, NULL, &netisr_adone_rport,
+		    MSGF_MPSAFE, stpoll_handler);
 }
 
 /*
@@ -690,12 +690,12 @@ iopoll_ctx_create(int cpuid, int poll_type)
 	io_ctx->poll_cpuid = cpuid;
 	iopoll_reset_state(io_ctx);
 
-	netmsg_init(&io_ctx->poll_netmsg, &netisr_adone_rport, MSGF_MPSAFE,
-		    iopoll_handler);
+	netmsg_init(&io_ctx->poll_netmsg, NULL, &netisr_adone_rport,
+		    MSGF_MPSAFE, iopoll_handler);
 	io_ctx->poll_netmsg.nm_lmsg.u.ms_resultp = io_ctx;
 
-	netmsg_init(&io_ctx->poll_more_netmsg, &netisr_adone_rport, MSGF_MPSAFE,
-		    iopollmore_handler);
+	netmsg_init(&io_ctx->poll_more_netmsg, NULL, &netisr_adone_rport,
+		    MSGF_MPSAFE, iopollmore_handler);
 	io_ctx->poll_more_netmsg.nm_lmsg.u.ms_resultp = io_ctx;
 
 	/*
@@ -1005,8 +1005,8 @@ sysctl_burstmax(SYSCTL_HANDLER_ARGS)
 		burst_max = MAX_IOPOLL_BURST_MAX;
 
 	nmsg = &msg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    sysctl_burstmax_handler);
+	netmsg_init(nmsg, &curthread->td_msgport, NULL,
+		    MSGF_MPSAFE, sysctl_burstmax_handler);
 	nmsg->nm_lmsg.u.ms_result = burst_max;
 	msg.ctx = io_ctx;
 
@@ -1048,8 +1048,8 @@ sysctl_eachburst(SYSCTL_HANDLER_ARGS)
 		return error;
 
 	nmsg = &msg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    sysctl_eachburst_handler);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, sysctl_eachburst_handler);
 	nmsg->nm_lmsg.u.ms_result = each_burst;
 	msg.ctx = io_ctx;
 
@@ -1269,8 +1269,8 @@ sysctl_pollhz(SYSCTL_HANDLER_ARGS)
 	else if (phz > IFPOLL_FREQ_MAX)
 		phz = IFPOLL_FREQ_MAX;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    sysctl_pollhz_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, sysctl_pollhz_handler);
 	nmsg.nm_lmsg.u.ms_result = phz;
 
 	return ifnet_domsg(&nmsg.nm_lmsg, comm->poll_cpuid);
@@ -1319,8 +1319,8 @@ sysctl_stfrac(SYSCTL_HANDLER_ARGS)
 	if (stfrac < 0)
 		return EINVAL;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    sysctl_stfrac_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, sysctl_stfrac_handler);
 	nmsg.nm_lmsg.u.ms_result = stfrac;
 
 	return ifnet_domsg(&nmsg.nm_lmsg, comm->poll_cpuid);
@@ -1357,8 +1357,8 @@ sysctl_txfrac(SYSCTL_HANDLER_ARGS)
 	if (txfrac < 0)
 		return EINVAL;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, MSGF_MPSAFE,
-		    sysctl_txfrac_handler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    MSGF_MPSAFE, sysctl_txfrac_handler);
 	nmsg.nm_lmsg.u.ms_result = txfrac;
 
 	return ifnet_domsg(&nmsg.nm_lmsg, comm->poll_cpuid);
diff --git a/sys/net/ipfw/ip_fw2.c b/sys/net/ipfw/ip_fw2.c
index b2816c7..6210748 100644
--- a/sys/net/ipfw/ip_fw2.c
+++ b/sys/net/ipfw/ip_fw2.c
@@ -2728,7 +2728,8 @@ ipfw_add_rule(struct ipfw_ioc_rule *ioc_rule, uint32_t rule_flags)
 	 */
 	bzero(&fwmsg, sizeof(fwmsg));
 	nmsg = &fwmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0, ipfw_add_rule_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_add_rule_dispatch);
 	fwmsg.ioc_rule = ioc_rule;
 	fwmsg.prev_rule = prev;
 	fwmsg.next_rule = prev == NULL ? NULL : f;
@@ -2746,8 +2747,8 @@ ipfw_add_rule(struct ipfw_ioc_rule *ioc_rule, uint32_t rule_flags)
 		 * CPUs have been setup.
 		 */
 		bzero(nmsg, sizeof(*nmsg));
-		netmsg_init(nmsg, &curthread->td_msgport, 0,
-			    ipfw_enable_state_dispatch);
+		netmsg_init(nmsg, NULL, &curthread->td_msgport,
+			    0, ipfw_enable_state_dispatch);
 		nmsg->nm_lmsg.u.ms_resultp = rule;
 
 		ifnet_domsg(&nmsg->nm_lmsg, 0);
@@ -2896,8 +2897,8 @@ ipfw_flush(int kill_default)
 	 * will be created.
 	 */
 	bzero(&dmsg, sizeof(dmsg));
-	netmsg_init(&dmsg.nmsg, &curthread->td_msgport, 0,
-		    ipfw_disable_rule_state_dispatch);
+	netmsg_init(&dmsg.nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_disable_rule_state_dispatch);
 	ifnet_domsg(&dmsg.nmsg.nm_lmsg, 0);
 
 	/*
@@ -2921,7 +2922,8 @@ ipfw_flush(int kill_default)
 	 * Press the 'flush' button
 	 */
 	bzero(&nmsg, sizeof(nmsg));
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, ipfw_flush_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_flush_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_result = kill_default;
 	ifnet_domsg(lmsg, 0);
@@ -3025,8 +3027,8 @@ ipfw_alt_delete_rule(uint16_t rulenum)
 		 */
 		bzero(&dmsg, sizeof(dmsg));
 		nmsg = &dmsg.nmsg;
-		netmsg_init(nmsg, &curthread->td_msgport, 0,
-			    ipfw_disable_rule_state_dispatch);
+		netmsg_init(nmsg, NULL, &curthread->td_msgport,
+			    0, ipfw_disable_rule_state_dispatch);
 		dmsg.start_rule = rule;
 		dmsg.rulenum = rulenum;
 
@@ -3056,8 +3058,8 @@ ipfw_alt_delete_rule(uint16_t rulenum)
 	 */
 	bzero(&dmsg, sizeof(dmsg));
 	nmsg = &dmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0,
-		    ipfw_alt_delete_rule_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_alt_delete_rule_dispatch);
 	dmsg.prev_rule = prev;
 	dmsg.start_rule = rule;
 	dmsg.rulenum = rulenum;
@@ -3157,8 +3159,8 @@ ipfw_alt_delete_ruleset(uint8_t set)
 		 */
 		bzero(&dmsg, sizeof(dmsg));
 		nmsg = &dmsg.nmsg;
-		netmsg_init(nmsg, &curthread->td_msgport, 0,
-			    ipfw_disable_ruleset_state_dispatch);
+		netmsg_init(nmsg, NULL, &curthread->td_msgport,
+			    0, ipfw_disable_ruleset_state_dispatch);
 		dmsg.from_set = set;
 
 		ifnet_domsg(&nmsg->nm_lmsg, 0);
@@ -3189,8 +3191,8 @@ ipfw_alt_delete_ruleset(uint8_t set)
 	 */
 	bzero(&dmsg, sizeof(dmsg));
 	nmsg = &dmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0,
-		    ipfw_alt_delete_ruleset_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_alt_delete_ruleset_dispatch);
 	dmsg.from_set = set;
 
 	ifnet_domsg(&nmsg->nm_lmsg, 0);
@@ -3241,8 +3243,8 @@ ipfw_alt_move_rule(uint16_t rulenum, uint8_t set)
 
 	bzero(&dmsg, sizeof(dmsg));
 	nmsg = &dmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0,
-		    ipfw_alt_move_rule_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_alt_move_rule_dispatch);
 	dmsg.start_rule = rule;
 	dmsg.rulenum = rulenum;
 	dmsg.to_set = set;
@@ -3274,8 +3276,8 @@ ipfw_alt_move_ruleset(uint8_t from_set, uint8_t to_set)
 
 	bzero(&dmsg, sizeof(dmsg));
 	nmsg = &dmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0,
-		    ipfw_alt_move_ruleset_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_alt_move_ruleset_dispatch);
 	dmsg.from_set = from_set;
 	dmsg.to_set = to_set;
 
@@ -3307,8 +3309,8 @@ ipfw_alt_swap_ruleset(uint8_t set1, uint8_t set2)
 
 	bzero(&dmsg, sizeof(dmsg));
 	nmsg = &dmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0,
-		    ipfw_alt_swap_ruleset_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_alt_swap_ruleset_dispatch);
 	dmsg.from_set = set1;
 	dmsg.to_set = set2;
 
@@ -3443,7 +3445,8 @@ ipfw_ctl_zero_entry(int rulenum, int log_only)
 
 	bzero(&zmsg, sizeof(zmsg));
 	nmsg = &zmsg.nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0, ipfw_zero_entry_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_zero_entry_dispatch);
 	zmsg.log_only = log_only;
 
 	if (rulenum == 0) {
@@ -3890,7 +3893,8 @@ ipfw_ctl_set_disable(uint32_t disable, uint32_t enable)
 	set_disable = (ipfw_ctx[mycpuid]->ipfw_set_disable | disable) & ~enable;
 
 	bzero(&nmsg, sizeof(nmsg));
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, ipfw_set_disable_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_set_disable_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_result32 = set_disable;
 
@@ -4293,8 +4297,8 @@ ipfw_sysctl_enable(SYSCTL_HANDLER_ARGS)
 	if (error || req->newptr == NULL)
 		return error;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0,
-		    ipfw_sysctl_enable_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_sysctl_enable_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_result = enable;
 
@@ -4405,8 +4409,8 @@ ipfw_init_dispatch(struct netmsg *nmsg)
 	}
 
 	bzero(&fwmsg, sizeof(fwmsg));
-	netmsg_init(&fwmsg.nmsg, &curthread->td_msgport, 0,
-		    ipfw_ctx_init_dispatch);
+	netmsg_init(&fwmsg.nmsg, NULL, &curthread->td_msgport,
+		    0, ipfw_ctx_init_dispatch);
 	ifnet_domsg(&fwmsg.nmsg.nm_lmsg, 0);
 
 	ip_fw_chk_ptr = ipfw_chk;
@@ -4433,7 +4437,7 @@ ipfw_init_dispatch(struct netmsg *nmsg)
 	}
 
 	callout_init_mp(&ipfw_timeout_h);
-	netmsg_init(&ipfw_timeout_netmsg, &netisr_adone_rport,
+	netmsg_init(&ipfw_timeout_netmsg, NULL, &netisr_adone_rport,
 		    MSGF_MPSAFE | MSGF_DROPABLE | MSGF_PRIORITY,
 		    ipfw_tick_dispatch);
 	lockinit(&dyn_lock, "ipfw_dyn", 0, 0);
@@ -4452,7 +4456,8 @@ ipfw_init(void)
 {
 	struct netmsg smsg;
 
-	netmsg_init(&smsg, &curthread->td_msgport, 0, ipfw_init_dispatch);
+	netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		    0, ipfw_init_dispatch);
 	return lwkt_domsg(IPFW_CFGPORT, &smsg.nm_lmsg, 0);
 }
 
@@ -4503,7 +4508,8 @@ ipfw_fini(void)
 {
 	struct netmsg smsg;
 
-	netmsg_init(&smsg, &curthread->td_msgport, 0, ipfw_fini_dispatch);
+	netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		    0, ipfw_fini_dispatch);
 	return lwkt_domsg(IPFW_CFGPORT, &smsg.nm_lmsg, 0);
 }
 
diff --git a/sys/net/ipfw/ip_fw2_glue.c b/sys/net/ipfw/ip_fw2_glue.c
index ca7d88f..3a1c947 100644
--- a/sys/net/ipfw/ip_fw2_glue.c
+++ b/sys/net/ipfw/ip_fw2_glue.c
@@ -68,7 +68,8 @@ ip_fw_sockopt(struct sockopt *sopt)
 			return EPERM;
 	}
 
-	netmsg_init(&smsg, &curthread->td_msgport, 0, ip_fw_sockopt_dispatch);
+	netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		    0, ip_fw_sockopt_dispatch);
 	smsg.nm_lmsg.u.ms_resultp = sopt;
 	return lwkt_domsg(IPFW_CFGPORT, &smsg.nm_lmsg, 0);
 }
diff --git a/sys/net/netisr.c b/sys/net/netisr.c
index c35c371..2a3d620 100644
--- a/sys/net/netisr.c
+++ b/sys/net/netisr.c
@@ -47,6 +47,7 @@
 #include <sys/interrupt.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
+#include <sys/socketvar.h>
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/netisr.h>
@@ -243,7 +244,8 @@ netmsg_service_sync(void)
     struct netmsg_port_registration *reg;
     struct netmsg smsg;
 
-    netmsg_init(&smsg, &curthread->td_msgport, MSGF_MPSAFE, netmsg_sync_func);
+    netmsg_init(&smsg, NULL, &curthread->td_msgport,
+		MSGF_MPSAFE, netmsg_sync_func);
 
     TAILQ_FOREACH(reg, &netreglist, npr_entry) {
 	lwkt_domsg(reg->npr_port, &smsg.nm_lmsg, 0);
@@ -261,12 +263,33 @@ netmsg_sync_func(struct netmsg *msg)
 }
 
 /*
- * Return current BGL lock state (1:locked, 0: unlocked)
+ * Service a netmsg request and modify the BGL lock state if appropriate.
+ * The new BGL lock state is returned (1:locked, 0:unlocked).
  */
 int
 netmsg_service(struct netmsg *msg, int mpsafe_mode, int mplocked)
 {
     /*
+     * If nm_so is non-NULL the message is related to a socket.  Sockets
+     * can migrate between protocol processing threads when they connect,
+     * due to an implied connect during a sendmsg(), or when a connection
+     * is accepted.
+     *
+     * If this occurs any messages already queued to the original thread
+     * or which race the change must be forwarded to the new protocol
+     * processing port.
+     *
+     * MPSAFE - socket changes are synchronous to the current protocol port
+     * 		so if the port can only change out from under us if it is
+     *		already different from the current port anyway so we forward
+     *		it.  It is possible to chase a changing port, which is fine.
+     */
+    if (msg->nm_so && msg->nm_so->so_port != &curthread->td_msgport) {
+	lwkt_forwardmsg(msg->nm_so->so_port, &msg->nm_lmsg);
+	return(mplocked);
+    }
+
+    /*
      * Adjust the mplock dynamically.
      */
     switch (mpsafe_mode) {
@@ -372,8 +395,8 @@ netisr_queue(int num, struct mbuf *m)
 
     pmsg = &m->m_hdr.mh_netmsg;
 
-    netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, NETISR_TO_MSGF(ni),
-    		ni->ni_handler);
+    netmsg_init(&pmsg->nm_netmsg, NULL, &netisr_apanic_rport,
+		NETISR_TO_MSGF(ni), ni->ni_handler);
     pmsg->nm_packet = m;
     pmsg->nm_netmsg.nm_lmsg.u.ms_result = num;
     lwkt_sendmsg(port, &pmsg->nm_netmsg.nm_lmsg);
@@ -395,7 +418,8 @@ netisr_register(int num, pkt_portfn_t mportfn,
     ni->ni_mport_pktinfo = mportfn_pktinfo;
     ni->ni_handler = handler;
     ni->ni_flags = flags;
-    netmsg_init(&ni->ni_netmsg, &netisr_adone_rport, NETISR_TO_MSGF(ni), NULL);
+    netmsg_init(&ni->ni_netmsg, NULL, &netisr_adone_rport,
+		NETISR_TO_MSGF(ni), NULL);
 }
 
 int
@@ -445,7 +469,7 @@ cur_netport(void)
 /* ARGSUSED */
 lwkt_port_t
 cpu0_soport(struct socket *so __unused, struct sockaddr *nam __unused,
-	    struct mbuf **dummy __unused, int req __unused)
+	    struct mbuf **dummy __unused)
 {
     return (&netisr_cpu[0].td_msgport);
 }
@@ -459,7 +483,7 @@ cpu0_ctlport(int cmd __unused, struct sockaddr *sa __unused,
 
 lwkt_port_t
 sync_soport(struct socket *so __unused, struct sockaddr *nam __unused,
-	    struct mbuf **dummy __unused, int req __unused)
+	    struct mbuf **dummy __unused)
 {
     return (&netisr_sync_port);
 }
@@ -487,8 +511,8 @@ schednetisr_remote(void *data)
     pmsg = &netisrs[num].ni_netmsg;
     crit_enter();
     if (pmsg->nm_lmsg.ms_flags & MSGF_DONE) {
-	netmsg_init(pmsg, &netisr_adone_rport, NETISR_TO_MSGF(ni),
-		    ni->ni_handler);
+	netmsg_init(pmsg, NULL, &netisr_adone_rport,
+		    NETISR_TO_MSGF(ni), ni->ni_handler);
 	pmsg->nm_lmsg.u.ms_result = num;
 	lwkt_sendmsg(port, &pmsg->nm_lmsg);
     }
@@ -556,7 +580,8 @@ netisr_run(int num, struct mbuf *m)
 
     pmsg = &m->m_hdr.mh_netmsg;
 
-    netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, 0, ni->ni_handler);
+    netmsg_init(&pmsg->nm_netmsg, NULL, &netisr_apanic_rport,
+		0, ni->ni_handler);
     pmsg->nm_packet = m;
     pmsg->nm_netmsg.nm_lmsg.u.ms_result = num;
 
diff --git a/sys/net/netmsg.h b/sys/net/netmsg.h
index 5b5d497..da0c5c2 100644
--- a/sys/net/netmsg.h
+++ b/sys/net/netmsg.h
@@ -50,6 +50,7 @@ typedef void (*netisr_fn_t)(struct netmsg *);
 typedef struct netmsg {
     struct lwkt_msg     nm_lmsg;
     netisr_fn_t		nm_dispatch;
+    struct socket	*nm_so;
 } *netmsg_t;
 
 #define MSGF_MPSAFE	MSGF_USER0
@@ -62,20 +63,17 @@ typedef struct netmsg {
 struct netmsg_pru_abort {
     struct netmsg	nm_netmsg;
     pru_abort_fn_t	nm_prufn;
-    struct socket	*nm_so;
 };
 
 struct netmsg_pru_accept {
     struct netmsg	nm_netmsg;
     pru_accept_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockaddr	**nm_nam;
 };
 
 struct netmsg_pru_attach {
     struct netmsg	nm_netmsg;
     pru_attach_fn_t	nm_prufn;
-    struct socket	*nm_so;
     int			nm_proto;
     struct pru_attach_info *nm_ai;
 };
@@ -83,7 +81,6 @@ struct netmsg_pru_attach {
 struct netmsg_pru_bind {
     struct netmsg	nm_netmsg;
     pru_bind_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockaddr	*nm_nam;
     struct thread	*nm_td;
 };
@@ -91,7 +88,6 @@ struct netmsg_pru_bind {
 struct netmsg_pru_connect {
     struct netmsg	nm_netmsg;
     pru_connect_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockaddr	*nm_nam;
     struct thread	*nm_td;
 };
@@ -106,7 +102,6 @@ struct netmsg_pru_connect2 {
 struct netmsg_pru_control {
     struct netmsg	nm_netmsg;
     pru_control_fn_t	nm_prufn;
-    struct socket	*nm_so;
     u_long		nm_cmd;
     caddr_t		nm_data;
     struct ifnet	*nm_ifp;
@@ -116,40 +111,34 @@ struct netmsg_pru_control {
 struct netmsg_pru_detach {
     struct netmsg	nm_netmsg;
     pru_detach_fn_t	nm_prufn;
-    struct socket	*nm_so;
 };
 
 struct netmsg_pru_disconnect {
     struct netmsg	nm_netmsg;
     pru_disconnect_fn_t	nm_prufn;
-    struct socket	*nm_so;
 };
 
 struct netmsg_pru_listen {
     struct netmsg	nm_netmsg;
     pru_listen_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct thread	*nm_td;
 };
 
 struct netmsg_pru_peeraddr {
     struct netmsg	nm_netmsg;
     pru_peeraddr_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockaddr	**nm_nam;
 };
 
 struct netmsg_pru_rcvd {
     struct netmsg	nm_netmsg;
     pru_rcvd_fn_t	nm_prufn;
-    struct socket	*nm_so;
     int			nm_flags;
 };
 
 struct netmsg_pru_rcvoob {
     struct netmsg	nm_netmsg;
     pru_rcvoob_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct mbuf		*nm_m;
     int			nm_flags;
 };
@@ -157,7 +146,6 @@ struct netmsg_pru_rcvoob {
 struct netmsg_pru_send {
     struct netmsg	nm_netmsg;
     pru_send_fn_t	nm_prufn;
-    struct socket	*nm_so;
     int			nm_flags;
     struct mbuf		*nm_m;
     struct sockaddr	*nm_addr;
@@ -168,27 +156,23 @@ struct netmsg_pru_send {
 struct netmsg_pru_sense {
     struct netmsg	nm_netmsg;
     pru_sense_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct stat		*nm_stat;
 };
 
 struct netmsg_pru_shutdown {
     struct netmsg	nm_netmsg;
     pru_shutdown_fn_t	nm_prufn;
-    struct socket	*nm_so;
 };
 
 struct netmsg_pru_sockaddr {
     struct netmsg	nm_netmsg;
     pru_sockaddr_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockaddr	**nm_nam;
 };
 
 struct netmsg_pru_sosend {
     struct netmsg	nm_netmsg;
     pru_sosend_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockaddr	*nm_addr;
     struct uio		*nm_uio;
     struct mbuf		*nm_top;
@@ -200,7 +184,6 @@ struct netmsg_pru_sosend {
 struct netmsg_pru_soreceive {
     struct netmsg	nm_netmsg;
     struct sockaddr	*nm_addr;
-    struct socket	*nm_so;
     struct sockaddr	**nm_paddr;
     struct uio		*nm_uio;
     struct sockbuf	*nm_sio;
@@ -211,7 +194,6 @@ struct netmsg_pru_soreceive {
 struct netmsg_pru_sopoll {
     struct netmsg	nm_netmsg;
     pru_sopoll_fn_t	nm_prufn;
-    struct socket	*nm_so;
     int			nm_events;
     struct ucred	*nm_cred;
     struct thread	*nm_td;
@@ -220,7 +202,6 @@ struct netmsg_pru_sopoll {
 struct netmsg_pru_ctloutput {
     struct netmsg	nm_netmsg;
     pru_ctloutput_fn_t	nm_prufn;
-    struct socket	*nm_so;
     struct sockopt	*nm_sopt;
 };
 
diff --git a/sys/net/netmsg2.h b/sys/net/netmsg2.h
index 24b815e..b55e9bb 100644
--- a/sys/net/netmsg2.h
+++ b/sys/net/netmsg2.h
@@ -43,21 +43,25 @@
 
 /*
  * Extended lwkt_initmsg() for netmsg's, also initializing the
- * dispatch function
+ * dispatch function.
  */
 static __inline void
-netmsg_init(netmsg_t msg, lwkt_port_t rport, int flags, netisr_fn_t dispatch)
+netmsg_init(netmsg_t msg, struct socket *so, lwkt_port_t rport,
+	    int flags, netisr_fn_t dispatch)
 {
     lwkt_initmsg(&msg->nm_lmsg, rport, flags);
     msg->nm_dispatch = dispatch;
+    msg->nm_so = so;
 }
 
 static __inline void
-netmsg_init_abortable(netmsg_t msg, lwkt_port_t rport, int flags,
-		      netisr_fn_t dispatch, void (*abortfn)(lwkt_msg_t))
+netmsg_init_abortable(netmsg_t msg, struct socket *so, lwkt_port_t rport,
+		      int flags, netisr_fn_t dispatch,
+		      void (*abortfn)(lwkt_msg_t))
 {
     lwkt_initmsg_abortable(&msg->nm_lmsg, rport, flags, abortfn);
     msg->nm_dispatch = dispatch;
+    msg->nm_so = so;
 }
 
 #endif /* _NET_NETMSG2_H_ */
diff --git a/sys/net/pf/pf.c b/sys/net/pf/pf.c
index e09622b..4afc291 100644
--- a/sys/net/pf/pf.c
+++ b/sys/net/pf/pf.c
@@ -2241,8 +2241,8 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
 		 */
 		if (pi_cpu != mycpu->gd_cpuid) {
 			msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_INTWAIT);
-			netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 0,
-				    in_pcblookup_hash_handler);
+			netmsg_init(&msg->nm_netmsg, NULL, &netisr_afree_rport,
+				    0, in_pcblookup_hash_handler);
 			msg->nm_pinp = &inp;
 			msg->nm_pcbinfo = pi;
 			msg->nm_saddr = saddr;
diff --git a/sys/net/pfil.c b/sys/net/pfil.c
index 8f9b4a3..6278664 100644
--- a/sys/net/pfil.c
+++ b/sys/net/pfil.c
@@ -269,7 +269,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
 	struct netmsg *nmsg;
 
 	nmsg = &pfilmsg.pfil_nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0, pfil_add_hook_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, pfil_add_hook_dispatch);
 	pfilmsg.pfil_func = func;
 	pfilmsg.pfil_arg = arg;
 	pfilmsg.pfil_flags = flags;
@@ -370,7 +371,8 @@ pfil_remove_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
 	struct netmsg *nmsg;
 
 	nmsg = &pfilmsg.pfil_nmsg;
-	netmsg_init(nmsg, &curthread->td_msgport, 0, pfil_remove_hook_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, pfil_remove_hook_dispatch);
 	pfilmsg.pfil_func = func;
 	pfilmsg.pfil_arg = arg;
 	pfilmsg.pfil_flags = flags;
diff --git a/sys/net/route.c b/sys/net/route.c
index b014dfb..74958b5 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -179,7 +179,8 @@ rtable_init(void)
 {
 	struct netmsg nmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, rtable_init_oncpu);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, rtable_init_oncpu);
 	ifnet_domsg(&nmsg.nm_lmsg, 0);
 }
 
@@ -386,7 +387,8 @@ rtfree_remote(struct rtentry *rt, int allow_panic)
 		print_backtrace();
 	}
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, rtfree_remote_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, rtfree_remote_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = rt;
 
@@ -524,8 +526,8 @@ rtredirect(struct sockaddr *dst, struct sockaddr *gateway,
 #ifdef SMP
 	struct netmsg_rtredirect msg;
 
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
-		    rtredirect_msghandler);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, rtredirect_msghandler);
 	msg.dst = dst;
 	msg.gateway = gateway;
 	msg.netmask = netmask;
@@ -744,8 +746,8 @@ rtrequest1_global(int req, struct rt_addrinfo *rtinfo,
 #ifdef SMP
 	struct netmsg_rtq msg;
 
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
-		    rtrequest1_msghandler);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, rtrequest1_msghandler);
 	msg.netmsg.nm_lmsg.ms_error = -1;
 	msg.req = req;
 	msg.rtinfo = rtinfo;
@@ -1660,8 +1662,8 @@ rtsearch_global(int req, struct rt_addrinfo *rtinfo,
 {
 	struct netmsg_rts msg;
 
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
-		    rtsearch_msghandler);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, rtsearch_msghandler);
 	msg.req = req;
 	msg.rtinfo = rtinfo;
 	msg.callback = callback;
@@ -1773,8 +1775,8 @@ rtmask_add_global(struct sockaddr *mask)
 {
 	struct netmsg nmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0,
-		    rtmask_add_msghandler);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, rtmask_add_msghandler);
 	nmsg.nm_lmsg.u.ms_resultp = mask;
 
 	return lwkt_domsg(rtable_portfn(0), &nmsg.nm_lmsg, 0);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index e437e09..b2011c4 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -374,9 +374,9 @@ rts_input_skip(struct mbuf *m, sa_family_t family, struct rawcb *skip)
 
 	M_ASSERTPKTHDR(m);
 
-	port = cpu0_soport(NULL, NULL, NULL, 0);
+	port = cpu0_soport(NULL, NULL, NULL); /* same as for routing socket */
 	pmsg = &m->m_hdr.mh_netmsg;
-	netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, 
+	netmsg_init(&pmsg->nm_netmsg, NULL, &netisr_apanic_rport, 
 		    0, rts_input_handler);
 	pmsg->nm_packet = m;
 	pmsg->nm_netmsg.nm_lmsg.u.ms_result = family;
diff --git a/sys/net/vlan/if_vlan.c b/sys/net/vlan/if_vlan.c
index 9cd0bcd..6355d88 100644
--- a/sys/net/vlan/if_vlan.c
+++ b/sys/net/vlan/if_vlan.c
@@ -373,7 +373,8 @@ vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_ifdetach_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_ifdetach_dispatch);
 	vmsg.nv_ifp_p = ifp;
 
 	lwkt_domsg(cpu_portfn(0), &nmsg->nm_lmsg, 0);
@@ -497,7 +498,8 @@ vlan_start(struct ifnet *ifp)
 		nmp = &m->m_hdr.mh_netmsg;
 		nmsg = &nmp->nm_netmsg;
 
-		netmsg_init(nmsg, &netisr_apanic_rport, 0, vlan_start_dispatch);
+		netmsg_init(nmsg, NULL, &netisr_apanic_rport,
+			    0, vlan_start_dispatch);
 		nmp->nm_packet = m;
 		nmsg->nm_lmsg.u.ms_resultp = ifp_p;
 
@@ -604,7 +606,8 @@ vlan_link(struct ifvlan *ifv, struct ifnet *ifp_p)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_link_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_link_dispatch);
 	vmsg.nv_ifv = ifv;
 	vmsg.nv_ifp_p = ifp_p;
 
@@ -713,7 +716,8 @@ vlan_config(struct ifvlan *ifv, const char *parent_name, uint16_t vlantag)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_config_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_config_dispatch);
 	vmsg.nv_ifv = ifv;
 	vmsg.nv_parent_name = parent_name;
 	vmsg.nv_vlantag = vlantag;
@@ -756,7 +760,8 @@ vlan_unlink(struct ifvlan *ifv, struct ifnet *ifp_p)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_unlink_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_unlink_dispatch);
 	vmsg.nv_ifv = ifv;
 	vmsg.nv_ifp_p = ifp_p;
 
@@ -855,7 +860,8 @@ vlan_unconfig(struct ifvlan *ifv)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_unconfig_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_unconfig_dispatch);
 	vmsg.nv_ifv = ifv;
 
 	return lwkt_domsg(cpu_portfn(0), &nmsg->nm_lmsg, 0);
@@ -998,7 +1004,8 @@ vlan_config_multi(struct ifvlan *ifv)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_multi_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_multi_dispatch);
 	vmsg.nv_ifv = ifv;
 
 	return lwkt_domsg(cpu_portfn(0), &nmsg->nm_lmsg, 0);
@@ -1031,7 +1038,8 @@ vlan_config_flags(struct ifvlan *ifv)
 	bzero(&vmsg, sizeof(vmsg));
 	nmsg = &vmsg.nv_nmsg;
 
-	netmsg_init(nmsg, &curthread->td_msgport, 0, vlan_flags_dispatch);
+	netmsg_init(nmsg, NULL, &curthread->td_msgport,
+		    0, vlan_flags_dispatch);
 	vmsg.nv_ifv = ifv;
 
 	return lwkt_domsg(cpu_portfn(0), &nmsg->nm_lmsg, 0);
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index d922ce9..5667b9b 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -430,8 +430,8 @@ arprequest_async(struct ifnet *ifp, const struct in_addr *sip,
 		return;
 
 	pmsg = &m->m_hdr.mh_netmsg;
-	netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, 0,
-		    arpreq_send_handler);
+	netmsg_init(&pmsg->nm_netmsg, NULL, &netisr_apanic_rport,
+		    0, arpreq_send_handler);
 	pmsg->nm_packet = m;
 	pmsg->nm_netmsg.nm_lmsg.u.ms_resultp = ifp;
 
@@ -744,7 +744,8 @@ arp_update_oncpu(struct mbuf *m, in_addr_t saddr, boolean_t create,
 			rt->rt_refcnt++;
 
 			pmsg = &m->m_hdr.mh_netmsg;
-			netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport,
+			netmsg_init(&pmsg->nm_netmsg, NULL,
+				    &netisr_apanic_rport,
 				    MSGF_MPSAFE | MSGF_PRIORITY,
 				    arp_hold_output);
 			pmsg->nm_packet = m;
@@ -908,8 +909,8 @@ match:
 	if (ifp->if_flags & IFF_STATICARP)
 		goto reply;
 #ifdef SMP
-	netmsg_init(&msg.netmsg, &curthread->td_msgport, 0, 
-		    arp_update_msghandler);
+	netmsg_init(&msg.netmsg, NULL, &curthread->td_msgport,
+		    0, arp_update_msghandler);
 	msg.m = m;
 	msg.saddr = isaddr.s_addr;
 	msg.create = (itaddr.s_addr == myaddr.s_addr);
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 43d265a..6a9a764 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -260,8 +260,8 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
 		arg.ifp = ifp;
 		arg.td = td;
 
-		netmsg_init(&nmsg, &curthread->td_msgport, 0,
-			    in_control_dispatch);
+		netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+			    0, in_control_dispatch);
 		msg = &nmsg.nm_lmsg;
 		msg->u.ms_resultp = &arg;
 
@@ -379,7 +379,8 @@ in_ialink(struct in_ifaddr *ia)
 	struct netmsg nmsg;
 	struct lwkt_msg *lmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, in_ialink_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, in_ialink_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = ia;
 
@@ -392,7 +393,8 @@ in_iaunlink(struct in_ifaddr *ia)
 	struct netmsg nmsg;
 	struct lwkt_msg *lmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, in_iaunlink_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, in_iaunlink_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = ia;
 
@@ -405,7 +407,8 @@ in_iahash_insert(struct in_ifaddr *ia)
 	struct netmsg nmsg;
 	struct lwkt_msg *lmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, in_iahashins_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, in_iahashins_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = ia;
 
@@ -418,7 +421,8 @@ in_iahash_remove(struct in_ifaddr *ia)
 	struct netmsg nmsg;
 	struct lwkt_msg *lmsg;
 
-	netmsg_init(&nmsg, &curthread->td_msgport, 0, in_iahashrem_dispatch);
+	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
+		    0, in_iahashrem_dispatch);
 	lmsg = &nmsg.nm_lmsg;
 	lmsg->u.ms_resultp = ia;
 
diff --git a/sys/netinet/ip_demux.c b/sys/netinet/ip_demux.c
index 767aa7c..046ebba 100644
--- a/sys/netinet/ip_demux.c
+++ b/sys/netinet/ip_demux.c
@@ -385,35 +385,25 @@ ip_mport_pktinfo(const struct pktinfo *pi, struct mbuf *m)
 }
 
 /*
- * Map a TCP socket to a protocol processing thread.
+ * Initital port when creating the socket, generally before
+ * binding or connect.
  */
 lwkt_port_t
-tcp_soport(struct socket *so, struct sockaddr *nam __unused,
-	   struct mbuf **dummy __unused, int req)
+tcp_soport_attach(struct socket *so)
 {
-	struct inpcb *inp;
-
-	/* The following processing all take place on Protocol Thread 0. */
-	if (req == PRU_BIND || req == PRU_CONNECT || req == PRU_ATTACH ||
-	    req == PRU_LISTEN)
-		return (&tcp_thread[0].td_msgport);
-
-	inp = so->so_pcb;
-	if (!inp)		/* connection reset by peer */
-		return (&tcp_thread[0].td_msgport);
+	return(&tcp_thread[0].td_msgport);
+}
 
-	/*
-	 * Already bound and connected or listening.  For TCP connections,
-	 * the (faddr, fport, laddr, lport) association cannot change now.
-	 *
-	 * Note: T/TCP code needs some reorganization to fit into
-	 * this model.  XXX JH
-	 *
-	 * Rely on type-stable memory and check in protocol handler
-	 * to fix race condition here w/ deallocation of inp.  XXX JH
-	 */
-	return (&tcp_thread[INP_MPORT_HASH_TCP(inp->inp_faddr.s_addr,
-	    inp->inp_laddr.s_addr, inp->inp_fport, inp->inp_lport)].td_msgport);
+/*
+ * This is used to map a socket to a message port for sendmsg() and friends.
+ * It is not called for any other purpose.  In the case of TCP we just return
+ * the port already installed in the socket.
+ */
+lwkt_port_t
+tcp_soport(struct socket *so, struct sockaddr *nam,
+	   struct mbuf **dummy __unused)
+{
+	return(so->so_port);
 }
 
 /*
@@ -468,38 +458,35 @@ tcp_addrport0(void)
 	return (&tcp_thread[0].td_msgport);
 }
 
+lwkt_port_t
+udp_addrport(in_addr_t faddr, in_port_t fport, in_addr_t laddr, in_port_t lport)
+{
+	return (&udp_thread[udp_addrcpu(faddr, fport,
+					laddr, lport)].td_msgport);
+}
+
 /*
- * Map a UDP socket to a protocol processing thread.
+ * Initital port when creating the socket, generally before
+ * binding or connect.
  */
 lwkt_port_t
-udp_soport(struct socket *so, struct sockaddr *nam __unused,
-	   struct mbuf **dummy __unused, int req)
+udp_soport_attach(struct socket *so)
 {
-	struct inpcb *inp;
-
-	/*
-	 * The following processing all take place on Protocol Thread 0:
-	 *   bind()
-	 *   attach() has a null socket parameter
-	 *   Fast and slow timeouts pass in null socket parameter
-	 */
-	if (req == PRU_BIND || so == NULL)
-		return (&udp_thread[0].td_msgport);
-
-	inp = so->so_pcb;
-
-#ifndef RSS
-	if (IN_MULTICAST(ntohl(inp->inp_laddr.s_addr)))
-		return (&udp_thread[0].td_msgport);
-#endif
-
-	/*
-	 * Rely on type-stable memory and check in protocol handler
-	 * to fix race condition here w/ deallocation of inp.  XXX JH
-	 */
+	return(&udp_thread[0].td_msgport);
+}
 
-	return (&udp_thread[INP_MPORT_HASH_UDP(inp->inp_faddr.s_addr,
-	    inp->inp_laddr.s_addr, inp->inp_fport, inp->inp_lport)].td_msgport);
+/*
+ * This is used to map a socket to a message port for sendmsg() and friends.
+ * It is not called for any other purpose.
+ *
+ * In the case of UDP we just return the port already installed in the socket,
+ * regardless of what (nam) is.
+ */
+lwkt_port_t
+udp_soport(struct socket *so, struct sockaddr *nam,
+	   struct mbuf **dummy __unused)
+{
+	return(so->so_port);
 }
 
 /*
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 5b1afc6..5293c27 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -159,17 +159,12 @@ div_input(struct mbuf *m, ...)
 }
 
 struct lwkt_port *
-div_soport(struct socket *so, struct sockaddr *nam,
-	   struct mbuf **mptr, int req)
+div_soport(struct socket *so, struct sockaddr *nam, struct mbuf **mptr)
 {
 	struct sockaddr_in *sin;
 	struct mbuf *m;
 	int dir;
 
-	/* Except for send(), everything happens on CPU0 */
-	if (req != PRU_SEND)
-		return cpu0_soport(so, nam, mptr, req);
-
 	sin = (struct sockaddr_in *)nam;
 	m = *mptr;
 	M_ASSERTPKTHDR(m);
@@ -484,6 +479,7 @@ div_attach(struct socket *so, int proto, struct pru_attach_info *ai)
 	 * The socket is always "connected" because
 	 * we always know "where" to send the packet.
 	 */
+	so->so_port = cpu0_soport(so, NULL, NULL);
 	so->so_state |= SS_ISCONNECTED;
 	return 0;
 }
diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h
index 8d7d231..f029e31 100644
--- a/sys/netinet/ip_divert.h
+++ b/sys/netinet/ip_divert.h
@@ -51,8 +51,7 @@ struct divert_info {
 void	div_init(void);
 void	div_input(struct mbuf *, ...);
 struct lwkt_port *
-	div_soport(struct socket *, struct sockaddr *,
-		   struct mbuf **, int);
+	div_soport(struct socket *, struct sockaddr *, struct mbuf **);
 
 extern struct mbuf *(*ip_divert_p)(struct mbuf *, int, int);
 
diff --git a/sys/netinet/ip_flow.c b/sys/netinet/ip_flow.c
index 1e4ca1e..7603027 100644
--- a/sys/netinet/ip_flow.c
+++ b/sys/netinet/ip_flow.c
@@ -558,8 +558,8 @@ ipflow_ifaddr(void *arg __unused, struct ifnet *ifp __unused,
 		return;
 	}
 
-	netmsg_init(&amsg.ipf_nmsg, &curthread->td_msgport, MSGF_PRIORITY,
-		    ipflow_ifaddr_handler);
+	netmsg_init(&amsg.ipf_nmsg, NULL, &curthread->td_msgport,
+		    MSGF_PRIORITY, ipflow_ifaddr_handler);
 	amsg.ipf_addr = ifatoia(ifa)->ia_addr.sin_addr;
 
 	ifnet_domsg(&amsg.ipf_nmsg.nm_lmsg, 0);
@@ -572,7 +572,7 @@ ipflow_init(void)
 	int i;
 
 	for (i = 0; i < ncpus; ++i) {
-		netmsg_init(&ipflow_timo_netmsgs[i], &netisr_adone_rport,
+		netmsg_init(&ipflow_timo_netmsgs[i], NULL, &netisr_adone_rport,
 			    MSGF_MPSAFE, ipflow_timo_dispatch);
 
 		ksnprintf(oid_name, sizeof(oid_name), "inuse%d", i);
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 4e209fc..fe74292 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -936,8 +936,8 @@ DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
 			return;
 
 		pmsg = &m->m_hdr.mh_netmsg;
-		netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, MSGF_MPSAFE,
-			    transport_processing_handler);
+		netmsg_init(&pmsg->nm_netmsg, NULL, &netisr_apanic_rport,
+			    MSGF_MPSAFE, transport_processing_handler);
 		pmsg->nm_packet = m;
 		pmsg->nm_netmsg.nm_lmsg.u.ms_result = hlen;
 
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 5918407..fa69e31 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1028,8 +1028,8 @@ no_valid_rt:
 		cpu = (inp->inp_pcbinfo->cpu + 1) % ncpus2;
 		msg = kmalloc(sizeof(struct netmsg_remwildcard),
 			      M_LWKTMSG, M_INTWAIT);
-		netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 0,
-			    in_pcbremwildcardhash_handler);
+		netmsg_init(&msg->nm_netmsg, NULL, &netisr_afree_rport,
+			    0, in_pcbremwildcardhash_handler);
 #ifdef INET6
 		msg->nm_isinet6 = isafinet6;
 #endif
@@ -1117,8 +1117,8 @@ tcp_drain(void)
 				    M_LWKTMSG, M_NOWAIT);
 			if (msg == NULL)
 				continue;
-			netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 0,
-				    tcp_drain_handler);
+			netmsg_init(&msg->nm_netmsg, NULL, &netisr_afree_rport,
+				    0, tcp_drain_handler);
 			msg->nm_head = &tcbinfo[cpu].pcblisthead;
 			lwkt_sendmsg(tcp_cport(cpu), &msg->nm_netmsg.nm_lmsg);
 		}
@@ -1454,8 +1454,8 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 		struct netmsg_tcp_notify nmsg;
 
 		KKASSERT(&curthread->td_msgport == cpu_portfn(0));
-		netmsg_init(&nmsg.nm_nmsg, &curthread->td_msgport, 0,
-			    tcp_notifyall_oncpu);
+		netmsg_init(&nmsg.nm_nmsg, NULL, &curthread->td_msgport,
+			    0, tcp_notifyall_oncpu);
 		nmsg.nm_faddr = faddr;
 		nmsg.nm_arg = arg;
 		nmsg.nm_notify = notify;
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 129c991..0f7e77f 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -337,8 +337,8 @@ syncache_init(void)
 			syncache_percpu->mrec[i].msg.nm_mrec =
 			    &syncache_percpu->mrec[i];
 			netmsg_init(&syncache_percpu->mrec[i].msg.nm_netmsg,
-				    &syncache_null_rport, 0,
-				    syncache_timer_handler);
+				    NULL, &syncache_null_rport,
+				    0, syncache_timer_handler);
 		}
 	}
 
@@ -628,6 +628,8 @@ syncache_unreach(struct in_conninfo *inc, struct tcphdr *th)
 
 /*
  * Build a new TCP socket structure from a syncache entry.
+ *
+ * This is called from the context of the SYN+ACK
  */
 static struct socket *
 syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
@@ -635,6 +637,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
 	struct inpcb *inp = NULL, *linp;
 	struct socket *so;
 	struct tcpcb *tp;
+	lwkt_port_t port;
 #ifdef INET6
 	const boolean_t isipv6 = sc->sc_inc.inc_isipv6;
 #else
@@ -657,11 +660,16 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
 		goto abort;
 	}
 
-	inp = so->so_pcb;
+	/*
+	 * Set the protocol processing port for the socket to the current
+	 * port (that the connection came in on).
+	 */
+	sosetport(so, &curthread->td_msgport);
 
 	/*
 	 * Insert new socket into hash list.
 	 */
+	inp = so->so_pcb;
 	inp->inp_inc.inc_isipv6 = sc->sc_inc.inc_isipv6;
 	if (isipv6) {
 		inp->in6p_laddr = sc->sc_inc.inc6_laddr;
@@ -749,6 +757,18 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
 		}
 	}
 
+	/*
+	 * The current port should be in the context of the SYN+ACK and
+	 * so should match the tcp address port.
+	 */
+	if (isipv6) {
+		port = tcp6_addrport();
+	} else {
+		port = tcp_addrport(inp->inp_faddr.s_addr, inp->inp_fport,
+				    inp->inp_laddr.s_addr, inp->inp_lport);
+	}
+	KKASSERT(port == &curthread->td_msgport);
+
 	tp = intotcpcb(inp);
 	tp->t_state = TCPS_SYN_RECEIVED;
 	tp->iss = sc->sc_iss;
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 9dac7fd..ff0d99d 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -700,7 +700,7 @@ tcp_create_timermsg(struct tcpcb *tp, struct lwkt_port *msgport)
 {
 	struct netmsg_tcp_timer *tmsg = tp->tt_msg;
 
-	netmsg_init(&tmsg->tt_nmsg, &netisr_adone_rport,
+	netmsg_init(&tmsg->tt_nmsg, NULL, &netisr_adone_rport,
 		    MSGF_DROPABLE | MSGF_PRIORITY, tcp_timer_handler);
 	tmsg->tt_cpuid = mycpuid;
 	tmsg->tt_msgport = msgport;
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 039d10d..916c2c4 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -133,12 +133,13 @@
 extern	char *tcpstates[];	/* XXX ??? */
 
 static int	tcp_attach (struct socket *, struct pru_attach_info *);
-static int	tcp_connect (struct tcpcb *, struct sockaddr *,
-				struct thread *);
+static int	tcp_connect (struct tcpcb *, int flags, struct mbuf *m,
+				struct sockaddr *, struct thread *);
 #ifdef INET6
-static int	tcp6_connect (struct tcpcb *, struct sockaddr *,
-				struct thread *);
-static int	tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
+static int	tcp6_connect (struct tcpcb *, int flags, struct mbuf *m,
+				struct sockaddr *, struct thread *);
+static int	tcp6_connect_oncpu(struct tcpcb *tp, int flags, struct mbuf *m,
+				struct sockaddr_in6 *sin6,
 				struct in6_addr *addr6);
 #endif /* INET6 */
 static struct tcpcb *
@@ -381,8 +382,8 @@ tcp_usr_listen(struct socket *so, struct thread *td)
 
 		msg = kmalloc(sizeof(struct netmsg_inswildcard), M_LWKTMSG,
 			      M_INTWAIT);
-		netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 0,
-			    in_pcbinswildcardhash_handler);
+		netmsg_init(&msg->nm_netmsg, NULL, &netisr_afree_rport,
+			    0, in_pcbinswildcardhash_handler);
 		msg->nm_inp = inp;
 		msg->nm_pcbinfo = &tcbinfo[cpu];
 		lwkt_sendmsg(tcp_cport(cpu), &msg->nm_netmsg.nm_lmsg);
@@ -430,8 +431,8 @@ tcp6_usr_listen(struct socket *so, struct thread *td)
 
 		msg = kmalloc(sizeof(struct netmsg_inswildcard), M_LWKTMSG,
 			      M_INTWAIT);
-		netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 0,
-			    in_pcbinswildcardhash_handler);
+		netmsg_init(&msg->nm_netmsg, NULL, &netisr_afree_rport,
+			    0, in_pcbinswildcardhash_handler);
 		msg->nm_inp = inp;
 		msg->nm_pcbinfo = &tcbinfo[cpu];
 		lwkt_sendmsg(tcp_cport(cpu), &msg->nm_netmsg.nm_lmsg);
@@ -443,45 +444,6 @@ tcp6_usr_listen(struct socket *so, struct thread *td)
 }
 #endif /* INET6 */
 
-#ifdef SMP
-static void
-tcp_output_dispatch(struct netmsg *nmsg)
-{
-	struct lwkt_msg *msg = &nmsg->nm_lmsg;
-	struct tcpcb *tp = msg->u.ms_resultp;
-	int error;
-
-	error = tcp_output(tp);
-	lwkt_replymsg(msg, error);
-}
-#endif
-
-static int
-tcp_conn_output(struct tcpcb *tp)
-{
-	int error;
-#ifdef SMP
-	struct inpcb *inp = tp->t_inpcb;
-	lwkt_port_t port;
-
-	port = tcp_addrport(inp->inp_faddr.s_addr, inp->inp_fport,
-			    inp->inp_laddr.s_addr, inp->inp_lport);
-	if (port != &curthread->td_msgport) {
-		struct netmsg nmsg;
-		struct lwkt_msg *msg;
-
-		netmsg_init(&nmsg, &curthread->td_msgport, 0,
-			    tcp_output_dispatch);
-		msg = &nmsg.nm_lmsg;
-		msg->u.ms_resultp = tp;
-
-		error = lwkt_domsg(port, msg, 0);
-	} else
-#endif
-		error = tcp_output(tp);
-	return error;
-}
-
 /*
  * Initiate connection to peer.
  * Create a template for use in transmissions on this connection.
@@ -514,11 +476,8 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 		goto out;
 	}
 
-	if ((error = tcp_connect(tp, nam, td)) != 0)
+	if ((error = tcp_connect(tp, 0, NULL, nam, td)) != 0)
 		goto out;
-
-	error = tcp_conn_output(tp);
-
 	COMMON_END(PRU_CONNECT);
 }
 
@@ -559,15 +518,15 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 		in6_sin6_2_sin(&sin, sin6p);
 		inp->inp_vflag |= INP_IPV4;
 		inp->inp_vflag &= ~INP_IPV6;
-		if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
+		error = tcp_connect(tp, 0, NULL, (struct sockaddr *)&sin, td);
+		if (error)
 			goto out;
-		error = tcp_conn_output(tp);
 		goto out;
 	}
 	inp->inp_vflag &= ~INP_IPV4;
 	inp->inp_vflag |= INP_IPV6;
 	inp->inp_inc.inc_isipv6 = 1;
-	if ((error = tcp6_connect(tp, nam, td)) != 0)
+	if ((error = tcp6_connect(tp, 0, NULL, nam, td)) != 0)
 		goto out;
 	error = tcp_output(tp);
 	COMMON_END(PRU_CONNECT);
@@ -713,8 +672,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
 		 * we checked SS_CANTSENDMORE, eg: while doing uiomove or a
 		 * network interrupt in the non-critical section of sosend().
 		 */
-		if (m)
-			m_freem(m);
+		m_freem(m);
 		if (control)
 			m_freem(control);
 		error = ECONNRESET;	/* XXX EPIPE? */
@@ -731,55 +689,51 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
 		/* TCP doesn't do control messages (rights, creds, etc) */
 		if (control->m_len) {
 			m_freem(control);
-			if (m)
-				m_freem(m);
+			m_freem(m);
 			error = EINVAL;
 			goto out;
 		}
 		m_freem(control);	/* empty control, just free it */
 	}
-	if(!(flags & PRUS_OOB)) {
-		ssb_appendstream(&so->so_snd, m);
-		if (nam && tp->t_state < TCPS_SYN_SENT) {
-			/*
-			 * Do implied connect if not yet connected,
-			 * initialize window to default value, and
-			 * initialize maxseg/maxopd using peer's cached
-			 * MSS.
-			 */
-#ifdef INET6
-			if (isipv6)
-				error = tcp6_connect(tp, nam, td);
-			else
-#endif /* INET6 */
-			error = tcp_connect(tp, nam, td);
-			if (error)
-				goto out;
-			tp->snd_wnd = TTCP_CLIENT_SND_WND;
-			tcp_mss(tp, -1);
-		}
 
-		if (flags & PRUS_EOF) {
-			/*
-			 * Close the send side of the connection after
-			 * the data is sent.
-			 */
-			socantsendmore(so);
-			tp = tcp_usrclosed(tp);
-		}
-		if (tp != NULL) {
-			if (flags & PRUS_MORETOCOME)
-				tp->t_flags |= TF_MORETOCOME;
-			error = tcp_output(tp);
-			if (flags & PRUS_MORETOCOME)
-				tp->t_flags &= ~TF_MORETOCOME;
-		}
-	} else {
+	/*
+	 * Don't let too much OOB data build up
+	 */
+	if (flags & PRUS_OOB) {
 		if (ssb_space(&so->so_snd) < -512) {
 			m_freem(m);
 			error = ENOBUFS;
 			goto out;
 		}
+	}
+
+	/*
+	 * Do implied connect if not yet connected.  Any data sent
+	 * with the connect is handled by tcp_connect() and friends.
+	 *
+	 * NOTE!  PROTOCOL THREAD MAY BE CHANGED BY THE CONNECT!
+	 */
+	if (nam && tp->t_state < TCPS_SYN_SENT) {
+#ifdef INET6
+		if (isipv6)
+			error = tcp6_connect(tp, flags, m, nam, td);
+		else
+#endif /* INET6 */
+		error = tcp_connect(tp, flags, m, nam, td);
+#if 0
+		/* WTF is this doing here? */
+		tp->snd_wnd = TTCP_CLIENT_SND_WND;
+		tcp_mss(tp, -1);
+#endif
+		goto out;
+	}
+
+	/*
+	 * Pump the data into the socket.
+	 */
+	if (m)
+		ssb_appendstream(&so->so_snd, m);
+	if (flags & PRUS_OOB) {
 		/*
 		 * According to RFC961 (Assigned Protocols),
 		 * the urgent pointer points to the last octet
@@ -788,29 +742,26 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
 		 * of data past the urgent section.
 		 * Otherwise, snd_up should be one lower.
 		 */
-		ssb_appendstream(&so->so_snd, m);
-		if (nam && tp->t_state < TCPS_SYN_SENT) {
-			/*
-			 * Do implied connect if not yet connected,
-			 * initialize window to default value, and
-			 * initialize maxseg/maxopd using peer's cached
-			 * MSS.
-			 */
-#ifdef INET6
-			if (isipv6)
-				error = tcp6_connect(tp, nam, td);
-			else
-#endif /* INET6 */
-			error = tcp_connect(tp, nam, td);
-			if (error)
-				goto out;
-			tp->snd_wnd = TTCP_CLIENT_SND_WND;
-			tcp_mss(tp, -1);
-		}
 		tp->snd_up = tp->snd_una + so->so_snd.ssb_cc;
 		tp->t_flags |= TF_FORCE;
 		error = tcp_output(tp);
 		tp->t_flags &= ~TF_FORCE;
+	} else {
+		if (flags & PRUS_EOF) {
+			/*
+			 * Close the send side of the connection after
+			 * the data is sent.
+			 */
+			socantsendmore(so);
+			tp = tcp_usrclosed(tp);
+		}
+		if (tp != NULL) {
+			if (flags & PRUS_MORETOCOME)
+				tp->t_flags |= TF_MORETOCOME;
+			error = tcp_output(tp);
+			if (flags & PRUS_MORETOCOME)
+				tp->t_flags &= ~TF_MORETOCOME;
+		}
 	}
 	COMMON_END((flags & PRUS_OOB) ? PRU_SENDOOB :
 		   ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
@@ -910,8 +861,8 @@ struct pr_usrreqs tcp6_usrreqs = {
 #endif /* INET6 */
 
 static int
-tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin,
-		  struct sockaddr_in *if_sin)
+tcp_connect_oncpu(struct tcpcb *tp, int flags, struct mbuf *m,
+		  struct sockaddr_in *sin, struct sockaddr_in *if_sin)
 {
 	struct inpcb *inp = tp->t_inpcb, *oinp;
 	struct socket *so = inp->inp_socket;
@@ -929,10 +880,12 @@ tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin,
 		if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
 		    otp->t_state == TCPS_TIME_WAIT &&
 		    (ticks - otp->t_starttime) < tcp_msl &&
-		    (otp->t_flags & TF_RCVD_CC))
+		    (otp->t_flags & TF_RCVD_CC)) {
 			tcp_close(otp);
-		else
+		} else {
+			m_freem(m);
 			return (EADDRINUSE);
+		}
 	}
 	if (inp->inp_laddr.s_addr == INADDR_ANY)
 		inp->inp_laddr = if_sin->sin_addr;
@@ -959,9 +912,13 @@ tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin,
 	}
 
 	/*
+	 * Now that no more errors can occur, change the protocol processing
+	 * port to the current thread (which is the correct thread).
+	 *
 	 * Create TCP timer message now; we are on the tcpcb's owner
 	 * CPU/thread.
 	 */
+	sosetport(so, &curthread->td_msgport);
 	tcp_create_timermsg(tp, &curthread->td_msgport);
 
 	/*
@@ -983,6 +940,12 @@ tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin,
 	tcp_callout_reset(tp, tp->tt_keep, tcp_keepinit, tcp_timer_keep);
 	tp->iss = tcp_new_isn(tp);
 	tcp_sendseqinit(tp);
+	if (m) {
+		ssb_appendstream(&so->so_snd, m);
+		m = NULL;
+		if (flags & PRUS_OOB)
+			tp->snd_up = tp->snd_una + so->so_snd.ssb_cc;
+	}
 
 	/*
 	 * Generate a CC value for this connection and
@@ -1002,7 +965,15 @@ tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin,
 		tp->t_flags |= TF_SENDCCNEW;
 	}
 
-	return (0);
+	/*
+	 * Close the send side of the connection after
+	 * the data is sent if flagged.
+	 */
+	if ((flags & (PRUS_OOB|PRUS_EOF)) == PRUS_EOF) {
+		socantsendmore(so);
+		tp = tcp_usrclosed(tp);
+	}
+	return (tcp_output(tp));
 }
 
 #ifdef SMP
@@ -1012,6 +983,8 @@ struct netmsg_tcp_connect {
 	struct tcpcb		*nm_tp;
 	struct sockaddr_in	*nm_sin;
 	struct sockaddr_in	*nm_ifsin;
+	int			nm_flags;
+	struct mbuf		*nm_m;
 };
 
 static void
@@ -1020,7 +993,8 @@ tcp_connect_handler(netmsg_t netmsg)
 	struct netmsg_tcp_connect *msg = (void *)netmsg;
 	int error;
 
-	error = tcp_connect_oncpu(msg->nm_tp, msg->nm_sin, msg->nm_ifsin);
+	error = tcp_connect_oncpu(msg->nm_tp, msg->nm_flags, msg->nm_m,
+				  msg->nm_sin, msg->nm_ifsin);
 	lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, error);
 }
 
@@ -1029,6 +1003,8 @@ struct netmsg_tcp6_connect {
 	struct tcpcb		*nm_tp;
 	struct sockaddr_in6	*nm_sin6;
 	struct in6_addr		*nm_addr6;
+	int			nm_flags;
+	struct mbuf		*nm_m;
 };
 
 static void
@@ -1037,7 +1013,8 @@ tcp6_connect_handler(netmsg_t netmsg)
 	struct netmsg_tcp6_connect *msg = (void *)netmsg;
 	int error;
 
-	error = tcp6_connect_oncpu(msg->nm_tp, msg->nm_sin6, msg->nm_addr6);
+	error = tcp6_connect_oncpu(msg->nm_tp, msg->nm_flags, msg->nm_m,
+				   msg->nm_sin6, msg->nm_addr6);
 	lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, error);
 }
 
@@ -1054,7 +1031,8 @@ tcp6_connect_handler(netmsg_t netmsg)
  * Initialize connection parameters and enter SYN-SENT state.
  */
 static int
-tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
+tcp_connect(struct tcpcb *tp, int flags, struct mbuf *m,
+	    struct sockaddr *nam, struct thread *td)
 {
 	struct inpcb *inp = tp->t_inpcb;
 	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
@@ -1064,20 +1042,26 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 	lwkt_port_t port;
 #endif
 
+	/*
+	 * Bind if we have to
+	 */
 	if (inp->inp_lport == 0) {
 		error = in_pcbbind(inp, NULL, td);
-		if (error)
+		if (error) {
+			m_freem(m);
 			return (error);
+		}
 	}
 
 	/*
-	 * Cannot simply call in_pcbconnect, because there might be an
-	 * earlier incarnation of this same connection still in
-	 * TIME_WAIT state, creating an ADDRINUSE error.
+	 * Calculate the correct protocol processing thread.  The connect
+	 * operation must run there.
 	 */
 	error = in_pcbladdr(inp, nam, &if_sin, td);
-	if (error)
+	if (error) {
+		m_freem(m);
 		return (error);
+	}
 
 #ifdef SMP
 	port = tcp_addrport(sin->sin_addr.s_addr, sin->sin_port,
@@ -1098,23 +1082,32 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 			RTFREE(ro->ro_rt);
 		bzero(ro, sizeof(*ro));
 
-		netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-			    tcp_connect_handler);
+		/*
+		 * NOTE: We haven't set so->so_port yet do not pass so
+		 *	 to netmsg_init() or it will be improperly forwarded.
+		 */
+		netmsg_init(&msg.nm_netmsg, NULL, &curthread->td_msgport,
+			    0, tcp_connect_handler);
 		msg.nm_tp = tp;
 		msg.nm_sin = sin;
 		msg.nm_ifsin = if_sin;
+		msg.nm_flags = flags;
+		msg.nm_m = m;
 		error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
-	} else
+	} else {
+		error = tcp_connect_oncpu(tp, flags, m, sin, if_sin);
+	}
+#else
+	error = tcp_connect_oncpu(tp, flags, m, sin, if_sin);
 #endif
-		error = tcp_connect_oncpu(tp, sin, if_sin);
-
 	return (error);
 }
 
 #ifdef INET6
 
 static int
-tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
+tcp6_connect(struct tcpcb *tp, int flags, struct mbuf *m,
+	     struct sockaddr *nam, struct thread *td)
 {
 	struct inpcb *inp = tp->t_inpcb;
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
@@ -1126,8 +1119,10 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 
 	if (inp->inp_lport == 0) {
 		error = in6_pcbbind(inp, NULL, td);
-		if (error)
-			return error;
+		if (error) {
+			m_freem(m);
+			return (error);
+		}
 	}
 
 	/*
@@ -1136,8 +1131,10 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 	 * TIME_WAIT state, creating an ADDRINUSE error.
 	 */
 	error = in6_pcbladdr(inp, nam, &addr6, td);
-	if (error)
-		return error;
+	if (error) {
+		m_freem(m);
+		return (error);
+	}
 
 #ifdef SMP
 	port = tcp6_addrport();	/* XXX hack for now, always cpu0 */
@@ -1155,22 +1152,26 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 			RTFREE(ro->ro_rt);
 		bzero(ro, sizeof(*ro));
 
-		netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
-			    tcp6_connect_handler);
+		netmsg_init(&msg.nm_netmsg, NULL, &curthread->td_msgport,
+			    0, tcp6_connect_handler);
 		msg.nm_tp = tp;
 		msg.nm_sin6 = sin6;
 		msg.nm_addr6 = addr6;
+		msg.nm_flags = flags;
+		msg.nm_m = m;
 		error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
-	} else
+	} else {
+		error = tcp6_connect_oncpu(tp, flags, m, sin6, addr6);
+	}
+#else
+	error = tcp6_connect_oncpu(tp, flags, m, sin6, addr6);
 #endif
-		error = tcp6_connect_oncpu(tp, sin6, addr6);
-
 	return (error);
 }
 
 static int
-tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
-		   struct in6_addr *addr6)
+tcp6_connect_oncpu(struct tcpcb *tp, int flags, struct mbuf *m,
+		   struct sockaddr_in6 *sin6, struct in6_addr *addr6)
 {
 	struct inpcb *inp = tp->t_inpcb;
 	struct socket *so = inp->inp_socket;
@@ -1179,6 +1180,11 @@ tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
 	struct rmxp_tao *taop;
 	struct rmxp_tao tao_noncached;
 
+	/*
+	 * Cannot simply call in_pcbconnect, because there might be an
+	 * earlier incarnation of this same connection still in
+	 * TIME_WAIT state, creating an ADDRINUSE error.
+	 */
 	oinp = in6_pcblookup_hash(inp->inp_cpcbinfo,
 				  &sin6->sin6_addr, sin6->sin6_port,
 				  IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) ?
@@ -1188,10 +1194,12 @@ tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
 		if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
 		    otp->t_state == TCPS_TIME_WAIT &&
 		    (ticks - otp->t_starttime) < tcp_msl &&
-		    (otp->t_flags & TF_RCVD_CC))
+		    (otp->t_flags & TF_RCVD_CC)) {
 			otp = tcp_close(otp);
-		else
+		} else {
+			m_freem(m);
 			return (EADDRINUSE);
+		}
 	}
 	if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
 		inp->in6p_laddr = *addr6;
@@ -1201,7 +1209,14 @@ tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
 		inp->in6p_flowinfo = sin6->sin6_flowinfo;
 	in_pcbinsconnhash(inp);
 
-	/* NOTE: must be done in tcpcb's owner thread */
+	/*
+	 * Now that no more errors can occur, change the protocol processing
+	 * port to the current thread (which is the correct thread).
+	 *
+	 * Create TCP timer message now; we are on the tcpcb's owner
+	 * CPU/thread.
+	 */
+	sosetport(so, &curthread->td_msgport);
 	tcp_create_timermsg(tp, &curthread->td_msgport);
 
 	/* Compute window scaling to request.  */
@@ -1218,6 +1233,12 @@ tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
 	tcp_callout_reset(tp, tp->tt_keep, tcp_keepinit, tcp_timer_keep);
 	tp->iss = tcp_new_isn(tp);
 	tcp_sendseqinit(tp);
+	if (m) {
+		ssb_appendstream(&so->so_snd, m);
+		m = NULL;
+		if (flags & PRUS_OOB)
+			tp->snd_up = tp->snd_una + so->so_snd.ssb_cc;
+	}
 
 	/*
 	 * Generate a CC value for this connection and
@@ -1237,7 +1258,15 @@ tcp6_connect_oncpu(struct tcpcb *tp, struct sockaddr_in6 *sin6,
 		tp->t_flags |= TF_SENDCCNEW;
 	}
 
-	return (0);
+	/*
+	 * Close the send side of the connection after
+	 * the data is sent if flagged.
+	 */
+	if ((flags & (PRUS_OOB|PRUS_EOF)) == PRUS_EOF) {
+		socantsendmore(so);
+		tp = tcp_usrclosed(tp);
+	}
+	return (tcp_output(tp));
 }
 
 #endif /* INET6 */
@@ -1430,6 +1459,7 @@ tcp_attach(struct socket *so, struct pru_attach_info *ai)
 		return (ENOBUFS);
 	}
 	tp->t_state = TCPS_CLOSED;
+	so->so_port = tcp_soport_attach(so);
 	return (0);
 }
 
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index fcccef6..0d5e97d 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -641,8 +641,9 @@ struct tcptemp *tcp_maketemplate (struct tcpcb *);
 void	 tcp_freetemplate (struct tcptemp *);
 void	 tcp_fillheaders (struct tcpcb *, void *, void *);
 struct lwkt_port *
-	 tcp_soport(struct socket *, struct sockaddr *,
-	 	    struct mbuf **, int);
+	 tcp_soport(struct socket *, struct sockaddr *, struct mbuf **);
+struct lwkt_port *
+	 tcp_soport_attach(struct socket *);
 struct lwkt_port *
 	 tcp_ctlport(int, struct sockaddr *, void *);
 struct tcpcb *
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index ac1c849..73f015f 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -683,8 +683,8 @@ udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 		struct netmsg_udp_notify nmsg;
 
 		KKASSERT(&curthread->td_msgport == cpu_portfn(0));
-		netmsg_init(&nmsg.nm_nmsg, &curthread->td_msgport, 0,
-			    udp_notifyall_oncpu);
+		netmsg_init(&nmsg.nm_nmsg, NULL, &curthread->td_msgport,
+			    0, udp_notifyall_oncpu);
 		nmsg.nm_faddr = faddr;
 		nmsg.nm_arg = inetctlerrmap[cmd];
 		nmsg.nm_notify = notify;
@@ -924,6 +924,7 @@ udp_attach(struct socket *so, int proto, struct pru_attach_info *ai)
 	crit_exit();
 	if (error)
 		return error;
+	so->so_port = udp_soport_attach(so);
 
 	inp = (struct inpcb *)so->so_pcb;
 	inp->inp_vflag |= INP_IPV4;
@@ -952,10 +953,39 @@ udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 	return error;
 }
 
+#ifdef SMP
+
+struct netmsg_udp_connect {
+	struct netmsg		nm_netmsg;
+	struct socket		*nm_so;
+	struct sockaddr_in	*nm_sin;
+	struct sockaddr_in	*nm_ifsin;
+	struct thread		*nm_td;
+};
+
+static int udp_connect_oncpu(struct socket *so, struct thread *td,
+			struct sockaddr_in *sin, struct sockaddr_in *if_sin);
+
+static void
+udp_connect_handler(netmsg_t netmsg)
+{
+	struct netmsg_udp_connect *msg = (void *)netmsg;
+	int error;
+
+	error = udp_connect_oncpu(msg->nm_so, msg->nm_td,
+				  msg->nm_sin, msg->nm_ifsin);
+	lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, error);
+}
+
+#endif
+
 static int
 udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
 	struct inpcb *inp;
+	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
+	struct sockaddr_in *if_sin;
+	lwkt_port_t port;
 	int error;
 
 	inp = so->so_pcb;
@@ -964,35 +994,84 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 	if (inp->inp_faddr.s_addr != INADDR_ANY)
 		return EISCONN;
 	error = 0;
-	crit_enter();
+
+	/*
+	 * Bind if we have to
+	 */
 	if (td->td_proc && td->td_proc->p_ucred->cr_prison != NULL &&
 	    inp->inp_laddr.s_addr == INADDR_ANY) {
 		error = in_pcbbind(inp, NULL, td);
+		if (error)
+			return (error);
 	}
-	if (error == 0) {
-		if (!prison_remote_ip(td, nam))
-			return(EAFNOSUPPORT); /* IPv6 only jail */
-		if (inp->inp_flags & INP_WILDCARD)
-			in_pcbremwildcardhash(inp);
-		error = in_pcbconnect(inp, nam, td);
-	}
-	crit_exit();
-	if (error == 0) {
-		soisconnected(so);
+
+	/*
+	 * Calculate the correct protocol processing thread.  The connect
+	 * operation must run there.
+	 */
+	error = in_pcbladdr(inp, nam, &if_sin, td);
+	if (error)
+		return(error);
+	if (!prison_remote_ip(td, nam))
+		return(EAFNOSUPPORT); /* IPv6 only jail */
+
+	port = udp_addrport(sin->sin_addr.s_addr, sin->sin_port,
+			    inp->inp_laddr.s_addr, inp->inp_lport);
+#ifdef SMP
+	if (port != &curthread->td_msgport) {
+		struct netmsg_udp_connect msg;
+		struct route *ro = &inp->inp_route;
 
 		/*
-		 * Make sure that the new target CPU is same as current CPU,
-		 * if it is not, then we will have to free the route entry
-		 * allocated on the current CPU.
+		 * in_pcbladdr() may have allocated a route entry for us
+		 * on the current CPU, but we need a route entry on the
+		 * inpcb's owner CPU, so free it here.
 		 */
-		if (udp_addrcpu(inp->inp_faddr.s_addr, inp->inp_fport,
-		    inp->inp_laddr.s_addr, inp->inp_lport) != mycpuid) {
-			struct route *ro = &inp->inp_route;
+		if (ro->ro_rt != NULL)
+			RTFREE(ro->ro_rt);
+		bzero(ro, sizeof(*ro));
 
-			if (ro->ro_rt != NULL)
-				RTFREE(ro->ro_rt);
-			bzero(ro, sizeof(*ro));
-		}
+		/*
+		 * NOTE: We haven't set so->so_port yet do not pass so
+		 *       to netmsg_init() or it will be improperly forwarded.
+		 */
+		netmsg_init(&msg.nm_netmsg, NULL, &curthread->td_msgport,
+			    0, udp_connect_handler);
+		msg.nm_so = so;
+		msg.nm_sin = sin;
+		msg.nm_ifsin = if_sin;
+		msg.nm_td = td;
+		error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0);
+	} else {
+		error = udp_connect_oncpu(so, td, sin, if_sin);
+	}
+#else
+	error = udp_connect_oncpu(tp, sin, if_sin);
+#endif
+	return (error);
+}
+
+static int
+udp_connect_oncpu(struct socket *so, struct thread *td,
+		  struct sockaddr_in *sin, struct sockaddr_in *if_sin)
+{
+	struct inpcb *inp;
+	int error;
+
+	inp = so->so_pcb;
+	if (inp->inp_flags & INP_WILDCARD)
+		in_pcbremwildcardhash(inp);
+	error = in_pcbconnect(inp, (struct sockaddr *)sin, td);
+
+	if (error == 0) {
+		/*
+		 * No more errors can occur, finish adjusting the socket
+		 * and change the processing port to reflect the connected
+		 * socket.  Once set we can no longer safely mess with the
+		 * socket.
+		 */
+		soisconnected(so);
+		sosetport(so, &curthread->td_msgport);
 	} else if (error == EAFNOSUPPORT) {	/* connection dissolved */
 		/*
 		 * Follow traditional BSD behavior and retain
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 8d8b5fa..f781f90 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -147,6 +147,8 @@ extern int	log_in_vain;
 
 int			udp_addrcpu (in_addr_t faddr, in_port_t fport,
 				     in_addr_t laddr, in_port_t lport);
+struct lwkt_port	*udp_addrport (in_addr_t faddr, in_port_t fport,
+				     in_addr_t laddr, in_port_t lport);
 void			udp_ctlinput (int, struct sockaddr *, void *);
 void			udp_init (void);
 void			udp_thread_init (void);
@@ -154,7 +156,8 @@ void			udp_input (struct mbuf *, ...);
 void			udp_notify (struct inpcb *inp, int error);
 int			udp_shutdown (struct socket *so);
 struct lwkt_port	*udp_soport (struct socket *, struct sockaddr *,
-				     struct mbuf **, int);
+				     struct mbuf **);
+struct lwkt_port	*udp_soport_attach (struct socket *);
 struct lwkt_port	*udp_ctlport (int, struct sockaddr *, void *);
 struct lwkt_port	*udp_cport (int);
 
diff --git a/sys/netinet6/ip6_demux.c b/sys/netinet6/ip6_demux.c
index 9e52fdb..2116f44 100644
--- a/sys/netinet6/ip6_demux.c
+++ b/sys/netinet6/ip6_demux.c
@@ -43,7 +43,7 @@
 #include <netinet6/tcp6_var.h>
 
 lwkt_port_t
-tcp6_soport(struct socket *so, struct sockaddr *nam, struct mbuf **m0, int req)
+tcp6_soport(struct socket *so, struct sockaddr *nam, struct mbuf **m0)
 {
 	struct inpcb *inp;
 
@@ -56,11 +56,12 @@ tcp6_soport(struct socket *so, struct sockaddr *nam, struct mbuf **m0, int req)
 	 */
 	if (so == NULL || (inp = so->so_pcb) == NULL ||
 	    (inp->inp_flags & IN6P_IPV6_V6ONLY) ||
-	    (inp->inp_vflag & INP_IPV4) == 0)
-		return cpu0_soport(so, nam, m0, req);
+	    (inp->inp_vflag & INP_IPV4) == 0) {
+		return cpu0_soport(so, nam, m0);
+	}
 
 	/* IPv4 mapped, fall back to IPv4 tcp_soport */
-	return tcp_soport(so, nam, m0, req);
+	return tcp_soport(so, nam, m0);
 }
 
 /*
diff --git a/sys/netinet6/ip6protosw.h b/sys/netinet6/ip6protosw.h
index 072002e..350eb1a 100644
--- a/sys/netinet6/ip6protosw.h
+++ b/sys/netinet6/ip6protosw.h
@@ -143,7 +143,7 @@ struct ip6protosw {
 /* user-protocol hook */
 	struct lwkt_port *(*pr_soport)
 			(struct socket *, struct sockaddr *,
-			 struct mbuf **, int);
+			 struct mbuf **);
 	struct lwkt_port *(*pr_ctlport)(int, struct sockaddr *, void *);
 
 /* utility hooks */
diff --git a/sys/netinet6/tcp6_var.h b/sys/netinet6/tcp6_var.h
index f97685a..6dd92c8 100644
--- a/sys/netinet6/tcp6_var.h
+++ b/sys/netinet6/tcp6_var.h
@@ -88,7 +88,7 @@ int	tcp6_input (struct mbuf **, int *, int);
 struct	rtentry *tcp_rtlookup6(struct in_conninfo *);
 
 struct	lwkt_port *tcp6_soport(struct socket *, struct sockaddr *,
-			       struct mbuf **, int);
+			       struct mbuf **);
 struct  lwkt_port *tcp6_addrport(void);
 
 extern struct	pr_usrreqs tcp6_usrreqs;
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 748429b..23da964 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -559,6 +559,7 @@ udp6_attach(struct socket *so, int proto, struct pru_attach_info *ai)
 	crit_exit();
 	if (error)
 		return error;
+	so->so_port = udp_soport_attach(so);
 	inp = (struct inpcb *)so->so_pcb;
 	inp->inp_vflag |= INP_IPV6;
 	if (!ip6_v6only)
@@ -660,6 +661,7 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 			inp->inp_vflag &= ~INP_IPV4;
 			inp->inp_vflag |= INP_IPV6;
 		}
+		/* sosetport(so, port); here, see udp v4 code */
 		soisconnected(so);
 	} else if (error == EAFNOSUPPORT) {	/* connection dissolved */
 		/*
diff --git a/sys/netproto/atm/atm_proto.c b/sys/netproto/atm/atm_proto.c
index 472fc22..55071d3 100644
--- a/sys/netproto/atm/atm_proto.c
+++ b/sys/netproto/atm/atm_proto.c
@@ -81,7 +81,7 @@ struct protosw atmsw[] = {
 	x,			/* pr_output */
 	x,			/* pr_ctlinput */
 	x,			/* pr_ctloutput */
-	0,			/* pr_mport */
+	NULL,			/* pr_mport */
 	NULL,			/* pr_ctlport */
 	0,			/* pr_init */
 	0,			/* pr_fasttimo */
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index e9d0609..88df95e 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -93,7 +93,7 @@ struct protosw {
 					/* control output (from above) */
 /* user-protocol hooks */
 	struct lwkt_port *(*pr_mport)(struct socket *, struct sockaddr *,
-				      struct mbuf **, int);
+				      struct mbuf **);
 	struct lwkt_port *(*pr_ctlport)(int, struct sockaddr *, void *);
 
 /* utility hooks */
@@ -328,10 +328,10 @@ int	pru_ctloutput_notsupp(struct socket *so, struct sockopt *sopt);
 int	pru_sense_null (struct socket *so, struct stat *sb);
 
 struct lwkt_port *cpu0_soport(struct socket *, struct sockaddr *,
-			      struct mbuf **, int);
+			      struct mbuf **);
 struct lwkt_port *cpu0_ctlport(int, struct sockaddr *, void *);
 struct lwkt_port *sync_soport(struct socket *, struct sockaddr *,
-			      struct mbuf **, int);
+			      struct mbuf **);
 
 #endif /* _KERNEL || _KERNEL_STRUCTURES */
 
diff --git a/sys/sys/socketops.h b/sys/sys/socketops.h
index e6ed498..a091ebe 100644
--- a/sys/sys/socketops.h
+++ b/sys/sys/socketops.h
@@ -82,7 +82,7 @@ int so_pru_bind (struct socket *so, struct sockaddr *nam, struct thread *td);
 int so_pru_connect (struct socket *so, struct sockaddr *nam, struct thread *td);
 int so_pru_connect2 (struct socket *so1, struct socket *so2);
 int so_pru_control (struct socket *so, u_long cmd, caddr_t data,
-		    struct ifnet *ifp);
+		struct ifnet *ifp);
 int so_pru_detach (struct socket *so);
 int so_pru_disconnect (struct socket *so);
 int so_pru_listen (struct socket *so, struct thread *td);
@@ -90,15 +90,15 @@ int so_pru_peeraddr (struct socket *so, struct sockaddr **nam);
 int so_pru_rcvd (struct socket *so, int flags);
 int so_pru_rcvoob (struct socket *so, struct mbuf *m, int flags);
 int so_pru_send (struct socket *so, int flags, struct mbuf *m,
-		 struct sockaddr *addr, struct mbuf *control,
-		 struct thread *td);
+		struct sockaddr *addr, struct mbuf *control,
+		struct thread *td);
 int so_pru_sense (struct socket *so, struct stat *sb);
 int so_pru_shutdown (struct socket *so);
 int so_pru_sockaddr (struct socket *so, struct sockaddr **nam);
 int so_pru_sopoll (struct socket *so, int events, struct ucred *cred);
 int so_pru_ctloutput(struct socket *so, struct sockopt *sopt);
 void so_pru_ctlinput(struct protosw *pr, int cmd,
-	    struct sockaddr *arg, void *extra);
+		struct sockaddr *arg, void *extra);
 
 #endif	/* _KERNEL */
 #endif	/* _SYS_SOCKETOPS_H_ */
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index d7190bd..ea3b5b6 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -99,6 +99,7 @@ struct socket {
 	void	*so_pcb;		/* protocol control block */
 	struct	protosw *so_proto;	/* protocol handle */
 	struct	socket *so_head;	/* back pointer to accept socket */
+	lwkt_port_t so_port;		/* message port */
 
 	/*
 	 * These fields are used to manage sockets capable of accepting
@@ -380,6 +381,7 @@ void	soisconnected (struct socket *so);
 void	soisconnecting (struct socket *so);
 void	soisdisconnected (struct socket *so);
 void	soisdisconnecting (struct socket *so);
+void	sosetport (struct socket *so, struct lwkt_port *port);
 int	solisten (struct socket *so, int backlog, struct thread *td);
 struct socket *sonewconn (struct socket *head, int connstatus);
 int	sooptcopyin (struct sockopt *sopt, void *buf, size_t len,
