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