Coder Social home page Coder Social logo

pmj / virtio-net-osx Goto Github PK

View Code? Open in Web Editor NEW
225.0 30.0 25.0 1.23 MB

Mac OS X driver for a (virtualised) "virtio" network device. Virtio network devices are supported by KVM and VirtualBox. Fastest virtual network device for VirtualBox OSX Guests, allows kernel debugging of guests via gdb.

Shell 0.04% C++ 95.33% C 4.63%

virtio-net-osx's Introduction

Virtio-Net for Mac OS X

What's this about?

Some virtualisation environments, namely Linux KVM/Qemu and VirtualBox support high-performance paravirtualised devices that follow the "Virtio" specification. This is a driver for using the virtio ethernet device from OS X guests. In VirtualBox, this device is known as the "Paravirtualised Network (virtio-net)".

Quick Start

Download the latest virtio-net driver installer to your VirtualBox or Qemu virtual machine running OS X 10.7 or newer. Run the installer. If your VM has any virtio-net devices enabled, they should now spring into life!

News

22 December 2013: I have updated the driver to version 0.9.4 (Beta 3) with some bug fixes and stability improvements. In particular, it is now possible to safely unload the driver at runtime, using kextunload /System/Library/Extensions/virtio-net.kext. This is useful for upgrading to newer versions without rebooting.

Version 0.9.2 was released in 2011, and the updates since have been bug fixes rather than feature enhancements. However, as I am now also using KVM, I'm strongly considering implementing drivers for more devices in the Virtio family and beyond. Of particular interest are:

  • Memory Balloon - For dynamically varying the amount of memory assigned to the virtual machine.
  • Console - Of interest to kernel developers: I'm hoping to get kprintf() output working via the virsh console.
  • Disk Storage - Currently, you have to use an emulated AHCI device for OS X VM disks. The virtio storage device should reduce the overhead and potentially offer some advanced features such as Discard ("TRIM") which is useful for VM image files as well as SSDs. The virtio SCSI device even supports hotplugging.
  • SPICE/qxl virtualised graphics adapter and desktop integration - Implementing a driver for this will offer better desktop integration (native mouse cursor and resizeable VM window) and eventually, it might offer better graphics performance, clipboard integration, etc. This isn't technically based on virtio, though.
  • 9P - This is for sharing parts of the host's file system with the guest OS.
  • Network - The virtio-net implementation in KVM is much higher performance and supports more features than VirtualBox's. This driver currently doesn't even

Some of this will eventually get done if I fund development myself. But if you have an interest in a particular feature, I'm available for funded development, and source code contributions are always welcome.

With that in mind, the next step is modularising the existing code by splitting the virtqueues and PCI device initialisation from the network-specific code so that the other drivers can be built upon the virtqueues.

Latest release

The current release is version 0.9.4 (the third beta for the 1.0), which includes support for message signaled interrupts (they are not available on VirtualBox unfortunately), and offloaded checksumming and TCP segmentation for IPv4. Transmit speeds with TSO are now on par with receive speeds and easily outperform the emulated Intel gigabit adapter.

Binaries (and the installer) are in the bin/ directory.

Version 0.9.4 works with both the VirtualBox and Qemu/KVM implementations of the virtio network device, and is known to work with OS X 10.7 (Snow öLeopard) through 10.9.x (Mavericks/Sea Lion), with both 32-bit and 64-bit kernels.

It might also run on 10.6 (it certainly will if you build it against the 10.6 SDK with no modification). I have had success reports with 10.5 with some modifications. I am planning to incorporate those changes once I have modularised the PCI code out from the network code.

Summary

Some virtualisation software (I know of VirtualBox and Linux KVM/Qemu) implements paravirtual hardware per the "virtio" specification. One type of virtio device is the "virtio-net" ethernet adapter. Linux and Windows guest drivers exist for it, but as far as I know, this is the only such driver for Mac OS X (10.6+).

Compared to the default emulated Intel gigabit device, the paravirtualised adapter in VirtualBox is approximately twice as fast at transmitting TCP data (with TSO), and about 4 times as fast at receiving.

Kernel debugging via gdb is now also supported by this driver. If the virtio-net device is the primary network adapter in the system (and the driver is the first network card driver to be loaded), you can attach gdb to an appropriately configured crashed kernel. Sending the ACPI Shutdown signal in VirtualBox is treated as a non-maskable interrupt (NMI) so if you specify that kernel debug flag as part of the boot args, you can attach the debugger that way.

Virtio and virtio-net

[virtio][virtio] is an open specification for virtualised "hardware" in virtual machines. Historically, virtual machine developers have either emulated popular real hardware devices in order to utilise existing drivers in operating systems, or implemented their own virtualised devices with drivers for each supported guest operating system. Neither approach is ideal. Emulating real hardware in software is often unnecessarily inefficient: some of the constraints of real hardware don't apply to virtualised hardware. VM-specific virtualised devices can be fast, but require specific driver for each supported guest operating system. Moreover, the VM developer usually maintains the drivers, and the specs are often not published. This prevents development of drivers for less popular guest operating systems.

An open specification presents an opportunity for separating the responsibilities for implementing the virtual hardware and the drivers, and also potentially allows for greater guest portability across different virtualisation solution.

The virtio spec (Version 0.9.5 as of this writing) includes a specification for a virtualised PCI ethernet network card. Implementations for such virtual hardware are present in Linux' KVM virtualisation solution and also in newer versions of VirtualBox. Drivers for guests exist for Linux (in the main tree) and for Windows.

Motivation

VirtualBox supports virtual machines running Mac OS X (when running on Apple hardware), but so far I have not found any virtio drivers. Virtual machines are great for testing and debugging kernel extensions; I have so far however been unable to connect gdb to a Mac OS X kernel running inside a VirtualBox VM with emulated "real" ethernet cards. This is an attempt to create a driver which supports kernel debugging for the virtio network interface, in addition to being a good choice for general VM networking. Performance has not been a priority but seems to be pretty good so far nevertheless.

Status

Receiving and transmitting packets works, the adapter is able to negotiate DHCP, send and receive pings, handle TCP connections, etc. The driver appears to be stable even when saturating the virtual network's bandwidth. Some benchmarks are in the docs/ directory, although these predate TSO support, which has almost doubled transmit speed in VirtualBox on my Core2Duo MacBook Air.

Startup and shutdown appear to work fine, as do disabling and re-enabling the device in Network Preferences and changing the adapter's configuration on the host side.

The driver detects link status changes and correctly communicates it to the operating system. This means that if you untick "cable connected" in the VirtualBox GUI for the network device, the adapter's dot in the guest's Network Preferences turns red, and back to green/yellow when you tick it. If you change the adapter's "wiring" (bridging, NAT, host-only, etc.) this is communicated as a brief status change which triggers a DHCP renew, as you'd want.

The "hardware" offers various advanced features, depending on implementation. Of those, this driver supports checksum offloading and automatic segmentation (TSO) for TCP on IPv4.

Reassembly of large packets, MAC address filtering/promiscuous mode, VLAN filtering, etc. are not implemented. Support may be added at a later date (patches welcome!).

Future refinements

Longer term, if we wish to support other virtio devices, the PCI device handling should be separated out into a distinct class from the ethernet controller. This could then take care of general feature negotiation, memory mapping, virtqueue handling, etc. To illustrate, the I/O registry hierarchy currently implemented by this driver is:

IOPCIDevice -> eu_philjordan_virtio_net[IOEthernetController] -> IOEthernetInterface

Where the object on the left side of the arrow is the provider of the one on the right. Under the proposed scheme, it would look something like this:

IOPCIDevice -> VirtioPCIDriver -> VirtioNetController[IOEthernetController] -> IOEthernetInterface

Other types of virtio devices would likewise attach to the VirtioPCIDriver.

Compiling

If you simply want to use the driver, just use the installer. For compiling it yourself, this repository contains an Xcode 4 project with which the KEXT can be built in a single step. The KEXT should work on versions 10.5 (Leopard) through 10.8 (Mountain Lion), but so far has only been tested on Snow Leopard and Mountain Lion. Since XCode 4 only runs on Snow Leopard and up, you'll need to create your own XCode 3 project if you want to compile it on Leopard.

License

I'm making the source code for this driver available under the [LGPL Version 3][lgpl]. The virtio_ring.h file is adapted from the virtio spec and 3-clause BSD licensed.

lgpl

virtio-net-osx's People

Contributors

pmj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

virtio-net-osx's Issues

Not working with MacOs Sierra

Host system:

Ubuntu 16.04

Guest:
Macos sierra

I installed the virtio driver installer, but, the device it's not reconigzed, shows: Cable unplugged

Not working with OS X Mavericks Server

Using QEMU/KVM, OS X 10.9.5.

To test, attach two network adapters to the VM, one the default e1000, and the other a virtio adapter.

Server.app refuses to acknowledge that the virtio adapter is connected. When editing the network configuration through the application, it will show the DHCP-provided settings, but will show the network as "Not Connected".
screen shot 2015-03-17 at 11 18 48 pm

In this screenshot, "Ethernet 2" is the virtio, "Ethernet" is the e1000.

Here's what's logged in system.log while Server.app is network checking:

Mar 17 23:20:56 moonside kernel[0]: flow_divert_kctl_disconnect (0): disconnecting group 1
Mar 17 23:20:56 moonside.local configd[26]: network changed: v4(en1!:10.0.0.72, en0-:10.0.0.5) DNS! Proxy+ SMB+
Mar 17 23:20:56 moonside kernel[0]: flow_divert_kctl_disconnect (0): disconnecting group 1

ifconfig (en0 = e1000 / en1 = virtio):

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=2b<RXCSUM,TXCSUM,VLAN_HWTAGGING,TSO4>
    ether 52:54:0e:8e:cc:7e 
    inet6 fe80::5054:eff:fe8e:cc7e%en0 prefixlen 64 scopeid 0x4 
    inet 10.0.0.5 netmask 0xfffffe00 broadcast 10.0.1.255
    nd6 options=1<PERFORMNUD>
    media: autoselect (1000baseT <full-duplex>)
    status: active
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=23<RXCSUM,TXCSUM,TSO4>
    ether 52:54:0e:8e:cc:8e 
    inet6 fe80::5054:eff:fe8e:cc8e%en1 prefixlen 64 scopeid 0x5 
    inet 10.0.0.72 netmask 0xfffffe00 broadcast 10.0.1.255
    nd6 options=1<PERFORMNUD>
    media: autoselect
    status: active

scp crash

Hello,

The driver works with an ssh logins or a ping to the vm well so far. But if one tries to copy files over ssh, crashing the entire network. I think that always happens when some traffic on the "Network Card" is generated.

I get in dmesg unfortunately not really an error message.
That is from time to time there:

kernel (0): virtio-net addPacketToQueue (): Warning! head mbuf 66 does not math mtu-seg 326

but not always.

Regards ralix

VNC/Screen Sharing error

When i enable the virtio driver in my qemu args VNC terminates after password authentication with the error "failed to recv data from socket" (windows TightVNC client). However with the default qemu e1000 driver all works fine.

Other connectivity seems fine from my brief tests with virtio, but VNC definitely seems to be effected.

I also see a number of the messages bellow in the Kernel log, which don't appear when using the e1000 driver:

2014-12-27 18:15:25 +0000 kernel[0]: virtio-net addPacketToQueue(): Warning! head mbuf 54 does not match mtu-seg 314

I'm on kernel 3.17.6-1-ARCH (Arch Linux) and qemu 2.1.2 currently, and running OSX 10.9.5 with virtio drivers 0.9.4

Thanks very much.

Network Utilities does not show input/output packet count.

I use your driver with VirtualBox (thanks!) and noticed network status is not updated.
I made small modification and it seems working.
Though link speed is not accurate ( always 1G), but prettier than 0.

diff --git a/virtio-net/virtio_net.cpp b/virtio-net/virtio_net.cpp
index 3332930..eeeb8f4 100644
--- a/virtio-net/virtio_net.cpp
+++ b/virtio-net/virtio_net.cpp
@@ -608,7 +608,11 @@ bool PJVirtioNet::updateLinkStatus()
    IONetworkMedium* medium = dict ? IONetworkMedium::getMediumWithType(dict, kIOMediumEthernetAuto) : 0;
    if (!medium)
        VIOLog("virtio-net updateLinkStatus: Warning, no medium found!\n");
-   setLinkStatus((link_is_up ? kIONetworkLinkActive : 0) | kIONetworkLinkValid, medium);
+    if(link_is_up)
+        setLinkStatus(kIONetworkLinkValid | kIONetworkLinkActive,
+                      medium,1000000000ul);
+    else
+       setLinkStatus(kIONetworkLinkValid, 0);
    return link_is_up;
 }

@@ -941,7 +945,11 @@ void PJVirtioNet::detectLinkStatusFeature(uint16_t device_specific_offset)
            status, (status & VIRTIO_NET_S_LINK_UP) ? "up" : "down");
        link_is_up = (status & VIRTIO_NET_S_LINK_UP) != 0;
    }
-   setLinkStatus((link_is_up ? kIONetworkLinkActive : 0) | kIONetworkLinkValid);
+    if(link_is_up)
+        setLinkStatus(kIONetworkLinkValid | kIONetworkLinkActive,
+                      getCurrentMedium(),1000000000ul);
+    else
+       setLinkStatus(kIONetworkLinkValid, 0);
 }

 bool PJVirtioNet::beginHandlingInterrupts()
@@ -1026,6 +1034,12 @@ bool PJVirtioNet::configureInterface(IONetworkInterface *netif)
        VIOLog("virtio-net configureInterface(): super failed\n");
        return false;
    }
+   // Get the generic network statistics structure.
+   IONetworkData * data = netif->getParameter(kIONetworkStatsKey);
+   if (!data || !(netStats = (IONetworkStats *) data->getBuffer())) {
+       VIOLog("virtio-net configureInterface(): getParameter(kIONetworkStatsKey) failed."); 
+       return false;
+   }
    return true;
 }

@@ -2198,6 +2212,7 @@ void PJVirtioNet::releaseSentPackets(bool from_debugger)
            virtio_net_packet* next = cur->next_free;

            freePacket(cur->mbuf);
+            netStats->outputPackets++;
            if (cur->mem)
            {
                packet_bufdesc_pool->setObject(cur->mem);
@@ -2254,6 +2269,7 @@ void PJVirtioNet::releaseSentPackets(bool from_debugger)
                    continue;
                }
                freePacket(packet->mbuf);
+                netStats->outputPackets++;
            }
            else
            {
@@ -2408,7 +2424,7 @@ void PJVirtioNet::handleReceivedPackets()
    }
    if (packets_submitted > 0)
    {
-       interface->flushInputQueue();
+       netStats->inputPackets += interface->flushInputQueue();
        //IOLog("virtio-net handleReceivedPackets(): %u received\n", packets_submitted);
    }
 }
diff --git a/virtio-net/virtio_net.h b/virtio-net/virtio_net.h
index 9c545b8..03b1aa8 100644
--- a/virtio-net/virtio_net.h
+++ b/virtio-net/virtio_net.h
@@ -320,6 +320,8 @@ protected:

    /// Low bit is atomically toggled on if the configuration change bit was detected in the interrupt handler
    volatile UInt8 received_config_change __attribute__((aligned(32)));
+private:
+   IONetworkStats * netStats;
 };

 #endif

Yosemite: Cable Unplugged

OS X Yosemite 10.10.4:

qemu -netdev bridge,id=br0,br=br0 \
      -device virtio-net-pci,netdev=br0,id=mac_vnet0 \
      -netdev user,smb=/,id=user0 \
      -device virtio-net-pci,netdev=user0,id=mac_vnet1 \
      [ ... ]

both interfaces show in "Network" as "Not Connected", "Cable Unplugged" and in ifconfig as UP,RUNNING but inactive. Safari of course reports "You Are Not Connected to the Internet".

obviously the driver is running since the interfaces are present, but I checked by kextstat | grep virtio.

the same setup works correctly (i.e. Internet access, SMB) with e1000-82545em. specifying a single bridge device also does not work. nor does the -net nic,model=virtio syntax.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.