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