ia64/xen-unstable

view linux-2.6.11-xen-sparse/drivers/xen/netback/loopback.c @ 5095:e81b60a0e170

bitkeeper revision 1.1516 (4292225caWyLsfo-mZ3yV4QmUhXSAQ)

Fix the veth0/vif0.0 loopback interfaces to properly assert integrity
of locally-generated packets. Hopefully this will fix dom0->domU
communications. As an aside, I think 'proto_csum_valid' is not a good
name for that field -- I may rename to 'proto_data_valid' or something
like that.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon May 23 18:35:08 2005 +0000 (2005-05-23)
parents 8a1faeb0d3c6
children 56a63f9f378f
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 */
24 #include <linux/config.h>
25 #include <linux/module.h>
26 #include <linux/netdevice.h>
27 #include <linux/inetdevice.h>
28 #include <linux/etherdevice.h>
29 #include <linux/skbuff.h>
30 #include <net/dst.h>
32 struct net_private {
33 struct net_device *loopback_dev;
34 struct net_device_stats stats;
35 };
37 static int loopback_open(struct net_device *dev)
38 {
39 struct net_private *np = netdev_priv(dev);
40 memset(&np->stats, 0, sizeof(np->stats));
41 netif_start_queue(dev);
42 return 0;
43 }
45 static int loopback_close(struct net_device *dev)
46 {
47 netif_stop_queue(dev);
48 return 0;
49 }
51 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
52 {
53 struct net_private *np = netdev_priv(dev);
55 dst_release(skb->dst);
56 skb->dst = NULL;
58 skb_orphan(skb);
60 np->stats.tx_bytes += skb->len;
61 np->stats.tx_packets++;
63 /* Switch to loopback context. */
64 dev = np->loopback_dev;
65 np = netdev_priv(dev);
67 np->stats.rx_bytes += skb->len;
68 np->stats.rx_packets++;
70 if ( skb->ip_summed == CHECKSUM_HW )
71 {
72 /* Defer checksum calculation. */
73 skb->proto_csum_blank = 1;
74 /* Must be a local packet: assert its integrity. */
75 skb->proto_csum_valid = 1;
76 }
78 skb->ip_summed = skb->proto_csum_valid ?
79 CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
81 skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
82 skb->protocol = eth_type_trans(skb, dev);
83 skb->dev = dev;
84 dev->last_rx = jiffies;
85 netif_rx(skb);
87 return 0;
88 }
90 static struct net_device_stats *loopback_get_stats(struct net_device *dev)
91 {
92 struct net_private *np = netdev_priv(dev);
93 return &np->stats;
94 }
96 static void loopback_construct(struct net_device *dev, struct net_device *lo)
97 {
98 struct net_private *np = netdev_priv(dev);
100 np->loopback_dev = lo;
102 dev->open = loopback_open;
103 dev->stop = loopback_close;
104 dev->hard_start_xmit = loopback_start_xmit;
105 dev->get_stats = loopback_get_stats;
107 dev->tx_queue_len = 0;
109 dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
111 /*
112 * We do not set a jumbo MTU on the interface. Otherwise the network
113 * stack will try to send large packets that will get dropped by the
114 * Ethernet bridge (unless the physical Ethernet interface is configured
115 * to transfer jumbo packets). If a larger MTU is desired then the system
116 * administrator can specify it using the 'ifconfig' command.
117 */
118 /*dev->mtu = 16*1024;*/
119 }
121 static int __init loopback_init(void)
122 {
123 struct net_device *dev1, *dev2;
124 int err = -ENOMEM;
126 dev1 = alloc_netdev(sizeof(struct net_private), "vif0.0", ether_setup);
127 dev2 = alloc_netdev(sizeof(struct net_private), "veth0", ether_setup);
128 if ( (dev1 == NULL) || (dev2 == NULL) )
129 goto fail;
131 loopback_construct(dev1, dev2);
132 loopback_construct(dev2, dev1);
134 dev1->features |= NETIF_F_NO_CSUM;
135 dev2->features |= NETIF_F_IP_CSUM;
137 /*
138 * Initialise a dummy MAC address for the 'dummy backend' interface. We
139 * choose the numerically largest non-broadcast address to prevent the
140 * address getting stolen by an Ethernet bridge for STP purposes.
141 */
142 memset(dev1->dev_addr, 0xFF, ETH_ALEN);
143 dev1->dev_addr[0] &= ~0x01;
145 if ( (err = register_netdev(dev1)) != 0 )
146 goto fail;
148 if ( (err = register_netdev(dev2)) != 0 )
149 {
150 unregister_netdev(dev1);
151 goto fail;
152 }
154 return 0;
156 fail:
157 if ( dev1 != NULL )
158 kfree(dev1);
159 if ( dev2 != NULL )
160 kfree(dev2);
161 return err;
162 }
164 module_init(loopback_init);