Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump/net/lib/libvirtif Push the bits accessing the netwo...
details: https://anonhg.NetBSD.org/src/rev/1f40b61c1819
branches: trunk
changeset: 785434:1f40b61c1819
user: pooka <pooka%NetBSD.org@localhost>
date: Wed Mar 13 21:13:45 2013 +0000
description:
Push the bits accessing the networking backend into hypercalls.
This allows a few highly desirable things to happen:
1) Linux support, which is included in this commit (thanks to wanq for
sending me the magic bits for accessing /dev/net/tun)
2) Reusing the kernel-side of the interface for devices such as
hardware packet processors which interact directly with user vm spaces
(not included in the commit).
diffstat:
sys/rump/net/lib/libvirtif/Makefile | 6 +-
sys/rump/net/lib/libvirtif/if_virt.c | 60 +++------
sys/rump/net/lib/libvirtif/rumpcomp_user.c | 180 +++++++++++++++++++++++++++++
sys/rump/net/lib/libvirtif/rumpcomp_user.h | 35 +++++
4 files changed, 240 insertions(+), 41 deletions(-)
diffs (truncated from 408 to 300 lines):
diff -r 9b1f5d0c30b7 -r 1f40b61c1819 sys/rump/net/lib/libvirtif/Makefile
--- a/sys/rump/net/lib/libvirtif/Makefile Wed Mar 13 13:38:05 2013 +0000
+++ b/sys/rump/net/lib/libvirtif/Makefile Wed Mar 13 21:13:45 2013 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.3 2009/05/28 00:02:17 pooka Exp $
+# $NetBSD: Makefile,v 1.4 2013/03/13 21:13:45 pooka Exp $
#
LIB= rumpnet_virtif
@@ -6,7 +6,9 @@
SRCS= if_virt.c
SRCS+= component.c
-CPPFLAGS+= -I${.CURDIR}/../../../librump/rumpkern
+CPPFLAGS+= -I${.CURDIR}/../../../librump/rumpkern -I${.CURDIR}
+
+RUMPCOMP_USER= #defined
.include <bsd.lib.mk>
.include <bsd.klinks.mk>
diff -r 9b1f5d0c30b7 -r 1f40b61c1819 sys/rump/net/lib/libvirtif/if_virt.c
--- a/sys/rump/net/lib/libvirtif/if_virt.c Wed Mar 13 13:38:05 2013 +0000
+++ b/sys/rump/net/lib/libvirtif/if_virt.c Wed Mar 13 21:13:45 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_virt.c,v 1.27 2012/09/14 16:29:22 pooka Exp $ */
+/* $NetBSD: if_virt.c,v 1.28 2013/03/13 21:13:45 pooka Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.27 2012/09/14 16:29:22 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.28 2013/03/13 21:13:45 pooka Exp $");
#include <sys/param.h>
#include <sys/condvar.h>
@@ -49,11 +49,12 @@
#include <netinet/in_var.h>
#include <rump/rump.h>
-#include <rump/rumpuser.h>
#include "rump_private.h"
#include "rump_net_private.h"
+#include "rumpcomp_user.h"
+
/*
* Virtual interface for userspace purposes. Uses tap(4) to
* interface with the kernel and just simply shovels data
@@ -69,7 +70,7 @@
struct virtif_sc {
struct ethercom sc_ec;
- int sc_tapfd;
+ struct virtif_user *sc_viu;
bool sc_dying;
struct lwp *sc_l_snd, *sc_l_rcv;
kmutex_t sc_mtx;
@@ -88,27 +89,23 @@
rump_virtif_create(int num)
{
struct virtif_sc *sc;
+ struct virtif_user *viu;
struct ifnet *ifp;
uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0x0a, 0x00, 0x0b, 0x0e, 0x01 };
- char tapdev[16];
- int fd, error = 0;
+ int error = 0;
if (num >= 0x100)
return E2BIG;
- snprintf(tapdev, sizeof(tapdev), "/dev/tap%d", num);
- fd = rumpuser_open(tapdev, RUMPUSER_OPEN_RDWR, &error);
- if (fd == -1) {
- printf("virtif_create: can't open /dev/tap%d: %d\n",
- num, error);
- return error;
- }
+ if ((viu = rumpcomp_virtif_create(num)) == NULL)
+ return ENXIO;
+
enaddr[2] = cprng_fast32() & 0xff;
enaddr[5] = num;
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
sc->sc_dying = false;
- sc->sc_tapfd = fd;
+ sc->sc_viu = viu;
mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
cv_init(&sc->sc_cv, "virtsnd");
@@ -168,6 +165,8 @@
cv_broadcast(&sc->sc_cv);
mutex_exit(&sc->sc_mtx);
+ rumpcomp_virtif_dying(sc->sc_viu);
+
virtif_stop(ifp, 1);
if_down(ifp);
@@ -180,7 +179,7 @@
sc->sc_l_rcv = NULL;
}
- rumpuser_close(sc->sc_tapfd, NULL);
+ rumpcomp_virtif_destroy(sc->sc_viu);
mutex_destroy(&sc->sc_mtx);
cv_destroy(&sc->sc_cv);
@@ -220,7 +219,6 @@
return rv;
}
-/* just send everything in-context */
static void
virtif_start(struct ifnet *ifp)
{
@@ -252,35 +250,21 @@
struct virtif_sc *sc = ifp->if_softc;
struct mbuf *m;
size_t plen = ETHER_MAX_LEN_JUMBO+1;
- struct pollfd pfd;
ssize_t n;
- int error, rv;
-
- pfd.fd = sc->sc_tapfd;
- pfd.events = POLLIN;
for (;;) {
m = m_gethdr(M_WAIT, MT_DATA);
MEXTMALLOC(m, plen, M_WAIT);
again:
- /* poll, but periodically check if we should die */
- rv = rumpuser_poll(&pfd, 1, POLLTIMO_MS, &error);
if (sc->sc_dying) {
m_freem(m);
break;
}
- if (rv == 0)
- goto again;
-
- n = rumpuser_read(sc->sc_tapfd, mtod(m, void *), plen, &error);
- KASSERT(n < ETHER_MAX_LEN_JUMBO);
- if (__predict_false(n < 0)) {
- if (n == -1 && error == EAGAIN) {
- goto again;
- }
-
- printf("%s: read from /dev/tap failed. host is down?\n",
+
+ n = rumpcomp_virtif_recv(sc->sc_viu, mtod(m, void *), plen);
+ if (n < 0) {
+ printf("%s: read hypercall failed. host if down?\n",
ifp->if_xname);
mutex_enter(&sc->sc_mtx);
/* could check if need go, done soon anyway */
@@ -314,8 +298,8 @@
struct ifnet *ifp = arg;
struct virtif_sc *sc = ifp->if_softc;
struct mbuf *m, *m0;
- struct rumpuser_iovec io[LB_SH];
- int i, error;
+ struct iovec io[LB_SH];
+ int i;
mutex_enter(&sc->sc_mtx);
KERNEL_LOCK(1, NULL);
@@ -341,11 +325,9 @@
if (i == LB_SH)
panic("lazy bum");
bpf_mtap(ifp, m0);
- KERNEL_UNLOCK_LAST(curlwp);
- rumpuser_writev(sc->sc_tapfd, io, i, &error);
+ rumpcomp_virtif_send(sc->sc_viu, io, i);
- KERNEL_LOCK(1, NULL);
m_freem(m0);
mutex_enter(&sc->sc_mtx);
}
diff -r 9b1f5d0c30b7 -r 1f40b61c1819 sys/rump/net/lib/libvirtif/rumpcomp_user.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/rump/net/lib/libvirtif/rumpcomp_user.c Wed Mar 13 21:13:45 2013 +0000
@@ -0,0 +1,180 @@
+/* $NetBSD: rumpcomp_user.c,v 1.1 2013/03/13 21:13:45 pooka Exp $ */
+
+/*
+ * Copyright (c) 2013 Antti Kantee. All Rights Reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __linux__
+#include <net/if.h>
+#include <linux/if_tun.h>
+#endif
+
+#include <rump/rumpuser_component.h>
+
+struct virtif_user {
+ int viu_fd;
+ int viu_dying;
+};
+
+static int
+opentapdev(int devnum)
+{
+ int fd = -1;
+
+#if defined(__NetBSD__) || defined(__DragonFly__)
+ char tapdev[64];
+
+ snprintf(tapdev, sizeof(tapdev), "/dev/tap%d", devnum);
+ fd = open(tapdev, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "rumpcomp_virtif_create: can't open %s: "
+ "%s\n", tapdev, strerror(errno));
+ }
+
+#elif defined(__linux__)
+ struct ifreq ifr;
+ char devname[16];
+
+ fd = open("/dev/net/tun", O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "rumpcomp_virtif_create: can't open %s: "
+ "%s\n", "/dev/net/tun", strerror(errno));
+ return -1;
+ }
+
+ snprintf(devname, sizeof(devname), "tun%d", devnum);
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name)-1);
+
+ if (ioctl(fd, TUNSETIFF, &ifr) == -1) {
+ close(fd);
+ fd = -1;
+ }
+
+#else
+ fprintf(stderr, "virtif not supported on this platform\n");
+#endif
+
+ return fd;
+}
+
+struct virtif_user *
+rumpcomp_virtif_create(int devnum)
+{
+ struct virtif_user *viu;
+ void *cookie;
+
+ cookie = rumpuser_component_unschedule();
+
+ viu = malloc(sizeof(*viu));
+ viu->viu_fd = opentapdev(devnum);
+ viu->viu_dying = 0;
+
+ out:
+ if (viu->viu_fd == -1) {
+ free(viu);
+ viu = NULL;
+ }
+
Home |
Main Index |
Thread Index |
Old Index