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

[Xen-changelog] Local netfront/netback emulation for domain0, to clean up and fix



ChangeSet 1.1159.283.1, 2005/05/16 17:45:13+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Local netfront/netback emulation for domain0, to clean up and fix
        Etherbridge setup.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile   |    2 
 linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c |  140 +++++++++++++++++
 tools/examples/network                                 |   82 +++++++--
 3 files changed, 206 insertions(+), 18 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile 
b/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile
--- a/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile      2005-05-16 
13:04:14 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile      2005-05-16 
13:04:14 -04:00
@@ -1,2 +1,2 @@
 
-obj-y  := netback.o control.o interface.o
+obj-y  := netback.o control.o interface.o loopback.o
diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c    2005-05-16 
13:04:14 -04:00
@@ -0,0 +1,140 @@
+/******************************************************************************
+ * netback/loopback.c
+ * 
+ * A two-interface loopback device to emulate a local netfront-netback
+ * connection. This ensures that local packet delivery looks identical
+ * to inter-domain delivery. Most importantly, packets delivered locally
+ * originating from other domains will get *copied* when they traverse this
+ * driver. This prevents unbounded delays in socket-buffer queues from
+ * causing the netback driver to "seize up".
+ * 
+ * This driver creates a symmetric pair of loopback interfaces with names
+ * vif0.0 and veth0. The intention is that 'vif0.0' is bound to an Ethernet
+ * bridge, just like a proper netback interface, while a local IP interface
+ * is configured on 'veth0'.
+ * 
+ * As with a real netback interface, vif0.0 is configured with a suitable
+ * dummy MAC address. No default is provided for veth0: a reasonable strategy
+ * is to transfer eth0's MAC address to veth0, and give eth0 a dummy address
+ * (to avoid confusing the Etherbridge).
+ * 
+ * Copyright (c) 2005 K A Fraser
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <net/dst.h>
+
+struct net_private {
+    struct net_device *loopback_dev;
+    struct net_device_stats stats;
+};
+
+static int loopback_open(struct net_device *dev)
+{
+    struct net_private *np = netdev_priv(dev);
+    memset(&np->stats, 0, sizeof(np->stats));
+    netif_start_queue(dev);
+    return 0;
+}
+
+static int loopback_close(struct net_device *dev)
+{
+    netif_stop_queue(dev);
+    return 0;
+}
+
+static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+    struct net_private *np = netdev_priv(dev);
+
+    dst_release(skb->dst);
+    skb->dst = NULL;
+
+    skb_orphan(skb);
+
+    np->stats.tx_bytes += skb->len;
+    np->stats.tx_packets++;
+
+    /* Switch to loopback context. */
+    dev = np->loopback_dev;
+    np  = netdev_priv(dev);
+
+    np->stats.rx_bytes += skb->len;
+    np->stats.rx_packets++;
+
+    skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
+    skb->protocol = eth_type_trans(skb, dev);
+    skb->dev      = dev;
+    dev->last_rx  = jiffies;
+    netif_rx(skb);
+
+    return 0;
+}
+
+static struct net_device_stats *loopback_get_stats(struct net_device *dev)
+{
+    struct net_private *np = netdev_priv(dev);
+    return &np->stats;
+}
+
+static void loopback_construct(struct net_device *dev, struct net_device *lo)
+{
+    struct net_private *np = netdev_priv(dev);
+
+    np->loopback_dev     = lo;
+
+    dev->open            = loopback_open;
+    dev->stop            = loopback_close;
+    dev->hard_start_xmit = loopback_start_xmit;
+    dev->get_stats       = loopback_get_stats;
+
+    dev->tx_queue_len    = 0;
+    dev->mtu             = 16*1024;
+}
+
+static int __init loopback_init(void)
+{
+    struct net_device *dev1, *dev2;
+    int err = -ENOMEM;
+
+    dev1 = alloc_netdev(sizeof(struct net_private), "vif0.0", ether_setup);
+    dev2 = alloc_netdev(sizeof(struct net_private), "veth0", ether_setup);
+    if ( (dev1 == NULL) || (dev2 == NULL) )
+        goto fail;
+
+    loopback_construct(dev1, dev2);
+    loopback_construct(dev2, dev1);
+
+    /*
+     * Initialise a dummy MAC address for the 'dummy backend' interface. We
+     * choose the numerically largest non-broadcast address to prevent the
+     * address getting stolen by an Ethernet bridge for STP purposes.
+     */
+    memset(dev1->dev_addr, 0xFF, ETH_ALEN);
+    dev1->dev_addr[0] &= ~0x01;
+
+    if ( (err = register_netdev(dev1)) != 0 )
+        goto fail;
+
+    if ( (err = register_netdev(dev2)) != 0 )
+    {
+        unregister_netdev(dev1);
+        goto fail;
+    }
+
+    return 0;
+
+ fail:
+    if ( dev1 != NULL )
+        kfree(dev1);
+    if ( dev2 != NULL )
+        kfree(dev2);
+    return err;
+}
+
+module_init(loopback_init);
diff -Nru a/tools/examples/network b/tools/examples/network
--- a/tools/examples/network    2005-05-16 13:04:14 -04:00
+++ b/tools/examples/network    2005-05-16 13:04:14 -04:00
@@ -74,6 +74,16 @@
 " | sh -e
 }
 
+# Usage: del_addrs src
+del_addrs () {
+    local src=$1
+    ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
+s/inet/ip addr del/
+s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@
+s/${src}/dev ${src}/
+" | sh -e
+}
+
 # Usage: transfer_routes src dst
 # Get all IP routes to device $src, delete them, and
 # add the same routes to device $dst.
@@ -97,11 +107,9 @@
 " | sh -e
 }
 
-# Usage: create_bridge dev bridge
-# Create bridge $bridge and add device $dev to it.
+# Usage: create_bridge bridge
 create_bridge () {
-    local dev=$1
-    local bridge=$2
+    local bridge=$1
 
     # Don't create the bridge if it already exists.
     if ! brctl show | grep -q ${bridge} ; then
@@ -112,6 +120,16 @@
     ifconfig ${bridge} up
 }
 
+# Usage: add_to_bridge bridge dev
+add_to_bridge () {
+    local bridge=$1
+    local dev=$2
+    # Don't add $dev to $bridge if it's already on a bridge.
+    if ! brctl show | grep -q ${dev} ; then
+        brctl addif ${bridge} ${dev}
+    fi
+}
+
 # Usage: antispoofing dev bridge
 # Set the default forwarding policy for $dev to drop.
 # Allow forwarding to the bridge.
@@ -143,15 +161,31 @@
     if [ "${bridge}" == "null" ] ; then
         return
     fi
-    # Create the bridge and give it the interface IP addresses.
-    # Move the interface routes onto the bridge.
-    create_bridge ${netdev} ${bridge}
-    transfer_addrs ${netdev} ${bridge}
-    transfer_routes ${netdev} ${bridge}
-    # Don't add $dev to $bridge if it's already on a bridge.
-    if ! brctl show | grep -q ${netdev} ; then
-        brctl addif ${bridge} ${netdev}
+
+    create_bridge ${bridge}
+
+    if ifconfig veth0 2>/dev/null | grep -q veth0 ; then
+        # Propagate MAC address and ARP responsibilities to virtual interface.
+        mac=`ifconfig ${netdev} | grep HWadd | sed -e 
's/.*\(..:..:..:..:..:..\).*/\1/'`
+        ifconfig veth0 down
+        ifconfig veth0 hw ether ${mac}
+        ifconfig veth0 arp up
+        transfer_addrs ${netdev} veth0
+        transfer_routes ${netdev} veth0
+        del_addrs ${netdev}
+        ifconfig ${netdev} -arp down
+        ifconfig ${netdev} hw ether fe:ff:ff:ff:ff:ff up
+        # Bring up second half of virtual device and attach it to the bridge.
+        ifconfig vif0.0 up
+        add_to_bridge ${bridge} vif0.0
+    else
+        transfer_addrs ${netdev} ${bridge}
+        transfer_routes ${netdev} ${bridge}
+        del_addrs ${netdev}
     fi
+
+    # Attach the real interface to the bridge.
+    add_to_bridge ${bridge} ${netdev}
     
     if [ ${antispoof} == 'yes' ] ; then
         antispoofing ${netdev} ${bridge}
@@ -162,16 +196,30 @@
     if [ "${bridge}" == "null" ] ; then
         return
     fi
-    # Remove the interface from the bridge.
-    # Move the routes back to the interface.
+
     brctl delif ${bridge} ${netdev}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.