ChangeSet 1.1863.1.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:06:35 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile 2005-05-16
13:06:35 -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:06:35 -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:06:35 -04:00
+++ b/tools/examples/network 2005-05-16 13:06:35 -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
|