1 /* $OpenBSD: if_tun.c,v 1.40 2001/12/10 06:10:53 jason Exp $ */ 2 /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 6 * Nottingham University 1987. 7 * 8 * This source may be freely distributed, however I would be interested 9 * in any changes that are made. 10 * 11 * This driver takes packets off the IP i/f and hands them up to a 12 * user process to have its wicked way with. This driver has its 13 * roots in a similar driver written by Phil Cockcroft (formerly) at 14 * UCL. This driver is based much more on read/write/select mode of 15 * operation though. 16 */ 17 18 /* #define TUN_DEBUG 9 */ 19 20 #include <sys/param.h> 21 #include <sys/kernel.h> 22 #include <sys/proc.h> 23 #include <sys/systm.h> 24 #include <sys/mbuf.h> 25 #include <sys/protosw.h> 26 #include <sys/socket.h> 27 #include <sys/ioctl.h> 28 #include <sys/errno.h> 29 #include <sys/syslog.h> 30 #include <sys/select.h> 31 #include <sys/file.h> 32 #include <sys/time.h> 33 #include <sys/device.h> 34 #include <sys/vnode.h> 35 #include <sys/signalvar.h> 36 #include <sys/conf.h> 37 38 #include <machine/cpu.h> 39 40 #include <net/if.h> 41 #include <net/if_types.h> 42 #include <net/netisr.h> 43 #include <net/route.h> 44 45 #ifdef INET 46 #include <netinet/in.h> 47 #include <netinet/in_systm.h> 48 #include <netinet/in_var.h> 49 #include <netinet/ip.h> 50 /* #include <netinet/if_ether.h> */ 51 #endif 52 53 #ifdef NS 54 #include <netns/ns.h> 55 #include <netns/ns_if.h> 56 #endif 57 58 #ifdef IPX 59 #include <netipx/ipx.h> 60 #include <netipx/ipx_if.h> 61 #endif 62 63 #ifdef NETATALK 64 #include <netatalk/at.h> 65 #include <netatalk/at_var.h> 66 #endif 67 68 #ifdef ISO 69 #include <netiso/iso.h> 70 #include <netiso/iso_var.h> 71 #endif 72 73 #include "bpfilter.h" 74 #if NBPFILTER > 0 75 #include <net/bpf.h> 76 #endif 77 78 #include <net/if_tun.h> 79 80 struct tun_softc { 81 struct ifnet tun_if; /* the interface */ 82 u_short tun_flags; /* misc flags */ 83 pid_t tun_pgid; /* the process group - if any */ 84 uid_t tun_siguid; /* uid for process that set tun_pgid */ 85 uid_t tun_sigeuid; /* euid for process that set tun_pgid */ 86 struct selinfo tun_rsel; /* read select */ 87 struct selinfo tun_wsel; /* write select (not used) */ 88 }; 89 90 #ifdef TUN_DEBUG 91 int tundebug = TUN_DEBUG; 92 #define TUNDEBUG(a) (tundebug? printf a : 0) 93 #else 94 #define TUNDEBUG(a) /* (tundebug? printf a : 0) */ 95 #endif 96 97 struct tun_softc *tunctl; 98 int ntun; 99 100 extern int ifqmaxlen; 101 102 void tunattach __P((int)); 103 int tunopen __P((dev_t, int, int, struct proc *)); 104 int tunclose __P((dev_t, int, int, struct proc *)); 105 int tun_ioctl __P((struct ifnet *, u_long, caddr_t)); 106 int tun_output __P((struct ifnet *, struct mbuf *, struct sockaddr *, 107 struct rtentry *rt)); 108 int tunioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); 109 int tunread __P((dev_t, struct uio *, int)); 110 int tunwrite __P((dev_t, struct uio *, int)); 111 int tunselect __P((dev_t, int, struct proc *)); 112 113 114 static int tuninit __P((struct tun_softc *)); 115 #ifdef ALTQ 116 static void tunstart __P((struct ifnet *)); 117 #endif 118 119 void 120 tunattach(n) 121 int n; 122 { 123 register int i; 124 struct ifnet *ifp; 125 126 ntun = n; 127 tunctl = malloc(ntun * sizeof(*tunctl), M_DEVBUF, M_WAITOK); 128 bzero(tunctl, ntun * sizeof(*tunctl)); 129 for (i = 0; i < ntun; i++) { 130 tunctl[i].tun_flags = TUN_INITED; 131 132 ifp = &tunctl[i].tun_if; 133 sprintf(ifp->if_xname, "tun%d", i); 134 ifp->if_softc = &tunctl[i]; 135 ifp->if_mtu = TUNMTU; 136 ifp->if_ioctl = tun_ioctl; 137 ifp->if_output = tun_output; 138 #ifdef ALTQ 139 ifp->if_start = tunstart; 140 #endif 141 ifp->if_flags = IFF_POINTOPOINT; 142 ifp->if_type = IFT_PROPVIRTUAL; 143 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 144 IFQ_SET_READY(&ifp->if_snd); 145 ifp->if_hdrlen = sizeof(u_int32_t); 146 ifp->if_collisions = 0; 147 ifp->if_ierrors = 0; 148 ifp->if_oerrors = 0; 149 ifp->if_ipackets = 0; 150 ifp->if_opackets = 0; 151 ifp->if_ibytes = 0; 152 ifp->if_obytes = 0; 153 if_attach(ifp); 154 #if NBPFILTER > 0 155 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); 156 #endif 157 } 158 } 159 160 /* 161 * tunnel open - must be superuser & the device must be 162 * configured in 163 */ 164 int 165 tunopen(dev, flag, mode, p) 166 dev_t dev; 167 int flag, mode; 168 struct proc *p; 169 { 170 struct tun_softc *tp; 171 struct ifnet *ifp; 172 register int unit, error; 173 174 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 175 return (error); 176 177 if ((unit = minor(dev)) >= ntun) 178 return (ENXIO); 179 180 tp = &tunctl[unit]; 181 if (tp->tun_flags & TUN_OPEN) 182 return EBUSY; 183 184 ifp = &tp->tun_if; 185 tp->tun_flags |= TUN_OPEN; 186 TUNDEBUG(("%s: open\n", ifp->if_xname)); 187 return (0); 188 } 189 190 /* 191 * tunclose - close the device; if closing the real device, flush pending 192 * output and (unless set STAYUP) bring down the interface. 193 */ 194 int 195 tunclose(dev, flag, mode, p) 196 dev_t dev; 197 int flag; 198 int mode; 199 struct proc *p; 200 { 201 register int unit, s; 202 struct tun_softc *tp; 203 struct ifnet *ifp; 204 205 if ((unit = minor(dev)) >= ntun) 206 return (ENXIO); 207 208 tp = &tunctl[unit]; 209 ifp = &tp->tun_if; 210 tp->tun_flags &= ~TUN_OPEN; 211 212 /* 213 * junk all pending output 214 */ 215 s = splimp(); 216 IFQ_PURGE(&ifp->if_snd); 217 splx(s); 218 219 if ((ifp->if_flags & IFF_UP) && !(tp->tun_flags & TUN_STAYUP)) { 220 s = splimp(); 221 if_down(ifp); 222 if (ifp->if_flags & IFF_RUNNING) { 223 /* find internet addresses and delete routes */ 224 register struct ifaddr *ifa; 225 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 226 #ifdef INET 227 if (ifa->ifa_addr->sa_family == AF_INET) { 228 rtinit(ifa, (int)RTM_DELETE, 229 (tp->tun_flags & TUN_DSTADDR)? 230 RTF_HOST : 0); 231 } 232 #endif 233 } 234 } 235 splx(s); 236 } 237 tp->tun_pgid = 0; 238 selwakeup(&tp->tun_rsel); 239 240 TUNDEBUG(("%s: closed\n", ifp->if_xname)); 241 return (0); 242 } 243 244 static int 245 tuninit(tp) 246 struct tun_softc *tp; 247 { 248 struct ifnet *ifp = &tp->tun_if; 249 register struct ifaddr *ifa; 250 251 TUNDEBUG(("%s: tuninit\n", ifp->if_xname)); 252 253 ifp->if_flags |= IFF_UP | IFF_RUNNING; 254 255 tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR|TUN_BRDADDR); 256 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 257 #ifdef INET 258 if (ifa->ifa_addr->sa_family == AF_INET) { 259 struct sockaddr_in *sin; 260 261 sin = satosin(ifa->ifa_addr); 262 if (sin && sin->sin_addr.s_addr) 263 tp->tun_flags |= TUN_IASET; 264 265 if (ifp->if_flags & IFF_POINTOPOINT) { 266 sin = satosin(ifa->ifa_dstaddr); 267 if (sin && sin->sin_addr.s_addr) 268 tp->tun_flags |= TUN_DSTADDR; 269 } else 270 tp->tun_flags &= ~TUN_DSTADDR; 271 272 if (ifp->if_flags & IFF_BROADCAST) { 273 sin = satosin(ifa->ifa_broadaddr); 274 if (sin && sin->sin_addr.s_addr) 275 tp->tun_flags |= TUN_BRDADDR; 276 } else 277 tp->tun_flags &= ~TUN_BRDADDR; 278 } 279 #endif 280 } 281 282 return 0; 283 } 284 285 /* 286 * Process an ioctl request. 287 */ 288 int 289 tun_ioctl(ifp, cmd, data) 290 struct ifnet *ifp; 291 u_long cmd; 292 caddr_t data; 293 { 294 int error = 0, s; 295 296 s = splimp(); 297 switch(cmd) { 298 case SIOCSIFADDR: 299 tuninit((struct tun_softc *)(ifp->if_softc)); 300 TUNDEBUG(("%s: address set\n", ifp->if_xname)); 301 break; 302 case SIOCSIFDSTADDR: 303 tuninit((struct tun_softc *)(ifp->if_softc)); 304 TUNDEBUG(("%s: destination address set\n", ifp->if_xname)); 305 break; 306 case SIOCSIFBRDADDR: 307 tuninit((struct tun_softc *)(ifp->if_softc)); 308 TUNDEBUG(("%s: broadcast address set\n", ifp->if_xname)); 309 break; 310 case SIOCSIFMTU: 311 ifp->if_mtu = ((struct ifreq *)data)->ifr_mtu; 312 break; 313 case SIOCADDMULTI: 314 case SIOCDELMULTI: { 315 struct ifreq *ifr = (struct ifreq *)data; 316 if (ifr == 0) { 317 error = EAFNOSUPPORT; /* XXX */ 318 break; 319 } 320 switch (ifr->ifr_addr.sa_family) { 321 #ifdef INET 322 case AF_INET: 323 break; 324 #endif 325 #ifdef INET6 326 case AF_INET6: 327 break; 328 #endif 329 default: 330 error = EAFNOSUPPORT; 331 break; 332 } 333 break; 334 } 335 336 case SIOCSIFFLAGS: 337 break; 338 default: 339 error = EINVAL; 340 } 341 splx(s); 342 return (error); 343 } 344 345 /* 346 * tun_output - queue packets from higher level ready to put out. 347 */ 348 int 349 tun_output(ifp, m0, dst, rt) 350 struct ifnet *ifp; 351 struct mbuf *m0; 352 struct sockaddr *dst; 353 struct rtentry *rt; 354 { 355 struct tun_softc *tp = ifp->if_softc; 356 int s, len, error; 357 u_int32_t *af; 358 ALTQ_DECL(struct altq_pktattr pktattr;) 359 360 TUNDEBUG(("%s: tun_output\n", ifp->if_xname)); 361 362 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 363 TUNDEBUG(("%s: not ready 0%o\n", ifp->if_xname, 364 tp->tun_flags)); 365 m_freem (m0); 366 return EHOSTDOWN; 367 } 368 369 /* 370 * if the queueing discipline needs packet classification, 371 * do it before prepending link headers. 372 */ 373 IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr); 374 375 M_PREPEND(m0, sizeof(*af), M_DONTWAIT); 376 af = mtod(m0, u_int32_t *); 377 *af = htonl(dst->sa_family); 378 379 #if NBPFILTER > 0 380 if (ifp->if_bpf) 381 bpf_mtap(ifp->if_bpf, m0); 382 #endif 383 384 len = m0->m_pkthdr.len + sizeof(*af); 385 s = splimp(); 386 IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error); 387 if (error) { 388 splx(s); 389 ifp->if_collisions++; 390 return (error); 391 } 392 splx(s); 393 ifp->if_opackets++; 394 ifp->if_obytes += len; 395 396 if (tp->tun_flags & TUN_RWAIT) { 397 tp->tun_flags &= ~TUN_RWAIT; 398 wakeup((caddr_t)tp); 399 } 400 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) 401 csignal(tp->tun_pgid, SIGIO, 402 tp->tun_siguid, tp->tun_sigeuid); 403 selwakeup(&tp->tun_rsel); 404 return 0; 405 } 406 407 /* 408 * the cdevsw interface is now pretty minimal. 409 */ 410 int 411 tunioctl(dev, cmd, data, flag, p) 412 dev_t dev; 413 u_long cmd; 414 caddr_t data; 415 int flag; 416 struct proc *p; 417 { 418 int unit, s; 419 struct tun_softc *tp; 420 struct tuninfo *tunp; 421 422 if ((unit = minor(dev)) >= ntun) 423 return (ENXIO); 424 425 tp = &tunctl[unit]; 426 427 s = splimp(); 428 switch (cmd) { 429 case TUNSIFINFO: 430 tunp = (struct tuninfo *)data; 431 tp->tun_if.if_mtu = tunp->mtu; 432 tp->tun_if.if_type = tunp->type; 433 tp->tun_if.if_flags = tunp->flags; 434 tp->tun_if.if_baudrate = tunp->baudrate; 435 break; 436 case TUNGIFINFO: 437 tunp = (struct tuninfo *)data; 438 tunp->mtu = tp->tun_if.if_mtu; 439 tunp->type = tp->tun_if.if_type; 440 tunp->flags = tp->tun_if.if_flags; 441 tunp->baudrate = tp->tun_if.if_baudrate; 442 break; 443 #ifdef TUN_DEBUG 444 case TUNSDEBUG: 445 tundebug = *(int *)data; 446 break; 447 case TUNGDEBUG: 448 *(int *)data = tundebug; 449 break; 450 #endif 451 case TUNSIFMODE: 452 switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) { 453 case IFF_POINTOPOINT: 454 case IFF_BROADCAST: 455 if (tp->tun_if.if_flags & IFF_UP) { 456 splx(s); 457 return (EBUSY); 458 } 459 tp->tun_if.if_flags &= 460 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST); 461 tp->tun_if.if_flags |= *(int *)data; 462 break; 463 default: 464 splx(s); 465 return (EINVAL); 466 } 467 break; 468 469 case FIONBIO: 470 if (*(int *)data) 471 tp->tun_flags |= TUN_NBIO; 472 else 473 tp->tun_flags &= ~TUN_NBIO; 474 break; 475 case FIOASYNC: 476 if (*(int *)data) 477 tp->tun_flags |= TUN_ASYNC; 478 else 479 tp->tun_flags &= ~TUN_ASYNC; 480 break; 481 case FIONREAD: 482 if (tp->tun_if.if_snd.ifq_head) 483 *(int *)data = tp->tun_if.if_snd.ifq_head->m_pkthdr.len; 484 else 485 *(int *)data = 0; 486 break; 487 case TIOCSPGRP: 488 tp->tun_pgid = *(int *)data; 489 tp->tun_siguid = p->p_cred->p_ruid; 490 tp->tun_sigeuid = p->p_ucred->cr_uid; 491 break; 492 case TIOCGPGRP: 493 *(int *)data = tp->tun_pgid; 494 break; 495 default: 496 splx(s); 497 return (ENOTTY); 498 } 499 splx(s); 500 return (0); 501 } 502 503 /* 504 * The cdevsw read interface - reads a packet at a time, or at 505 * least as much of a packet as can be read. 506 */ 507 int 508 tunread(dev, uio, ioflag) 509 dev_t dev; 510 struct uio *uio; 511 int ioflag; 512 { 513 int unit; 514 struct tun_softc *tp; 515 struct ifnet *ifp; 516 struct mbuf *m, *m0; 517 int error = 0, len, s; 518 519 if ((unit = minor(dev)) >= ntun) 520 return (ENXIO); 521 522 tp = &tunctl[unit]; 523 ifp = &tp->tun_if; 524 TUNDEBUG(("%s: read\n", ifp->if_xname)); 525 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 526 TUNDEBUG(("%s: not ready 0%o\n", ifp->if_xname, 527 tp->tun_flags)); 528 return EHOSTDOWN; 529 } 530 531 tp->tun_flags &= ~TUN_RWAIT; 532 533 s = splimp(); 534 do { 535 while ((tp->tun_flags & TUN_READY) != TUN_READY) 536 if ((error = tsleep((caddr_t)tp, 537 (PZERO+1)|PCATCH, "tunread", 0)) != 0) { 538 splx(s); 539 return (error); 540 } 541 IFQ_DEQUEUE(&ifp->if_snd, m0); 542 if (m0 == 0) { 543 if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) { 544 splx(s); 545 return EWOULDBLOCK; 546 } 547 tp->tun_flags |= TUN_RWAIT; 548 if ((error = tsleep((caddr_t)tp, 549 (PZERO + 1)|PCATCH, "tunread", 0)) != 0) { 550 splx(s); 551 return (error); 552 } 553 } 554 } while (m0 == 0); 555 splx(s); 556 557 while (m0 && uio->uio_resid > 0 && error == 0) { 558 len = min(uio->uio_resid, m0->m_len); 559 if (len != 0) 560 error = uiomove(mtod(m0, caddr_t), len, uio); 561 MFREE(m0, m); 562 m0 = m; 563 } 564 565 if (m0) { 566 TUNDEBUG(("Dropping mbuf\n")); 567 m_freem(m0); 568 } 569 if (error) 570 ifp->if_ierrors++; 571 572 return error; 573 } 574 575 /* 576 * the cdevsw write interface - an atomic write is a packet - or else! 577 */ 578 int 579 tunwrite(dev, uio, ioflag) 580 dev_t dev; 581 struct uio *uio; 582 int ioflag; 583 { 584 int unit; 585 struct ifnet *ifp; 586 struct ifqueue *ifq; 587 u_int32_t *th; 588 struct mbuf *top, **mp, *m; 589 int isr; 590 int error=0, s, tlen, mlen; 591 592 if ((unit = minor(dev)) >= ntun) 593 return (ENXIO); 594 595 ifp = &tunctl[unit].tun_if; 596 TUNDEBUG(("%s: tunwrite\n", ifp->if_xname)); 597 598 if (uio->uio_resid == 0 || uio->uio_resid > TUNMRU) { 599 TUNDEBUG(("%s: len=%d!\n", ifp->if_xname, uio->uio_resid)); 600 return EMSGSIZE; 601 } 602 tlen = uio->uio_resid; 603 604 /* get a header mbuf */ 605 MGETHDR(m, M_DONTWAIT, MT_DATA); 606 if (m == NULL) 607 return ENOBUFS; 608 mlen = MHLEN; 609 610 top = 0; 611 mp = ⊤ 612 while (error == 0 && uio->uio_resid > 0) { 613 m->m_len = min(mlen, uio->uio_resid); 614 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 615 *mp = m; 616 mp = &m->m_next; 617 if (uio->uio_resid > 0) { 618 MGET (m, M_DONTWAIT, MT_DATA); 619 if (m == 0) { 620 error = ENOBUFS; 621 break; 622 } 623 mlen = MLEN; 624 } 625 } 626 if (error) { 627 if (top) 628 m_freem (top); 629 ifp->if_ierrors++; 630 return error; 631 } 632 633 top->m_pkthdr.len = tlen; 634 top->m_pkthdr.rcvif = ifp; 635 636 #if NBPFILTER > 0 637 if (ifp->if_bpf) 638 bpf_mtap(ifp->if_bpf, top); 639 #endif 640 641 th = mtod(top, u_int32_t *); 642 /* strip the tunnel header */ 643 top->m_data += sizeof(*th); 644 top->m_len -= sizeof(*th); 645 top->m_pkthdr.len -= sizeof(*th); 646 647 switch (ntohl(*th)) { 648 #ifdef INET 649 case AF_INET: 650 ifq = &ipintrq; 651 isr = NETISR_IP; 652 break; 653 #endif 654 #ifdef INET6 655 case AF_INET6: 656 ifq = &ip6intrq; 657 isr = NETISR_IPV6; 658 break; 659 #endif 660 #ifdef NS 661 case AF_NS: 662 ifq = &nsintrq; 663 isr = NETISR_NS; 664 break; 665 #endif 666 #ifdef IPX 667 case AF_IPX: 668 ifq = &ipxintrq; 669 isr = NETISR_IPX; 670 break; 671 #endif 672 #ifdef NETATALK 673 case AF_APPLETALK: 674 ifq = &atintrq2; 675 isr = NETISR_ATALK; 676 break; 677 #endif 678 #ifdef ISO 679 case AF_ISO: 680 ifq = &clnlintrq; 681 isr = NETISR_ISO; 682 break; 683 #endif 684 default: 685 m_freem(top); 686 return EAFNOSUPPORT; 687 } 688 689 s = splimp(); 690 if (IF_QFULL(ifq)) { 691 IF_DROP(ifq); 692 splx(s); 693 ifp->if_collisions++; 694 m_freem(top); 695 return ENOBUFS; 696 } 697 IF_ENQUEUE(ifq, top); 698 schednetisr(isr); 699 ifp->if_ipackets++; 700 ifp->if_ibytes += top->m_pkthdr.len; 701 splx(s); 702 return error; 703 } 704 705 /* 706 * tunselect - the select interface, this is only useful on reads 707 * really. The write detect always returns true, write never blocks 708 * anyway, it either accepts the packet or drops it. 709 */ 710 int 711 tunselect(dev, rw, p) 712 dev_t dev; 713 int rw; 714 struct proc *p; 715 { 716 int unit, s; 717 struct tun_softc *tp; 718 struct ifnet *ifp; 719 720 if ((unit = minor(dev)) >= ntun) 721 return (ENXIO); 722 723 tp = &tunctl[unit]; 724 ifp = &tp->tun_if; 725 s = splimp(); 726 TUNDEBUG(("%s: tunselect\n", ifp->if_xname)); 727 728 switch (rw) { 729 case FREAD: 730 if (ifp->if_snd.ifq_len > 0) { 731 splx(s); 732 TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname, 733 ifp->if_snd.ifq_len)); 734 return 1; 735 } 736 selrecord(curproc, &tp->tun_rsel); 737 break; 738 case FWRITE: 739 splx(s); 740 return 1; 741 } 742 splx(s); 743 TUNDEBUG(("%s: tunselect waiting\n", ifp->if_xname)); 744 return 0; 745 } 746 747 #ifdef ALTQ 748 /* 749 * Start packet transmission on the interface. 750 * when the interface queue is rate-limited by ALTQ or TBR, 751 * if_start is needed to drain packets from the queue in order 752 * to notify readers when outgoing packets become ready. 753 */ 754 static void 755 tunstart(ifp) 756 struct ifnet *ifp; 757 { 758 struct tun_softc *tp = ifp->if_softc; 759 struct mbuf *m; 760 761 if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd)) 762 return; 763 764 IFQ_POLL(&ifp->if_snd, m); 765 if (m != NULL) { 766 if (tp->tun_flags & TUN_RWAIT) { 767 tp->tun_flags &= ~TUN_RWAIT; 768 wakeup((caddr_t)tp); 769 } 770 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) 771 csignal(tp->tun_pgid, SIGIO, 772 tp->tun_siguid, tp->tun_sigeuid); 773 selwakeup(&tp->tun_rsel); 774 } 775 } 776 #endif 777