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