# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 67d7e01c8277fdd9be9c5834e233cb0c8fddb00d
# Parent 4cdf880c94633aadff4d4d45f7a88d7e97f0e9dd
It was suggested on the xen-users list that it would be useful if the
loopback driver could instantiate an arbitrary number of interfaces, so
the attached patch does that.
[Also retab at the same time]
diff -r 4cdf880c9463 -r 67d7e01c8277
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Thu Sep 8
20:39:58 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Fri Sep 9
09:07:59 2005
@@ -29,136 +29,163 @@
#include <linux/skbuff.h>
#include <net/dst.h>
+static int nloopbacks = 1;
+module_param(nloopbacks, int, 0);
+MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
+
struct net_private {
- struct net_device *loopback_dev;
- struct net_device_stats stats;
+ 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;
+ 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;
+ 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);
+ struct net_private *np = netdev_priv(dev);
- dst_release(skb->dst);
- skb->dst = NULL;
+ dst_release(skb->dst);
+ skb->dst = NULL;
- skb_orphan(skb);
+ skb_orphan(skb);
- np->stats.tx_bytes += skb->len;
- np->stats.tx_packets++;
+ np->stats.tx_bytes += skb->len;
+ np->stats.tx_packets++;
- /* Switch to loopback context. */
- dev = np->loopback_dev;
- np = netdev_priv(dev);
+ /* Switch to loopback context. */
+ dev = np->loopback_dev;
+ np = netdev_priv(dev);
- np->stats.rx_bytes += skb->len;
- np->stats.rx_packets++;
+ np->stats.rx_bytes += skb->len;
+ np->stats.rx_packets++;
- if ( skb->ip_summed == CHECKSUM_HW )
- {
- /* Defer checksum calculation. */
- skb->proto_csum_blank = 1;
- /* Must be a local packet: assert its integrity. */
- skb->proto_csum_valid = 1;
- }
+ if (skb->ip_summed == CHECKSUM_HW) {
+ /* Defer checksum calculation. */
+ skb->proto_csum_blank = 1;
+ /* Must be a local packet: assert its integrity. */
+ skb->proto_csum_valid = 1;
+ }
- skb->ip_summed = skb->proto_csum_valid ?
- CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
+ skb->ip_summed = skb->proto_csum_valid ?
+ CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
- 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);
+ 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;
+ return 0;
}
static struct net_device_stats *loopback_get_stats(struct net_device *dev)
{
- struct net_private *np = netdev_priv(dev);
- return &np->stats;
+ 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);
+ struct net_private *np = netdev_priv(dev);
- np->loopback_dev = lo;
+ 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->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->tx_queue_len = 0;
- dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
+ dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
- /*
- * We do not set a jumbo MTU on the interface. Otherwise the network
- * stack will try to send large packets that will get dropped by the
- * Ethernet bridge (unless the physical Ethernet interface is configured
- * to transfer jumbo packets). If a larger MTU is desired then the system
- * administrator can specify it using the 'ifconfig' command.
- */
- /*dev->mtu = 16*1024;*/
+ /*
+ * We do not set a jumbo MTU on the interface. Otherwise the network
+ * stack will try to send large packets that will get dropped by the
+ * Ethernet bridge (unless the physical Ethernet interface is
+ * configured to transfer jumbo packets). If a larger MTU is desired
+ * then the system administrator can specify it using the 'ifconfig'
+ * command.
+ */
+ /*dev->mtu = 16*1024;*/
+}
+
+static int __init make_loopback(int i)
+{
+ struct net_device *dev1, *dev2;
+ char dev_name[IFNAMSIZ];
+ int err = -ENOMEM;
+
+ sprintf(dev_name, "vif0.%d", i);
+ dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
+ sprintf(dev_name, "veth%d", i);
+ dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
+ if ((dev1 == NULL) || (dev2 == NULL))
+ goto fail;
+
+ loopback_construct(dev1, dev2);
+ loopback_construct(dev2, dev1);
+
+ dev1->features |= NETIF_F_NO_CSUM;
+ dev2->features |= NETIF_F_IP_CSUM;
+
+ /*
+ * 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;
}
static int __init loopback_init(void)
{
- struct net_device *dev1, *dev2;
- int err = -ENOMEM;
+ int i, err = 0;
- 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;
+ for (i = 0; i < nloopbacks; i++)
+ if ((err = make_loopback(i)) != 0)
+ break;
- loopback_construct(dev1, dev2);
- loopback_construct(dev2, dev1);
-
- dev1->features |= NETIF_F_NO_CSUM;
- dev2->features |= NETIF_F_IP_CSUM;
-
- /*
- * 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;
+ return err;
}
module_init(loopback_init);
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|