WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Local netfront/netback emulation for domain0, to clean u

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Local netfront/netback emulation for domain0, to clean up and fix
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Mon, 16 May 2005 16:45:13 +0000
Delivery-date: Mon, 16 May 2005 17:03:39 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
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

<Prev in Thread] Current Thread [Next in Thread>