diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-05-16 16:45:19 +0000 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-05-16 16:45:19 +0000 |
commit | 19827936403d1d3ba9b2b22d1894c3b120e053f9 (patch) | |
tree | ea916db56893f81920663905134b99e0f5644dd0 | |
parent | 8fd9f78a4ec579577e5f1b1642de24950bb489f3 (diff) | |
parent | af97a9b0457e7e9b5529ac34874657cc4fcc2083 (diff) | |
download | xen-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-- | .rootkeys | 1 | ||||
-rw-r--r-- | linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile | 2 | ||||
-rw-r--r-- | linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c | 140 | ||||
-rwxr-xr-x | tools/examples/network | 82 |
4 files changed, 207 insertions, 18 deletions
@@ -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 ;; |