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