1 /* 2 * Copyright (c) 2003, 2004 Jeffrey Hsu. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Jeffrey M. Hsu. 16 * 4. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $DragonFly: src/sys/kern/uipc_msg.c,v 1.3 2004/03/06 23:19:01 dillon Exp $ 31 */ 32 33 #if defined(SMP) || defined(ALWAYS_MSG) 34 35 #include <sys/param.h> 36 #include <sys/systm.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 46 #include <net/netisr.h> 47 #include <net/netmsg.h> 48 49 static int netmsg_pru_dispatcher(struct netmsg *msg); 50 51 int 52 so_pru_abort(struct socket *so) 53 { 54 int error; 55 struct netmsg_pru_abort msg; 56 lwkt_port_t port; 57 58 if (!so->so_proto->pr_mport) 59 return ((*so->so_proto->pr_usrreqs->pru_abort)(so)); 60 61 port = so->so_proto->pr_mport(so, NULL); 62 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_ABORT); 63 msg.nm_handler = netmsg_pru_dispatcher; 64 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort; 65 msg.nm_so = so; 66 error = lwkt_domsg(port, &msg.nm_lmsg); 67 return (error); 68 } 69 70 int 71 so_pru_accept(struct socket *so, struct sockaddr **nam) 72 { 73 int error; 74 struct netmsg_pru_accept msg; 75 lwkt_port_t port; 76 77 if (!so->so_proto->pr_mport) 78 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam)); 79 80 port = so->so_proto->pr_mport(so, NULL); 81 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_ACCEPT); 82 msg.nm_handler = netmsg_pru_dispatcher; 83 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept; 84 msg.nm_so = so; 85 msg.nm_nam = nam; 86 error = lwkt_domsg(port, &msg.nm_lmsg); 87 return (error); 88 } 89 90 int 91 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai) 92 { 93 int error; 94 struct netmsg_pru_attach msg; 95 lwkt_port_t port; 96 97 if (!so->so_proto->pr_mport) 98 return ((*so->so_proto->pr_usrreqs->pru_attach)(so, proto, ai)); 99 100 port = so->so_proto->pr_mport(NULL, NULL); 101 102 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_ATTACH); 103 msg.nm_handler = netmsg_pru_dispatcher; 104 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach; 105 msg.nm_so = so; 106 msg.nm_proto = proto; 107 msg.nm_ai = ai; 108 error = lwkt_domsg(port, &msg.nm_lmsg); 109 return (error); 110 } 111 112 int 113 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 114 { 115 int error; 116 struct netmsg_pru_bind msg; 117 lwkt_port_t port; 118 119 if (!so->so_proto->pr_mport) 120 return ((*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td)); 121 122 /* Send mesg to thread for new address. */ 123 port = so->so_proto->pr_mport(NULL, nam); 124 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_BIND); 125 msg.nm_handler = netmsg_pru_dispatcher; 126 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind; 127 msg.nm_so = so; 128 msg.nm_nam = nam; 129 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 130 error = lwkt_domsg(port, &msg.nm_lmsg); 131 return (error); 132 } 133 134 int 135 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 136 { 137 int error; 138 struct netmsg_pru_connect msg; 139 lwkt_port_t port; 140 141 if (!so->so_proto->pr_mport) 142 return ((*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td)); 143 144 port = so->so_proto->pr_mport(so, NULL); 145 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONNECT); 146 msg.nm_handler = netmsg_pru_dispatcher; 147 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect; 148 msg.nm_so = so; 149 msg.nm_nam = nam; 150 msg.nm_td = td; 151 error = lwkt_domsg(port, &msg.nm_lmsg); 152 return (error); 153 } 154 155 int 156 so_pru_connect2(struct socket *so1, struct socket *so2) 157 { 158 int error; 159 struct netmsg_pru_connect2 msg; 160 lwkt_port_t port; 161 162 if (!so1->so_proto->pr_mport) 163 return ((*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2)); 164 165 /* 166 * Actually, connect2() is only called for Unix domain sockets 167 * and we currently short-circuit that above, so the following 168 * code is never reached. 169 */ 170 panic("connect2 on socket type %d", so1->so_type); 171 port = so1->so_proto->pr_mport(so1, NULL); 172 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONNECT2); 173 msg.nm_handler = netmsg_pru_dispatcher; 174 msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2; 175 msg.nm_so1 = so1; 176 msg.nm_so2 = so2; 177 error = lwkt_domsg(port, &msg.nm_lmsg); 178 return (error); 179 } 180 181 int 182 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, 183 struct thread *td) 184 { 185 int error; 186 struct netmsg_pru_control msg; 187 lwkt_port_t port; 188 189 if (!so->so_proto->pr_mport) 190 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 191 ifp, td)); 192 193 port = so->so_proto->pr_mport(so, NULL); 194 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONTROL); 195 msg.nm_handler = netmsg_pru_dispatcher; 196 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control; 197 msg.nm_so = so; 198 msg.nm_cmd = cmd; 199 msg.nm_data = data; 200 msg.nm_ifp = ifp; 201 msg.nm_td = td; 202 error = lwkt_domsg(port, &msg.nm_lmsg); 203 return (error); 204 } 205 206 int 207 so_pru_detach(struct socket *so) 208 { 209 int error; 210 struct netmsg_pru_detach msg; 211 lwkt_port_t port; 212 213 if (!so->so_proto->pr_mport) 214 return ((*so->so_proto->pr_usrreqs->pru_detach)(so)); 215 216 port = so->so_proto->pr_mport(so, NULL); 217 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DETACH); 218 msg.nm_handler = netmsg_pru_dispatcher; 219 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; 220 msg.nm_so = so; 221 error = lwkt_domsg(port, &msg.nm_lmsg); 222 return (error); 223 } 224 225 int 226 so_pru_disconnect(struct socket *so) 227 { 228 int error; 229 struct netmsg_pru_disconnect msg; 230 lwkt_port_t port; 231 232 if (!so->so_proto->pr_mport) 233 return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so)); 234 235 port = so->so_proto->pr_mport(so, NULL); 236 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DISCONNECT); 237 msg.nm_handler = netmsg_pru_dispatcher; 238 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; 239 msg.nm_so = so; 240 error = lwkt_domsg(port, &msg.nm_lmsg); 241 return (error); 242 } 243 244 int 245 so_pru_listen(struct socket *so, struct thread *td) 246 { 247 int error; 248 struct netmsg_pru_listen msg; 249 lwkt_port_t port; 250 251 if (!so->so_proto->pr_mport) 252 return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td)); 253 254 port = so->so_proto->pr_mport(so, NULL); 255 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_LISTEN); 256 msg.nm_handler = netmsg_pru_dispatcher; 257 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; 258 msg.nm_so = so; 259 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 260 error = lwkt_domsg(port, &msg.nm_lmsg); 261 return (error); 262 } 263 264 int 265 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 266 { 267 int error; 268 struct netmsg_pru_peeraddr msg; 269 lwkt_port_t port; 270 271 if (!so->so_proto->pr_mport) 272 return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam)); 273 274 port = so->so_proto->pr_mport(so, NULL); 275 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_PEERADDR); 276 msg.nm_handler = netmsg_pru_dispatcher; 277 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; 278 msg.nm_so = so; 279 msg.nm_nam = nam; 280 error = lwkt_domsg(port, &msg.nm_lmsg); 281 return (error); 282 } 283 284 int 285 so_pru_rcvd(struct socket *so, int flags) 286 { 287 int error; 288 struct netmsg_pru_rcvd msg; 289 lwkt_port_t port; 290 291 if (!so->so_proto->pr_mport) 292 return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags)); 293 294 port = so->so_proto->pr_mport(so, NULL); 295 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVD); 296 msg.nm_handler = netmsg_pru_dispatcher; 297 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; 298 msg.nm_so = so; 299 msg.nm_flags = flags; 300 error = lwkt_domsg(port, &msg.nm_lmsg); 301 return (error); 302 } 303 304 int 305 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 306 { 307 int error; 308 struct netmsg_pru_rcvoob msg; 309 lwkt_port_t port; 310 311 if (!so->so_proto->pr_mport) 312 return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags)); 313 314 port = so->so_proto->pr_mport(so, NULL); 315 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVOOB); 316 msg.nm_handler = netmsg_pru_dispatcher; 317 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob; 318 msg.nm_so = so; 319 msg.nm_m = m; 320 msg.nm_flags = flags; 321 error = lwkt_domsg(port, &msg.nm_lmsg); 322 return (error); 323 } 324 325 int 326 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 327 struct mbuf *control, struct thread *td) 328 { 329 int error; 330 struct netmsg_pru_send msg; 331 lwkt_port_t port; 332 333 if (!so->so_proto->pr_mport) 334 return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m, 335 addr, control, td)); 336 337 port = so->so_proto->pr_mport(so, NULL); 338 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SEND); 339 msg.nm_handler = netmsg_pru_dispatcher; 340 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send; 341 msg.nm_so = so; 342 msg.nm_flags = flags; 343 msg.nm_m = m; 344 msg.nm_addr = addr; 345 msg.nm_control = control; 346 msg.nm_td = td; 347 error = lwkt_domsg(port, &msg.nm_lmsg); 348 return (error); 349 } 350 351 int 352 so_pru_sense(struct socket *so, struct stat *sb) 353 { 354 int error; 355 struct netmsg_pru_sense msg; 356 lwkt_port_t port; 357 358 if (!so->so_proto->pr_mport) 359 return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb)); 360 361 port = so->so_proto->pr_mport(so, NULL); 362 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SENSE); 363 msg.nm_handler = netmsg_pru_dispatcher; 364 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense; 365 msg.nm_so = so; 366 msg.nm_stat = sb; 367 error = lwkt_domsg(port, &msg.nm_lmsg); 368 return (error); 369 } 370 371 int 372 so_pru_shutdown(struct socket *so) 373 { 374 int error; 375 struct netmsg_pru_shutdown msg; 376 lwkt_port_t port; 377 378 if (!so->so_proto->pr_mport) 379 return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so)); 380 381 port = so->so_proto->pr_mport(so, NULL); 382 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SHUTDOWN); 383 msg.nm_handler = netmsg_pru_dispatcher; 384 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; 385 msg.nm_so = so; 386 error = lwkt_domsg(port, &msg.nm_lmsg); 387 return (error); 388 } 389 390 int 391 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 392 { 393 int error; 394 struct netmsg_pru_sockaddr msg; 395 lwkt_port_t port; 396 397 if (!so->so_proto->pr_mport) 398 return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam)); 399 400 port = so->so_proto->pr_mport(so, NULL); 401 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOCKADDR); 402 msg.nm_handler = netmsg_pru_dispatcher; 403 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; 404 msg.nm_so = so; 405 msg.nm_nam = nam; 406 error = lwkt_domsg(port, &msg.nm_lmsg); 407 return (error); 408 } 409 410 int 411 so_pru_sopoll(struct socket *so, int events, struct ucred *cred, 412 struct thread *td) 413 { 414 int error; 415 struct netmsg_pru_sopoll msg; 416 lwkt_port_t port; 417 418 if (!so->so_proto->pr_mport) 419 return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events, 420 cred, td)); 421 422 port = so->so_proto->pr_mport(so, NULL); 423 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOPOLL); 424 msg.nm_handler = netmsg_pru_dispatcher; 425 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll; 426 msg.nm_so = so; 427 msg.nm_events = events; 428 msg.nm_cred = cred; 429 msg.nm_td = td; 430 error = lwkt_domsg(port, &msg.nm_lmsg); 431 return (error); 432 } 433 434 int 435 so_pr_ctloutput(struct socket *so, struct sockopt *sopt) 436 { 437 return ((*so->so_proto->pr_ctloutput)(so, sopt)); 438 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 439 struct netmsg_pr_ctloutput msg; 440 lwkt_port_t port; 441 int error; 442 443 if (!so->so_proto->pr_mport) 444 return ((*so->so_proto->pr_ctloutput)(so, sopt)); 445 446 port = so->so_proto->pr_mport(so, NULL); 447 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PR_CTLOUTPUT); 448 msg.nm_handler = netmsg_pr_dispatcher; 449 msg.nm_prfn = so->so_proto->pr_ctloutput; 450 msg.nm_so = so; 451 msg.nm_sopt = sopt; 452 error = lwkt_domsg(port, &msg.nm_lmsg); 453 return (error); 454 #endif 455 } 456 457 /* 458 * If we convert all the pru_usrreq functions for all the protocols 459 * to take a message directly, this layer can go away. 460 */ 461 static int 462 netmsg_pru_dispatcher(struct netmsg *msg) 463 { 464 int error; 465 466 switch (msg->nm_lmsg.ms_cmd) { 467 case CMD_NETMSG_PRU_ABORT: 468 { 469 struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg; 470 471 error = nm->nm_prufn(nm->nm_so); 472 break; 473 } 474 case CMD_NETMSG_PRU_ACCEPT: 475 { 476 struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg; 477 478 error = nm->nm_prufn(nm->nm_so, nm->nm_nam); 479 break; 480 } 481 case CMD_NETMSG_PRU_ATTACH: 482 { 483 struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg; 484 485 error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai); 486 break; 487 } 488 case CMD_NETMSG_PRU_BIND: 489 { 490 struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg; 491 492 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td); 493 break; 494 } 495 case CMD_NETMSG_PRU_CONNECT: 496 { 497 struct netmsg_pru_connect *nm = 498 (struct netmsg_pru_connect *)msg; 499 500 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td); 501 break; 502 } 503 case CMD_NETMSG_PRU_CONNECT2: 504 { 505 struct netmsg_pru_connect2 *nm = 506 (struct netmsg_pru_connect2 *)msg; 507 508 error = nm->nm_prufn(nm->nm_so1, nm->nm_so2); 509 break; 510 } 511 case CMD_NETMSG_PRU_CONTROL: 512 { 513 struct netmsg_pru_control *nm = 514 (struct netmsg_pru_control *)msg; 515 516 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data, 517 nm->nm_ifp, nm->nm_td); 518 break; 519 } 520 case CMD_NETMSG_PRU_DETACH: 521 { 522 struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg; 523 524 error = nm->nm_prufn(nm->nm_so); 525 break; 526 } 527 case CMD_NETMSG_PRU_DISCONNECT: 528 { 529 struct netmsg_pru_disconnect *nm = 530 (struct netmsg_pru_disconnect *)msg; 531 532 error = nm->nm_prufn(nm->nm_so); 533 break; 534 } 535 case CMD_NETMSG_PRU_LISTEN: 536 { 537 struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg; 538 539 error = nm->nm_prufn(nm->nm_so, nm->nm_td); 540 break; 541 } 542 case CMD_NETMSG_PRU_PEERADDR: 543 { 544 struct netmsg_pru_peeraddr *nm = 545 (struct netmsg_pru_peeraddr *)msg; 546 547 error = nm->nm_prufn(nm->nm_so, nm->nm_nam); 548 break; 549 } 550 case CMD_NETMSG_PRU_RCVD: 551 { 552 struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg; 553 554 error = nm->nm_prufn(nm->nm_so, nm->nm_flags); 555 break; 556 } 557 case CMD_NETMSG_PRU_RCVOOB: 558 { 559 struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg; 560 561 error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags); 562 break; 563 } 564 case CMD_NETMSG_PRU_SEND: 565 { 566 struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg; 567 568 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m, 569 nm->nm_addr, nm->nm_control, nm->nm_td); 570 break; 571 } 572 case CMD_NETMSG_PRU_SENSE: 573 { 574 struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg; 575 576 error = nm->nm_prufn(nm->nm_so, nm->nm_stat); 577 break; 578 } 579 case CMD_NETMSG_PRU_SHUTDOWN: 580 { 581 struct netmsg_pru_shutdown *nm = 582 (struct netmsg_pru_shutdown *)msg; 583 584 error = nm->nm_prufn(nm->nm_so); 585 break; 586 } 587 case CMD_NETMSG_PRU_SOCKADDR: 588 { 589 struct netmsg_pru_sockaddr *nm = 590 (struct netmsg_pru_sockaddr *)msg; 591 592 error = nm->nm_prufn(nm->nm_so, nm->nm_nam); 593 break; 594 } 595 case CMD_NETMSG_PRU_SOPOLL: 596 { 597 struct netmsg_pru_sopoll *nm = 598 (struct netmsg_pru_sopoll *)msg; 599 600 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, 601 nm->nm_td); 602 break; 603 } 604 default: 605 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd); 606 break; 607 } 608 return(error); 609 } 610 611 /* 612 * If we convert all the protosw pr_ functions for all the protocols 613 * to take a message directly, this layer can go away. 614 */ 615 int 616 netmsg_pr_dispatcher(struct netmsg *msg) 617 { 618 int error = 0; 619 620 switch (msg->nm_lmsg.ms_cmd) { 621 case CMD_NETMSG_PR_CTLOUTPUT: 622 { 623 struct netmsg_pr_ctloutput *nm = 624 (struct netmsg_pr_ctloutput *)msg; 625 626 error = nm->nm_prfn(nm->nm_so, nm->nm_sopt); 627 break; 628 } 629 case CMD_NETMSG_PR_TIMEOUT: 630 { 631 struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg; 632 633 nm->nm_prfn(); 634 break; 635 } 636 default: 637 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd); 638 break; 639 } 640 return(error); 641 } 642 643 #endif 644