ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/netback/loopback.c @ 14100:e47738923a05

[LINUX] Purge include <linux/config.h>. It has been obsolete for some time now.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Fri Feb 23 16:56:45 2007 +0000 (2007-02-23)
parents 9977b8785570
children
line source
1 /******************************************************************************
2 * netback/loopback.c
3 *
4 * A two-interface loopback device to emulate a local netfront-netback
5 * connection. This ensures that local packet delivery looks identical
6 * to inter-domain delivery. Most importantly, packets delivered locally
7 * originating from other domains will get *copied* when they traverse this
8 * driver. This prevents unbounded delays in socket-buffer queues from
9 * causing the netback driver to "seize up".
10 *
11 * This driver creates a symmetric pair of loopback interfaces with names
12 * vif0.0 and veth0. The intention is that 'vif0.0' is bound to an Ethernet
13 * bridge, just like a proper netback interface, while a local IP interface
14 * is configured on 'veth0'.
15 *
16 * As with a real netback interface, vif0.0 is configured with a suitable
17 * dummy MAC address. No default is provided for veth0: a reasonable strategy
18 * is to transfer eth0's MAC address to veth0, and give eth0 a dummy address
19 * (to avoid confusing the Etherbridge).
20 *
21 * Copyright (c) 2005 K A Fraser
22 *
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License version 2
25 * as published by the Free Software Foundation; or, when distributed
26 * separately from the Linux kernel or incorporated into other
27 * software packages, subject to the following license:
28 *
29 * Permission is hereby granted, free of charge, to any person obtaining a copy
30 * of this source file (the "Software"), to deal in the Software without
31 * restriction, including without limitation the rights to use, copy, modify,
32 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
33 * and to permit persons to whom the Software is furnished to do so, subject to
34 * the following conditions:
35 *
36 * The above copyright notice and this permission notice shall be included in
37 * all copies or substantial portions of the Software.
38 *
39 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
44 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
45 * IN THE SOFTWARE.
46 */
48 #include <linux/module.h>
49 #include <linux/netdevice.h>
50 #include <linux/inetdevice.h>
51 #include <linux/etherdevice.h>
52 #include <linux/skbuff.h>
53 #include <linux/ethtool.h>
54 #include <net/dst.h>
55 #include <net/xfrm.h> /* secpath_reset() */
56 #include <asm/hypervisor.h> /* is_initial_xendomain() */
58 static int nloopbacks = -1;
59 module_param(nloopbacks, int, 0);
60 MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
62 struct net_private {
63 struct net_device *loopback_dev;
64 struct net_device_stats stats;
65 };
67 static int loopback_open(struct net_device *dev)
68 {
69 struct net_private *np = netdev_priv(dev);
70 memset(&np->stats, 0, sizeof(np->stats));
71 netif_start_queue(dev);
72 return 0;
73 }
75 static int loopback_close(struct net_device *dev)
76 {
77 netif_stop_queue(dev);
78 return 0;
79 }
81 #ifdef CONFIG_X86
82 static int is_foreign(unsigned long pfn)
83 {
84 /* NB. Play it safe for auto-translation mode. */
85 return (xen_feature(XENFEAT_auto_translated_physmap) ||
86 (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT));
87 }
88 #else
89 /* How to detect a foreign mapping? Play it safe. */
90 #define is_foreign(pfn) (1)
91 #endif
93 static int skb_remove_foreign_references(struct sk_buff *skb)
94 {
95 struct page *page;
96 unsigned long pfn;
97 int i, off;
98 char *vaddr;
100 BUG_ON(skb_shinfo(skb)->frag_list);
102 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
103 pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page);
104 if (!is_foreign(pfn))
105 continue;
107 page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
108 if (unlikely(!page))
109 return 0;
111 vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
112 off = skb_shinfo(skb)->frags[i].page_offset;
113 memcpy(page_address(page) + off,
114 vaddr + off,
115 skb_shinfo(skb)->frags[i].size);
116 kunmap_skb_frag(vaddr);
118 put_page(skb_shinfo(skb)->frags[i].page);
119 skb_shinfo(skb)->frags[i].page = page;
120 }
122 return 1;
123 }
125 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
126 {
127 struct net_private *np = netdev_priv(dev);
129 if (!skb_remove_foreign_references(skb)) {
130 np->stats.tx_dropped++;
131 dev_kfree_skb(skb);
132 return 0;
133 }
135 dst_release(skb->dst);
136 skb->dst = NULL;
138 skb_orphan(skb);
140 np->stats.tx_bytes += skb->len;
141 np->stats.tx_packets++;
143 /* Switch to loopback context. */
144 dev = np->loopback_dev;
145 np = netdev_priv(dev);
147 np->stats.rx_bytes += skb->len;
148 np->stats.rx_packets++;
150 if (skb->ip_summed == CHECKSUM_HW) {
151 /* Defer checksum calculation. */
152 skb->proto_csum_blank = 1;
153 /* Must be a local packet: assert its integrity. */
154 skb->proto_data_valid = 1;
155 }
157 skb->ip_summed = skb->proto_data_valid ?
158 CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
160 skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
161 skb->protocol = eth_type_trans(skb, dev);
162 skb->dev = dev;
163 dev->last_rx = jiffies;
165 /* Flush netfilter context: rx'ed skbuffs not expected to have any. */
166 nf_reset(skb);
167 secpath_reset(skb);
169 netif_rx(skb);
171 return 0;
172 }
174 static struct net_device_stats *loopback_get_stats(struct net_device *dev)
175 {
176 struct net_private *np = netdev_priv(dev);
177 return &np->stats;
178 }
180 static struct ethtool_ops network_ethtool_ops =
181 {
182 .get_tx_csum = ethtool_op_get_tx_csum,
183 .set_tx_csum = ethtool_op_set_tx_csum,
184 .get_sg = ethtool_op_get_sg,
185 .set_sg = ethtool_op_set_sg,
186 .get_tso = ethtool_op_get_tso,
187 .set_tso = ethtool_op_set_tso,
188 .get_link = ethtool_op_get_link,
189 };
191 /*
192 * Nothing to do here. Virtual interface is point-to-point and the
193 * physical interface is probably promiscuous anyway.
194 */
195 static void loopback_set_multicast_list(struct net_device *dev)
196 {
197 }
199 static void loopback_construct(struct net_device *dev, struct net_device *lo)
200 {
201 struct net_private *np = netdev_priv(dev);
203 np->loopback_dev = lo;
205 dev->open = loopback_open;
206 dev->stop = loopback_close;
207 dev->hard_start_xmit = loopback_start_xmit;
208 dev->get_stats = loopback_get_stats;
209 dev->set_multicast_list = loopback_set_multicast_list;
210 dev->change_mtu = NULL; /* allow arbitrary mtu */
212 dev->tx_queue_len = 0;
214 dev->features = (NETIF_F_HIGHDMA |
215 NETIF_F_LLTX |
216 NETIF_F_TSO |
217 NETIF_F_SG |
218 NETIF_F_IP_CSUM);
220 SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
222 /*
223 * We do not set a jumbo MTU on the interface. Otherwise the network
224 * stack will try to send large packets that will get dropped by the
225 * Ethernet bridge (unless the physical Ethernet interface is
226 * configured to transfer jumbo packets). If a larger MTU is desired
227 * then the system administrator can specify it using the 'ifconfig'
228 * command.
229 */
230 /*dev->mtu = 16*1024;*/
231 }
233 static int __init make_loopback(int i)
234 {
235 struct net_device *dev1, *dev2;
236 char dev_name[IFNAMSIZ];
237 int err = -ENOMEM;
239 sprintf(dev_name, "vif0.%d", i);
240 dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
241 if (!dev1)
242 return err;
244 sprintf(dev_name, "veth%d", i);
245 dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
246 if (!dev2)
247 goto fail_netdev2;
249 loopback_construct(dev1, dev2);
250 loopback_construct(dev2, dev1);
252 /*
253 * Initialise a dummy MAC address for the 'dummy backend' interface. We
254 * choose the numerically largest non-broadcast address to prevent the
255 * address getting stolen by an Ethernet bridge for STP purposes.
256 */
257 memset(dev1->dev_addr, 0xFF, ETH_ALEN);
258 dev1->dev_addr[0] &= ~0x01;
260 if ((err = register_netdev(dev1)) != 0)
261 goto fail;
263 if ((err = register_netdev(dev2)) != 0) {
264 unregister_netdev(dev1);
265 goto fail;
266 }
268 return 0;
270 fail:
271 free_netdev(dev2);
272 fail_netdev2:
273 free_netdev(dev1);
274 return err;
275 }
277 static void __exit clean_loopback(int i)
278 {
279 struct net_device *dev1, *dev2;
280 char dev_name[IFNAMSIZ];
282 sprintf(dev_name, "vif0.%d", i);
283 dev1 = dev_get_by_name(dev_name);
284 sprintf(dev_name, "veth%d", i);
285 dev2 = dev_get_by_name(dev_name);
286 if (dev1 && dev2) {
287 unregister_netdev(dev2);
288 unregister_netdev(dev1);
289 free_netdev(dev2);
290 free_netdev(dev1);
291 }
292 }
294 static int __init loopback_init(void)
295 {
296 int i, err = 0;
298 if (nloopbacks == -1)
299 nloopbacks = is_initial_xendomain() ? 4 : 0;
301 for (i = 0; i < nloopbacks; i++)
302 if ((err = make_loopback(i)) != 0)
303 break;
305 return err;
306 }
308 module_init(loopback_init);
310 static void __exit loopback_exit(void)
311 {
312 int i;
314 for (i = nloopbacks; i-- > 0; )
315 clean_loopback(i);
316 }
318 module_exit(loopback_exit);
320 MODULE_LICENSE("Dual BSD/GPL");