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.5 2004/03/24 21:58:44 hsu 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 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp, 184 td)); 185 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 186 int error; 187 struct netmsg_pru_control msg; 188 lwkt_port_t port; 189 190 if (!so->so_proto->pr_mport) 191 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 192 ifp, td)); 193 194 port = so->so_proto->pr_mport(so, NULL); 195 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONTROL); 196 msg.nm_handler = netmsg_pru_dispatcher; 197 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control; 198 msg.nm_so = so; 199 msg.nm_cmd = cmd; 200 msg.nm_data = data; 201 msg.nm_ifp = ifp; 202 msg.nm_td = td; 203 error = lwkt_domsg(port, &msg.nm_lmsg); 204 return (error); 205 #endif 206 } 207 208 int 209 so_pru_detach(struct socket *so) 210 { 211 int error; 212 struct netmsg_pru_detach msg; 213 lwkt_port_t port; 214 215 if (!so->so_proto->pr_mport) 216 return ((*so->so_proto->pr_usrreqs->pru_detach)(so)); 217 218 port = so->so_proto->pr_mport(so, NULL); 219 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DETACH); 220 msg.nm_handler = netmsg_pru_dispatcher; 221 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; 222 msg.nm_so = so; 223 error = lwkt_domsg(port, &msg.nm_lmsg); 224 return (error); 225 } 226 227 int 228 so_pru_disconnect(struct socket *so) 229 { 230 int error; 231 struct netmsg_pru_disconnect msg; 232 lwkt_port_t port; 233 234 if (!so->so_proto->pr_mport) 235 return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so)); 236 237 port = so->so_proto->pr_mport(so, NULL); 238 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DISCONNECT); 239 msg.nm_handler = netmsg_pru_dispatcher; 240 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; 241 msg.nm_so = so; 242 error = lwkt_domsg(port, &msg.nm_lmsg); 243 return (error); 244 } 245 246 int 247 so_pru_listen(struct socket *so, struct thread *td) 248 { 249 int error; 250 struct netmsg_pru_listen msg; 251 lwkt_port_t port; 252 253 if (!so->so_proto->pr_mport) 254 return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td)); 255 256 port = so->so_proto->pr_mport(so, NULL); 257 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_LISTEN); 258 msg.nm_handler = netmsg_pru_dispatcher; 259 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; 260 msg.nm_so = so; 261 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 262 error = lwkt_domsg(port, &msg.nm_lmsg); 263 return (error); 264 } 265 266 int 267 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 268 { 269 int error; 270 struct netmsg_pru_peeraddr msg; 271 lwkt_port_t port; 272 273 if (!so->so_proto->pr_mport) 274 return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam)); 275 276 port = so->so_proto->pr_mport(so, NULL); 277 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_PEERADDR); 278 msg.nm_handler = netmsg_pru_dispatcher; 279 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; 280 msg.nm_so = so; 281 msg.nm_nam = nam; 282 error = lwkt_domsg(port, &msg.nm_lmsg); 283 return (error); 284 } 285 286 int 287 so_pru_rcvd(struct socket *so, int flags) 288 { 289 int error; 290 struct netmsg_pru_rcvd msg; 291 lwkt_port_t port; 292 293 if (!so->so_proto->pr_mport) 294 return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags)); 295 296 port = so->so_proto->pr_mport(so, NULL); 297 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVD); 298 msg.nm_handler = netmsg_pru_dispatcher; 299 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; 300 msg.nm_so = so; 301 msg.nm_flags = flags; 302 error = lwkt_domsg(port, &msg.nm_lmsg); 303 return (error); 304 } 305 306 int 307 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 308 { 309 int error; 310 struct netmsg_pru_rcvoob msg; 311 lwkt_port_t port; 312 313 if (!so->so_proto->pr_mport) 314 return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags)); 315 316 port = so->so_proto->pr_mport(so, NULL); 317 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVOOB); 318 msg.nm_handler = netmsg_pru_dispatcher; 319 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob; 320 msg.nm_so = so; 321 msg.nm_m = m; 322 msg.nm_flags = flags; 323 error = lwkt_domsg(port, &msg.nm_lmsg); 324 return (error); 325 } 326 327 int 328 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 329 struct mbuf *control, struct thread *td) 330 { 331 int error; 332 struct netmsg_pru_send msg; 333 lwkt_port_t port; 334 335 if (!so->so_proto->pr_mport) 336 return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m, 337 addr, control, td)); 338 339 port = so->so_proto->pr_mport(so, NULL); 340 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SEND); 341 msg.nm_handler = netmsg_pru_dispatcher; 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_lmsg); 350 return (error); 351 } 352 353 int 354 so_pru_sense(struct socket *so, struct stat *sb) 355 { 356 int error; 357 struct netmsg_pru_sense msg; 358 lwkt_port_t port; 359 360 if (!so->so_proto->pr_mport) 361 return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb)); 362 363 port = so->so_proto->pr_mport(so, NULL); 364 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SENSE); 365 msg.nm_handler = netmsg_pru_dispatcher; 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_lmsg); 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 if (!so->so_proto->pr_mport) 381 return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so)); 382 383 port = so->so_proto->pr_mport(so, NULL); 384 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SHUTDOWN); 385 msg.nm_handler = netmsg_pru_dispatcher; 386 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; 387 msg.nm_so = so; 388 error = lwkt_domsg(port, &msg.nm_lmsg); 389 return (error); 390 } 391 392 int 393 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 394 { 395 int error; 396 struct netmsg_pru_sockaddr msg; 397 lwkt_port_t port; 398 399 if (!so->so_proto->pr_mport) 400 return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam)); 401 402 port = so->so_proto->pr_mport(so, NULL); 403 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOCKADDR); 404 msg.nm_handler = netmsg_pru_dispatcher; 405 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; 406 msg.nm_so = so; 407 msg.nm_nam = nam; 408 error = lwkt_domsg(port, &msg.nm_lmsg); 409 return (error); 410 } 411 412 int 413 so_pru_sopoll(struct socket *so, int events, struct ucred *cred, 414 struct thread *td) 415 { 416 int error; 417 struct netmsg_pru_sopoll msg; 418 lwkt_port_t port; 419 420 if (!so->so_proto->pr_mport) 421 return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events, 422 cred, td)); 423 424 port = so->so_proto->pr_mport(so, NULL); 425 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOPOLL); 426 msg.nm_handler = netmsg_pru_dispatcher; 427 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll; 428 msg.nm_so = so; 429 msg.nm_events = events; 430 msg.nm_cred = cred; 431 msg.nm_td = td; 432 error = lwkt_domsg(port, &msg.nm_lmsg); 433 return (error); 434 } 435 436 int 437 so_pr_ctloutput(struct socket *so, struct sockopt *sopt) 438 { 439 return ((*so->so_proto->pr_ctloutput)(so, sopt)); 440 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 441 struct netmsg_pr_ctloutput msg; 442 lwkt_port_t port; 443 int error; 444 445 if (!so->so_proto->pr_mport) 446 return ((*so->so_proto->pr_ctloutput)(so, sopt)); 447 448 port = so->so_proto->pr_mport(so, NULL); 449 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PR_CTLOUTPUT); 450 msg.nm_handler = netmsg_pr_dispatcher; 451 msg.nm_prfn = so->so_proto->pr_ctloutput; 452 msg.nm_so = so; 453 msg.nm_sopt = sopt; 454 error = lwkt_domsg(port, &msg.nm_lmsg); 455 return (error); 456 #endif 457 } 458 459 /* 460 * If we convert all the pru_usrreq functions for all the protocols 461 * to take a message directly, this layer can go away. 462 */ 463 static int 464 netmsg_pru_dispatcher(struct netmsg *msg) 465 { 466 int error; 467 468 switch (msg->nm_lmsg.ms_cmd) { 469 case CMD_NETMSG_PRU_ABORT: 470 { 471 struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg; 472 473 error = nm->nm_prufn(nm->nm_so); 474 break; 475 } 476 case CMD_NETMSG_PRU_ACCEPT: 477 { 478 struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg; 479 480 error = nm->nm_prufn(nm->nm_so, nm->nm_nam); 481 break; 482 } 483 case CMD_NETMSG_PRU_ATTACH: 484 { 485 struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg; 486 487 error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai); 488 break; 489 } 490 case CMD_NETMSG_PRU_BIND: 491 { 492 struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg; 493 494 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td); 495 break; 496 } 497 case CMD_NETMSG_PRU_CONNECT: 498 { 499 struct netmsg_pru_connect *nm = 500 (struct netmsg_pru_connect *)msg; 501 502 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td); 503 break; 504 } 505 case CMD_NETMSG_PRU_CONNECT2: 506 { 507 struct netmsg_pru_connect2 *nm = 508 (struct netmsg_pru_connect2 *)msg; 509 510 error = nm->nm_prufn(nm->nm_so1, nm->nm_so2); 511 break; 512 } 513 case CMD_NETMSG_PRU_CONTROL: 514 { 515 struct netmsg_pru_control *nm = 516 (struct netmsg_pru_control *)msg; 517 518 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data, 519 nm->nm_ifp, nm->nm_td); 520 break; 521 } 522 case CMD_NETMSG_PRU_DETACH: 523 { 524 struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg; 525 526 error = nm->nm_prufn(nm->nm_so); 527 break; 528 } 529 case CMD_NETMSG_PRU_DISCONNECT: 530 { 531 struct netmsg_pru_disconnect *nm = 532 (struct netmsg_pru_disconnect *)msg; 533 534 error = nm->nm_prufn(nm->nm_so); 535 break; 536 } 537 case CMD_NETMSG_PRU_LISTEN: 538 { 539 struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg; 540 541 error = nm->nm_prufn(nm->nm_so, nm->nm_td); 542 break; 543 } 544 case CMD_NETMSG_PRU_PEERADDR: 545 { 546 struct netmsg_pru_peeraddr *nm = 547 (struct netmsg_pru_peeraddr *)msg; 548 549 error = nm->nm_prufn(nm->nm_so, nm->nm_nam); 550 break; 551 } 552 case CMD_NETMSG_PRU_RCVD: 553 { 554 struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg; 555 556 error = nm->nm_prufn(nm->nm_so, nm->nm_flags); 557 break; 558 } 559 case CMD_NETMSG_PRU_RCVOOB: 560 { 561 struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg; 562 563 error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags); 564 break; 565 } 566 case CMD_NETMSG_PRU_SEND: 567 { 568 struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg; 569 570 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m, 571 nm->nm_addr, nm->nm_control, nm->nm_td); 572 break; 573 } 574 case CMD_NETMSG_PRU_SENSE: 575 { 576 struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg; 577 578 error = nm->nm_prufn(nm->nm_so, nm->nm_stat); 579 break; 580 } 581 case CMD_NETMSG_PRU_SHUTDOWN: 582 { 583 struct netmsg_pru_shutdown *nm = 584 (struct netmsg_pru_shutdown *)msg; 585 586 error = nm->nm_prufn(nm->nm_so); 587 break; 588 } 589 case CMD_NETMSG_PRU_SOCKADDR: 590 { 591 struct netmsg_pru_sockaddr *nm = 592 (struct netmsg_pru_sockaddr *)msg; 593 594 error = nm->nm_prufn(nm->nm_so, nm->nm_nam); 595 break; 596 } 597 case CMD_NETMSG_PRU_SOPOLL: 598 { 599 struct netmsg_pru_sopoll *nm = 600 (struct netmsg_pru_sopoll *)msg; 601 602 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, 603 nm->nm_td); 604 break; 605 } 606 default: 607 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd); 608 break; 609 } 610 return(error); 611 } 612 613 /* 614 * If we convert all the protosw pr_ functions for all the protocols 615 * to take a message directly, this layer can go away. 616 */ 617 int 618 netmsg_pr_dispatcher(struct netmsg *msg) 619 { 620 int error = 0; 621 622 switch (msg->nm_lmsg.ms_cmd) { 623 case CMD_NETMSG_PR_CTLOUTPUT: 624 { 625 struct netmsg_pr_ctloutput *nm = 626 (struct netmsg_pr_ctloutput *)msg; 627 628 error = nm->nm_prfn(nm->nm_so, nm->nm_sopt); 629 break; 630 } 631 case CMD_NETMSG_PR_TIMEOUT: 632 { 633 struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg; 634 635 nm->nm_prfn(); 636 break; 637 } 638 default: 639 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd); 640 break; 641 } 642 return(error); 643 } 644 645