aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-05-16 16:45:19 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-05-16 16:45:19 +0000
commit19827936403d1d3ba9b2b22d1894c3b120e053f9 (patch)
treeea916db56893f81920663905134b99e0f5644dd0
parent8fd9f78a4ec579577e5f1b1642de24950bb489f3 (diff)
parentaf97a9b0457e7e9b5529ac34874657cc4fcc2083 (diff)
downloadxen-19827936403d1d3ba9b2b22d1894c3b120e053f9.tar.gz
xen-19827936403d1d3ba9b2b22d1894c3b120e053f9.tar.bz2
xen-19827936403d1d3ba9b2b22d1894c3b120e053f9.zip
bitkeeper revision 1.1159.258.131 (4288ce1fwiCrIr8WyDZa4a1UHmCikw)
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk into firebug.cl.cam.ac.uk:/local/scratch/kaf24/xen-2.0-testing.bk
-rw-r--r--.rootkeys1
-rw-r--r--linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile2
-rw-r--r--linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c140
-rwxr-xr-xtools/examples/network82
4 files changed, 207 insertions, 18 deletions
diff --git a/.rootkeys b/.rootkeys
index 5fe88a2228..c1be6086c8 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -275,6 +275,7 @@
4097ba831lpGeLlPg-bfV8XarVVuoQ linux-2.6.11-xen-sparse/drivers/xen/netback/common.h
4097ba83wvv8yi5P5xugCUBAdb6O-A linux-2.6.11-xen-sparse/drivers/xen/netback/control.c
4097ba83byY5bTSugJGZ1exTxIcMKw linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c
+4288ce19CHtBLg600EZ8TNuSPLs5Ng linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c
4087cf0dGmSbFhFZyIZBJzvqxY-qBw linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c
40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.11-xen-sparse/drivers/xen/netfront/Kconfig
40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.11-xen-sparse/drivers/xen/netfront/Makefile
diff --git a/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile
index 3279442145..5085bf034d 100644
--- a/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile
@@ -1,2 +1,2 @@
-obj-y := netback.o control.o interface.o
+obj-y := netback.o control.o interface.o loopback.o
diff --git a/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c b/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c
new file mode 100644
index 0000000000..9dffff0fc2
--- /dev/null
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c
@@ -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 --git a/tools/examples/network b/tools/examples/network
index 229881d737..12ff1c5eee 100755
--- a/tools/examples/network
+++ b/tools/examples/network
@@ -74,6 +74,16 @@ s/${src}/dev ${dst}/
" | 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 @@ d
" | 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 @@ create_bridge () {
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 @@ op_start () {
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 @@ op_stop () {
if [ "${bridge}" == "null" ] ; then
return
fi
- # Remove the interface from the bridge.
- # Move the routes back to the interface.
+
brctl delif ${bridge} ${netdev}
- transfer_routes ${bridge} ${netdev}
- # It's not our place to be enabling forwarding...
+ if ifconfig veth0 2>/dev/null | grep -q veth0 ; then
+ brctl delif ${bridge} vif0.0
+ ifconfig vif0.0 down
+ mac=`ifconfig veth0 | grep HWadd | sed -e 's/.*\(..:..:..:..:..:..\).*/\1/'`
+ ifconfig ${netdev} down
+ ifconfig ${netdev} hw ether ${mac}
+ ifconfig ${netdev} arp up
+ transfer_addrs veth0 ${netdev}
+ transfer_routes veth0 ${netdev}
+ del_addrs veth0
+ ifconfig veth0 -arp down
+ ifconfig veth0 hw ether 00:00:00:00:00:00
+ else
+ transfer_addrs ${bridge} ${netdev}
+ transfer_routes ${bridge} ${netdev}
+ del_addrs ${bridge}
+ fi
}
case ${OP} in
- start)
+ start)
op_start
;;