From f14c1f25051884918f54d1f5409c08c7417742fa Mon Sep 17 00:00:00 2001 From: xez Date: Mon, 15 Jun 2015 23:06:43 -0700 Subject: [PATCH] VirtIO networking, add support for TAP devices --- Makefile | 3 +- README.md | 18 +++++-- ...{pci_virtio_net.c => pci_virtio_net_tap.c} | 54 +++++++++++++++++-- ..._virtio_vmnet.c => pci_virtio_net_vmnet.c} | 4 +- 4 files changed, 69 insertions(+), 10 deletions(-) rename src/{pci_virtio_net.c => pci_virtio_net_tap.c} (95%) rename src/{pci_virtio_vmnet.c => pci_virtio_net_vmnet.c} (99%) diff --git a/Makefile b/Makefile index 587b409..4917f47 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,8 @@ XHYVE_SRC := \ src/pci_lpc.c \ src/pci_uart.c \ src/pci_virtio_block.c \ - src/pci_virtio_vmnet.c \ + src/pci_virtio_net_tap.c \ + src/pci_virtio_net_vmnet.c \ src/pci_virtio_rnd.c \ src/pm.c \ src/post.c \ diff --git a/README.md b/README.md index 557df5d..7c8b5d6 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,18 @@ If you want the same IP address across VM reboots, assign a UUID to a particular $ xhyve [-U uuid] +**Optional:** + +If you need more advanced networking and already have a configured [TAP](http://tuntaposx.sourceforge.net) device you can use it with: + + virtio-tap,tapX + +instead of: + + virtio-net + +Where *X* is your tap device, i.e. */dev/tapX*. + Issues ------ Right now, if you have (any version of) VirtualBox running and attempt to run @@ -178,12 +190,12 @@ TODO - some 32-bit guests are broken (support PAE paging in VMCS) - PCID guest support (performance) - block_if: - - OS X does not support preadv/pwritev, we need to serialize reads and writes for the time being until we find a better solution. + - OS X does not support preadv/pwritev, we need to serialize reads and writes for the time being until we find a better solution. (performance) - support block devices other than plain files - virtio_net: - - make it not require root - unify TAP and vmnet backends - - performance: send/receive more than a single packet at a time + - vmnet: make it not require root + - vmnet: send/receive more than a single packet at a time (performance) - ACPI tables don't work - bhyve creates ASL on the fly and then calls out to an ASL compiler (iasl) on every VM boot to create the DSDT: diff --git a/src/pci_virtio_net.c b/src/pci_virtio_net_tap.c similarity index 95% rename from src/pci_virtio_net.c rename to src/pci_virtio_net_tap.c index 97475f7..4268528 100644 --- a/src/pci_virtio_net.c +++ b/src/pci_virtio_net_tap.c @@ -51,6 +51,8 @@ #include #include +#define USE_MEVENT 0 + #define VTNET_RINGSZ 1024 #define VTNET_MAXSEGS 32 @@ -370,6 +372,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) vq_endchains(vq, 1); } +#if USE_MEVENT static void pci_vtnet_tap_callback(UNUSED int fd, UNUSED enum ev_type type, void *param) { @@ -383,6 +386,37 @@ pci_vtnet_tap_callback(UNUSED int fd, UNUSED enum ev_type type, void *param) } +#else /* !USE_MEVENT */ + +static void * +pci_vtnet_tap_select_func(void *vsc) { + struct pci_vtnet_softc *sc; + fd_set rfd; + + sc = vsc; + + assert(sc); + assert(sc->vsc_tapfd != -1); + + FD_ZERO(&rfd); + FD_SET(sc->vsc_tapfd, &rfd); + + while (1) { + if (select((sc->vsc_tapfd + 1), &rfd, NULL, NULL, NULL) == -1) { + abort(); + } + + pthread_mutex_lock(&sc->rx_mtx); + sc->rx_in_progress = 1; + pci_vtnet_tap_rx(sc); + sc->rx_in_progress = 0; + pthread_mutex_unlock(&sc->rx_mtx); + } + + return (NULL); +} +#endif + static void pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) { @@ -542,6 +576,9 @@ pci_vtnet_init(struct pci_devinst *pi, char *opts) char *devname; char *vtopts; int mac_provided; +#if !USE_MEVENT + pthread_t sthrd; +#endif sc = calloc(1, sizeof(struct pci_vtnet_softc)); @@ -601,6 +638,7 @@ pci_vtnet_init(struct pci_devinst *pi, char *opts) sc->vsc_tapfd = -1; } +#if USE_MEVENT sc->vsc_mevp = mevent_add(sc->vsc_tapfd, EVF_READ, pci_vtnet_tap_callback, @@ -610,7 +648,15 @@ pci_vtnet_init(struct pci_devinst *pi, char *opts) close(sc->vsc_tapfd); sc->vsc_tapfd = -1; } - } + +#else /* !USE_MEVENT */ + if (pthread_create(&sthrd, NULL, pci_vtnet_tap_select_func, sc)) { + WPRINTF(("Could not create tap receive thread\n")); + close(sc->vsc_tapfd); + sc->vsc_tapfd = -1; + } +#endif + } } /* @@ -715,10 +761,10 @@ pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features) } } -static struct pci_devemu pci_de_vnet = { - .pe_emu = "virtio-net", +static struct pci_devemu pci_de_vnet_tap = { + .pe_emu = "virtio-tap", .pe_init = pci_vtnet_init, .pe_barwrite = vi_pci_write, .pe_barread = vi_pci_read }; -PCI_EMUL_SET(pci_de_vnet); +PCI_EMUL_SET(pci_de_vnet_tap); diff --git a/src/pci_virtio_vmnet.c b/src/pci_virtio_net_vmnet.c similarity index 99% rename from src/pci_virtio_vmnet.c rename to src/pci_virtio_net_vmnet.c index 3036cb4..a309cb1 100644 --- a/src/pci_virtio_vmnet.c +++ b/src/pci_virtio_net_vmnet.c @@ -811,10 +811,10 @@ pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features) } } -static struct pci_devemu pci_de_vnet = { +static struct pci_devemu pci_de_vnet_vmnet = { .pe_emu = "virtio-net", .pe_init = pci_vtnet_init, .pe_barwrite = vi_pci_write, .pe_barread = vi_pci_read }; -PCI_EMUL_SET(pci_de_vnet); +PCI_EMUL_SET(pci_de_vnet_vmnet);