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 #include #include +#include #include #include #include @@ -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 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,