1 /* $NetBSD: sockin.c,v 1.58 2014/08/09 05:33:01 rtr Exp $ */ 2 3 /* 4 * Copyright (c) 2008, 2009 Antti Kantee. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: sockin.c,v 1.58 2014/08/09 05:33:01 rtr Exp $"); 30 31 #include <sys/param.h> 32 #include <sys/condvar.h> 33 #include <sys/domain.h> 34 #include <sys/kmem.h> 35 #include <sys/kthread.h> 36 #include <sys/mbuf.h> 37 #include <sys/mutex.h> 38 #include <sys/once.h> 39 #include <sys/poll.h> 40 #include <sys/protosw.h> 41 #include <sys/queue.h> 42 #include <sys/socket.h> 43 #include <sys/socketvar.h> 44 #include <sys/time.h> 45 46 #include <net/bpf.h> 47 #include <net/if.h> 48 #include <net/radix.h> 49 50 #include <netinet/in.h> 51 #include <netinet/in_systm.h> 52 #include <netinet/ip.h> 53 54 #include <rump/rumpuser.h> 55 56 #include "rump_private.h" 57 #include "sockin_user.h" 58 59 /* 60 * An inet communication domain which uses the socket interface. 61 * Supports IPv4 & IPv6 UDP/TCP. 62 */ 63 64 DOMAIN_DEFINE(sockindomain); 65 DOMAIN_DEFINE(sockin6domain); 66 67 static int sockin_do_init(void); 68 static void sockin_init(void); 69 static int sockin_attach(struct socket *, int); 70 static void sockin_detach(struct socket *); 71 static int sockin_accept(struct socket *, struct mbuf *); 72 static int sockin_connect2(struct socket *, struct socket *); 73 static int sockin_bind(struct socket *, struct mbuf *, struct lwp *); 74 static int sockin_listen(struct socket *, struct lwp *); 75 static int sockin_connect(struct socket *, struct mbuf *, struct lwp *); 76 static int sockin_disconnect(struct socket *); 77 static int sockin_shutdown(struct socket *); 78 static int sockin_abort(struct socket *); 79 static int sockin_ioctl(struct socket *, u_long, void *, struct ifnet *); 80 static int sockin_stat(struct socket *, struct stat *); 81 static int sockin_peeraddr(struct socket *, struct mbuf *); 82 static int sockin_sockaddr(struct socket *, struct mbuf *); 83 static int sockin_rcvd(struct socket *, int, struct lwp *); 84 static int sockin_recvoob(struct socket *, struct mbuf *, int); 85 static int sockin_send(struct socket *, struct mbuf *, struct mbuf *, 86 struct mbuf *, struct lwp *); 87 static int sockin_sendoob(struct socket *, struct mbuf *, struct mbuf *); 88 static int sockin_purgeif(struct socket *, struct ifnet *); 89 static int sockin_usrreq(struct socket *, int, struct mbuf *, 90 struct mbuf *, struct mbuf *, struct lwp *); 91 static int sockin_ctloutput(int op, struct socket *, struct sockopt *); 92 93 static const struct pr_usrreqs sockin_usrreqs = { 94 .pr_attach = sockin_attach, 95 .pr_detach = sockin_detach, 96 .pr_accept = sockin_accept, 97 .pr_bind = sockin_bind, 98 .pr_listen = sockin_listen, 99 .pr_connect = sockin_connect, 100 .pr_connect2 = sockin_connect2, 101 .pr_disconnect = sockin_disconnect, 102 .pr_shutdown = sockin_shutdown, 103 .pr_abort = sockin_abort, 104 .pr_ioctl = sockin_ioctl, 105 .pr_stat = sockin_stat, 106 .pr_peeraddr = sockin_peeraddr, 107 .pr_sockaddr = sockin_sockaddr, 108 .pr_rcvd = sockin_rcvd, 109 .pr_recvoob = sockin_recvoob, 110 .pr_send = sockin_send, 111 .pr_sendoob = sockin_sendoob, 112 .pr_purgeif = sockin_purgeif, 113 .pr_generic = sockin_usrreq, 114 }; 115 116 const struct protosw sockinsw[] = { 117 { 118 .pr_type = SOCK_DGRAM, 119 .pr_domain = &sockindomain, 120 .pr_protocol = IPPROTO_UDP, 121 .pr_flags = PR_ATOMIC|PR_ADDR, 122 .pr_usrreqs = &sockin_usrreqs, 123 .pr_ctloutput = sockin_ctloutput, 124 }, 125 { 126 .pr_type = SOCK_STREAM, 127 .pr_domain = &sockindomain, 128 .pr_protocol = IPPROTO_TCP, 129 .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_ABRTACPTDIS, 130 .pr_usrreqs = &sockin_usrreqs, 131 .pr_ctloutput = sockin_ctloutput, 132 }}; 133 const struct protosw sockin6sw[] = { 134 { 135 .pr_type = SOCK_DGRAM, 136 .pr_domain = &sockin6domain, 137 .pr_protocol = IPPROTO_UDP, 138 .pr_flags = PR_ATOMIC|PR_ADDR, 139 .pr_usrreqs = &sockin_usrreqs, 140 .pr_ctloutput = sockin_ctloutput, 141 }, 142 { 143 .pr_type = SOCK_STREAM, 144 .pr_domain = &sockin6domain, 145 .pr_protocol = IPPROTO_TCP, 146 .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_ABRTACPTDIS, 147 .pr_usrreqs = &sockin_usrreqs, 148 .pr_ctloutput = sockin_ctloutput, 149 }}; 150 151 struct domain sockindomain = { 152 .dom_family = PF_INET, 153 .dom_name = "socket_inet", 154 .dom_init = sockin_init, 155 .dom_externalize = NULL, 156 .dom_dispose = NULL, 157 .dom_protosw = sockinsw, 158 .dom_protoswNPROTOSW = &sockinsw[__arraycount(sockinsw)], 159 .dom_rtattach = rt_inithead, 160 .dom_rtoffset = 32, 161 .dom_maxrtkey = sizeof(struct sockaddr_in), 162 .dom_ifattach = NULL, 163 .dom_ifdetach = NULL, 164 .dom_ifqueues = { NULL }, 165 .dom_link = { NULL }, 166 .dom_mowner = MOWNER_INIT("",""), 167 .dom_rtcache = { NULL }, 168 .dom_sockaddr_cmp = NULL 169 }; 170 struct domain sockin6domain = { 171 .dom_family = PF_INET6, 172 .dom_name = "socket_inet6", 173 .dom_init = sockin_init, 174 .dom_externalize = NULL, 175 .dom_dispose = NULL, 176 .dom_protosw = sockin6sw, 177 .dom_protoswNPROTOSW = &sockin6sw[__arraycount(sockin6sw)], 178 .dom_rtattach = rt_inithead, 179 .dom_rtoffset = 32, 180 .dom_maxrtkey = sizeof(struct sockaddr_in6), 181 .dom_ifattach = NULL, 182 .dom_ifdetach = NULL, 183 .dom_ifqueues = { NULL }, 184 .dom_link = { NULL }, 185 .dom_mowner = MOWNER_INIT("",""), 186 .dom_rtcache = { NULL }, 187 .dom_sockaddr_cmp = NULL 188 }; 189 190 #define SO2S(so) ((intptr_t)(so->so_internal)) 191 #define SOCKIN_SBSIZE 65536 192 193 struct sockin_unit { 194 struct socket *su_so; 195 196 LIST_ENTRY(sockin_unit) su_entries; 197 }; 198 static LIST_HEAD(, sockin_unit) su_ent = LIST_HEAD_INITIALIZER(su_ent); 199 static kmutex_t su_mtx; 200 static bool rebuild; 201 static int nsock; 202 203 /* XXX: for the bpf hack */ 204 static struct ifnet sockin_if; 205 int ifpromisc(struct ifnet *ifp, int pswitch) { return 0; } 206 207 static int 208 registersock(struct socket *so, int news) 209 { 210 struct sockin_unit *su; 211 212 su = kmem_alloc(sizeof(*su), KM_NOSLEEP); 213 if (!su) 214 return ENOMEM; 215 216 so->so_internal = (void *)(intptr_t)news; 217 su->su_so = so; 218 219 mutex_enter(&su_mtx); 220 LIST_INSERT_HEAD(&su_ent, su, su_entries); 221 nsock++; 222 rebuild = true; 223 mutex_exit(&su_mtx); 224 225 return 0; 226 } 227 228 static void 229 removesock(struct socket *so) 230 { 231 struct sockin_unit *su_iter; 232 233 mutex_enter(&su_mtx); 234 LIST_FOREACH(su_iter, &su_ent, su_entries) { 235 if (su_iter->su_so == so) 236 break; 237 } 238 if (!su_iter) 239 panic("no such socket"); 240 241 LIST_REMOVE(su_iter, su_entries); 242 nsock--; 243 rebuild = true; 244 mutex_exit(&su_mtx); 245 246 rumpuser_close(SO2S(su_iter->su_so)); 247 kmem_free(su_iter, sizeof(*su_iter)); 248 } 249 250 static void 251 sockin_process(struct socket *so) 252 { 253 struct sockaddr_in6 from; 254 struct iovec io; 255 struct msghdr rmsg; 256 struct mbuf *m; 257 size_t n, plen; 258 int error; 259 260 m = m_gethdr(M_WAIT, MT_DATA); 261 if (so->so_proto->pr_type == SOCK_DGRAM) { 262 plen = IP_MAXPACKET; 263 MEXTMALLOC(m, plen, M_DONTWAIT); 264 } else { 265 plen = MCLBYTES; 266 MCLGET(m, M_DONTWAIT); 267 } 268 if ((m->m_flags & M_EXT) == 0) { 269 m_freem(m); 270 return; 271 } 272 273 memset(&rmsg, 0, sizeof(rmsg)); 274 io.iov_base = mtod(m, void *); 275 io.iov_len = plen; 276 rmsg.msg_iov = &io; 277 rmsg.msg_iovlen = 1; 278 rmsg.msg_name = (struct sockaddr *)&from; 279 rmsg.msg_namelen = sizeof(from); 280 281 error = rumpcomp_sockin_recvmsg(SO2S(so), &rmsg, 0, &n); 282 if (error || n == 0) { 283 m_freem(m); 284 285 /* Treat a TCP socket a goner */ 286 if (error != EAGAIN && so->so_proto->pr_type == SOCK_STREAM) { 287 mutex_enter(softnet_lock); 288 soisdisconnected(so); 289 mutex_exit(softnet_lock); 290 removesock(so); 291 } 292 return; 293 } 294 m->m_len = m->m_pkthdr.len = n; 295 296 bpf_mtap_af(&sockin_if, AF_UNSPEC, m); 297 298 mutex_enter(softnet_lock); 299 if (so->so_proto->pr_type == SOCK_DGRAM) { 300 if (!sbappendaddr(&so->so_rcv, rmsg.msg_name, m, NULL)) { 301 m_freem(m); 302 } 303 } else { 304 sbappendstream(&so->so_rcv, m); 305 } 306 307 sorwakeup(so); 308 mutex_exit(softnet_lock); 309 } 310 311 static void 312 sockin_waccept(struct socket *so) 313 { 314 struct socket *nso; 315 struct sockaddr_in6 sin; 316 int news, error, slen; 317 318 slen = sizeof(sin); 319 error = rumpcomp_sockin_accept(SO2S(so), (struct sockaddr *)&sin, 320 &slen, &news); 321 if (error) 322 return; 323 324 mutex_enter(softnet_lock); 325 nso = sonewconn(so, true); 326 if (nso == NULL) 327 goto errout; 328 if (registersock(nso, news) != 0) 329 goto errout; 330 mutex_exit(softnet_lock); 331 return; 332 333 errout: 334 rumpuser_close(news); 335 if (nso) 336 soclose(nso); 337 mutex_exit(softnet_lock); 338 } 339 340 #define POLLTIMEOUT 100 /* check for new entries every 100ms */ 341 342 /* XXX: doesn't handle socket (kernel) locking properly? */ 343 static void 344 sockinworker(void *arg) 345 { 346 struct pollfd *pfds = NULL, *npfds; 347 struct sockin_unit *su_iter; 348 struct socket *so; 349 int cursock = 0, i, rv, error; 350 351 /* 352 * Loop reading requests. Check for new sockets periodically 353 * (could be smarter, but I'm lazy). 354 */ 355 for (;;) { 356 if (rebuild) { 357 npfds = NULL; 358 mutex_enter(&su_mtx); 359 if (nsock) 360 npfds = kmem_alloc(nsock * sizeof(*npfds), 361 KM_NOSLEEP); 362 if (npfds || nsock == 0) { 363 if (pfds) 364 kmem_free(pfds, cursock*sizeof(*pfds)); 365 pfds = npfds; 366 cursock = nsock; 367 rebuild = false; 368 369 i = 0; 370 LIST_FOREACH(su_iter, &su_ent, su_entries) { 371 pfds[i].fd = SO2S(su_iter->su_so); 372 pfds[i].events = POLLIN; 373 pfds[i].revents = 0; 374 i++; 375 } 376 KASSERT(i == nsock); 377 } 378 mutex_exit(&su_mtx); 379 } 380 381 /* find affected sockets & process */ 382 error = rumpcomp_sockin_poll(pfds, cursock, POLLTIMEOUT, &rv); 383 for (i = 0; i < cursock && rv > 0 && error == 0; i++) { 384 if (pfds[i].revents & POLLIN) { 385 mutex_enter(&su_mtx); 386 LIST_FOREACH(su_iter, &su_ent, su_entries) { 387 if (SO2S(su_iter->su_so)==pfds[i].fd) { 388 so = su_iter->su_so; 389 mutex_exit(&su_mtx); 390 if(so->so_options&SO_ACCEPTCONN) 391 sockin_waccept(so); 392 else 393 sockin_process(so); 394 mutex_enter(&su_mtx); 395 break; 396 } 397 } 398 /* if we can't find it, just wing it */ 399 KASSERT(rebuild || su_iter); 400 mutex_exit(&su_mtx); 401 pfds[i].revents = 0; 402 rv--; 403 i = -1; 404 continue; 405 } 406 407 /* something else? ignore */ 408 if (pfds[i].revents) { 409 pfds[i].revents = 0; 410 rv--; 411 } 412 } 413 KASSERT(rv <= 0); 414 } 415 416 } 417 418 static int 419 sockin_do_init(void) 420 { 421 int rv; 422 423 if (rump_threads) { 424 if ((rv = kthread_create(PRI_NONE, 0, NULL, sockinworker, 425 NULL, NULL, "sockwork")) != 0) 426 panic("sockin_init: could not create worker thread\n"); 427 } else { 428 printf("sockin_init: no threads => no worker thread\n"); 429 } 430 mutex_init(&su_mtx, MUTEX_DEFAULT, IPL_NONE); 431 strlcpy(sockin_if.if_xname, "sockin0", sizeof(sockin_if.if_xname)); 432 bpf_attach(&sockin_if, DLT_NULL, 0); 433 return 0; 434 } 435 436 static void 437 sockin_init(void) 438 { 439 static ONCE_DECL(init); 440 441 RUN_ONCE(&init, sockin_do_init); 442 } 443 444 static int 445 sockin_attach(struct socket *so, int proto) 446 { 447 const int type = so->so_proto->pr_type; 448 int error, news, family; 449 450 sosetlock(so); 451 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 452 error = soreserve(so, SOCKIN_SBSIZE, SOCKIN_SBSIZE); 453 if (error) 454 return error; 455 } 456 457 family = so->so_proto->pr_domain->dom_family; 458 KASSERT(family == PF_INET || family == PF_INET6); 459 error = rumpcomp_sockin_socket(family, type, 0, &news); 460 if (error) 461 return error; 462 463 /* For UDP sockets, make sure we can send/recv maximum. */ 464 if (type == SOCK_DGRAM) { 465 int sbsize = SOCKIN_SBSIZE; 466 error = rumpcomp_sockin_setsockopt(news, 467 SOL_SOCKET, SO_SNDBUF, 468 &sbsize, sizeof(sbsize)); 469 sbsize = SOCKIN_SBSIZE; 470 error = rumpcomp_sockin_setsockopt(news, 471 SOL_SOCKET, SO_RCVBUF, 472 &sbsize, sizeof(sbsize)); 473 } 474 475 if ((error = registersock(so, news)) != 0) 476 rumpuser_close(news); 477 478 return error; 479 } 480 481 static void 482 sockin_detach(struct socket *so) 483 { 484 panic("sockin_detach: IMPLEMENT ME\n"); 485 } 486 487 static int 488 sockin_accept(struct socket *so, struct mbuf *nam) 489 { 490 KASSERT(solocked(so)); 491 492 /* we do all the work in the worker thread */ 493 return 0; 494 } 495 496 static int 497 sockin_bind(struct socket *so, struct mbuf *nam, struct lwp *l) 498 { 499 KASSERT(solocked(so)); 500 KASSERT(nam != NULL); 501 502 return rumpcomp_sockin_bind(SO2S(so), 503 mtod(nam, const struct sockaddr *), 504 nam->m_len); 505 } 506 507 static int 508 sockin_listen(struct socket *so, struct lwp *l) 509 { 510 KASSERT(solocked(so)); 511 512 return rumpcomp_sockin_listen(SO2S(so), so->so_qlimit); 513 } 514 515 static int 516 sockin_connect(struct socket *so, struct mbuf *nam, struct lwp *l) 517 { 518 int error = 0; 519 520 KASSERT(solocked(so)); 521 KASSERT(nam != NULL); 522 523 error = rumpcomp_sockin_connect(SO2S(so), 524 mtod(nam, struct sockaddr *), nam->m_len); 525 if (error == 0) 526 soisconnected(so); 527 528 return error; 529 } 530 531 static int 532 sockin_connect2(struct socket *so, struct socket *so2) 533 { 534 KASSERT(solocked(so)); 535 536 panic("sockin_connect2: IMPLEMENT ME, connect2 not supported"); 537 } 538 539 static int 540 sockin_disconnect(struct socket *so) 541 { 542 KASSERT(solocked(so)); 543 544 panic("sockin_disconnect: IMPLEMENT ME, disconnect not supported"); 545 } 546 547 static int 548 sockin_shutdown(struct socket *so) 549 { 550 KASSERT(solocked(so)); 551 552 removesock(so); 553 return 0; 554 } 555 556 static int 557 sockin_abort(struct socket *so) 558 { 559 KASSERT(solocked(so)); 560 561 panic("sockin_abort: IMPLEMENT ME, abort not supported"); 562 } 563 564 static int 565 sockin_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 566 { 567 return ENOTTY; 568 } 569 570 static int 571 sockin_stat(struct socket *so, struct stat *ub) 572 { 573 KASSERT(solocked(so)); 574 575 return 0; 576 } 577 578 static int 579 sockin_peeraddr(struct socket *so, struct mbuf *nam) 580 { 581 KASSERT(solocked(so)); 582 583 int error = 0; 584 int slen = nam->m_len; 585 586 error = rumpcomp_sockin_getname(SO2S(so), 587 mtod(nam, struct sockaddr *), &slen, RUMPCOMP_SOCKIN_PEERNAME); 588 if (error == 0) 589 nam->m_len = slen; 590 return error; 591 } 592 593 static int 594 sockin_sockaddr(struct socket *so, struct mbuf *nam) 595 { 596 KASSERT(solocked(so)); 597 598 int error = 0; 599 int slen = nam->m_len; 600 601 error = rumpcomp_sockin_getname(SO2S(so), 602 mtod(nam, struct sockaddr *), &slen, RUMPCOMP_SOCKIN_SOCKNAME); 603 if (error == 0) 604 nam->m_len = slen; 605 return error; 606 } 607 608 static int 609 sockin_rcvd(struct socket *so, int flags, struct lwp *l) 610 { 611 KASSERT(solocked(so)); 612 613 panic("sockin_rcvd: IMPLEMENT ME, rcvd not supported"); 614 } 615 616 static int 617 sockin_recvoob(struct socket *so, struct mbuf *m, int flags) 618 { 619 KASSERT(solocked(so)); 620 621 panic("sockin_recvoob: IMPLEMENT ME, recvoob not supported"); 622 } 623 624 static int 625 sockin_send(struct socket *so, struct mbuf *m, struct mbuf *nam, 626 struct mbuf *control, struct lwp *l) 627 { 628 struct sockaddr *saddr; 629 struct msghdr mhdr; 630 size_t iov_max, i; 631 struct iovec iov_buf[32], *iov; 632 struct mbuf *m2; 633 size_t tot, n; 634 int error = 0; 635 int s; 636 637 bpf_mtap_af(&sockin_if, AF_UNSPEC, m); 638 639 memset(&mhdr, 0, sizeof(mhdr)); 640 641 iov_max = 0; 642 for (m2 = m; m2 != NULL; m2 = m2->m_next) { 643 iov_max++; 644 } 645 646 if (iov_max <= __arraycount(iov_buf)) { 647 iov = iov_buf; 648 } else { 649 iov = kmem_alloc(sizeof(struct iovec) * iov_max, 650 KM_SLEEP); 651 } 652 653 tot = 0; 654 for (i = 0, m2 = m; m2 != NULL; m2 = m2->m_next, i++) { 655 iov[i].iov_base = m2->m_data; 656 iov[i].iov_len = m2->m_len; 657 tot += m2->m_len; 658 } 659 mhdr.msg_iov = iov; 660 mhdr.msg_iovlen = i; 661 s = SO2S(so); 662 663 if (nam != NULL) { 664 saddr = mtod(nam, struct sockaddr *); 665 mhdr.msg_name = saddr; 666 mhdr.msg_namelen = saddr->sa_len; 667 } 668 669 rumpcomp_sockin_sendmsg(s, &mhdr, 0, &n); 670 671 if (iov != iov_buf) 672 kmem_free(iov, sizeof(struct iovec) * iov_max); 673 674 m_freem(m); 675 m_freem(control); 676 677 /* this assumes too many things to list.. buthey, testing */ 678 if (!rump_threads) 679 sockin_process(so); 680 681 return error; 682 } 683 684 static int 685 sockin_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 686 { 687 KASSERT(solocked(so)); 688 689 panic("sockin_sendoob: IMPLEMENT ME, sendoob not supported"); 690 } 691 692 static int 693 sockin_purgeif(struct socket *so, struct ifnet *ifp) 694 { 695 696 panic("sockin_purgeif: IMPLEMENT ME, purgeif not supported"); 697 } 698 699 static int 700 sockin_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, 701 struct mbuf *control, struct lwp *l) 702 { 703 KASSERT(req != PRU_ACCEPT); 704 KASSERT(req != PRU_BIND); 705 KASSERT(req != PRU_LISTEN); 706 KASSERT(req != PRU_CONNECT); 707 KASSERT(req != PRU_CONNECT2); 708 KASSERT(req != PRU_DISCONNECT); 709 KASSERT(req != PRU_SHUTDOWN); 710 KASSERT(req != PRU_ABORT); 711 KASSERT(req != PRU_CONTROL); 712 KASSERT(req != PRU_SENSE); 713 KASSERT(req != PRU_PEERADDR); 714 KASSERT(req != PRU_SOCKADDR); 715 KASSERT(req != PRU_RCVD); 716 KASSERT(req != PRU_RCVOOB); 717 KASSERT(req != PRU_SEND); 718 KASSERT(req != PRU_SENDOOB); 719 KASSERT(req != PRU_PURGEIF); 720 721 panic("sockin_usrreq: IMPLEMENT ME, req %d not supported", req); 722 723 return 0; 724 } 725 726 static int 727 sockin_ctloutput(int op, struct socket *so, struct sockopt *sopt) 728 { 729 730 return rumpcomp_sockin_setsockopt(SO2S(so), sopt->sopt_level, 731 sopt->sopt_name, sopt->sopt_data, sopt->sopt_size); 732 } 733 734 int sockin_unavailable(void); 735 int 736 sockin_unavailable(void) 737 { 738 739 panic("interface not available in with sockin"); 740 } 741 __strong_alias(rtrequest,sockin_unavailable); 742 __strong_alias(ifunit,sockin_unavailable); 743 __strong_alias(ifreq_setaddr,sockin_unavailable); 744