1 /* 2 * Copyright (c) 2003, 2004 Jeffrey M. Hsu. All rights reserved. 3 * Copyright (c) 2003, 2004 The DragonFly Project. All rights reserved. 4 * 5 * This code is derived from software contributed to The DragonFly Project 6 * by Jeffrey M. Hsu. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of The DragonFly Project nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific, prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/msgport.h> 38 #include <sys/protosw.h> 39 #include <sys/socket.h> 40 #include <sys/socketvar.h> 41 #include <sys/socketops.h> 42 #include <sys/thread.h> 43 #include <sys/thread2.h> 44 #include <sys/msgport2.h> 45 #include <sys/mbuf.h> 46 #include <vm/pmap.h> 47 #include <net/netmsg2.h> 48 49 #include <net/netisr.h> 50 #include <net/netmsg.h> 51 52 /* 53 * Abort a socket and free it. Called from soabort() only. soabort() 54 * got a ref on the socket which we must free on reply. 55 */ 56 void 57 so_pru_abort(struct socket *so) 58 { 59 struct netmsg_pru_abort msg; 60 61 netmsg_init(&msg.base, so, &curthread->td_msgport, 62 0, so->so_proto->pr_usrreqs->pru_abort); 63 (void)lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 64 sofree(msg.base.nm_so); 65 } 66 67 /* 68 * Abort a socket and free it, asynchronously. Called from 69 * soaborta() only. soaborta() got a ref on the socket which we must 70 * free on reply. 71 */ 72 void 73 so_pru_aborta(struct socket *so) 74 { 75 struct netmsg_pru_abort *msg; 76 77 msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_WAITOK | M_ZERO); 78 netmsg_init(&msg->base, so, &netisr_afree_free_so_rport, 79 0, so->so_proto->pr_usrreqs->pru_abort); 80 lwkt_sendmsg(so->so_port, &msg->base.lmsg); 81 } 82 83 /* 84 * Abort a socket and free it. Called from soabort_oncpu() only. 85 * Caller must make sure that the current CPU is inpcb's owner CPU. 86 */ 87 void 88 so_pru_abort_oncpu(struct socket *so) 89 { 90 struct netmsg_pru_abort msg; 91 netisr_fn_t func = so->so_proto->pr_usrreqs->pru_abort; 92 93 netmsg_init(&msg.base, so, &netisr_adone_rport, 0, func); 94 msg.base.lmsg.ms_flags &= ~(MSGF_REPLY | MSGF_DONE); 95 msg.base.lmsg.ms_flags |= MSGF_SYNC; 96 func((netmsg_t)&msg); 97 KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE); 98 sofree(msg.base.nm_so); 99 } 100 101 int 102 so_pru_accept(struct socket *so, struct sockaddr **nam) 103 { 104 struct netmsg_pru_accept msg; 105 106 netmsg_init(&msg.base, so, &curthread->td_msgport, 107 0, so->so_proto->pr_usrreqs->pru_accept); 108 msg.nm_nam = nam; 109 110 return lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 111 } 112 113 int 114 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai) 115 { 116 struct netmsg_pru_attach msg; 117 int error; 118 119 netmsg_init(&msg.base, so, &curthread->td_msgport, 120 0, so->so_proto->pr_usrreqs->pru_attach); 121 msg.nm_proto = proto; 122 msg.nm_ai = ai; 123 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 124 return (error); 125 } 126 127 int 128 so_pru_attach_direct(struct socket *so, int proto, struct pru_attach_info *ai) 129 { 130 struct netmsg_pru_attach msg; 131 netisr_fn_t func = so->so_proto->pr_usrreqs->pru_attach; 132 133 netmsg_init(&msg.base, so, &netisr_adone_rport, 0, func); 134 msg.base.lmsg.ms_flags &= ~(MSGF_REPLY | MSGF_DONE); 135 msg.base.lmsg.ms_flags |= MSGF_SYNC; 136 msg.nm_proto = proto; 137 msg.nm_ai = ai; 138 func((netmsg_t)&msg); 139 KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE); 140 return(msg.base.lmsg.ms_error); 141 } 142 143 /* 144 * NOTE: If the target port changes the bind operation will deal with it. 145 */ 146 int 147 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 148 { 149 struct netmsg_pru_bind msg; 150 int error; 151 152 netmsg_init(&msg.base, so, &curthread->td_msgport, 153 0, so->so_proto->pr_usrreqs->pru_bind); 154 msg.nm_nam = nam; 155 msg.nm_td = td; /* used only for prison_ip() */ 156 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 157 return (error); 158 } 159 160 int 161 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 162 { 163 struct netmsg_pru_connect msg; 164 int error; 165 166 netmsg_init(&msg.base, so, &curthread->td_msgport, 167 0, so->so_proto->pr_usrreqs->pru_connect); 168 msg.nm_nam = nam; 169 msg.nm_td = td; 170 msg.nm_m = NULL; 171 msg.nm_flags = 0; 172 msg.nm_reconnect = 0; 173 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 174 return (error); 175 } 176 177 int 178 so_pru_connect2(struct socket *so1, struct socket *so2) 179 { 180 struct netmsg_pru_connect2 msg; 181 int error; 182 183 netmsg_init(&msg.base, so1, &curthread->td_msgport, 184 0, so1->so_proto->pr_usrreqs->pru_connect2); 185 msg.nm_so1 = so1; 186 msg.nm_so2 = so2; 187 error = lwkt_domsg(so1->so_port, &msg.base.lmsg, 0); 188 return (error); 189 } 190 191 /* 192 * WARNING! Synchronous call from user context. Control function may do 193 * copyin/copyout. 194 */ 195 int 196 so_pru_control_direct(struct socket *so, u_long cmd, caddr_t data, 197 struct ifnet *ifp) 198 { 199 struct netmsg_pru_control msg; 200 netisr_fn_t func = so->so_proto->pr_usrreqs->pru_control; 201 202 netmsg_init(&msg.base, so, &netisr_adone_rport, 0, func); 203 msg.base.lmsg.ms_flags &= ~(MSGF_REPLY | MSGF_DONE); 204 msg.base.lmsg.ms_flags |= MSGF_SYNC; 205 msg.nm_cmd = cmd; 206 msg.nm_data = data; 207 msg.nm_ifp = ifp; 208 msg.nm_td = curthread; 209 func((netmsg_t)&msg); 210 KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE); 211 return(msg.base.lmsg.ms_error); 212 } 213 214 int 215 so_pru_detach(struct socket *so) 216 { 217 struct netmsg_pru_detach msg; 218 int error; 219 220 netmsg_init(&msg.base, so, &curthread->td_msgport, 221 0, so->so_proto->pr_usrreqs->pru_detach); 222 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 223 return (error); 224 } 225 226 void 227 so_pru_detach_direct(struct socket *so) 228 { 229 struct netmsg_pru_detach msg; 230 netisr_fn_t func = so->so_proto->pr_usrreqs->pru_detach; 231 232 netmsg_init(&msg.base, so, &netisr_adone_rport, 0, func); 233 msg.base.lmsg.ms_flags &= ~(MSGF_REPLY | MSGF_DONE); 234 msg.base.lmsg.ms_flags |= MSGF_SYNC; 235 func((netmsg_t)&msg); 236 KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE); 237 } 238 239 int 240 so_pru_disconnect(struct socket *so) 241 { 242 struct netmsg_pru_disconnect msg; 243 int error; 244 245 netmsg_init(&msg.base, so, &curthread->td_msgport, 246 0, so->so_proto->pr_usrreqs->pru_disconnect); 247 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 248 return (error); 249 } 250 251 void 252 so_pru_disconnect_direct(struct socket *so) 253 { 254 struct netmsg_pru_disconnect msg; 255 netisr_fn_t func = so->so_proto->pr_usrreqs->pru_disconnect; 256 257 netmsg_init(&msg.base, so, &netisr_adone_rport, 0, func); 258 msg.base.lmsg.ms_flags &= ~(MSGF_REPLY | MSGF_DONE); 259 msg.base.lmsg.ms_flags |= MSGF_SYNC; 260 func((netmsg_t)&msg); 261 KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE); 262 } 263 264 int 265 so_pru_listen(struct socket *so, struct thread *td) 266 { 267 struct netmsg_pru_listen msg; 268 int error; 269 270 netmsg_init(&msg.base, so, &curthread->td_msgport, 271 0, so->so_proto->pr_usrreqs->pru_listen); 272 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 273 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 274 return (error); 275 } 276 277 int 278 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 279 { 280 struct netmsg_pru_peeraddr msg; 281 int error; 282 283 netmsg_init(&msg.base, so, &curthread->td_msgport, 284 0, so->so_proto->pr_usrreqs->pru_peeraddr); 285 msg.nm_nam = nam; 286 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 287 return (error); 288 } 289 290 int 291 so_pru_rcvd(struct socket *so, int flags) 292 { 293 struct netmsg_pru_rcvd msg; 294 int error; 295 296 netmsg_init(&msg.base, so, &curthread->td_msgport, 297 0, so->so_proto->pr_usrreqs->pru_rcvd); 298 msg.nm_flags = flags; 299 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 300 return (error); 301 } 302 303 int 304 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 305 { 306 struct netmsg_pru_rcvoob msg; 307 int error; 308 309 netmsg_init(&msg.base, so, &curthread->td_msgport, 310 0, so->so_proto->pr_usrreqs->pru_rcvoob); 311 msg.nm_m = m; 312 msg.nm_flags = flags; 313 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 314 return (error); 315 } 316 317 /* 318 * NOTE: If the target port changes the implied connect will deal with it. 319 */ 320 int 321 so_pru_send(struct socket *so, int flags, struct mbuf *m, 322 struct sockaddr *addr, struct mbuf *control, struct thread *td) 323 { 324 struct netmsg_pru_send msg; 325 int error; 326 327 netmsg_init(&msg.base, so, &curthread->td_msgport, 328 0, so->so_proto->pr_usrreqs->pru_send); 329 msg.nm_flags = flags; 330 msg.nm_m = m; 331 msg.nm_addr = addr; 332 msg.nm_control = control; 333 msg.nm_td = td; 334 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 335 return (error); 336 } 337 338 void 339 so_pru_sync(struct socket *so) 340 { 341 struct netmsg_base msg; 342 343 netmsg_init(&msg, so, &curthread->td_msgport, 0, 344 netmsg_sync_handler); 345 lwkt_domsg(so->so_port, &msg.lmsg, 0); 346 } 347 348 void 349 so_pru_send_async(struct socket *so, int flags, struct mbuf *m, 350 struct sockaddr *addr0, struct mbuf *control, struct thread *td) 351 { 352 struct netmsg_pru_send *msg; 353 struct sockaddr *addr = NULL; 354 355 KASSERT(so->so_proto->pr_flags & PR_ASYNC_SEND, 356 ("async pru_send is not supported")); 357 358 flags |= PRUS_NOREPLY; 359 if (addr0 != NULL) { 360 addr = kmalloc(addr0->sa_len, M_SONAME, M_WAITOK); 361 memcpy(addr, addr0, addr0->sa_len); 362 flags |= PRUS_FREEADDR; 363 } 364 365 msg = &m->m_hdr.mh_sndmsg; 366 netmsg_init(&msg->base, so, &netisr_apanic_rport, 367 0, so->so_proto->pr_usrreqs->pru_send); 368 msg->nm_flags = flags; 369 msg->nm_m = m; 370 msg->nm_addr = addr; 371 msg->nm_control = control; 372 msg->nm_td = td; 373 lwkt_sendmsg(so->so_port, &msg->base.lmsg); 374 } 375 376 int 377 so_pru_sense(struct socket *so, struct stat *sb) 378 { 379 struct netmsg_pru_sense msg; 380 int error; 381 382 netmsg_init(&msg.base, so, &curthread->td_msgport, 383 0, so->so_proto->pr_usrreqs->pru_sense); 384 msg.nm_stat = sb; 385 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 386 return (error); 387 } 388 389 int 390 so_pru_shutdown(struct socket *so) 391 { 392 struct netmsg_pru_shutdown msg; 393 int error; 394 395 netmsg_init(&msg.base, so, &curthread->td_msgport, 396 0, so->so_proto->pr_usrreqs->pru_shutdown); 397 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 398 return (error); 399 } 400 401 int 402 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 403 { 404 struct netmsg_pru_sockaddr msg; 405 int error; 406 407 netmsg_init(&msg.base, so, &curthread->td_msgport, 408 0, so->so_proto->pr_usrreqs->pru_sockaddr); 409 msg.nm_nam = nam; 410 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 411 return (error); 412 } 413 414 int 415 so_pr_ctloutput(struct socket *so, struct sockopt *sopt) 416 { 417 struct netmsg_pr_ctloutput msg; 418 int error; 419 420 KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val)); 421 netmsg_init(&msg.base, so, &curthread->td_msgport, 422 0, so->so_proto->pr_ctloutput); 423 msg.nm_sopt = sopt; 424 error = lwkt_domsg(so->so_port, &msg.base.lmsg, 0); 425 return (error); 426 } 427 428 /* 429 * Protocol control input, typically via icmp. 430 * 431 * If the protocol pr_ctlport is not NULL we call it to figure out the 432 * protocol port. If NULL is returned we can just return, otherwise 433 * we issue a netmsg to call pr_ctlinput in the proper thread. 434 * 435 * This must be done synchronously as arg and/or extra may point to 436 * temporary data. 437 */ 438 void 439 so_pru_ctlinput(struct protosw *pr, int cmd, struct sockaddr *arg, void *extra) 440 { 441 struct netmsg_pru_ctlinput msg; 442 lwkt_port_t port; 443 444 if (pr->pr_ctlport == NULL) 445 return; 446 KKASSERT(pr->pr_ctlinput != NULL); 447 port = pr->pr_ctlport(cmd, arg, extra); 448 if (port == NULL) 449 return; 450 netmsg_init(&msg.base, NULL, &curthread->td_msgport, 451 0, pr->pr_ctlinput); 452 msg.nm_cmd = cmd; 453 msg.nm_arg = arg; 454 msg.nm_extra = extra; 455 lwkt_domsg(port, &msg.base.lmsg, 0); 456 } 457 458 /* 459 * If we convert all the protosw pr_ functions for all the protocols 460 * to take a message directly, this layer can go away. For the moment 461 * our dispatcher ignores the return value, but since we are handling 462 * the replymsg ourselves we return EASYNC by convention. 463 */ 464 465 /* 466 * Handle a predicate event request. This function is only called once 467 * when the predicate message queueing request is received. 468 */ 469 void 470 netmsg_so_notify(netmsg_t msg) 471 { 472 struct lwkt_token *tok; 473 struct signalsockbuf *ssb; 474 475 ssb = (msg->notify.nm_etype & NM_REVENT) ? 476 &msg->base.nm_so->so_rcv : 477 &msg->base.nm_so->so_snd; 478 479 /* 480 * Reply immediately if the event has occured, otherwise queue the 481 * request. 482 * 483 * NOTE: Socket can change if this is an accept predicate so cache 484 * the token. 485 */ 486 tok = lwkt_token_pool_lookup(msg->base.nm_so); 487 lwkt_gettoken(tok); 488 if (msg->notify.nm_predicate(&msg->notify)) { 489 lwkt_reltoken(tok); 490 lwkt_replymsg(&msg->base.lmsg, 491 msg->base.lmsg.ms_error); 492 } else { 493 TAILQ_INSERT_TAIL(&ssb->ssb_kq.ki_mlist, &msg->notify, nm_list); 494 atomic_set_int(&ssb->ssb_flags, SSB_MEVENT); 495 lwkt_reltoken(tok); 496 } 497 } 498 499 /* 500 * Called by doio when trying to abort a netmsg_so_notify message. 501 * Unlike the other functions this one is dispatched directly by 502 * the LWKT subsystem, so it takes a lwkt_msg_t as an argument. 503 * 504 * The original message, lmsg, is under the control of the caller and 505 * will not be destroyed until we return so we can safely reference it 506 * in our synchronous abort request. 507 * 508 * This part of the abort request occurs on the originating cpu which 509 * means we may race the message flags and the original message may 510 * not even have been processed by the target cpu yet. 511 */ 512 void 513 netmsg_so_notify_doabort(lwkt_msg_t lmsg) 514 { 515 struct netmsg_so_notify_abort msg; 516 517 if ((lmsg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) { 518 netmsg_init(&msg.base, NULL, &curthread->td_msgport, 519 0, netmsg_so_notify_abort); 520 msg.nm_notifymsg = (void *)lmsg; 521 lwkt_domsg(lmsg->ms_target_port, &msg.base.lmsg, 0); 522 } 523 } 524 525 /* 526 * Predicate requests can be aborted. This function is only called once 527 * and will interlock against processing/reply races (since such races 528 * occur on the same thread that controls the port where the abort is 529 * requeued). 530 * 531 * This part of the abort request occurs on the target cpu. The message 532 * flags must be tested again in case the test that we did on the 533 * originating cpu raced. Since messages are handled in sequence, the 534 * original message will have already been handled by the loop and either 535 * replied to or queued. 536 * 537 * We really only need to interlock with MSGF_REPLY (a bit that is set on 538 * our cpu when we reply). Note that MSGF_DONE is not set until the 539 * reply reaches the originating cpu. Test both bits anyway. 540 */ 541 void 542 netmsg_so_notify_abort(netmsg_t msg) 543 { 544 struct netmsg_so_notify_abort *abrtmsg = &msg->notify_abort; 545 struct netmsg_so_notify *nmsg = abrtmsg->nm_notifymsg; 546 struct signalsockbuf *ssb; 547 548 /* 549 * The original notify message is not destroyed until after the 550 * abort request is returned, so we can check its state. 551 */ 552 lwkt_getpooltoken(nmsg->base.nm_so); 553 if ((nmsg->base.lmsg.ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) { 554 ssb = (nmsg->nm_etype & NM_REVENT) ? 555 &nmsg->base.nm_so->so_rcv : 556 &nmsg->base.nm_so->so_snd; 557 TAILQ_REMOVE(&ssb->ssb_kq.ki_mlist, nmsg, nm_list); 558 lwkt_relpooltoken(nmsg->base.nm_so); 559 lwkt_replymsg(&nmsg->base.lmsg, EINTR); 560 } else { 561 lwkt_relpooltoken(nmsg->base.nm_so); 562 } 563 564 /* 565 * Reply to the abort message 566 */ 567 lwkt_replymsg(&abrtmsg->base.lmsg, 0); 568 } 569