Added patch headers.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / netback / loopback.c
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  */
47
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() */
57 #include <../net/core/kmap_skb.h> /* k{,un}map_skb_frag() */
58
59 static int nloopbacks = -1;
60 module_param(nloopbacks, int, 0);
61 MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
62
63 struct net_private {
64         struct net_device *loopback_dev;
65         struct net_device_stats stats;
66 };
67
68 static int loopback_open(struct net_device *dev)
69 {
70         struct net_private *np = netdev_priv(dev);
71         memset(&np->stats, 0, sizeof(np->stats));
72         netif_start_queue(dev);
73         return 0;
74 }
75
76 static int loopback_close(struct net_device *dev)
77 {
78         netif_stop_queue(dev);
79         return 0;
80 }
81
82 #ifdef CONFIG_X86
83 static int is_foreign(unsigned long pfn)
84 {
85         /* NB. Play it safe for auto-translation mode. */
86         return (xen_feature(XENFEAT_auto_translated_physmap) ||
87                 (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT));
88 }
89 #else
90 /* How to detect a foreign mapping? Play it safe. */
91 #define is_foreign(pfn) (1)
92 #endif
93
94 static int skb_remove_foreign_references(struct sk_buff *skb)
95 {
96         struct page *page;
97         unsigned long pfn;
98         int i, off;
99         char *vaddr;
100
101         BUG_ON(skb_shinfo(skb)->frag_list);
102
103         if (skb_cloned(skb) &&
104             unlikely(pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
105                 return 0;
106
107         for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
108                 pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page);
109                 if (!is_foreign(pfn))
110                         continue;
111                 
112                 page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
113                 if (unlikely(!page))
114                         return 0;
115
116                 vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
117                 off = skb_shinfo(skb)->frags[i].page_offset;
118                 memcpy(page_address(page) + off,
119                        vaddr + off,
120                        skb_shinfo(skb)->frags[i].size);
121                 kunmap_skb_frag(vaddr);
122
123                 put_page(skb_shinfo(skb)->frags[i].page);
124                 skb_shinfo(skb)->frags[i].page = page;
125         }
126
127         return 1;
128 }
129
130 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
131 {
132         struct net_private *np = netdev_priv(dev);
133
134         if (!skb_remove_foreign_references(skb)) {
135                 np->stats.tx_dropped++;
136                 dev_kfree_skb(skb);
137                 return NETDEV_TX_OK;
138         }
139
140         dst_release(skb_dst(skb));
141         skb_dst_set(skb, NULL);
142
143         skb_orphan(skb);
144
145         np->stats.tx_bytes += skb->len;
146         np->stats.tx_packets++;
147
148         /* Switch to loopback context. */
149         dev = np->loopback_dev;
150         np  = netdev_priv(dev);
151
152         np->stats.rx_bytes += skb->len;
153         np->stats.rx_packets++;
154
155         if (skb->ip_summed == CHECKSUM_PARTIAL) {
156                 /* Defer checksum calculation. */
157                 skb->proto_csum_blank = 1;
158                 /* Must be a local packet: assert its integrity. */
159                 skb->proto_data_valid = 1;
160         }
161
162         skb->ip_summed = skb->proto_data_valid ?
163                 CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
164
165         skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
166         skb->protocol = eth_type_trans(skb, dev);
167         skb->dev      = dev;
168         dev->last_rx  = jiffies;
169
170         /* Flush netfilter context: rx'ed skbuffs not expected to have any. */
171         nf_reset(skb);
172         secpath_reset(skb);
173
174         netif_rx(skb);
175
176         return NETDEV_TX_OK;
177 }
178
179 static struct net_device_stats *loopback_get_stats(struct net_device *dev)
180 {
181         struct net_private *np = netdev_priv(dev);
182         return &np->stats;
183 }
184
185 static const struct ethtool_ops network_ethtool_ops =
186 {
187         .get_tx_csum = ethtool_op_get_tx_csum,
188         .set_tx_csum = ethtool_op_set_tx_csum,
189         .get_sg = ethtool_op_get_sg,
190         .set_sg = ethtool_op_set_sg,
191         .get_tso = ethtool_op_get_tso,
192         .set_tso = ethtool_op_set_tso,
193         .get_link = ethtool_op_get_link,
194 };
195
196 /*
197  * Nothing to do here. Virtual interface is point-to-point and the
198  * physical interface is probably promiscuous anyway.
199  */
200 static void loopback_set_multicast_list(struct net_device *dev)
201 {
202 }
203
204 static const struct net_device_ops loopback_netdev_ops = {
205         .ndo_open               = loopback_open,
206         .ndo_stop               = loopback_close,
207         .ndo_start_xmit         = loopback_start_xmit,
208         .ndo_set_multicast_list = loopback_set_multicast_list,
209         .ndo_change_mtu         = NULL, /* allow arbitrary mtu */
210         .ndo_get_stats          = loopback_get_stats,
211 };
212
213 static void loopback_construct(struct net_device *dev, struct net_device *lo)
214 {
215         struct net_private *np = netdev_priv(dev);
216
217         np->loopback_dev     = lo;
218         dev->netdev_ops      = &loopback_netdev_ops;
219         dev->tx_queue_len    = 0;
220
221         dev->features        = (NETIF_F_HIGHDMA |
222                                 NETIF_F_LLTX |
223                                 NETIF_F_TSO |
224                                 NETIF_F_SG |
225                                 NETIF_F_IP_CSUM);
226
227         SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
228
229         /*
230          * We do not set a jumbo MTU on the interface. Otherwise the network
231          * stack will try to send large packets that will get dropped by the
232          * Ethernet bridge (unless the physical Ethernet interface is
233          * configured to transfer jumbo packets). If a larger MTU is desired
234          * then the system administrator can specify it using the 'ifconfig'
235          * command.
236          */
237         /*dev->mtu             = 16*1024;*/
238 }
239
240 static int __init make_loopback(int i)
241 {
242         struct net_device *dev1, *dev2;
243         char dev_name[IFNAMSIZ];
244         int err = -ENOMEM;
245
246         sprintf(dev_name, "vif0.%d", i);
247         dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
248         if (!dev1)
249                 return err;
250
251         sprintf(dev_name, "veth%d", i);
252         dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
253         if (!dev2)
254                 goto fail_netdev2;
255
256         loopback_construct(dev1, dev2);
257         loopback_construct(dev2, dev1);
258
259         /*
260          * Initialise a dummy MAC address for the 'dummy backend' interface. We
261          * choose the numerically largest non-broadcast address to prevent the
262          * address getting stolen by an Ethernet bridge for STP purposes.
263          */
264         memset(dev1->dev_addr, 0xFF, ETH_ALEN);
265         dev1->dev_addr[0] &= ~0x01;
266
267         if ((err = register_netdev(dev1)) != 0)
268                 goto fail;
269
270         if ((err = register_netdev(dev2)) != 0) {
271                 unregister_netdev(dev1);
272                 goto fail;
273         }
274
275         return 0;
276
277  fail:
278         free_netdev(dev2);
279  fail_netdev2:
280         free_netdev(dev1);
281         return err;
282 }
283
284 static void __exit clean_loopback(int i)
285 {
286         struct net_device *dev1, *dev2;
287         char dev_name[IFNAMSIZ];
288
289         sprintf(dev_name, "vif0.%d", i);
290         dev1 = dev_get_by_name(&init_net, dev_name);
291         sprintf(dev_name, "veth%d", i);
292         dev2 = dev_get_by_name(&init_net, dev_name);
293         if (dev1 && dev2) {
294                 unregister_netdev(dev2);
295                 unregister_netdev(dev1);
296                 free_netdev(dev2);
297                 free_netdev(dev1);
298         }
299 }
300
301 static int __init loopback_init(void)
302 {
303         int i, err = 0;
304
305         if (nloopbacks == -1)
306                 nloopbacks = is_initial_xendomain() ? 4 : 0;
307
308         for (i = 0; i < nloopbacks; i++)
309                 if ((err = make_loopback(i)) != 0)
310                         break;
311
312         return err;
313 }
314
315 module_init(loopback_init);
316
317 static void __exit loopback_exit(void)
318 {
319         int i;
320
321         for (i = nloopbacks; i-- > 0; )
322                 clean_loopback(i);
323 }
324
325 module_exit(loopback_exit);
326
327 MODULE_LICENSE("Dual BSD/GPL");