Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Addition of tap(4).



details:   https://anonhg.NetBSD.org/src/rev/a1ee16e7b011
branches:  trunk
changeset: 572594:a1ee16e7b011
user:      cube <cube%NetBSD.org@localhost>
date:      Sat Jan 08 22:27:54 2005 +0000

description:
Addition of tap(4).

NAME
     tap - virtual Ethernet device

SYNOPSIS
     pseudo-device tap

DESCRIPTION
     The tap driver allows the creation and use of virtual Ethernet devices.
     Those interfaces appear just as any real Ethernet NIC to the kernel, but
     can also be accessed by userland through a character device node in order
     to read frames being sent by the system or to inject frames.

     In that respect it is very similar to what tun(4) provides, but the added
     Ethernet layer allows easy integration with machine emulators or virtual
     Ethernet networks through the use of bridge(4) with tunneling.

``Qui tacet consentire videtur.''

diffstat:

 sys/conf/files   |     4 +-
 sys/conf/majors  |     3 +-
 sys/net/if_tap.c |  1372 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/net/if_tap.h |    40 +
 4 files changed, 1417 insertions(+), 2 deletions(-)

diffs (truncated from 1459 to 300 lines):

diff -r 66626250f34b -r a1ee16e7b011 sys/conf/files
--- a/sys/conf/files    Sat Jan 08 22:16:23 2005 +0000
+++ b/sys/conf/files    Sat Jan 08 22:27:54 2005 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.704 2005/01/08 02:57:08 joff Exp $
+#      $NetBSD: files,v 1.705 2005/01/08 22:27:54 cube Exp $
 
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
@@ -1070,6 +1070,7 @@
 defpseudo gif:         ifnet
 defpseudo faith:       ifnet
 defpseudo stf:         ifnet
+defpseudo tap {[unit = -1]}:           ifnet, ether, bpf_filter
 
 defpseudo sequencer
 defpseudo clockctl
@@ -1308,6 +1309,7 @@
 file   net/if_spppsubr.c               sppp
 file   net/if_strip.c                  strip                   needs-flag
 file   net/if_tokensubr.c              token                   needs-flag
+file   net/if_tap.c                    tap
 file   net/if_tun.c                    tun                     needs-flag
 file   net/if_vlan.c                   vlan                    needs-flag
 file   net/if_pppoe.c                  pppoe                   needs-flag
diff -r 66626250f34b -r a1ee16e7b011 sys/conf/majors
--- a/sys/conf/majors   Sat Jan 08 22:16:23 2005 +0000
+++ b/sys/conf/majors   Sat Jan 08 22:27:54 2005 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: majors,v 1.12 2004/09/25 03:30:44 thorpej Exp $
+# $NetBSD: majors,v 1.13 2005/01/08 22:27:54 cube Exp $
 #
 # Device majors for Machine-Independent drivers.
 #
@@ -18,3 +18,4 @@
 device-major   atabus          char 166                atabus
 device-major   drvctl          char 167                drvctl
 device-major   dk              char 168 block 168
+device-major   tap             char 169                tap
diff -r 66626250f34b -r a1ee16e7b011 sys/net/if_tap.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net/if_tap.c  Sat Jan 08 22:27:54 2005 +0000
@@ -0,0 +1,1372 @@
+/*     $NetBSD: if_tap.c,v 1.1 2005/01/08 22:27:54 cube Exp $  */
+
+/*
+ *  Copyright (c) 2003, 2004 The NetBSD Foundation.
+ *  All rights reserved.
+ *
+ *  This code is derived from software contributed to the NetBSD Foundation
+ *   by Quentin Garnier.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. All advertising materials mentioning features or use of this software
+ *     must display the following acknowledgement:
+ *         This product includes software developed by the NetBSD
+ *         Foundation, Inc. and its contributors.
+ *  4. Neither the name of The NetBSD Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * tap(4) is a virtual Ethernet interface.  It appears as a real Ethernet
+ * device to the system, but can also be accessed by userland through a
+ * character device interface, which allows reading and injecting frames.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.1 2005/01/08 22:27:54 cube Exp $");
+
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/ksyms.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_ether.h>
+#include <net/if_media.h>
+#include <net/if_tap.h>
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+/*
+ * sysctl node management
+ *
+ * It's not really possible to use a SYSCTL_SETUP block with
+ * current LKM implementation, so it is easier to just define
+ * our own function.
+ *
+ * The handler function is a "helper" in Andrew Brown's sysctl
+ * framework terminology.  It is used as a gateway for sysctl
+ * requests over the nodes.
+ *
+ * tap_log allows the module to log creations of nodes and
+ * destroy them all at once using sysctl_teardown.
+ */
+static int tap_node;
+static int     tap_sysctl_handler(SYSCTLFN_PROTO);
+
+/*
+ * Since we're an Ethernet device, we need the 3 following
+ * components: a leading struct device, a struct ethercom,
+ * and also a struct ifmedia since we don't attach a PHY to
+ * ourselves. We could emulate one, but there's no real
+ * point.
+ */
+
+struct tap_softc {
+       struct device   sc_dev;
+       struct ifmedia  sc_im;
+       struct ethercom sc_ec;
+       int             sc_flags;
+#define        TAP_INUSE       0x00000001      /* tap device can only be opened once */
+#define TAP_ASYNCIO    0x00000002      /* user is using async I/O (SIGIO) on the device */
+#define TAP_NBIO       0x00000004      /* user wants calls to avoid blocking */
+#define TAP_GOING      0x00000008      /* interface is being destroyed */
+       struct selinfo  sc_rsel;
+       pid_t           sc_pgid; /* For async. IO */
+       struct lock     sc_rdlock;
+       struct simplelock       sc_kqlock;
+};
+
+/* autoconf(9) glue */
+
+void   tapattach(int);
+
+static int     tap_match(struct device *, struct cfdata *, void *);
+static void    tap_attach(struct device *, struct device *, void *);
+static int     tap_detach(struct device*, int);
+
+/* Ethernet address helper functions */
+
+static char    *tap_ether_sprintf(char *, const u_char *);
+static int     tap_ether_aton(u_char *, char *);
+
+CFATTACH_DECL(tap, sizeof(struct tap_softc),
+    tap_match, tap_attach, tap_detach, NULL);
+extern struct cfdriver tap_cd;
+
+/* Real device access routines */
+static int     tap_dev_close(struct tap_softc *);
+static int     tap_dev_read(int, struct uio *, int);
+static int     tap_dev_write(int, struct uio *, int);
+static int     tap_dev_ioctl(int, u_long, caddr_t, struct proc *);
+static int     tap_dev_poll(int, int, struct proc *);
+static int     tap_dev_kqfilter(int, struct knote *);
+
+/* Fileops access routines */
+static int     tap_fops_close(struct file *, struct proc *);
+static int     tap_fops_read(struct file *, off_t *, struct uio *,
+    struct ucred *, int);
+static int     tap_fops_write(struct file *, off_t *, struct uio *,
+    struct ucred *, int);
+static int     tap_fops_ioctl(struct file *, u_long, void *,
+    struct proc *);
+static int     tap_fops_poll(struct file *, int, struct proc *);
+static int     tap_fops_kqfilter(struct file *, struct knote *);
+
+static const struct fileops tap_fileops = {
+       tap_fops_read,
+       tap_fops_write,
+       tap_fops_ioctl,
+       fnullop_fcntl,
+       tap_fops_poll,
+       fbadop_stat,
+       tap_fops_close,
+       tap_fops_kqfilter,
+};
+
+/* Helper for cloning open() */
+static int     tap_dev_cloner(struct proc *);
+
+/* Character device routines */
+static int     tap_cdev_open(dev_t, int, int, struct proc *);
+static int     tap_cdev_close(dev_t, int, int, struct proc *);
+static int     tap_cdev_read(dev_t, struct uio *, int);
+static int     tap_cdev_write(dev_t, struct uio *, int);
+static int     tap_cdev_ioctl(dev_t, u_long, caddr_t, int, struct proc *);
+static int     tap_cdev_poll(dev_t, int, struct proc *);
+static int     tap_cdev_kqfilter(dev_t, struct knote *);
+
+const struct cdevsw tap_cdevsw = {
+       tap_cdev_open, tap_cdev_close,
+       tap_cdev_read, tap_cdev_write,
+       tap_cdev_ioctl, nostop, notty,
+       tap_cdev_poll, nommap,
+       tap_cdev_kqfilter,
+};
+
+#define TAP_CLONER     0xfffff         /* Maximal minor value */
+
+/* kqueue-related routines */
+static void    tap_kqdetach(struct knote *);
+static int     tap_kqread(struct knote *, long);
+
+/*
+ * Those are needed by the if_media interface.
+ */
+
+static int     tap_mediachange(struct ifnet *);
+static void    tap_mediastatus(struct ifnet *, struct ifmediareq *);
+
+/*
+ * Those are needed by the ifnet interface, and would typically be
+ * there for any network interface driver.
+ * Some other routines are optional: watchdog and drain.
+ */
+
+static void    tap_start(struct ifnet *);
+static void    tap_stop(struct ifnet *, int);
+static int     tap_init(struct ifnet *);
+static int     tap_ioctl(struct ifnet *, u_long, caddr_t);
+
+/* This is an internal function to keep tap_ioctl readable */
+static int     tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *);
+
+/*
+ * tap is a clonable interface, although it is highly unrealistic for
+ * an Ethernet device.
+ *
+ * Here are the bits needed for a clonable interface.
+ */
+static int     tap_clone_create(struct if_clone *, int);
+static int     tap_clone_destroy(struct ifnet *);
+
+struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap",
+                                       tap_clone_create,
+                                       tap_clone_destroy);
+
+/* Helper functionis shared by the two cloning code paths */
+static struct tap_softc *      tap_clone_creator(int);
+static int     tap_clone_destroyer(struct device *);
+
+void
+tapattach(int n)
+{
+       int error;
+
+       error = config_cfattach_attach(tap_cd.cd_name, &tap_ca);
+       if (error) {
+               aprint_error("%s: unable to register cfattach\n",
+                   tap_cd.cd_name);
+               (void)config_cfdriver_detach(&tap_cd);
+               return;
+       }
+
+       if_clone_attach(&tap_cloners);
+}
+
+/* Pretty much useless for a pseudo-device */
+static int
+tap_match(struct device *self, struct cfdata *cfdata, void *arg)
+{
+       return (1);
+}
+
+void
+tap_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct tap_softc *sc = (struct tap_softc *)self;
+       struct ifnet *ifp;
+       u_int8_t enaddr[ETHER_ADDR_LEN] =
+           { 0xf0, 0x0b, 0xa4, 0xff, 0xff, 0xff };
+       char enaddrstr[18];
+       uint32_t ui;
+       int error;
+       struct sysctlnode *node;



Home | Main Index | Thread Index | Old Index