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 * $DragonFly: src/sys/kern/uipc_msg.c,v 1.26 2008/10/27 02:56:30 sephe Exp $ 34 */ 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/msgport.h> 40 #include <sys/protosw.h> 41 #include <sys/socket.h> 42 #include <sys/socketvar.h> 43 #include <sys/socketops.h> 44 #include <sys/thread.h> 45 #include <sys/thread2.h> 46 #include <sys/msgport2.h> 47 #include <vm/pmap.h> 48 #include <net/netmsg2.h> 49 50 #include <net/netisr.h> 51 #include <net/netmsg.h> 52 53 /* 54 * Abort a socket and free it. Called from soabort() only. 55 * 56 * The SS_ABORTING flag must already be set. 57 */ 58 void 59 so_pru_abort(struct socket *so) 60 { 61 struct netmsg_pru_abort msg; 62 lwkt_port_t port; 63 64 KKASSERT(so->so_state & SS_ABORTING); 65 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT); 66 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 67 0, netmsg_pru_abort); 68 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort; 69 msg.nm_so = so; 70 (void)lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 71 } 72 73 /* 74 * Abort a socket and free it, asynchronously. Called from 75 * soaborta() only. 76 * 77 * The SS_ABORTING flag must already be set. 78 */ 79 void 80 so_pru_aborta(struct socket *so) 81 { 82 struct netmsg_pru_abort *msg; 83 lwkt_port_t port; 84 85 KKASSERT(so->so_state & SS_ABORTING); 86 msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_WAITOK | M_ZERO); 87 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT); 88 netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 89 0, netmsg_pru_abort); 90 msg->nm_prufn = so->so_proto->pr_usrreqs->pru_abort; 91 msg->nm_so = so; 92 lwkt_sendmsg(port, &msg->nm_netmsg.nm_lmsg); 93 } 94 95 /* 96 * Abort a socket and free it. Called from soabort_oncpu() only. 97 * Caller must make sure that the current CPU is inpcb's owner CPU. 98 * 99 * The SS_ABORTING flag must already be set. 100 */ 101 void 102 so_pru_abort_oncpu(struct socket *so) 103 { 104 so->so_proto->pr_usrreqs->pru_abort(so); 105 } 106 107 int 108 so_pru_accept(struct socket *so, struct sockaddr **nam) 109 { 110 /* Block (memory allocation) in process context. XXX JH */ 111 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam)); 112 113 #ifdef notdef 114 int error; 115 struct netmsg_pru_accept msg; 116 lwkt_port_t port; 117 118 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ACCEPT); 119 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 120 netmsg_pru_accept); 121 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept; 122 msg.nm_so = so; 123 msg.nm_nam = nam; 124 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 125 return (error); 126 #endif 127 } 128 129 int 130 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai) 131 { 132 int error; 133 struct netmsg_pru_attach msg; 134 lwkt_port_t port; 135 136 port = so->so_proto->pr_mport(NULL, NULL, NULL, PRU_ATTACH); 137 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 138 netmsg_pru_attach); 139 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach; 140 msg.nm_so = so; 141 msg.nm_proto = proto; 142 msg.nm_ai = ai; 143 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 144 return (error); 145 } 146 147 int 148 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 149 { 150 int error; 151 struct netmsg_pru_bind msg; 152 lwkt_port_t port; 153 154 /* Send mesg to thread for new address. */ 155 port = so->so_proto->pr_mport(NULL, nam, NULL, PRU_BIND); 156 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 157 netmsg_pru_bind); 158 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind; 159 msg.nm_so = so; 160 msg.nm_nam = nam; 161 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 162 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 163 return (error); 164 } 165 166 int 167 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 168 { 169 int error; 170 struct netmsg_pru_connect msg; 171 lwkt_port_t port; 172 173 port = so->so_proto->pr_mport(so, nam, NULL, PRU_CONNECT); 174 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 175 netmsg_pru_connect); 176 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect; 177 msg.nm_so = so; 178 msg.nm_nam = nam; 179 msg.nm_td = td; 180 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 181 return (error); 182 } 183 184 int 185 so_pru_connect2(struct socket *so1, struct socket *so2) 186 { 187 int error; 188 struct netmsg_pru_connect2 msg; 189 lwkt_port_t port; 190 191 port = so1->so_proto->pr_mport(so1, NULL, NULL, PRU_CONNECT2); 192 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 193 netmsg_pru_connect2); 194 msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2; 195 msg.nm_so1 = so1; 196 msg.nm_so2 = so2; 197 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 198 return (error); 199 } 200 201 int 202 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) 203 { 204 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp, 205 curthread)); 206 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 207 int error; 208 struct netmsg_pru_control msg; 209 lwkt_port_t port; 210 211 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CONTROL); 212 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 213 netmsg_pru_control); 214 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control; 215 msg.nm_so = so; 216 msg.nm_cmd = cmd; 217 msg.nm_data = data; 218 msg.nm_ifp = ifp; 219 msg.nm_td = td; 220 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 221 return (error); 222 #endif 223 } 224 225 int 226 so_pru_detach(struct socket *so) 227 { 228 int error; 229 struct netmsg_pru_detach msg; 230 lwkt_port_t port; 231 232 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DETACH); 233 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 234 netmsg_pru_detach); 235 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; 236 msg.nm_so = so; 237 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 238 return (error); 239 } 240 241 int 242 so_pru_disconnect(struct socket *so) 243 { 244 int error; 245 struct netmsg_pru_disconnect msg; 246 lwkt_port_t port; 247 248 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DISCONNECT); 249 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 250 netmsg_pru_disconnect); 251 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; 252 msg.nm_so = so; 253 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 254 return (error); 255 } 256 257 int 258 so_pru_listen(struct socket *so, struct thread *td) 259 { 260 int error; 261 struct netmsg_pru_listen msg; 262 lwkt_port_t port; 263 264 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_LISTEN); 265 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 266 netmsg_pru_listen); 267 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; 268 msg.nm_so = so; 269 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 270 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 271 return (error); 272 } 273 274 int 275 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 276 { 277 int error; 278 struct netmsg_pru_peeraddr msg; 279 lwkt_port_t port; 280 281 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_PEERADDR); 282 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 283 netmsg_pru_peeraddr); 284 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; 285 msg.nm_so = so; 286 msg.nm_nam = nam; 287 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 288 return (error); 289 } 290 291 int 292 so_pru_rcvd(struct socket *so, int flags) 293 { 294 int error; 295 struct netmsg_pru_rcvd msg; 296 lwkt_port_t port; 297 298 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVD); 299 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 300 netmsg_pru_rcvd); 301 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; 302 msg.nm_so = so; 303 msg.nm_flags = flags; 304 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 305 return (error); 306 } 307 308 int 309 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 310 { 311 int error; 312 struct netmsg_pru_rcvoob msg; 313 lwkt_port_t port; 314 315 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVOOB); 316 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 317 netmsg_pru_rcvoob); 318 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob; 319 msg.nm_so = so; 320 msg.nm_m = m; 321 msg.nm_flags = flags; 322 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 323 return (error); 324 } 325 326 int 327 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 328 struct mbuf *control, struct thread *td) 329 { 330 int error; 331 struct netmsg_pru_send msg; 332 lwkt_port_t port; 333 334 port = so->so_proto->pr_mport(so, addr, &m, PRU_SEND); 335 if (port == NULL) { 336 KKASSERT(m == NULL); 337 return EINVAL; 338 } 339 340 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 341 netmsg_pru_send); 342 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send; 343 msg.nm_so = so; 344 msg.nm_flags = flags; 345 msg.nm_m = m; 346 msg.nm_addr = addr; 347 msg.nm_control = control; 348 msg.nm_td = td; 349 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 350 return (error); 351 } 352 353 /* 354 * MPSAFE 355 */ 356 int 357 so_pru_sense(struct socket *so, struct stat *sb) 358 { 359 int error; 360 struct netmsg_pru_sense msg; 361 lwkt_port_t port; 362 363 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SENSE); 364 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 365 netmsg_pru_sense); 366 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense; 367 msg.nm_so = so; 368 msg.nm_stat = sb; 369 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 370 return (error); 371 } 372 373 int 374 so_pru_shutdown(struct socket *so) 375 { 376 int error; 377 struct netmsg_pru_shutdown msg; 378 lwkt_port_t port; 379 380 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SHUTDOWN); 381 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 382 netmsg_pru_shutdown); 383 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; 384 msg.nm_so = so; 385 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 386 return (error); 387 } 388 389 int 390 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 391 { 392 int error; 393 struct netmsg_pru_sockaddr msg; 394 lwkt_port_t port; 395 396 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOCKADDR); 397 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 398 netmsg_pru_sockaddr); 399 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; 400 msg.nm_so = so; 401 msg.nm_nam = nam; 402 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 403 return (error); 404 } 405 406 int 407 so_pru_sopoll(struct socket *so, int events, struct ucred *cred) 408 { 409 int error; 410 struct netmsg_pru_sopoll msg; 411 lwkt_port_t port; 412 413 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOPOLL); 414 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 415 netmsg_pru_sopoll); 416 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll; 417 msg.nm_so = so; 418 msg.nm_events = events; 419 msg.nm_cred = cred; 420 msg.nm_td = curthread; 421 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 422 return (error); 423 } 424 425 int 426 so_pru_ctloutput(struct socket *so, struct sockopt *sopt) 427 { 428 struct netmsg_pru_ctloutput msg; 429 lwkt_port_t port; 430 int error; 431 432 KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val)); 433 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CTLOUTPUT); 434 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 435 netmsg_pru_ctloutput); 436 /* TBD: move pr_ctloutput to pr_usrreqs */ 437 msg.nm_prufn = so->so_proto->pr_ctloutput; 438 msg.nm_so = so; 439 msg.nm_sopt = sopt; 440 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 441 return (error); 442 } 443 444 /* 445 * Protocol control input, typically via icmp. 446 * 447 * If the protocol pr_ctlport is not NULL we call it to figure out the 448 * protocol port. If NULL is returned we can just return, otherwise 449 * we issue a netmsg to call pr_ctlinput in the proper thread. 450 * 451 * This must be done synchronously as arg and/or extra may point to 452 * temporary data. 453 */ 454 void 455 so_pru_ctlinput(struct protosw *pr, int cmd, struct sockaddr *arg, void *extra) 456 { 457 struct netmsg_pru_ctlinput msg; 458 lwkt_port_t port; 459 460 if (pr->pr_ctlport == NULL) 461 return; 462 KKASSERT(pr->pr_ctlinput != NULL); 463 port = pr->pr_ctlport(cmd, arg, extra); 464 if (port == NULL) 465 return; 466 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 467 netmsg_pru_ctlinput); 468 msg.nm_prufn = pr->pr_ctlinput; 469 msg.nm_cmd = cmd; 470 msg.nm_arg = arg; 471 msg.nm_extra = extra; 472 lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 473 } 474 475 /* 476 * If we convert all the protosw pr_ functions for all the protocols 477 * to take a message directly, this layer can go away. For the moment 478 * our dispatcher ignores the return value, but since we are handling 479 * the replymsg ourselves we return EASYNC by convention. 480 */ 481 482 /* 483 * Abort and destroy a socket. 484 */ 485 void 486 netmsg_pru_abort(netmsg_t msg) 487 { 488 struct netmsg_pru_abort *nm = (void *)msg; 489 struct socket *so = nm->nm_so; 490 int error; 491 492 KKASSERT(so->so_state & SS_ABORTING); 493 so->so_state &= ~SS_ABORTING; 494 error = nm->nm_prufn(so); 495 if (error) 496 sofree(so); 497 lwkt_replymsg(&msg->nm_lmsg, error); 498 } 499 500 #ifdef notused 501 void 502 netmsg_pru_accept(netmsg_t msg) 503 { 504 struct netmsg_pru_accept *nm = (void *)msg; 505 506 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 507 } 508 #endif 509 510 void 511 netmsg_pru_attach(netmsg_t msg) 512 { 513 struct netmsg_pru_attach *nm = (void *)msg; 514 515 lwkt_replymsg(&msg->nm_lmsg, 516 nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai)); 517 } 518 519 void 520 netmsg_pru_bind(netmsg_t msg) 521 { 522 struct netmsg_pru_bind *nm = (void *)msg; 523 524 lwkt_replymsg(&msg->nm_lmsg, 525 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 526 } 527 528 void 529 netmsg_pru_connect(netmsg_t msg) 530 { 531 struct netmsg_pru_connect *nm = (void *)msg; 532 533 lwkt_replymsg(&msg->nm_lmsg, 534 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 535 } 536 537 void 538 netmsg_pru_connect2(netmsg_t msg) 539 { 540 struct netmsg_pru_connect2 *nm = (void *)msg; 541 542 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so1, nm->nm_so2)); 543 } 544 545 void 546 netmsg_pru_control(netmsg_t msg) 547 { 548 struct netmsg_pru_control *nm = (void *)msg; 549 int error; 550 551 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data, 552 nm->nm_ifp, nm->nm_td); 553 lwkt_replymsg(&msg->nm_lmsg, error); 554 } 555 556 void 557 netmsg_pru_detach(netmsg_t msg) 558 { 559 struct netmsg_pru_detach *nm = (void *)msg; 560 561 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 562 } 563 564 void 565 netmsg_pru_disconnect(netmsg_t msg) 566 { 567 struct netmsg_pru_disconnect *nm = (void *)msg; 568 569 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 570 } 571 572 void 573 netmsg_pru_listen(netmsg_t msg) 574 { 575 struct netmsg_pru_listen *nm = (void *)msg; 576 577 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_td)); 578 } 579 580 void 581 netmsg_pru_peeraddr(netmsg_t msg) 582 { 583 struct netmsg_pru_peeraddr *nm = (void *)msg; 584 585 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 586 } 587 588 void 589 netmsg_pru_rcvd(netmsg_t msg) 590 { 591 struct netmsg_pru_rcvd *nm = (void *)msg; 592 593 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_flags)); 594 } 595 596 void 597 netmsg_pru_rcvoob(netmsg_t msg) 598 { 599 struct netmsg_pru_rcvoob *nm = (void *)msg; 600 601 lwkt_replymsg(&msg->nm_lmsg, 602 nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags)); 603 } 604 605 void 606 netmsg_pru_send(netmsg_t msg) 607 { 608 struct netmsg_pru_send *nm = (void *)msg; 609 int error; 610 611 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m, 612 nm->nm_addr, nm->nm_control, nm->nm_td); 613 lwkt_replymsg(&msg->nm_lmsg, error); 614 } 615 616 void 617 netmsg_pru_sense(netmsg_t msg) 618 { 619 struct netmsg_pru_sense *nm = (void *)msg; 620 621 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_stat)); 622 } 623 624 void 625 netmsg_pru_shutdown(netmsg_t msg) 626 { 627 struct netmsg_pru_shutdown *nm = (void *)msg; 628 629 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 630 } 631 632 void 633 netmsg_pru_sockaddr(netmsg_t msg) 634 { 635 struct netmsg_pru_sockaddr *nm = (void *)msg; 636 637 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 638 } 639 640 void 641 netmsg_pru_sopoll(netmsg_t msg) 642 { 643 struct netmsg_pru_sopoll *nm = (void *)msg; 644 int error; 645 646 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td); 647 lwkt_replymsg(&msg->nm_lmsg, error); 648 } 649 650 void 651 netmsg_pru_ctloutput(netmsg_t msg) 652 { 653 struct netmsg_pru_ctloutput *nm = (void *)msg; 654 655 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_sopt)); 656 } 657 658 void 659 netmsg_pru_ctlinput(netmsg_t msg) 660 { 661 struct netmsg_pru_ctlinput *nm = (void *)msg; 662 663 nm->nm_prufn(nm->nm_cmd, nm->nm_arg, nm->nm_extra); 664 lwkt_replymsg(&nm->nm_netmsg.nm_lmsg, 0); 665 } 666 667 void 668 netmsg_pr_timeout(netmsg_t msg) 669 { 670 struct netmsg_pr_timeout *nm = (void *)msg; 671 672 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prfn()); 673 } 674 675 /* 676 * Handle a predicate event request. This function is only called once 677 * when the predicate message queueing request is received. 678 */ 679 void 680 netmsg_so_notify(netmsg_t netmsg) 681 { 682 struct netmsg_so_notify *msg = (void *)netmsg; 683 struct signalsockbuf *ssb; 684 685 ssb = (msg->nm_etype & NM_REVENT) ? 686 &msg->nm_so->so_rcv : 687 &msg->nm_so->so_snd; 688 689 /* 690 * Reply immediately if the event has occured, otherwise queue the 691 * request. 692 */ 693 if (msg->nm_predicate(&msg->nm_netmsg)) { 694 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, 695 msg->nm_netmsg.nm_lmsg.ms_error); 696 } else { 697 TAILQ_INSERT_TAIL(&ssb->ssb_sel.si_mlist, msg, nm_list); 698 ssb->ssb_flags |= SSB_MEVENT; 699 } 700 } 701 702 /* 703 * Called by doio when trying to abort a netmsg_so_notify message. 704 * Unlike the other functions this one is dispatched directly by 705 * the LWKT subsystem, so it takes a lwkt_msg_t as an argument. 706 * 707 * The original message, lmsg, is under the control of the caller and 708 * will not be destroyed until we return so we can safely reference it 709 * in our synchronous abort request. 710 * 711 * This part of the abort request occurs on the originating cpu which 712 * means we may race the message flags and the original message may 713 * not even have been processed by the target cpu yet. 714 */ 715 void 716 netmsg_so_notify_doabort(lwkt_msg_t lmsg) 717 { 718 struct netmsg_so_notify_abort msg; 719 720 if ((lmsg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) { 721 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 722 netmsg_so_notify_abort); 723 msg.nm_notifymsg = (void *)lmsg; 724 lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg, 0); 725 } 726 } 727 728 /* 729 * Predicate requests can be aborted. This function is only called once 730 * and will interlock against processing/reply races (since such races 731 * occur on the same thread that controls the port where the abort is 732 * requeued). 733 * 734 * This part of the abort request occurs on the target cpu. The message 735 * flags must be tested again in case the test that we did on the 736 * originating cpu raced. Since messages are handled in sequence, the 737 * original message will have already been handled by the loop and either 738 * replied to or queued. 739 * 740 * We really only need to interlock with MSGF_REPLY (a bit that is set on 741 * our cpu when we reply). Note that MSGF_DONE is not set until the 742 * reply reaches the originating cpu. Test both bits anyway. 743 */ 744 void 745 netmsg_so_notify_abort(netmsg_t netmsg) 746 { 747 struct netmsg_so_notify_abort *abrtmsg = (void *)netmsg; 748 struct netmsg_so_notify *msg = abrtmsg->nm_notifymsg; 749 struct signalsockbuf *ssb; 750 751 /* 752 * The original notify message is not destroyed until after the 753 * abort request is returned, so we can check its state. 754 */ 755 if ((msg->nm_netmsg.nm_lmsg.ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) { 756 ssb = (msg->nm_etype & NM_REVENT) ? 757 &msg->nm_so->so_rcv : 758 &msg->nm_so->so_snd; 759 TAILQ_REMOVE(&ssb->ssb_sel.si_mlist, msg, nm_list); 760 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, EINTR); 761 } 762 763 /* 764 * Reply to the abort message 765 */ 766 lwkt_replymsg(&abrtmsg->nm_netmsg.nm_lmsg, 0); 767 } 768 769