[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |