if_tap.c revision 163986
1/*- 2 * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * BASED ON: 27 * ------------------------------------------------------------------------- 28 * 29 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 30 * Nottingham University 1987. 31 */ 32 33/* 34 * $FreeBSD: head/sys/net/if_tap.c 163986 2006-11-04 20:54:37Z csjp $ 35 * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $ 36 */ 37 38#include "opt_compat.h" 39#include "opt_inet.h" 40 41#include <sys/param.h> 42#include <sys/conf.h> 43#include <sys/fcntl.h> 44#include <sys/filio.h> 45#include <sys/kernel.h> 46#include <sys/malloc.h> 47#include <sys/mbuf.h> 48#include <sys/module.h> 49#include <sys/poll.h> 50#include <sys/proc.h> 51#include <sys/selinfo.h> 52#include <sys/signalvar.h> 53#include <sys/socket.h> 54#include <sys/sockio.h> 55#include <sys/sysctl.h> 56#include <sys/systm.h> 57#include <sys/ttycom.h> 58#include <sys/uio.h> 59#include <sys/queue.h> 60 61#include <net/bpf.h> 62#include <net/ethernet.h> 63#include <net/if.h> 64#include <net/if_dl.h> 65#include <net/route.h> 66#include <net/if_types.h> 67 68#include <netinet/in.h> 69 70#include <net/if_tapvar.h> 71#include <net/if_tap.h> 72 73 74#define CDEV_NAME "tap" 75#define TAPDEBUG if (tapdebug) printf 76 77#define TAP "tap" 78#define VMNET "vmnet" 79#define TAPMAXUNIT 0x7fff 80#define VMNET_DEV_MASK CLONE_FLAG0 81 82/* module */ 83static int tapmodevent(module_t, int, void *); 84 85/* device */ 86static void tapclone(void *, struct ucred *, char *, int, 87 struct cdev **); 88static void tapcreate(struct cdev *); 89 90/* network interface */ 91static void tapifstart(struct ifnet *); 92static int tapifioctl(struct ifnet *, u_long, caddr_t); 93static void tapifinit(void *); 94 95/* character device */ 96static d_open_t tapopen; 97static d_close_t tapclose; 98static d_read_t tapread; 99static d_write_t tapwrite; 100static d_ioctl_t tapioctl; 101static d_poll_t tappoll; 102static d_kqfilter_t tapkqfilter; 103 104/* kqueue(2) */ 105static int tapkqread(struct knote *, long); 106static int tapkqwrite(struct knote *, long); 107static void tapkqdetach(struct knote *); 108 109static struct filterops tap_read_filterops = { 110 .f_isfd = 1, 111 .f_attach = NULL, 112 .f_detach = tapkqdetach, 113 .f_event = tapkqread, 114}; 115 116static struct filterops tap_write_filterops = { 117 .f_isfd = 1, 118 .f_attach = NULL, 119 .f_detach = tapkqdetach, 120 .f_event = tapkqwrite, 121}; 122 123static struct cdevsw tap_cdevsw = { 124 .d_version = D_VERSION, 125 .d_flags = D_PSEUDO | D_NEEDGIANT, 126 .d_open = tapopen, 127 .d_close = tapclose, 128 .d_read = tapread, 129 .d_write = tapwrite, 130 .d_ioctl = tapioctl, 131 .d_poll = tappoll, 132 .d_name = CDEV_NAME, 133 .d_kqfilter = tapkqfilter, 134}; 135 136/* 137 * All global variables in if_tap.c are locked with tapmtx, with the 138 * exception of tapdebug, which is accessed unlocked; tapclones is 139 * static at runtime. 140 */ 141static struct mtx tapmtx; 142static int tapdebug = 0; /* debug flag */ 143static int tapuopen = 0; /* allow user open() */ 144static SLIST_HEAD(, tap_softc) taphead; /* first device */ 145static struct clonedevs *tapclones; 146 147MALLOC_DECLARE(M_TAP); 148MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface"); 149SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, ""); 150 151SYSCTL_DECL(_net_link); 152SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0, 153 "Ethernet tunnel software network interface"); 154SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0, 155 "Allow user to open /dev/tap (based on node permissions)"); 156SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, ""); 157 158DEV_MODULE(if_tap, tapmodevent, NULL); 159 160/* 161 * tapmodevent 162 * 163 * module event handler 164 */ 165static int 166tapmodevent(module_t mod, int type, void *data) 167{ 168 static eventhandler_tag eh_tag = NULL; 169 struct tap_softc *tp = NULL; 170 struct ifnet *ifp = NULL; 171 int s; 172 173 switch (type) { 174 case MOD_LOAD: 175 176 /* intitialize device */ 177 178 mtx_init(&tapmtx, "tapmtx", NULL, MTX_DEF); 179 SLIST_INIT(&taphead); 180 181 clone_setup(&tapclones); 182 eh_tag = EVENTHANDLER_REGISTER(dev_clone, tapclone, 0, 1000); 183 if (eh_tag == NULL) { 184 clone_cleanup(&tapclones); 185 mtx_destroy(&tapmtx); 186 return (ENOMEM); 187 } 188 return (0); 189 190 case MOD_UNLOAD: 191 /* 192 * The EBUSY algorithm here can't quite atomically 193 * guarantee that this is race-free since we have to 194 * release the tap mtx to deregister the clone handler. 195 */ 196 mtx_lock(&tapmtx); 197 SLIST_FOREACH(tp, &taphead, tap_next) { 198 mtx_lock(&tp->tap_mtx); 199 if (tp->tap_flags & TAP_OPEN) { 200 mtx_unlock(&tp->tap_mtx); 201 mtx_unlock(&tapmtx); 202 return (EBUSY); 203 } 204 mtx_unlock(&tp->tap_mtx); 205 } 206 mtx_unlock(&tapmtx); 207 208 EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); 209 210 mtx_lock(&tapmtx); 211 while ((tp = SLIST_FIRST(&taphead)) != NULL) { 212 SLIST_REMOVE_HEAD(&taphead, tap_next); 213 mtx_unlock(&tapmtx); 214 215 ifp = tp->tap_ifp; 216 217 TAPDEBUG("detaching %s\n", ifp->if_xname); 218 219 /* Unlocked read. */ 220 KASSERT(!(tp->tap_flags & TAP_OPEN), 221 ("%s flags is out of sync", ifp->if_xname)); 222 223 knlist_destroy(&tp->tap_rsel.si_note); 224 destroy_dev(tp->tap_dev); 225 s = splimp(); 226 ether_ifdetach(ifp); 227 if_free_type(ifp, IFT_ETHER); 228 splx(s); 229 230 mtx_destroy(&tp->tap_mtx); 231 free(tp, M_TAP); 232 mtx_lock(&tapmtx); 233 } 234 mtx_unlock(&tapmtx); 235 clone_cleanup(&tapclones); 236 237 mtx_destroy(&tapmtx); 238 239 break; 240 241 default: 242 return (EOPNOTSUPP); 243 } 244 245 return (0); 246} /* tapmodevent */ 247 248 249/* 250 * DEVFS handler 251 * 252 * We need to support two kind of devices - tap and vmnet 253 */ 254static void 255tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) 256{ 257 u_int extra; 258 int i, unit; 259 char *device_name = name; 260 261 if (*dev != NULL) 262 return; 263 264 device_name = TAP; 265 extra = 0; 266 if (strcmp(name, TAP) == 0) { 267 unit = -1; 268 } else if (strcmp(name, VMNET) == 0) { 269 device_name = VMNET; 270 extra = VMNET_DEV_MASK; 271 unit = -1; 272 } else if (dev_stdclone(name, NULL, device_name, &unit) != 1) { 273 device_name = VMNET; 274 extra = VMNET_DEV_MASK; 275 if (dev_stdclone(name, NULL, device_name, &unit) != 1) 276 return; 277 } 278 279 /* find any existing device, or allocate new unit number */ 280 i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra); 281 if (i) { 282 *dev = make_dev(&tap_cdevsw, unit2minor(unit | extra), 283 UID_ROOT, GID_WHEEL, 0600, "%s%d", device_name, unit); 284 if (*dev != NULL) { 285 dev_ref(*dev); 286 (*dev)->si_flags |= SI_CHEAPCLONE; 287 } 288 } 289} /* tapclone */ 290 291 292/* 293 * tapcreate 294 * 295 * to create interface 296 */ 297static void 298tapcreate(struct cdev *dev) 299{ 300 struct ifnet *ifp = NULL; 301 struct tap_softc *tp = NULL; 302 unsigned short macaddr_hi; 303 int unit, s; 304 char *name = NULL; 305 u_char eaddr[6]; 306 307 dev->si_flags &= ~SI_CHEAPCLONE; 308 309 /* allocate driver storage and create device */ 310 MALLOC(tp, struct tap_softc *, sizeof(*tp), M_TAP, M_WAITOK | M_ZERO); 311 mtx_init(&tp->tap_mtx, "tap_mtx", NULL, MTX_DEF); 312 mtx_lock(&tapmtx); 313 SLIST_INSERT_HEAD(&taphead, tp, tap_next); 314 mtx_unlock(&tapmtx); 315 316 unit = dev2unit(dev); 317 318 /* select device: tap or vmnet */ 319 if (unit & VMNET_DEV_MASK) { 320 name = VMNET; 321 tp->tap_flags |= TAP_VMNET; 322 } else 323 name = TAP; 324 325 unit &= TAPMAXUNIT; 326 327 TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, minor(dev)); 328 329 /* generate fake MAC address: 00 bd xx xx xx unit_no */ 330 macaddr_hi = htons(0x00bd); 331 bcopy(&macaddr_hi, eaddr, sizeof(short)); 332 bcopy(&ticks, &eaddr[2], sizeof(long)); 333 eaddr[5] = (u_char)unit; 334 335 /* fill the rest and attach interface */ 336 ifp = tp->tap_ifp = if_alloc(IFT_ETHER); 337 if (ifp == NULL) 338 panic("%s%d: can not if_alloc()", name, unit); 339 ifp->if_softc = tp; 340 if_initname(ifp, name, unit); 341 ifp->if_init = tapifinit; 342 ifp->if_start = tapifstart; 343 ifp->if_ioctl = tapifioctl; 344 ifp->if_mtu = ETHERMTU; 345 ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); 346 ifp->if_snd.ifq_maxlen = ifqmaxlen; 347 348 dev->si_drv1 = tp; 349 tp->tap_dev = dev; 350 351 s = splimp(); 352 ether_ifattach(ifp, eaddr); 353 splx(s); 354 355 mtx_lock(&tp->tap_mtx); 356 tp->tap_flags |= TAP_INITED; 357 mtx_unlock(&tp->tap_mtx); 358 359 knlist_init(&tp->tap_rsel.si_note, NULL, NULL, NULL, NULL); 360 361 TAPDEBUG("interface %s is created. minor = %#x\n", 362 ifp->if_xname, minor(dev)); 363} /* tapcreate */ 364 365 366/* 367 * tapopen 368 * 369 * to open tunnel. must be superuser 370 */ 371static int 372tapopen(struct cdev *dev, int flag, int mode, struct thread *td) 373{ 374 struct tap_softc *tp = NULL; 375 struct ifnet *ifp = NULL; 376 int s; 377 378 if (tapuopen == 0 && suser(td) != 0) 379 return (EPERM); 380 381 if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT) 382 return (ENXIO); 383 384 /* 385 * XXXRW: Non-atomic test-and-set of si_drv1. Currently protected 386 * by Giant, but the race actually exists under memory pressure as 387 * well even when running with Giant, as malloc() may sleep. 388 */ 389 tp = dev->si_drv1; 390 if (tp == NULL) { 391 tapcreate(dev); 392 tp = dev->si_drv1; 393 } 394 395 mtx_lock(&tp->tap_mtx); 396 if (tp->tap_flags & TAP_OPEN) { 397 mtx_unlock(&tp->tap_mtx); 398 return (EBUSY); 399 } 400 401 bcopy(IF_LLADDR(tp->tap_ifp), tp->ether_addr, sizeof(tp->ether_addr)); 402 tp->tap_pid = td->td_proc->p_pid; 403 tp->tap_flags |= TAP_OPEN; 404 ifp = tp->tap_ifp; 405 mtx_unlock(&tp->tap_mtx); 406 407 s = splimp(); 408 ifp->if_drv_flags |= IFF_DRV_RUNNING; 409 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 410 splx(s); 411 412 TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, minor(dev)); 413 414 return (0); 415} /* tapopen */ 416 417 418/* 419 * tapclose 420 * 421 * close the device - mark i/f down & delete routing info 422 */ 423static int 424tapclose(struct cdev *dev, int foo, int bar, struct thread *td) 425{ 426 struct ifaddr *ifa; 427 struct tap_softc *tp = dev->si_drv1; 428 struct ifnet *ifp = tp->tap_ifp; 429 int s; 430 431 /* junk all pending output */ 432 IF_DRAIN(&ifp->if_snd); 433 434 /* 435 * do not bring the interface down, and do not anything with 436 * interface, if we are in VMnet mode. just close the device. 437 */ 438 439 mtx_lock(&tp->tap_mtx); 440 if (((tp->tap_flags & TAP_VMNET) == 0) && (ifp->if_flags & IFF_UP)) { 441 mtx_unlock(&tp->tap_mtx); 442 s = splimp(); 443 if_down(ifp); 444 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 445 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 446 rtinit(ifa, (int)RTM_DELETE, 0); 447 } 448 if_purgeaddrs(ifp); 449 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 450 } 451 splx(s); 452 } else 453 mtx_unlock(&tp->tap_mtx); 454 455 funsetown(&tp->tap_sigio); 456 selwakeuppri(&tp->tap_rsel, PZERO+1); 457 KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0); 458 459 mtx_lock(&tp->tap_mtx); 460 tp->tap_flags &= ~TAP_OPEN; 461 tp->tap_pid = 0; 462 mtx_unlock(&tp->tap_mtx); 463 464 TAPDEBUG("%s is closed. minor = %#x\n", 465 ifp->if_xname, minor(dev)); 466 467 return (0); 468} /* tapclose */ 469 470 471/* 472 * tapifinit 473 * 474 * network interface initialization function 475 */ 476static void 477tapifinit(void *xtp) 478{ 479 struct tap_softc *tp = (struct tap_softc *)xtp; 480 struct ifnet *ifp = tp->tap_ifp; 481 482 TAPDEBUG("initializing %s\n", ifp->if_xname); 483 484 ifp->if_drv_flags |= IFF_DRV_RUNNING; 485 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 486 487 /* attempt to start output */ 488 tapifstart(ifp); 489} /* tapifinit */ 490 491 492/* 493 * tapifioctl 494 * 495 * Process an ioctl request on network interface 496 */ 497static int 498tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 499{ 500 struct tap_softc *tp = ifp->if_softc; 501 struct ifstat *ifs = NULL; 502 int s, dummy; 503 504 switch (cmd) { 505 case SIOCSIFFLAGS: /* XXX -- just like vmnet does */ 506 case SIOCADDMULTI: 507 case SIOCDELMULTI: 508 break; 509 510 case SIOCGIFSTATUS: 511 s = splimp(); 512 ifs = (struct ifstat *)data; 513 dummy = strlen(ifs->ascii); 514 mtx_lock(&tp->tap_mtx); 515 if (tp->tap_pid != 0 && dummy < sizeof(ifs->ascii)) 516 snprintf(ifs->ascii + dummy, 517 sizeof(ifs->ascii) - dummy, 518 "\tOpened by PID %d\n", tp->tap_pid); 519 mtx_unlock(&tp->tap_mtx); 520 splx(s); 521 break; 522 523 default: 524 s = splimp(); 525 dummy = ether_ioctl(ifp, cmd, data); 526 splx(s); 527 return (dummy); 528 /* NOT REACHED */ 529 } 530 531 return (0); 532} /* tapifioctl */ 533 534 535/* 536 * tapifstart 537 * 538 * queue packets from higher level ready to put out 539 */ 540static void 541tapifstart(struct ifnet *ifp) 542{ 543 struct tap_softc *tp = ifp->if_softc; 544 int s; 545 546 TAPDEBUG("%s starting\n", ifp->if_xname); 547 548 /* 549 * do not junk pending output if we are in VMnet mode. 550 * XXX: can this do any harm because of queue overflow? 551 */ 552 553 mtx_lock(&tp->tap_mtx); 554 if (((tp->tap_flags & TAP_VMNET) == 0) && 555 ((tp->tap_flags & TAP_READY) != TAP_READY)) { 556 struct mbuf *m = NULL; 557 558 mtx_unlock(&tp->tap_mtx); 559 560 /* Unlocked read. */ 561 TAPDEBUG("%s not ready, tap_flags = 0x%x\n", ifp->if_xname, 562 tp->tap_flags); 563 564 s = splimp(); 565 do { 566 IF_DEQUEUE(&ifp->if_snd, m); 567 if (m != NULL) 568 m_freem(m); 569 ifp->if_oerrors ++; 570 } while (m != NULL); 571 splx(s); 572 573 return; 574 } 575 mtx_unlock(&tp->tap_mtx); 576 577 s = splimp(); 578 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 579 580 if (ifp->if_snd.ifq_len != 0) { 581 mtx_lock(&tp->tap_mtx); 582 if (tp->tap_flags & TAP_RWAIT) { 583 tp->tap_flags &= ~TAP_RWAIT; 584 wakeup(tp); 585 } 586 587 if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL)) { 588 mtx_unlock(&tp->tap_mtx); 589 pgsigio(&tp->tap_sigio, SIGIO, 0); 590 } else 591 mtx_unlock(&tp->tap_mtx); 592 593 selwakeuppri(&tp->tap_rsel, PZERO+1); 594 KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0); 595 ifp->if_opackets ++; /* obytes are counted in ether_output */ 596 } 597 598 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 599 splx(s); 600} /* tapifstart */ 601 602 603/* 604 * tapioctl 605 * 606 * the cdevsw interface is now pretty minimal 607 */ 608static int 609tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 610{ 611 struct tap_softc *tp = dev->si_drv1; 612 struct ifnet *ifp = tp->tap_ifp; 613 struct tapinfo *tapp = NULL; 614 int s; 615 int f; 616#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 617 defined(COMPAT_FREEBSD4) 618 int ival; 619#endif 620 621 switch (cmd) { 622 case TAPSIFINFO: 623 s = splimp(); 624 tapp = (struct tapinfo *)data; 625 ifp->if_mtu = tapp->mtu; 626 ifp->if_type = tapp->type; 627 ifp->if_baudrate = tapp->baudrate; 628 splx(s); 629 break; 630 631 case TAPGIFINFO: 632 tapp = (struct tapinfo *)data; 633 tapp->mtu = ifp->if_mtu; 634 tapp->type = ifp->if_type; 635 tapp->baudrate = ifp->if_baudrate; 636 break; 637 638 case TAPSDEBUG: 639 tapdebug = *(int *)data; 640 break; 641 642 case TAPGDEBUG: 643 *(int *)data = tapdebug; 644 break; 645 646 case FIONBIO: 647 break; 648 649 case FIOASYNC: 650 s = splimp(); 651 mtx_lock(&tp->tap_mtx); 652 if (*(int *)data) 653 tp->tap_flags |= TAP_ASYNC; 654 else 655 tp->tap_flags &= ~TAP_ASYNC; 656 mtx_unlock(&tp->tap_mtx); 657 splx(s); 658 break; 659 660 case FIONREAD: 661 s = splimp(); 662 if (ifp->if_snd.ifq_head) { 663 struct mbuf *mb = ifp->if_snd.ifq_head; 664 665 for(*(int *)data = 0;mb != NULL;mb = mb->m_next) 666 *(int *)data += mb->m_len; 667 } else 668 *(int *)data = 0; 669 splx(s); 670 break; 671 672 case FIOSETOWN: 673 return (fsetown(*(int *)data, &tp->tap_sigio)); 674 675 case FIOGETOWN: 676 *(int *)data = fgetown(&tp->tap_sigio); 677 return (0); 678 679 /* this is deprecated, FIOSETOWN should be used instead */ 680 case TIOCSPGRP: 681 return (fsetown(-(*(int *)data), &tp->tap_sigio)); 682 683 /* this is deprecated, FIOGETOWN should be used instead */ 684 case TIOCGPGRP: 685 *(int *)data = -fgetown(&tp->tap_sigio); 686 return (0); 687 688 /* VMware/VMnet port ioctl's */ 689 690 case SIOCGIFFLAGS: /* get ifnet flags */ 691 bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags)); 692 break; 693 694#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 695 defined(COMPAT_FREEBSD4) 696 case _IO('V', 0): 697 ival = IOCPARM_IVAL(data); 698 data = (caddr_t)&ival; 699 /* FALLTHROUGH */ 700#endif 701 case VMIO_SIOCSIFFLAGS: /* VMware/VMnet SIOCSIFFLAGS */ 702 f = *(int *)data; 703 f &= 0x0fff; 704 f &= ~IFF_CANTCHANGE; 705 f |= IFF_UP; 706 707 s = splimp(); 708 ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE); 709 splx(s); 710 break; 711 712 case OSIOCGIFADDR: /* get MAC address of the remote side */ 713 case SIOCGIFADDR: 714 mtx_lock(&tp->tap_mtx); 715 bcopy(tp->ether_addr, data, sizeof(tp->ether_addr)); 716 mtx_unlock(&tp->tap_mtx); 717 break; 718 719 case SIOCSIFADDR: /* set MAC address of the remote side */ 720 mtx_lock(&tp->tap_mtx); 721 bcopy(data, tp->ether_addr, sizeof(tp->ether_addr)); 722 mtx_unlock(&tp->tap_mtx); 723 break; 724 725 default: 726 return (ENOTTY); 727 } 728 return (0); 729} /* tapioctl */ 730 731 732/* 733 * tapread 734 * 735 * the cdevsw read interface - reads a packet at a time, or at 736 * least as much of a packet as can be read 737 */ 738static int 739tapread(struct cdev *dev, struct uio *uio, int flag) 740{ 741 struct tap_softc *tp = dev->si_drv1; 742 struct ifnet *ifp = tp->tap_ifp; 743 struct mbuf *m = NULL; 744 int error = 0, len, s; 745 746 TAPDEBUG("%s reading, minor = %#x\n", ifp->if_xname, minor(dev)); 747 748 mtx_lock(&tp->tap_mtx); 749 if ((tp->tap_flags & TAP_READY) != TAP_READY) { 750 mtx_unlock(&tp->tap_mtx); 751 752 /* Unlocked read. */ 753 TAPDEBUG("%s not ready. minor = %#x, tap_flags = 0x%x\n", 754 ifp->if_xname, minor(dev), tp->tap_flags); 755 756 return (EHOSTDOWN); 757 } 758 759 tp->tap_flags &= ~TAP_RWAIT; 760 mtx_unlock(&tp->tap_mtx); 761 762 /* sleep until we get a packet */ 763 do { 764 s = splimp(); 765 IF_DEQUEUE(&ifp->if_snd, m); 766 splx(s); 767 768 if (m == NULL) { 769 if (flag & O_NONBLOCK) 770 return (EWOULDBLOCK); 771 772 mtx_lock(&tp->tap_mtx); 773 tp->tap_flags |= TAP_RWAIT; 774 mtx_unlock(&tp->tap_mtx); 775 error = tsleep(tp,PCATCH|(PZERO+1),"taprd",0); 776 if (error) 777 return (error); 778 } 779 } while (m == NULL); 780 781 /* feed packet to bpf */ 782 BPF_MTAP(ifp, m); 783 784 /* xfer packet to user space */ 785 while ((m != NULL) && (uio->uio_resid > 0) && (error == 0)) { 786 len = min(uio->uio_resid, m->m_len); 787 if (len == 0) 788 break; 789 790 error = uiomove(mtod(m, void *), len, uio); 791 m = m_free(m); 792 } 793 794 if (m != NULL) { 795 TAPDEBUG("%s dropping mbuf, minor = %#x\n", ifp->if_xname, 796 minor(dev)); 797 m_freem(m); 798 } 799 800 return (error); 801} /* tapread */ 802 803 804/* 805 * tapwrite 806 * 807 * the cdevsw write interface - an atomic write is a packet - or else! 808 */ 809static int 810tapwrite(struct cdev *dev, struct uio *uio, int flag) 811{ 812 struct tap_softc *tp = dev->si_drv1; 813 struct ifnet *ifp = tp->tap_ifp; 814 struct mbuf *m; 815 816 TAPDEBUG("%s writting, minor = %#x\n", 817 ifp->if_xname, minor(dev)); 818 819 if (uio->uio_resid == 0) 820 return (0); 821 822 if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) { 823 TAPDEBUG("%s invalid packet len = %d, minor = %#x\n", 824 ifp->if_xname, uio->uio_resid, minor(dev)); 825 826 return (EIO); 827 } 828 829 if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, ETHER_ALIGN, 830 M_PKTHDR)) == NULL) { 831 ifp->if_ierrors ++; 832 return (ENOBUFS); 833 } 834 835 m->m_pkthdr.rcvif = ifp; 836 837 /* Pass packet up to parent. */ 838 (*ifp->if_input)(ifp, m); 839 ifp->if_ipackets ++; /* ibytes are counted in parent */ 840 841 return (0); 842} /* tapwrite */ 843 844 845/* 846 * tappoll 847 * 848 * the poll interface, this is only useful on reads 849 * really. the write detect always returns true, write never blocks 850 * anyway, it either accepts the packet or drops it 851 */ 852static int 853tappoll(struct cdev *dev, int events, struct thread *td) 854{ 855 struct tap_softc *tp = dev->si_drv1; 856 struct ifnet *ifp = tp->tap_ifp; 857 int s, revents = 0; 858 859 TAPDEBUG("%s polling, minor = %#x\n", 860 ifp->if_xname, minor(dev)); 861 862 s = splimp(); 863 if (events & (POLLIN | POLLRDNORM)) { 864 if (ifp->if_snd.ifq_len > 0) { 865 TAPDEBUG("%s have data in queue. len = %d, " \ 866 "minor = %#x\n", ifp->if_xname, 867 ifp->if_snd.ifq_len, minor(dev)); 868 869 revents |= (events & (POLLIN | POLLRDNORM)); 870 } else { 871 TAPDEBUG("%s waiting for data, minor = %#x\n", 872 ifp->if_xname, minor(dev)); 873 874 selrecord(td, &tp->tap_rsel); 875 } 876 } 877 878 if (events & (POLLOUT | POLLWRNORM)) 879 revents |= (events & (POLLOUT | POLLWRNORM)); 880 881 splx(s); 882 return (revents); 883} /* tappoll */ 884 885 886/* 887 * tap_kqfilter 888 * 889 * support for kevent() system call 890 */ 891static int 892tapkqfilter(struct cdev *dev, struct knote *kn) 893{ 894 int s; 895 struct tap_softc *tp = dev->si_drv1; 896 struct ifnet *ifp = tp->tap_ifp; 897 898 s = splimp(); 899 switch (kn->kn_filter) { 900 case EVFILT_READ: 901 TAPDEBUG("%s kqfilter: EVFILT_READ, minor = %#x\n", 902 ifp->if_xname, minor(dev)); 903 kn->kn_fop = &tap_read_filterops; 904 break; 905 906 case EVFILT_WRITE: 907 TAPDEBUG("%s kqfilter: EVFILT_WRITE, minor = %#x\n", 908 ifp->if_xname, minor(dev)); 909 kn->kn_fop = &tap_write_filterops; 910 break; 911 912 default: 913 TAPDEBUG("%s kqfilter: invalid filter, minor = %#x\n", 914 ifp->if_xname, minor(dev)); 915 splx(s); 916 return (EINVAL); 917 /* NOT REACHED */ 918 } 919 splx(s); 920 921 kn->kn_hook = (caddr_t) dev; 922 knlist_add(&tp->tap_rsel.si_note, kn, 0); 923 924 return (0); 925} /* tapkqfilter */ 926 927 928/* 929 * tap_kqread 930 * 931 * Return true if there is data in the interface queue 932 */ 933static int 934tapkqread(struct knote *kn, long hint) 935{ 936 int ret, s; 937 struct cdev *dev = (struct cdev *)(kn->kn_hook); 938 struct tap_softc *tp = dev->si_drv1; 939 struct ifnet *ifp = tp->tap_ifp; 940 941 s = splimp(); 942 if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) { 943 TAPDEBUG("%s have data in queue. len = %d, minor = %#x\n", 944 ifp->if_xname, ifp->if_snd.ifq_len, minor(dev)); 945 ret = 1; 946 } else { 947 TAPDEBUG("%s waiting for data, minor = %#x\n", 948 ifp->if_xname, minor(dev)); 949 ret = 0; 950 } 951 splx(s); 952 953 return (ret); 954} /* tapkqread */ 955 956 957/* 958 * tap_kqwrite 959 * 960 * Always can write. Return the MTU in kn->data 961 */ 962static int 963tapkqwrite(struct knote *kn, long hint) 964{ 965 int s; 966 struct tap_softc *tp = ((struct cdev *) kn->kn_hook)->si_drv1; 967 struct ifnet *ifp = tp->tap_ifp; 968 969 s = splimp(); 970 kn->kn_data = ifp->if_mtu; 971 splx(s); 972 973 return (1); 974} /* tapkqwrite */ 975 976 977static void 978tapkqdetach(struct knote *kn) 979{ 980 struct tap_softc *tp = ((struct cdev *) kn->kn_hook)->si_drv1; 981 982 knlist_remove(&tp->tap_rsel.si_note, kn, 0); 983} /* tapkqdetach */ 984 985