direct-io.hg
changeset 6694:67d7e01c8277
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]
loopback driver could instantiate an arbitrary number of interfaces, so
the attached patch does that.
[Also retab at the same time]
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Fri Sep 09 09:07:59 2005 +0000 (2005-09-09) |
parents | 4cdf880c9463 |
children | 6563a12e0ad7 |
files | linux-2.6-xen-sparse/drivers/xen/netback/loopback.c |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Thu Sep 08 20:39:58 2005 +0000 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Fri Sep 09 09:07:59 2005 +0000 1.3 @@ -29,136 +29,163 @@ 1.4 #include <linux/skbuff.h> 1.5 #include <net/dst.h> 1.6 1.7 +static int nloopbacks = 1; 1.8 +module_param(nloopbacks, int, 0); 1.9 +MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create"); 1.10 + 1.11 struct net_private { 1.12 - struct net_device *loopback_dev; 1.13 - struct net_device_stats stats; 1.14 + struct net_device *loopback_dev; 1.15 + struct net_device_stats stats; 1.16 }; 1.17 1.18 static int loopback_open(struct net_device *dev) 1.19 { 1.20 - struct net_private *np = netdev_priv(dev); 1.21 - memset(&np->stats, 0, sizeof(np->stats)); 1.22 - netif_start_queue(dev); 1.23 - return 0; 1.24 + struct net_private *np = netdev_priv(dev); 1.25 + memset(&np->stats, 0, sizeof(np->stats)); 1.26 + netif_start_queue(dev); 1.27 + return 0; 1.28 } 1.29 1.30 static int loopback_close(struct net_device *dev) 1.31 { 1.32 - netif_stop_queue(dev); 1.33 - return 0; 1.34 + netif_stop_queue(dev); 1.35 + return 0; 1.36 } 1.37 1.38 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev) 1.39 { 1.40 - struct net_private *np = netdev_priv(dev); 1.41 + struct net_private *np = netdev_priv(dev); 1.42 1.43 - dst_release(skb->dst); 1.44 - skb->dst = NULL; 1.45 + dst_release(skb->dst); 1.46 + skb->dst = NULL; 1.47 1.48 - skb_orphan(skb); 1.49 + skb_orphan(skb); 1.50 1.51 - np->stats.tx_bytes += skb->len; 1.52 - np->stats.tx_packets++; 1.53 + np->stats.tx_bytes += skb->len; 1.54 + np->stats.tx_packets++; 1.55 1.56 - /* Switch to loopback context. */ 1.57 - dev = np->loopback_dev; 1.58 - np = netdev_priv(dev); 1.59 + /* Switch to loopback context. */ 1.60 + dev = np->loopback_dev; 1.61 + np = netdev_priv(dev); 1.62 1.63 - np->stats.rx_bytes += skb->len; 1.64 - np->stats.rx_packets++; 1.65 + np->stats.rx_bytes += skb->len; 1.66 + np->stats.rx_packets++; 1.67 1.68 - if ( skb->ip_summed == CHECKSUM_HW ) 1.69 - { 1.70 - /* Defer checksum calculation. */ 1.71 - skb->proto_csum_blank = 1; 1.72 - /* Must be a local packet: assert its integrity. */ 1.73 - skb->proto_csum_valid = 1; 1.74 - } 1.75 + if (skb->ip_summed == CHECKSUM_HW) { 1.76 + /* Defer checksum calculation. */ 1.77 + skb->proto_csum_blank = 1; 1.78 + /* Must be a local packet: assert its integrity. */ 1.79 + skb->proto_csum_valid = 1; 1.80 + } 1.81 1.82 - skb->ip_summed = skb->proto_csum_valid ? 1.83 - CHECKSUM_UNNECESSARY : CHECKSUM_NONE; 1.84 + skb->ip_summed = skb->proto_csum_valid ? 1.85 + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; 1.86 1.87 - skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */ 1.88 - skb->protocol = eth_type_trans(skb, dev); 1.89 - skb->dev = dev; 1.90 - dev->last_rx = jiffies; 1.91 - netif_rx(skb); 1.92 + skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */ 1.93 + skb->protocol = eth_type_trans(skb, dev); 1.94 + skb->dev = dev; 1.95 + dev->last_rx = jiffies; 1.96 + netif_rx(skb); 1.97 1.98 - return 0; 1.99 + return 0; 1.100 } 1.101 1.102 static struct net_device_stats *loopback_get_stats(struct net_device *dev) 1.103 { 1.104 - struct net_private *np = netdev_priv(dev); 1.105 - return &np->stats; 1.106 + struct net_private *np = netdev_priv(dev); 1.107 + return &np->stats; 1.108 } 1.109 1.110 static void loopback_construct(struct net_device *dev, struct net_device *lo) 1.111 { 1.112 - struct net_private *np = netdev_priv(dev); 1.113 + struct net_private *np = netdev_priv(dev); 1.114 + 1.115 + np->loopback_dev = lo; 1.116 1.117 - np->loopback_dev = lo; 1.118 + dev->open = loopback_open; 1.119 + dev->stop = loopback_close; 1.120 + dev->hard_start_xmit = loopback_start_xmit; 1.121 + dev->get_stats = loopback_get_stats; 1.122 + 1.123 + dev->tx_queue_len = 0; 1.124 + 1.125 + dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX; 1.126 1.127 - dev->open = loopback_open; 1.128 - dev->stop = loopback_close; 1.129 - dev->hard_start_xmit = loopback_start_xmit; 1.130 - dev->get_stats = loopback_get_stats; 1.131 + /* 1.132 + * We do not set a jumbo MTU on the interface. Otherwise the network 1.133 + * stack will try to send large packets that will get dropped by the 1.134 + * Ethernet bridge (unless the physical Ethernet interface is 1.135 + * configured to transfer jumbo packets). If a larger MTU is desired 1.136 + * then the system administrator can specify it using the 'ifconfig' 1.137 + * command. 1.138 + */ 1.139 + /*dev->mtu = 16*1024;*/ 1.140 +} 1.141 1.142 - dev->tx_queue_len = 0; 1.143 +static int __init make_loopback(int i) 1.144 +{ 1.145 + struct net_device *dev1, *dev2; 1.146 + char dev_name[IFNAMSIZ]; 1.147 + int err = -ENOMEM; 1.148 1.149 - dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX; 1.150 + sprintf(dev_name, "vif0.%d", i); 1.151 + dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup); 1.152 + sprintf(dev_name, "veth%d", i); 1.153 + dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup); 1.154 + if ((dev1 == NULL) || (dev2 == NULL)) 1.155 + goto fail; 1.156 + 1.157 + loopback_construct(dev1, dev2); 1.158 + loopback_construct(dev2, dev1); 1.159 + 1.160 + dev1->features |= NETIF_F_NO_CSUM; 1.161 + dev2->features |= NETIF_F_IP_CSUM; 1.162 1.163 - /* 1.164 - * We do not set a jumbo MTU on the interface. Otherwise the network 1.165 - * stack will try to send large packets that will get dropped by the 1.166 - * Ethernet bridge (unless the physical Ethernet interface is configured 1.167 - * to transfer jumbo packets). If a larger MTU is desired then the system 1.168 - * administrator can specify it using the 'ifconfig' command. 1.169 - */ 1.170 - /*dev->mtu = 16*1024;*/ 1.171 + /* 1.172 + * Initialise a dummy MAC address for the 'dummy backend' interface. We 1.173 + * choose the numerically largest non-broadcast address to prevent the 1.174 + * address getting stolen by an Ethernet bridge for STP purposes. 1.175 + */ 1.176 + memset(dev1->dev_addr, 0xFF, ETH_ALEN); 1.177 + dev1->dev_addr[0] &= ~0x01; 1.178 + 1.179 + if ((err = register_netdev(dev1)) != 0) 1.180 + goto fail; 1.181 + 1.182 + if ((err = register_netdev(dev2)) != 0) { 1.183 + unregister_netdev(dev1); 1.184 + goto fail; 1.185 + } 1.186 + 1.187 + return 0; 1.188 + 1.189 + fail: 1.190 + if (dev1 != NULL) 1.191 + kfree(dev1); 1.192 + if (dev2 != NULL) 1.193 + kfree(dev2); 1.194 + return err; 1.195 } 1.196 1.197 static int __init loopback_init(void) 1.198 { 1.199 - struct net_device *dev1, *dev2; 1.200 - int err = -ENOMEM; 1.201 - 1.202 - dev1 = alloc_netdev(sizeof(struct net_private), "vif0.0", ether_setup); 1.203 - dev2 = alloc_netdev(sizeof(struct net_private), "veth0", ether_setup); 1.204 - if ( (dev1 == NULL) || (dev2 == NULL) ) 1.205 - goto fail; 1.206 - 1.207 - loopback_construct(dev1, dev2); 1.208 - loopback_construct(dev2, dev1); 1.209 - 1.210 - dev1->features |= NETIF_F_NO_CSUM; 1.211 - dev2->features |= NETIF_F_IP_CSUM; 1.212 + int i, err = 0; 1.213 1.214 - /* 1.215 - * Initialise a dummy MAC address for the 'dummy backend' interface. We 1.216 - * choose the numerically largest non-broadcast address to prevent the 1.217 - * address getting stolen by an Ethernet bridge for STP purposes. 1.218 - */ 1.219 - memset(dev1->dev_addr, 0xFF, ETH_ALEN); 1.220 - dev1->dev_addr[0] &= ~0x01; 1.221 - 1.222 - if ( (err = register_netdev(dev1)) != 0 ) 1.223 - goto fail; 1.224 + for (i = 0; i < nloopbacks; i++) 1.225 + if ((err = make_loopback(i)) != 0) 1.226 + break; 1.227 1.228 - if ( (err = register_netdev(dev2)) != 0 ) 1.229 - { 1.230 - unregister_netdev(dev1); 1.231 - goto fail; 1.232 - } 1.233 - 1.234 - return 0; 1.235 - 1.236 - fail: 1.237 - if ( dev1 != NULL ) 1.238 - kfree(dev1); 1.239 - if ( dev2 != NULL ) 1.240 - kfree(dev2); 1.241 - return err; 1.242 + return err; 1.243 } 1.244 1.245 module_init(loopback_init); 1.246 + 1.247 +/* 1.248 + * Local variables: 1.249 + * c-file-style: "linux" 1.250 + * indent-tabs-mode: t 1.251 + * c-indent-level: 8 1.252 + * c-basic-offset: 8 1.253 + * tab-width: 8 1.254 + * End: 1.255 + */