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