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 "use_tun.h" 21 #include "opt_atalk.h" 22 #include "opt_inet.h" 23 #include "opt_inet6.h" 24 #include "opt_ipx.h" 25 26 #include <sys/param.h> 27 #include <sys/proc.h> 28 #include <sys/priv.h> 29 #include <sys/systm.h> 30 #include <sys/mbuf.h> 31 #include <sys/socket.h> 32 #include <sys/conf.h> 33 #include <sys/device.h> 34 #include <sys/filio.h> 35 #include <sys/sockio.h> 36 #include <sys/thread2.h> 37 #include <sys/ttycom.h> 38 #include <sys/poll.h> 39 #include <sys/signalvar.h> 40 #include <sys/filedesc.h> 41 #include <sys/kernel.h> 42 #include <sys/sysctl.h> 43 #include <sys/uio.h> 44 #include <sys/vnode.h> 45 #include <sys/malloc.h> 46 47 #include <sys/mplock2.h> 48 49 #include <net/if.h> 50 #include <net/if_types.h> 51 #include <net/ifq_var.h> 52 #include <net/netisr.h> 53 #include <net/route.h> 54 #include <sys/devfs.h> 55 56 #ifdef INET 57 #include <netinet/in.h> 58 #endif 59 60 #include <net/bpf.h> 61 62 #include "if_tunvar.h" 63 #include "if_tun.h" 64 65 static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface"); 66 67 static void tunattach (void *); 68 PSEUDO_SET(tunattach, if_tun); 69 70 static void tuncreate (cdev_t dev); 71 72 #define TUNDEBUG if (tundebug) if_printf 73 static int tundebug = 0; 74 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 75 76 static int tunoutput (struct ifnet *, struct mbuf *, struct sockaddr *, 77 struct rtentry *rt); 78 static int tunifioctl (struct ifnet *, u_long, caddr_t, struct ucred *); 79 static int tuninit (struct ifnet *); 80 static void tunstart(struct ifnet *); 81 82 static d_open_t tunopen; 83 static d_close_t tunclose; 84 static d_read_t tunread; 85 static d_write_t tunwrite; 86 static d_ioctl_t tunioctl; 87 static d_poll_t tunpoll; 88 89 static d_clone_t tunclone; 90 DEVFS_DECLARE_CLONE_BITMAP(tun); 91 92 #if NTUN <= 1 93 #define TUN_PREALLOCATED_UNITS 4 94 #else 95 #define TUN_PREALLOCATED_UNITS NTUN 96 #endif 97 98 #define CDEV_MAJOR 52 99 static struct dev_ops tun_ops = { 100 { "tun", CDEV_MAJOR, 0 }, 101 .d_open = tunopen, 102 .d_close = tunclose, 103 .d_read = tunread, 104 .d_write = tunwrite, 105 .d_ioctl = tunioctl, 106 .d_poll = tunpoll, 107 }; 108 109 static void 110 tunattach(void *dummy) 111 { 112 int i; 113 make_autoclone_dev(&tun_ops, &DEVFS_CLONE_BITMAP(tun), 114 tunclone, UID_UUCP, GID_DIALER, 0600, "tun"); 115 for (i = 0; i < TUN_PREALLOCATED_UNITS; i++) { 116 make_dev(&tun_ops, i, UID_UUCP, GID_DIALER, 0600, "tun%d", i); 117 devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tun), i); 118 } 119 /* Doesn't need uninit because unloading is not possible, see PSEUDO_SET */ 120 } 121 122 static int 123 tunclone(struct dev_clone_args *ap) 124 { 125 int unit; 126 127 unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(tun), 0); 128 ap->a_dev = make_only_dev(&tun_ops, unit, UID_UUCP, GID_DIALER, 0600, 129 "tun%d", unit); 130 131 return 0; 132 } 133 134 static void 135 tuncreate(cdev_t dev) 136 { 137 struct tun_softc *sc; 138 struct ifnet *ifp; 139 140 #if 0 141 dev = make_dev(&tun_ops, minor(dev), 142 UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev)); 143 #endif 144 145 MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO); 146 sc->tun_flags = TUN_INITED; 147 148 ifp = &sc->tun_if; 149 if_initname(ifp, "tun", lminor(dev)); 150 ifp->if_mtu = TUNMTU; 151 ifp->if_ioctl = tunifioctl; 152 ifp->if_output = tunoutput; 153 ifp->if_start = tunstart; 154 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 155 ifp->if_type = IFT_PPP; 156 ifq_set_maxlen(&ifp->if_snd, ifqmaxlen); 157 ifq_set_ready(&ifp->if_snd); 158 ifp->if_softc = sc; 159 if_attach(ifp, NULL); 160 bpfattach(ifp, DLT_NULL, sizeof(u_int)); 161 dev->si_drv1 = sc; 162 } 163 164 /* 165 * tunnel open - must be superuser & the device must be 166 * configured in 167 */ 168 static int 169 tunopen(struct dev_open_args *ap) 170 { 171 cdev_t dev = ap->a_head.a_dev; 172 struct ifnet *ifp; 173 struct tun_softc *tp; 174 int error; 175 176 if ((error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) != 0) 177 return (error); 178 179 tp = dev->si_drv1; 180 if (!tp) { 181 tuncreate(dev); 182 tp = dev->si_drv1; 183 } 184 if (tp->tun_flags & TUN_OPEN) 185 return EBUSY; 186 tp->tun_pid = curproc->p_pid; 187 ifp = &tp->tun_if; 188 tp->tun_flags |= TUN_OPEN; 189 TUNDEBUG(ifp, "open\n"); 190 return (0); 191 } 192 193 /* 194 * tunclose - close the device - mark i/f down & delete 195 * routing info 196 */ 197 static int 198 tunclose(struct dev_close_args *ap) 199 { 200 cdev_t dev = ap->a_head.a_dev; 201 struct tun_softc *tp; 202 struct ifnet *ifp; 203 204 tp = dev->si_drv1; 205 ifp = &tp->tun_if; 206 207 tp->tun_flags &= ~TUN_OPEN; 208 tp->tun_pid = 0; 209 210 /* Junk all pending output. */ 211 ifq_purge(&ifp->if_snd); 212 213 if (ifp->if_flags & IFF_UP) 214 if_down(ifp); 215 ifp->if_flags &= ~IFF_RUNNING; 216 if_purgeaddrs_nolink(ifp); 217 218 funsetown(tp->tun_sigio); 219 selwakeup(&tp->tun_rsel); 220 221 TUNDEBUG(ifp, "closed\n"); 222 #if 0 223 if (dev->si_uminor >= TUN_PREALLOCATED_UNITS) { 224 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tun), dev->si_uminor); 225 } 226 #endif 227 return (0); 228 } 229 230 static int 231 tuninit(struct ifnet *ifp) 232 { 233 struct tun_softc *tp = ifp->if_softc; 234 struct ifaddr_container *ifac; 235 int error = 0; 236 237 TUNDEBUG(ifp, "tuninit\n"); 238 239 ifp->if_flags |= IFF_UP | IFF_RUNNING; 240 getmicrotime(&ifp->if_lastchange); 241 242 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) { 243 struct ifaddr *ifa = ifac->ifa; 244 245 if (ifa->ifa_addr == NULL) { 246 error = EFAULT; 247 /* XXX: Should maybe return straight off? */ 248 } else { 249 #ifdef INET 250 if (ifa->ifa_addr->sa_family == AF_INET) { 251 struct sockaddr_in *si; 252 253 si = (struct sockaddr_in *)ifa->ifa_addr; 254 if (si->sin_addr.s_addr) 255 tp->tun_flags |= TUN_IASET; 256 } 257 #endif 258 } 259 } 260 return (error); 261 } 262 263 /* 264 * Process an ioctl request. 265 * 266 * MPSAFE 267 */ 268 int 269 tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) 270 { 271 struct ifreq *ifr = (struct ifreq *)data; 272 struct tun_softc *tp = ifp->if_softc; 273 struct ifstat *ifs; 274 int error = 0; 275 276 switch(cmd) { 277 case SIOCGIFSTATUS: 278 ifs = (struct ifstat *)data; 279 if (tp->tun_pid) 280 ksprintf(ifs->ascii + strlen(ifs->ascii), 281 "\tOpened by PID %d\n", tp->tun_pid); 282 break; 283 case SIOCSIFADDR: 284 error = tuninit(ifp); 285 TUNDEBUG(ifp, "address set, error=%d\n", error); 286 break; 287 case SIOCSIFDSTADDR: 288 error = tuninit(ifp); 289 TUNDEBUG(ifp, "destination address set, error=%d\n", error); 290 break; 291 case SIOCSIFMTU: 292 ifp->if_mtu = ifr->ifr_mtu; 293 TUNDEBUG(ifp, "mtu set\n"); 294 break; 295 case SIOCSIFFLAGS: 296 case SIOCADDMULTI: 297 case SIOCDELMULTI: 298 break; 299 default: 300 error = EINVAL; 301 } 302 return (error); 303 } 304 305 /* 306 * tunoutput - queue packets from higher level ready to put out. 307 * 308 * MPSAFE 309 */ 310 static int 311 tunoutput_serialized(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, 312 struct rtentry *rt) 313 { 314 struct tun_softc *tp = ifp->if_softc; 315 int error; 316 struct altq_pktattr pktattr; 317 318 TUNDEBUG(ifp, "tunoutput\n"); 319 320 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 321 TUNDEBUG(ifp, "not ready 0%o\n", tp->tun_flags); 322 m_freem (m0); 323 return EHOSTDOWN; 324 } 325 326 /* 327 * if the queueing discipline needs packet classification, 328 * do it before prepending link headers. 329 */ 330 ifq_classify(&ifp->if_snd, m0, dst->sa_family, &pktattr); 331 332 /* BPF write needs to be handled specially */ 333 if (dst->sa_family == AF_UNSPEC) { 334 dst->sa_family = *(mtod(m0, int *)); 335 m0->m_len -= sizeof(int); 336 m0->m_pkthdr.len -= sizeof(int); 337 m0->m_data += sizeof(int); 338 } 339 340 if (ifp->if_bpf) { 341 /* 342 * We need to prepend the address family as 343 * a four byte field. 344 */ 345 uint32_t af = dst->sa_family; 346 347 bpf_ptap(ifp->if_bpf, m0, &af, sizeof(af)); 348 } 349 350 /* prepend sockaddr? this may abort if the mbuf allocation fails */ 351 if (tp->tun_flags & TUN_LMODE) { 352 /* allocate space for sockaddr */ 353 M_PREPEND(m0, dst->sa_len, MB_DONTWAIT); 354 355 /* if allocation failed drop packet */ 356 if (m0 == NULL){ 357 IF_DROP(&ifp->if_snd); 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 IF_DROP(&ifp->if_snd); 372 ifp->if_oerrors++; 373 return ENOBUFS; 374 } else 375 *(u_int32_t *)m0->m_data = htonl(dst->sa_family); 376 } else { 377 #ifdef INET 378 if (dst->sa_family != AF_INET) 379 #endif 380 { 381 m_freem(m0); 382 return EAFNOSUPPORT; 383 } 384 } 385 386 error = ifq_handoff(ifp, m0, &pktattr); 387 if (error) { 388 ifp->if_collisions++; 389 } else { 390 ifp->if_opackets++; 391 if (tp->tun_flags & TUN_RWAIT) { 392 tp->tun_flags &= ~TUN_RWAIT; 393 wakeup((caddr_t)tp); 394 } 395 get_mplock(); 396 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) 397 pgsigio(tp->tun_sigio, SIGIO, 0); 398 selwakeup(&tp->tun_rsel); 399 rel_mplock(); 400 } 401 return (error); 402 } 403 404 static int 405 tunoutput(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, 406 struct rtentry *rt) 407 { 408 int error; 409 410 ifnet_serialize_all(ifp); 411 error = tunoutput_serialized(ifp, m0, dst, rt); 412 ifnet_deserialize_all(ifp); 413 414 return error; 415 } 416 417 /* 418 * the ops interface is now pretty minimal. 419 */ 420 static int 421 tunioctl(struct dev_ioctl_args *ap) 422 { 423 cdev_t dev = ap->a_head.a_dev; 424 struct tun_softc *tp = dev->si_drv1; 425 struct tuninfo *tunp; 426 427 switch (ap->a_cmd) { 428 case TUNSIFINFO: 429 tunp = (struct tuninfo *)ap->a_data; 430 if (tunp->mtu < IF_MINMTU) 431 return (EINVAL); 432 tp->tun_if.if_mtu = tunp->mtu; 433 tp->tun_if.if_type = tunp->type; 434 tp->tun_if.if_baudrate = tunp->baudrate; 435 break; 436 case TUNGIFINFO: 437 tunp = (struct tuninfo *)ap->a_data; 438 tunp->mtu = tp->tun_if.if_mtu; 439 tunp->type = tp->tun_if.if_type; 440 tunp->baudrate = tp->tun_if.if_baudrate; 441 break; 442 case TUNSDEBUG: 443 tundebug = *(int *)ap->a_data; 444 break; 445 case TUNGDEBUG: 446 *(int *)ap->a_data = tundebug; 447 break; 448 case TUNSLMODE: 449 if (*(int *)ap->a_data) { 450 tp->tun_flags |= TUN_LMODE; 451 tp->tun_flags &= ~TUN_IFHEAD; 452 } else 453 tp->tun_flags &= ~TUN_LMODE; 454 break; 455 case TUNSIFHEAD: 456 if (*(int *)ap->a_data) { 457 tp->tun_flags |= TUN_IFHEAD; 458 tp->tun_flags &= ~TUN_LMODE; 459 } else 460 tp->tun_flags &= ~TUN_IFHEAD; 461 break; 462 case TUNGIFHEAD: 463 *(int *)ap->a_data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0; 464 break; 465 case TUNSIFMODE: 466 /* deny this if UP */ 467 if (tp->tun_if.if_flags & IFF_UP) 468 return(EBUSY); 469 470 switch (*(int *)ap->a_data & ~IFF_MULTICAST) { 471 case IFF_POINTOPOINT: 472 case IFF_BROADCAST: 473 tp->tun_if.if_flags &= ~(IFF_BROADCAST|IFF_POINTOPOINT); 474 tp->tun_if.if_flags |= *(int *)ap->a_data; 475 break; 476 default: 477 return(EINVAL); 478 } 479 break; 480 case TUNSIFPID: 481 tp->tun_pid = curproc->p_pid; 482 break; 483 case FIOASYNC: 484 if (*(int *)ap->a_data) 485 tp->tun_flags |= TUN_ASYNC; 486 else 487 tp->tun_flags &= ~TUN_ASYNC; 488 break; 489 case FIONREAD: 490 if (!ifq_is_empty(&tp->tun_if.if_snd)) { 491 struct mbuf *mb; 492 493 mb = ifq_poll(&tp->tun_if.if_snd); 494 for( *(int *)ap->a_data = 0; mb != 0; mb = mb->m_next) 495 *(int *)ap->a_data += mb->m_len; 496 } else { 497 *(int *)ap->a_data = 0; 498 } 499 break; 500 case FIOSETOWN: 501 return (fsetown(*(int *)ap->a_data, &tp->tun_sigio)); 502 503 case FIOGETOWN: 504 *(int *)ap->a_data = fgetown(tp->tun_sigio); 505 return (0); 506 507 /* This is deprecated, FIOSETOWN should be used instead. */ 508 case TIOCSPGRP: 509 return (fsetown(-(*(int *)ap->a_data), &tp->tun_sigio)); 510 511 /* This is deprecated, FIOGETOWN should be used instead. */ 512 case TIOCGPGRP: 513 *(int *)ap->a_data = -fgetown(tp->tun_sigio); 514 return (0); 515 516 default: 517 return (ENOTTY); 518 } 519 return (0); 520 } 521 522 /* 523 * The ops read interface - reads a packet at a time, or at 524 * least as much of a packet as can be read. 525 */ 526 static int 527 tunread(struct dev_read_args *ap) 528 { 529 cdev_t dev = ap->a_head.a_dev; 530 struct uio *uio = ap->a_uio; 531 struct tun_softc *tp = dev->si_drv1; 532 struct ifnet *ifp = &tp->tun_if; 533 struct mbuf *m0; 534 int error=0, len; 535 536 TUNDEBUG(ifp, "read\n"); 537 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 538 TUNDEBUG(ifp, "not ready 0%o\n", tp->tun_flags); 539 return EHOSTDOWN; 540 } 541 542 tp->tun_flags &= ~TUN_RWAIT; 543 544 ifnet_serialize_all(ifp); 545 546 while ((m0 = ifq_dequeue(&ifp->if_snd, NULL)) == NULL) { 547 if (ap->a_ioflag & IO_NDELAY) { 548 ifnet_deserialize_all(ifp); 549 return EWOULDBLOCK; 550 } 551 tp->tun_flags |= TUN_RWAIT; 552 ifnet_deserialize_all(ifp); 553 if ((error = tsleep(tp, PCATCH, "tunread", 0)) != 0) 554 return error; 555 ifnet_serialize_all(ifp); 556 } 557 558 ifnet_deserialize_all(ifp); 559 560 while (m0 && uio->uio_resid > 0 && error == 0) { 561 len = (int)szmin(uio->uio_resid, m0->m_len); 562 if (len != 0) 563 error = uiomove(mtod(m0, caddr_t), (size_t)len, uio); 564 m0 = m_free(m0); 565 } 566 567 if (m0) { 568 TUNDEBUG(ifp, "Dropping mbuf\n"); 569 m_freem(m0); 570 } 571 return error; 572 } 573 574 /* 575 * the ops write interface - an atomic write is a packet - or else! 576 */ 577 static int 578 tunwrite(struct dev_write_args *ap) 579 { 580 cdev_t dev = ap->a_head.a_dev; 581 struct uio *uio = ap->a_uio; 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; 586 size_t tlen, mlen; 587 uint32_t family; 588 int isr; 589 590 TUNDEBUG(ifp, "tunwrite\n"); 591 592 if (uio->uio_resid == 0) 593 return 0; 594 595 if (uio->uio_resid > TUNMRU) { 596 TUNDEBUG(ifp, "len=%zd!\n", 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 = (int)szmin(mlen, uio->uio_resid); 611 error = uiomove(mtod (m, caddr_t), (size_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 = (int)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(struct dev_poll_args *ap) 707 { 708 cdev_t dev = ap->a_head.a_dev; 709 struct tun_softc *tp = dev->si_drv1; 710 struct ifnet *ifp = &tp->tun_if; 711 int revents = 0; 712 713 TUNDEBUG(ifp, "tunpoll\n"); 714 715 ifnet_serialize_all(ifp); 716 717 if (ap->a_events & (POLLIN | POLLRDNORM)) { 718 if (!ifq_is_empty(&ifp->if_snd)) { 719 TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len); 720 revents |= ap->a_events & (POLLIN | POLLRDNORM); 721 } else { 722 TUNDEBUG(ifp, "tunpoll waiting\n"); 723 selrecord(curthread, &tp->tun_rsel); 724 } 725 } 726 if (ap->a_events & (POLLOUT | POLLWRNORM)) 727 revents |= ap->a_events & (POLLOUT | POLLWRNORM); 728 729 ifnet_deserialize_all(ifp); 730 ap->a_events = revents; 731 return(0); 732 } 733 734 /* 735 * Start packet transmission on the interface. 736 * when the interface queue is rate-limited by ALTQ, 737 * if_start is needed to drain packets from the queue in order 738 * to notify readers when outgoing packets become ready. 739 */ 740 static void 741 tunstart(struct ifnet *ifp) 742 { 743 struct tun_softc *tp = ifp->if_softc; 744 struct mbuf *m; 745 746 if (!ifq_is_enabled(&ifp->if_snd)) 747 return; 748 749 m = ifq_poll(&ifp->if_snd); 750 if (m != NULL) { 751 if (tp->tun_flags & TUN_RWAIT) { 752 tp->tun_flags &= ~TUN_RWAIT; 753 wakeup((caddr_t)tp); 754 } 755 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) 756 pgsigio(tp->tun_sigio, SIGIO, 0); 757 selwakeup(&tp->tun_rsel); 758 } 759 } 760