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