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