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