1 /* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 5 * Nottingham University 1987. 6 * 7 * This source may be freely distributed, however I would be interested 8 * in any changes that are made. 9 * 10 * This driver takes packets off the IP i/f and hands them up to a 11 * user process to have its wicked way with. This driver has it's 12 * roots in a similar driver written by Phil Cockcroft (formerly) at 13 * UCL. This driver is based much more on read/write/poll mode of 14 * operation though. 15 * 16 * $FreeBSD: src/sys/net/if_tun.c,v 1.74.2.8 2002/02/13 00:43:11 dillon Exp $ 17 * $DragonFly: src/sys/net/tun/if_tun.c,v 1.37 2008/06/05 18:06:32 swildner Exp $ 18 */ 19 20 #include "opt_atalk.h" 21 #include "opt_inet.h" 22 #include "opt_inet6.h" 23 #include "opt_ipx.h" 24 25 #include <sys/param.h> 26 #include <sys/proc.h> 27 #include <sys/priv.h> 28 #include <sys/systm.h> 29 #include <sys/mbuf.h> 30 #include <sys/socket.h> 31 #include <sys/conf.h> 32 #include <sys/device.h> 33 #include <sys/filio.h> 34 #include <sys/sockio.h> 35 #include <sys/thread2.h> 36 #include <sys/ttycom.h> 37 #include <sys/poll.h> 38 #include <sys/signalvar.h> 39 #include <sys/filedesc.h> 40 #include <sys/kernel.h> 41 #include <sys/sysctl.h> 42 #include <sys/uio.h> 43 #include <sys/vnode.h> 44 #include <sys/malloc.h> 45 46 #include <net/if.h> 47 #include <net/if_types.h> 48 #include <net/ifq_var.h> 49 #include <net/netisr.h> 50 #include <net/route.h> 51 52 #ifdef INET 53 #include <netinet/in.h> 54 #endif 55 56 #include <net/bpf.h> 57 58 #include "if_tunvar.h" 59 #include "if_tun.h" 60 61 static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface"); 62 63 static void tunattach (void *); 64 PSEUDO_SET(tunattach, if_tun); 65 66 static void tuncreate (cdev_t dev); 67 68 #define TUNDEBUG if (tundebug) if_printf 69 static int tundebug = 0; 70 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 71 72 static int tunoutput (struct ifnet *, struct mbuf *, struct sockaddr *, 73 struct rtentry *rt); 74 static int tunifioctl (struct ifnet *, u_long, caddr_t, struct ucred *); 75 static int tuninit (struct ifnet *); 76 static void tunstart(struct ifnet *); 77 78 static d_open_t tunopen; 79 static d_close_t tunclose; 80 static d_read_t tunread; 81 static d_write_t tunwrite; 82 static d_ioctl_t tunioctl; 83 static d_poll_t tunpoll; 84 85 #define CDEV_MAJOR 52 86 static struct dev_ops tun_ops = { 87 { "tun", CDEV_MAJOR, 0 }, 88 .d_open = tunopen, 89 .d_close = tunclose, 90 .d_read = tunread, 91 .d_write = tunwrite, 92 .d_ioctl = tunioctl, 93 .d_poll = tunpoll, 94 }; 95 96 static void 97 tunattach(void *dummy) 98 { 99 dev_ops_add(&tun_ops, 0, 0); 100 } 101 102 static void 103 tuncreate(cdev_t dev) 104 { 105 struct tun_softc *sc; 106 struct ifnet *ifp; 107 108 dev = make_dev(&tun_ops, minor(dev), 109 UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev)); 110 111 MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO); 112 sc->tun_flags = TUN_INITED; 113 114 ifp = &sc->tun_if; 115 if_initname(ifp, "tun", lminor(dev)); 116 ifp->if_mtu = TUNMTU; 117 ifp->if_ioctl = tunifioctl; 118 ifp->if_output = tunoutput; 119 ifp->if_start = tunstart; 120 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 121 ifp->if_type = IFT_PPP; 122 ifq_set_maxlen(&ifp->if_snd, ifqmaxlen); 123 ifq_set_ready(&ifp->if_snd); 124 ifp->if_softc = sc; 125 if_attach(ifp, NULL); 126 bpfattach(ifp, DLT_NULL, sizeof(u_int)); 127 dev->si_drv1 = sc; 128 } 129 130 /* 131 * tunnel open - must be superuser & the device must be 132 * configured in 133 */ 134 static int 135 tunopen(struct dev_open_args *ap) 136 { 137 cdev_t dev = ap->a_head.a_dev; 138 struct ifnet *ifp; 139 struct tun_softc *tp; 140 int error; 141 142 if ((error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) != 0) 143 return (error); 144 145 tp = dev->si_drv1; 146 if (!tp) { 147 tuncreate(dev); 148 tp = dev->si_drv1; 149 } 150 if (tp->tun_flags & TUN_OPEN) 151 return EBUSY; 152 tp->tun_pid = curproc->p_pid; 153 ifp = &tp->tun_if; 154 tp->tun_flags |= TUN_OPEN; 155 TUNDEBUG(ifp, "open\n"); 156 return (0); 157 } 158 159 /* 160 * tunclose - close the device - mark i/f down & delete 161 * routing info 162 */ 163 static int 164 tunclose(struct dev_close_args *ap) 165 { 166 cdev_t dev = ap->a_head.a_dev; 167 struct tun_softc *tp; 168 struct ifnet *ifp; 169 170 tp = dev->si_drv1; 171 ifp = &tp->tun_if; 172 173 tp->tun_flags &= ~TUN_OPEN; 174 tp->tun_pid = 0; 175 176 /* Junk all pending output. */ 177 lwkt_serialize_enter(ifp->if_serializer); 178 ifq_purge(&ifp->if_snd); 179 lwkt_serialize_exit(ifp->if_serializer); 180 181 if (ifp->if_flags & IFF_UP) { 182 lwkt_serialize_enter(ifp->if_serializer); 183 if_down(ifp); 184 lwkt_serialize_exit(ifp->if_serializer); 185 } 186 ifp->if_flags &= ~IFF_RUNNING; 187 if_purgeaddrs_nolink(ifp); 188 189 funsetown(tp->tun_sigio); 190 selwakeup(&tp->tun_rsel); 191 192 TUNDEBUG(ifp, "closed\n"); 193 return (0); 194 } 195 196 static int 197 tuninit(struct ifnet *ifp) 198 { 199 struct tun_softc *tp = ifp->if_softc; 200 struct ifaddr_container *ifac; 201 int error = 0; 202 203 TUNDEBUG(ifp, "tuninit\n"); 204 205 ifp->if_flags |= IFF_UP | IFF_RUNNING; 206 getmicrotime(&ifp->if_lastchange); 207 208 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) { 209 struct ifaddr *ifa = ifac->ifa; 210 211 if (ifa->ifa_addr == NULL) { 212 error = EFAULT; 213 /* XXX: Should maybe return straight off? */ 214 } else { 215 #ifdef INET 216 if (ifa->ifa_addr->sa_family == AF_INET) { 217 struct sockaddr_in *si; 218 219 si = (struct sockaddr_in *)ifa->ifa_addr; 220 if (si->sin_addr.s_addr) 221 tp->tun_flags |= TUN_IASET; 222 } 223 #endif 224 } 225 } 226 return (error); 227 } 228 229 /* 230 * Process an ioctl request. 231 * 232 * MPSAFE 233 */ 234 int 235 tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) 236 { 237 struct ifreq *ifr = (struct ifreq *)data; 238 struct tun_softc *tp = ifp->if_softc; 239 struct ifstat *ifs; 240 int error = 0; 241 242 switch(cmd) { 243 case SIOCGIFSTATUS: 244 ifs = (struct ifstat *)data; 245 if (tp->tun_pid) 246 ksprintf(ifs->ascii + strlen(ifs->ascii), 247 "\tOpened by PID %d\n", tp->tun_pid); 248 break; 249 case SIOCSIFADDR: 250 error = tuninit(ifp); 251 TUNDEBUG(ifp, "address set, error=%d\n", error); 252 break; 253 case SIOCSIFDSTADDR: 254 error = tuninit(ifp); 255 TUNDEBUG(ifp, "destination address set, error=%d\n", error); 256 break; 257 case SIOCSIFMTU: 258 ifp->if_mtu = ifr->ifr_mtu; 259 TUNDEBUG(ifp, "mtu set\n"); 260 break; 261 case SIOCSIFFLAGS: 262 case SIOCADDMULTI: 263 case SIOCDELMULTI: 264 break; 265 default: 266 error = EINVAL; 267 } 268 return (error); 269 } 270 271 /* 272 * tunoutput - queue packets from higher level ready to put out. 273 * 274 * MPSAFE 275 */ 276 static int 277 tunoutput_serialized(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, 278 struct rtentry *rt) 279 { 280 struct tun_softc *tp = ifp->if_softc; 281 int error; 282 struct altq_pktattr pktattr; 283 284 TUNDEBUG(ifp, "tunoutput\n"); 285 286 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 287 TUNDEBUG(ifp, "not ready 0%o\n", tp->tun_flags); 288 m_freem (m0); 289 return EHOSTDOWN; 290 } 291 292 /* 293 * if the queueing discipline needs packet classification, 294 * do it before prepending link headers. 295 */ 296 ifq_classify(&ifp->if_snd, m0, dst->sa_family, &pktattr); 297 298 /* BPF write needs to be handled specially */ 299 if (dst->sa_family == AF_UNSPEC) { 300 dst->sa_family = *(mtod(m0, int *)); 301 m0->m_len -= sizeof(int); 302 m0->m_pkthdr.len -= sizeof(int); 303 m0->m_data += sizeof(int); 304 } 305 306 if (ifp->if_bpf) { 307 /* 308 * We need to prepend the address family as 309 * a four byte field. 310 */ 311 uint32_t af = dst->sa_family; 312 313 bpf_ptap(ifp->if_bpf, m0, &af, sizeof(af)); 314 } 315 316 /* prepend sockaddr? this may abort if the mbuf allocation fails */ 317 if (tp->tun_flags & TUN_LMODE) { 318 /* allocate space for sockaddr */ 319 M_PREPEND(m0, dst->sa_len, MB_DONTWAIT); 320 321 /* if allocation failed drop packet */ 322 if (m0 == NULL){ 323 IF_DROP(&ifp->if_snd); 324 ifp->if_oerrors++; 325 return (ENOBUFS); 326 } else { 327 bcopy(dst, m0->m_data, dst->sa_len); 328 } 329 } 330 331 if (tp->tun_flags & TUN_IFHEAD) { 332 /* Prepend the address family */ 333 M_PREPEND(m0, 4, MB_DONTWAIT); 334 335 /* if allocation failed drop packet */ 336 if (m0 == NULL){ 337 IF_DROP(&ifp->if_snd); 338 ifp->if_oerrors++; 339 return ENOBUFS; 340 } else 341 *(u_int32_t *)m0->m_data = htonl(dst->sa_family); 342 } else { 343 #ifdef INET 344 if (dst->sa_family != AF_INET) 345 #endif 346 { 347 m_freem(m0); 348 return EAFNOSUPPORT; 349 } 350 } 351 352 error = ifq_handoff(ifp, m0, &pktattr); 353 if (error) { 354 ifp->if_collisions++; 355 } else { 356 ifp->if_opackets++; 357 if (tp->tun_flags & TUN_RWAIT) { 358 tp->tun_flags &= ~TUN_RWAIT; 359 wakeup((caddr_t)tp); 360 } 361 get_mplock(); 362 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) 363 pgsigio(tp->tun_sigio, SIGIO, 0); 364 selwakeup(&tp->tun_rsel); 365 rel_mplock(); 366 } 367 return (error); 368 } 369 370 static int 371 tunoutput(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, 372 struct rtentry *rt) 373 { 374 int error; 375 376 lwkt_serialize_enter(ifp->if_serializer); 377 error = tunoutput_serialized(ifp, m0, dst, rt); 378 lwkt_serialize_exit(ifp->if_serializer); 379 380 return error; 381 } 382 383 /* 384 * the ops interface is now pretty minimal. 385 */ 386 static int 387 tunioctl(struct dev_ioctl_args *ap) 388 { 389 cdev_t dev = ap->a_head.a_dev; 390 struct tun_softc *tp = dev->si_drv1; 391 struct tuninfo *tunp; 392 393 switch (ap->a_cmd) { 394 case TUNSIFINFO: 395 tunp = (struct tuninfo *)ap->a_data; 396 if (tunp->mtu < IF_MINMTU) 397 return (EINVAL); 398 tp->tun_if.if_mtu = tunp->mtu; 399 tp->tun_if.if_type = tunp->type; 400 tp->tun_if.if_baudrate = tunp->baudrate; 401 break; 402 case TUNGIFINFO: 403 tunp = (struct tuninfo *)ap->a_data; 404 tunp->mtu = tp->tun_if.if_mtu; 405 tunp->type = tp->tun_if.if_type; 406 tunp->baudrate = tp->tun_if.if_baudrate; 407 break; 408 case TUNSDEBUG: 409 tundebug = *(int *)ap->a_data; 410 break; 411 case TUNGDEBUG: 412 *(int *)ap->a_data = tundebug; 413 break; 414 case TUNSLMODE: 415 if (*(int *)ap->a_data) { 416 tp->tun_flags |= TUN_LMODE; 417 tp->tun_flags &= ~TUN_IFHEAD; 418 } else 419 tp->tun_flags &= ~TUN_LMODE; 420 break; 421 case TUNSIFHEAD: 422 if (*(int *)ap->a_data) { 423 tp->tun_flags |= TUN_IFHEAD; 424 tp->tun_flags &= ~TUN_LMODE; 425 } else 426 tp->tun_flags &= ~TUN_IFHEAD; 427 break; 428 case TUNGIFHEAD: 429 *(int *)ap->a_data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0; 430 break; 431 case TUNSIFMODE: 432 /* deny this if UP */ 433 if (tp->tun_if.if_flags & IFF_UP) 434 return(EBUSY); 435 436 switch (*(int *)ap->a_data & ~IFF_MULTICAST) { 437 case IFF_POINTOPOINT: 438 case IFF_BROADCAST: 439 tp->tun_if.if_flags &= ~(IFF_BROADCAST|IFF_POINTOPOINT); 440 tp->tun_if.if_flags |= *(int *)ap->a_data; 441 break; 442 default: 443 return(EINVAL); 444 } 445 break; 446 case TUNSIFPID: 447 tp->tun_pid = curproc->p_pid; 448 break; 449 case FIOASYNC: 450 if (*(int *)ap->a_data) 451 tp->tun_flags |= TUN_ASYNC; 452 else 453 tp->tun_flags &= ~TUN_ASYNC; 454 break; 455 case FIONREAD: 456 lwkt_serialize_enter(tp->tun_if.if_serializer); 457 if (!ifq_is_empty(&tp->tun_if.if_snd)) { 458 struct mbuf *mb; 459 460 mb = ifq_poll(&tp->tun_if.if_snd); 461 for( *(int *)ap->a_data = 0; mb != 0; mb = mb->m_next) 462 *(int *)ap->a_data += mb->m_len; 463 } else { 464 *(int *)ap->a_data = 0; 465 } 466 lwkt_serialize_exit(tp->tun_if.if_serializer); 467 break; 468 case FIOSETOWN: 469 return (fsetown(*(int *)ap->a_data, &tp->tun_sigio)); 470 471 case FIOGETOWN: 472 *(int *)ap->a_data = fgetown(tp->tun_sigio); 473 return (0); 474 475 /* This is deprecated, FIOSETOWN should be used instead. */ 476 case TIOCSPGRP: 477 return (fsetown(-(*(int *)ap->a_data), &tp->tun_sigio)); 478 479 /* This is deprecated, FIOGETOWN should be used instead. */ 480 case TIOCGPGRP: 481 *(int *)ap->a_data = -fgetown(tp->tun_sigio); 482 return (0); 483 484 default: 485 return (ENOTTY); 486 } 487 return (0); 488 } 489 490 /* 491 * The ops read interface - reads a packet at a time, or at 492 * least as much of a packet as can be read. 493 */ 494 static int 495 tunread(struct dev_read_args *ap) 496 { 497 cdev_t dev = ap->a_head.a_dev; 498 struct uio *uio = ap->a_uio; 499 struct tun_softc *tp = dev->si_drv1; 500 struct ifnet *ifp = &tp->tun_if; 501 struct mbuf *m0; 502 int error=0, len; 503 504 TUNDEBUG(ifp, "read\n"); 505 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 506 TUNDEBUG(ifp, "not ready 0%o\n", tp->tun_flags); 507 return EHOSTDOWN; 508 } 509 510 tp->tun_flags &= ~TUN_RWAIT; 511 512 lwkt_serialize_enter(ifp->if_serializer); 513 514 while ((m0 = ifq_dequeue(&ifp->if_snd, NULL)) == NULL) { 515 if (ap->a_ioflag & IO_NDELAY) { 516 lwkt_serialize_exit(ifp->if_serializer); 517 return EWOULDBLOCK; 518 } 519 tp->tun_flags |= TUN_RWAIT; 520 lwkt_serialize_exit(ifp->if_serializer); 521 if ((error = tsleep(tp, PCATCH, "tunread", 0)) != 0) 522 return error; 523 lwkt_serialize_enter(ifp->if_serializer); 524 } 525 526 lwkt_serialize_exit(ifp->if_serializer); 527 528 while (m0 && uio->uio_resid > 0 && error == 0) { 529 len = min(uio->uio_resid, m0->m_len); 530 if (len != 0) 531 error = uiomove(mtod(m0, caddr_t), len, uio); 532 m0 = m_free(m0); 533 } 534 535 if (m0) { 536 TUNDEBUG(ifp, "Dropping mbuf\n"); 537 m_freem(m0); 538 } 539 return error; 540 } 541 542 /* 543 * the ops write interface - an atomic write is a packet - or else! 544 */ 545 static int 546 tunwrite(struct dev_write_args *ap) 547 { 548 cdev_t dev = ap->a_head.a_dev; 549 struct uio *uio = ap->a_uio; 550 struct tun_softc *tp = dev->si_drv1; 551 struct ifnet *ifp = &tp->tun_if; 552 struct mbuf *top, **mp, *m; 553 int error=0, tlen, mlen; 554 uint32_t family; 555 int isr; 556 557 TUNDEBUG(ifp, "tunwrite\n"); 558 559 if (uio->uio_resid == 0) 560 return 0; 561 562 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) { 563 TUNDEBUG(ifp, "len=%d!\n", uio->uio_resid); 564 return EIO; 565 } 566 tlen = uio->uio_resid; 567 568 /* get a header mbuf */ 569 MGETHDR(m, MB_DONTWAIT, MT_DATA); 570 if (m == NULL) 571 return ENOBUFS; 572 mlen = MHLEN; 573 574 top = 0; 575 mp = ⊤ 576 while (error == 0 && uio->uio_resid > 0) { 577 m->m_len = min(mlen, uio->uio_resid); 578 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 579 *mp = m; 580 mp = &m->m_next; 581 if (uio->uio_resid > 0) { 582 MGET (m, MB_DONTWAIT, MT_DATA); 583 if (m == 0) { 584 error = ENOBUFS; 585 break; 586 } 587 mlen = MLEN; 588 } 589 } 590 if (error) { 591 if (top) 592 m_freem (top); 593 ifp->if_ierrors++; 594 return error; 595 } 596 597 top->m_pkthdr.len = tlen; 598 top->m_pkthdr.rcvif = ifp; 599 600 if (ifp->if_bpf) { 601 if (tp->tun_flags & TUN_IFHEAD) { 602 /* 603 * Conveniently, we already have a 4-byte address 604 * family prepended to our packet ! 605 * Inconveniently, it's in the wrong byte order ! 606 */ 607 if ((top = m_pullup(top, sizeof(family))) == NULL) 608 return ENOBUFS; 609 *mtod(top, u_int32_t *) = 610 ntohl(*mtod(top, u_int32_t *)); 611 bpf_mtap(ifp->if_bpf, top); 612 *mtod(top, u_int32_t *) = 613 htonl(*mtod(top, u_int32_t *)); 614 } else { 615 /* 616 * We need to prepend the address family as 617 * a four byte field. 618 */ 619 static const uint32_t af = AF_INET; 620 621 bpf_ptap(ifp->if_bpf, top, &af, sizeof(af)); 622 } 623 } 624 625 if (tp->tun_flags & TUN_IFHEAD) { 626 if (top->m_len < sizeof(family) && 627 (top = m_pullup(top, sizeof(family))) == NULL) 628 return ENOBUFS; 629 family = ntohl(*mtod(top, u_int32_t *)); 630 m_adj(top, sizeof(family)); 631 } else 632 family = AF_INET; 633 634 ifp->if_ibytes += top->m_pkthdr.len; 635 ifp->if_ipackets++; 636 637 switch (family) { 638 #ifdef INET 639 case AF_INET: 640 isr = NETISR_IP; 641 break; 642 #endif 643 #ifdef INET6 644 case AF_INET6: 645 isr = NETISR_IPV6; 646 break; 647 #endif 648 #ifdef IPX 649 case AF_IPX: 650 isr = NETISR_IPX; 651 break; 652 #endif 653 #ifdef NETATALK 654 case AF_APPLETALK: 655 isr = NETISR_ATALK2; 656 break; 657 #endif 658 default: 659 m_freem(m); 660 return (EAFNOSUPPORT); 661 } 662 663 netisr_dispatch(isr, top); 664 return (0); 665 } 666 667 /* 668 * tunpoll - the poll interface, this is only useful on reads 669 * really. The write detect always returns true, write never blocks 670 * anyway, it either accepts the packet or drops it. 671 */ 672 static int 673 tunpoll(struct dev_poll_args *ap) 674 { 675 cdev_t dev = ap->a_head.a_dev; 676 struct tun_softc *tp = dev->si_drv1; 677 struct ifnet *ifp = &tp->tun_if; 678 int revents = 0; 679 680 TUNDEBUG(ifp, "tunpoll\n"); 681 682 lwkt_serialize_enter(ifp->if_serializer); 683 684 if (ap->a_events & (POLLIN | POLLRDNORM)) { 685 if (!ifq_is_empty(&ifp->if_snd)) { 686 TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len); 687 revents |= ap->a_events & (POLLIN | POLLRDNORM); 688 } else { 689 TUNDEBUG(ifp, "tunpoll waiting\n"); 690 selrecord(curthread, &tp->tun_rsel); 691 } 692 } 693 if (ap->a_events & (POLLOUT | POLLWRNORM)) 694 revents |= ap->a_events & (POLLOUT | POLLWRNORM); 695 696 lwkt_serialize_exit(ifp->if_serializer); 697 ap->a_events = revents; 698 return(0); 699 } 700 701 /* 702 * Start packet transmission on the interface. 703 * when the interface queue is rate-limited by ALTQ, 704 * if_start is needed to drain packets from the queue in order 705 * to notify readers when outgoing packets become ready. 706 */ 707 static void 708 tunstart(struct ifnet *ifp) 709 { 710 struct tun_softc *tp = ifp->if_softc; 711 struct mbuf *m; 712 713 if (!ifq_is_enabled(&ifp->if_snd)) 714 return; 715 716 m = ifq_poll(&ifp->if_snd); 717 if (m != NULL) { 718 if (tp->tun_flags & TUN_RWAIT) { 719 tp->tun_flags &= ~TUN_RWAIT; 720 wakeup((caddr_t)tp); 721 } 722 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) 723 pgsigio(tp->tun_sigio, SIGIO, 0); 724 selwakeup(&tp->tun_rsel); 725 } 726 } 727