aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-10-16 04:27:31 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:08 -0400
commitb53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0a (patch)
tree50e19688753650e27b1f7fc1d48eb8683666e6b7 /arch/um
parentcd1ae0e49bdd814cfaa2e5ab28cff21a30e20085 (diff)
uml: network driver MTU cleanups
A bunch of MTU-related cleanups in the network code. First, there is the addition of the notion of a maximally-sized packet, which is the MTU plus headers. This is used to size the skb that will receive a packet. This allows ether_adjust_skb to go away, as it was used to resize the skb after it was allocated. Since the skb passed into the low-level read routine is no longer resized, and possibly reallocated, there, they (and the write routines) don't need to get an sk_buff **. They just need the sk_buff * now. The callers of ether_adjust_skb still need to do the skb_put, so that's now inlined. The MAX_PACKET definitions in most of the drivers are gone. The set_mtu methods were all the same and did nothing, so they can be removed. The ethertap driver had a typo which doubled the size of the packet rather than adding two bytes to it. It also wasn't defining its setup_size, causing a zero-byte kmalloc and crash when the invalid pointer returned from kmalloc was dereferenced. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/drivers/daemon_kern.c15
-rw-r--r--arch/um/drivers/daemon_user.c11
-rw-r--r--arch/um/drivers/mcast_kern.c13
-rw-r--r--arch/um/drivers/mcast_user.c11
-rw-r--r--arch/um/drivers/net_kern.c42
-rw-r--r--arch/um/drivers/pcap_kern.c13
-rw-r--r--arch/um/drivers/pcap_user.c9
-rw-r--r--arch/um/drivers/slip_kern.c10
-rw-r--r--arch/um/drivers/slip_user.c9
-rw-r--r--arch/um/drivers/slirp_kern.c14
-rw-r--r--arch/um/drivers/slirp_user.c9
-rw-r--r--arch/um/drivers/vde_kern.c19
-rw-r--r--arch/um/drivers/vde_user.c11
-rw-r--r--arch/um/include/net_kern.h13
-rw-r--r--arch/um/include/net_user.h4
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c30
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c9
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c15
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c11
19 files changed, 80 insertions, 188 deletions
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index ac507bb87fea..d53ff52bb404 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -39,20 +39,15 @@ static void daemon_init(struct net_device *dev, void *data)
39 printk("\n"); 39 printk("\n");
40} 40}
41 41
42static int daemon_read(int fd, struct sk_buff **skb, 42static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
43 struct uml_net_private *lp)
44{ 43{
45 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 44 return net_recvfrom(fd, skb_mac_header(skb),
46 if (*skb == NULL) 45 skb->dev->mtu + ETH_HEADER_OTHER);
47 return -ENOMEM;
48 return net_recvfrom(fd, skb_mac_header(*skb),
49 (*skb)->dev->mtu + ETH_HEADER_OTHER);
50} 46}
51 47
52static int daemon_write(int fd, struct sk_buff **skb, 48static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
53 struct uml_net_private *lp)
54{ 49{
55 return daemon_user_write(fd, (*skb)->data, (*skb)->len, 50 return daemon_user_write(fd, skb->data, skb->len,
56 (struct daemon_data *) &lp->user); 51 (struct daemon_data *) &lp->user);
57} 52}
58 53
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 90983d480ac6..f23c109a055c 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -19,8 +19,6 @@
19#include "um_malloc.h" 19#include "um_malloc.h"
20#include "user.h" 20#include "user.h"
21 21
22#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
23
24enum request_type { REQ_NEW_CONTROL }; 22enum request_type { REQ_NEW_CONTROL };
25 23
26#define SWITCH_MAGIC 0xfeedface 24#define SWITCH_MAGIC 0xfeedface
@@ -184,18 +182,13 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
184 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); 182 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
185} 183}
186 184
187static int daemon_set_mtu(int mtu, void *data)
188{
189 return mtu;
190}
191
192const struct net_user_info daemon_user_info = { 185const struct net_user_info daemon_user_info = {
193 .init = daemon_user_init, 186 .init = daemon_user_init,
194 .open = daemon_open, 187 .open = daemon_open,
195 .close = NULL, 188 .close = NULL,
196 .remove = daemon_remove, 189 .remove = daemon_remove,
197 .set_mtu = daemon_set_mtu,
198 .add_address = NULL, 190 .add_address = NULL,
199 .delete_address = NULL, 191 .delete_address = NULL,
200 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 192 .mtu = ETH_MAX_PACKET,
193 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
201}; 194};
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index 5027b870d11d..822092f149be 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -39,18 +39,15 @@ static void mcast_init(struct net_device *dev, void *data)
39 dpri->addr, dpri->port, dpri->ttl); 39 dpri->addr, dpri->port, dpri->ttl);
40} 40}
41 41
42static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) 42static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
43{ 43{
44 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 44 return net_recvfrom(fd, skb_mac_header(skb),
45 if (*skb == NULL) 45 skb->dev->mtu + ETH_HEADER_OTHER);
46 return -ENOMEM;
47 return net_recvfrom(fd, skb_mac_header(*skb),
48 (*skb)->dev->mtu + ETH_HEADER_OTHER);
49} 46}
50 47
51static int mcast_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 48static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
52{ 49{
53 return mcast_user_write(fd, (*skb)->data, (*skb)->len, 50 return mcast_user_write(fd, skb->data, skb->len,
54 (struct mcast_data *) &lp->user); 51 (struct mcast_data *) &lp->user);
55} 52}
56 53
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index e427b5322a36..5f647d7a7292 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -20,8 +20,6 @@
20#include "um_malloc.h" 20#include "um_malloc.h"
21#include "user.h" 21#include "user.h"
22 22
23#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
24
25static struct sockaddr_in *new_addr(char *addr, unsigned short port) 23static struct sockaddr_in *new_addr(char *addr, unsigned short port)
26{ 24{
27 struct sockaddr_in *sin; 25 struct sockaddr_in *sin;
@@ -154,18 +152,13 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
154 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); 152 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
155} 153}
156 154
157static int mcast_set_mtu(int mtu, void *data)
158{
159 return mtu;
160}
161
162const struct net_user_info mcast_user_info = { 155const struct net_user_info mcast_user_info = {
163 .init = mcast_user_init, 156 .init = mcast_user_init,
164 .open = mcast_open, 157 .open = mcast_open,
165 .close = mcast_close, 158 .close = mcast_close,
166 .remove = mcast_remove, 159 .remove = mcast_remove,
167 .set_mtu = mcast_set_mtu,
168 .add_address = NULL, 160 .add_address = NULL,
169 .delete_address = NULL, 161 .delete_address = NULL,
170 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 162 .mtu = ETH_MAX_PACKET,
163 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
171}; 164};
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index b097a24c1496..59811cc880e0 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -41,16 +41,16 @@ static int uml_net_rx(struct net_device *dev)
41 struct sk_buff *skb; 41 struct sk_buff *skb;
42 42
43 /* If we can't allocate memory, try again next round. */ 43 /* If we can't allocate memory, try again next round. */
44 skb = dev_alloc_skb(dev->mtu); 44 skb = dev_alloc_skb(lp->max_packet);
45 if (skb == NULL) { 45 if (skb == NULL) {
46 lp->stats.rx_dropped++; 46 lp->stats.rx_dropped++;
47 return 0; 47 return 0;
48 } 48 }
49 49
50 skb->dev = dev; 50 skb->dev = dev;
51 skb_put(skb, dev->mtu); 51 skb_put(skb, lp->max_packet);
52 skb_reset_mac_header(skb); 52 skb_reset_mac_header(skb);
53 pkt_len = (*lp->read)(lp->fd, &skb, lp); 53 pkt_len = (*lp->read)(lp->fd, skb, lp);
54 54
55 if (pkt_len > 0) { 55 if (pkt_len > 0) {
56 skb_trim(skb, pkt_len); 56 skb_trim(skb, pkt_len);
@@ -178,7 +178,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
178 178
179 spin_lock_irqsave(&lp->lock, flags); 179 spin_lock_irqsave(&lp->lock, flags);
180 180
181 len = (*lp->write)(lp->fd, &skb, lp); 181 len = (*lp->write)(lp->fd, skb, lp);
182 182
183 if (len == skb->len) { 183 if (len == skb->len) {
184 lp->stats.tx_packets++; 184 lp->stats.tx_packets++;
@@ -240,22 +240,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr)
240 240
241static int uml_net_change_mtu(struct net_device *dev, int new_mtu) 241static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
242{ 242{
243 struct uml_net_private *lp = dev->priv;
244 int err = 0;
245
246 spin_lock_irq(&lp->lock);
247
248 new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
249 if (new_mtu < 0) {
250 err = new_mtu;
251 goto out;
252 }
253
254 dev->mtu = new_mtu; 243 dev->mtu = new_mtu;
255 244
256 out: 245 return 0;
257 spin_unlock_irq(&lp->lock);
258 return err;
259} 246}
260 247
261static void uml_net_get_drvinfo(struct net_device *dev, 248static void uml_net_get_drvinfo(struct net_device *dev,
@@ -427,6 +414,7 @@ static void eth_configure(int n, void *init, char *mac,
427 .dev = dev, 414 .dev = dev,
428 .fd = -1, 415 .fd = -1,
429 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, 416 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
417 .max_packet = transport->user->max_packet,
430 .protocol = transport->kern->protocol, 418 .protocol = transport->kern->protocol,
431 .open = transport->user->open, 419 .open = transport->user->open,
432 .close = transport->user->close, 420 .close = transport->user->close,
@@ -434,8 +422,7 @@ static void eth_configure(int n, void *init, char *mac,
434 .read = transport->kern->read, 422 .read = transport->kern->read,
435 .write = transport->kern->write, 423 .write = transport->kern->write,
436 .add_address = transport->user->add_address, 424 .add_address = transport->user->add_address,
437 .delete_address = transport->user->delete_address, 425 .delete_address = transport->user->delete_address });
438 .set_mtu = transport->user->set_mtu });
439 426
440 init_timer(&lp->tl); 427 init_timer(&lp->tl);
441 spin_lock_init(&lp->lock); 428 spin_lock_init(&lp->lock);
@@ -447,7 +434,7 @@ static void eth_configure(int n, void *init, char *mac,
447 goto out_unregister; 434 goto out_unregister;
448 435
449 set_ether_mac(dev, device->mac); 436 set_ether_mac(dev, device->mac);
450 dev->mtu = transport->user->max_packet; 437 dev->mtu = transport->user->mtu;
451 dev->open = uml_net_open; 438 dev->open = uml_net_open;
452 dev->hard_start_xmit = uml_net_start_xmit; 439 dev->hard_start_xmit = uml_net_start_xmit;
453 dev->stop = uml_net_close; 440 dev->stop = uml_net_close;
@@ -807,19 +794,6 @@ static void close_devices(void)
807 794
808__uml_exitcall(close_devices); 795__uml_exitcall(close_devices);
809 796
810struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
811{
812 if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
813 struct sk_buff *skb2;
814
815 skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
816 dev_kfree_skb(skb);
817 skb = skb2;
818 }
819 if (skb != NULL) skb_put(skb, extra);
820 return skb;
821}
822
823void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, 797void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
824 void *), 798 void *),
825 void *arg) 799 void *arg)
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index da0403efbc0d..3a750dd39be1 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -31,19 +31,14 @@ void pcap_init(struct net_device *dev, void *data)
31 printk("pcap backend, host interface %s\n", ppri->host_if); 31 printk("pcap backend, host interface %s\n", ppri->host_if);
32} 32}
33 33
34static int pcap_read(int fd, struct sk_buff **skb, 34static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
35 struct uml_net_private *lp)
36{ 35{
37 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 36 return pcap_user_read(fd, skb_mac_header(skb),
38 if (*skb == NULL) 37 skb->dev->mtu + ETH_HEADER_OTHER,
39 return -ENOMEM;
40
41 return pcap_user_read(fd, skb_mac_header(*skb),
42 (*skb)->dev->mtu + ETH_HEADER_OTHER,
43 (struct pcap_data *) &lp->user); 38 (struct pcap_data *) &lp->user);
44} 39}
45 40
46static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 41static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
47{ 42{
48 return -EPERM; 43 return -EPERM;
49} 44}
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index cf996b82af56..e9809356c530 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -13,8 +13,6 @@
13#include "um_malloc.h" 13#include "um_malloc.h"
14#include "user.h" 14#include "user.h"
15 15
16#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
17
18#define PCAP_FD(p) (*(int *)(p)) 16#define PCAP_FD(p) (*(int *)(p))
19 17
20static int pcap_user_init(void *data, void *dev) 18static int pcap_user_init(void *data, void *dev)
@@ -23,7 +21,8 @@ static int pcap_user_init(void *data, void *dev)
23 pcap_t *p; 21 pcap_t *p;
24 char errors[PCAP_ERRBUF_SIZE]; 22 char errors[PCAP_ERRBUF_SIZE];
25 23
26 p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); 24 p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
25 pri->promisc, 0, errors);
27 if (p == NULL) { 26 if (p == NULL) {
28 printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - " 27 printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
29 "'%s'\n", errors); 28 "'%s'\n", errors);
@@ -133,8 +132,8 @@ const struct net_user_info pcap_user_info = {
133 .open = pcap_open, 132 .open = pcap_open,
134 .close = NULL, 133 .close = NULL,
135 .remove = pcap_remove, 134 .remove = pcap_remove,
136 .set_mtu = NULL,
137 .add_address = NULL, 135 .add_address = NULL,
138 .delete_address = NULL, 136 .delete_address = NULL,
139 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 137 .mtu = ETH_MAX_PACKET,
138 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
140}; 139};
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 05ed351de6b5..ae67e7158e71 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -47,17 +47,15 @@ static unsigned short slip_protocol(struct sk_buff *skbuff)
47 return htons(ETH_P_IP); 47 return htons(ETH_P_IP);
48} 48}
49 49
50static int slip_read(int fd, struct sk_buff **skb, 50static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
51 struct uml_net_private *lp)
52{ 51{
53 return slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, 52 return slip_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
54 (struct slip_data *) &lp->user); 53 (struct slip_data *) &lp->user);
55} 54}
56 55
57static int slip_write(int fd, struct sk_buff **skb, 56static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
58 struct uml_net_private *lp)
59{ 57{
60 return slip_user_write(fd, (*skb)->data, (*skb)->len, 58 return slip_user_write(fd, skb->data, skb->len,
61 (struct slip_data *) &lp->user); 59 (struct slip_data *) &lp->user);
62} 60}
63 61
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index d78f324e7298..5f06204d6871 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -230,11 +230,6 @@ int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
230 return slip_proto_write(fd, buf, len, &pri->slip); 230 return slip_proto_write(fd, buf, len, &pri->slip);
231} 231}
232 232
233static int slip_set_mtu(int mtu, void *data)
234{
235 return mtu;
236}
237
238static void slip_add_addr(unsigned char *addr, unsigned char *netmask, 233static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
239 void *data) 234 void *data)
240{ 235{
@@ -260,8 +255,8 @@ const struct net_user_info slip_user_info = {
260 .open = slip_open, 255 .open = slip_open,
261 .close = slip_close, 256 .close = slip_close,
262 .remove = NULL, 257 .remove = NULL,
263 .set_mtu = slip_set_mtu,
264 .add_address = slip_add_addr, 258 .add_address = slip_add_addr,
265 .delete_address = slip_del_addr, 259 .delete_address = slip_del_addr,
266 .max_packet = BUF_SIZE 260 .mtu = BUF_SIZE,
261 .max_packet = BUF_SIZE,
267}; 262};
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index b208d5e4a405..240ee650865d 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -52,18 +52,16 @@ static unsigned short slirp_protocol(struct sk_buff *skbuff)
52 return htons(ETH_P_IP); 52 return htons(ETH_P_IP);
53} 53}
54 54
55static int slirp_read(int fd, struct sk_buff **skb, 55static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
56 struct uml_net_private *lp)
57{ 56{
58 return slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, 57 return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
59 (struct slirp_data *) &lp->user); 58 (struct slirp_data *) &lp->user);
60} 59}
61 60
62static int slirp_write(int fd, struct sk_buff **skb, 61static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
63 struct uml_net_private *lp)
64{ 62{
65 return slirp_user_write(fd, (*skb)->data, (*skb)->len, 63 return slirp_user_write(fd, skb->data, skb->len,
66 (struct slirp_data *) &lp->user); 64 (struct slirp_data *) &lp->user);
67} 65}
68 66
69const struct net_kern_info slirp_kern_info = { 67const struct net_kern_info slirp_kern_info = {
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index a4755bc33e1e..1865089ff41a 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -124,18 +124,13 @@ int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
124 return slip_proto_write(fd, buf, len, &pri->slip); 124 return slip_proto_write(fd, buf, len, &pri->slip);
125} 125}
126 126
127static int slirp_set_mtu(int mtu, void *data)
128{
129 return mtu;
130}
131
132const struct net_user_info slirp_user_info = { 127const struct net_user_info slirp_user_info = {
133 .init = slirp_user_init, 128 .init = slirp_user_init,
134 .open = slirp_open, 129 .open = slirp_open,
135 .close = slirp_close, 130 .close = slirp_close,
136 .remove = NULL, 131 .remove = NULL,
137 .set_mtu = slirp_set_mtu,
138 .add_address = NULL, 132 .add_address = NULL,
139 .delete_address = NULL, 133 .delete_address = NULL,
140 .max_packet = BUF_SIZE 134 .mtu = BUF_SIZE,
135 .max_packet = BUF_SIZE,
141}; 136};
diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c
index c5d01685d2b5..add7e722defb 100644
--- a/arch/um/drivers/vde_kern.c
+++ b/arch/um/drivers/vde_kern.c
@@ -36,30 +36,25 @@ static void vde_init(struct net_device *dev, void *data)
36 printk("\n"); 36 printk("\n");
37} 37}
38 38
39static int vde_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) 39static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
40{ 40{
41 struct vde_data *pri = (struct vde_data *) &lp->user; 41 struct vde_data *pri = (struct vde_data *) &lp->user;
42 42
43 if (pri->conn != NULL) { 43 if (pri->conn != NULL)
44 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 44 return vde_user_read(pri->conn, skb_mac_header(skb),
45 if (*skb == NULL) 45 skb->dev->mtu + ETH_HEADER_OTHER);
46 return -ENOMEM;
47
48 return vde_user_read(pri->conn, skb_mac_header(*skb),
49 (*skb)->dev->mtu + ETH_HEADER_OTHER);
50 }
51 46
52 printk(KERN_ERR "vde_read - we have no VDECONN to read from"); 47 printk(KERN_ERR "vde_read - we have no VDECONN to read from");
53 return -EBADF; 48 return -EBADF;
54} 49}
55 50
56static int vde_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 51static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
57{ 52{
58 struct vde_data *pri = (struct vde_data *) &lp->user; 53 struct vde_data *pri = (struct vde_data *) &lp->user;
59 54
60 if (pri->conn != NULL) 55 if (pri->conn != NULL)
61 return vde_user_write((void *)pri->conn, (*skb)->data, 56 return vde_user_write((void *)pri->conn, skb->data,
62 (*skb)->len); 57 skb->len);
63 58
64 printk(KERN_ERR "vde_write - we have no VDECONN to write to"); 59 printk(KERN_ERR "vde_write - we have no VDECONN to write to");
65 return -EBADF; 60 return -EBADF;
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
index 7533cd3cbba4..d9941fe5f931 100644
--- a/arch/um/drivers/vde_user.c
+++ b/arch/um/drivers/vde_user.c
@@ -12,8 +12,6 @@
12#include "user.h" 12#include "user.h"
13#include "vde.h" 13#include "vde.h"
14 14
15#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
16
17static int vde_user_init(void *data, void *dev) 15static int vde_user_init(void *data, void *dev)
18{ 16{
19 struct vde_data *pri = data; 17 struct vde_data *pri = data;
@@ -65,20 +63,15 @@ static void vde_remove(void *data)
65 printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove"); 63 printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove");
66} 64}
67 65
68static int vde_set_mtu(int mtu, void *data)
69{
70 return mtu;
71}
72
73const struct net_user_info vde_user_info = { 66const struct net_user_info vde_user_info = {
74 .init = vde_user_init, 67 .init = vde_user_init,
75 .open = vde_user_open, 68 .open = vde_user_open,
76 .close = NULL, 69 .close = NULL,
77 .remove = vde_remove, 70 .remove = vde_remove,
78 .set_mtu = vde_set_mtu,
79 .add_address = NULL, 71 .add_address = NULL,
80 .delete_address = NULL, 72 .delete_address = NULL,
81 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 73 .mtu = ETH_MAX_PACKET,
74 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
82}; 75};
83 76
84void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) 77void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 9237056b9103..d843c7924a7c 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -30,24 +30,24 @@ struct uml_net_private {
30 struct work_struct work; 30 struct work_struct work;
31 int fd; 31 int fd;
32 unsigned char mac[ETH_ALEN]; 32 unsigned char mac[ETH_ALEN];
33 int max_packet;
33 unsigned short (*protocol)(struct sk_buff *); 34 unsigned short (*protocol)(struct sk_buff *);
34 int (*open)(void *); 35 int (*open)(void *);
35 void (*close)(int, void *); 36 void (*close)(int, void *);
36 void (*remove)(void *); 37 void (*remove)(void *);
37 int (*read)(int, struct sk_buff **skb, struct uml_net_private *); 38 int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
38 int (*write)(int, struct sk_buff **skb, struct uml_net_private *); 39 int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
39 40
40 void (*add_address)(unsigned char *, unsigned char *, void *); 41 void (*add_address)(unsigned char *, unsigned char *, void *);
41 void (*delete_address)(unsigned char *, unsigned char *, void *); 42 void (*delete_address)(unsigned char *, unsigned char *, void *);
42 int (*set_mtu)(int mtu, void *);
43 char user[0]; 43 char user[0];
44}; 44};
45 45
46struct net_kern_info { 46struct net_kern_info {
47 void (*init)(struct net_device *, void *); 47 void (*init)(struct net_device *, void *);
48 unsigned short (*protocol)(struct sk_buff *); 48 unsigned short (*protocol)(struct sk_buff *);
49 int (*read)(int, struct sk_buff **skb, struct uml_net_private *); 49 int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
50 int (*write)(int, struct sk_buff **skb, struct uml_net_private *); 50 int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
51}; 51};
52 52
53struct transport { 53struct transport {
@@ -62,7 +62,6 @@ struct transport {
62 62
63extern struct net_device *ether_init(int); 63extern struct net_device *ether_init(int);
64extern unsigned short ether_protocol(struct sk_buff *); 64extern unsigned short ether_protocol(struct sk_buff *);
65extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
66extern int tap_setup_common(char *str, char *type, char **dev_name, 65extern int tap_setup_common(char *str, char *type, char **dev_name,
67 char **mac_out, char **gate_addr); 66 char **mac_out, char **gate_addr);
68extern void register_transport(struct transport *new); 67extern void register_transport(struct transport *new);
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index cfe7c50634b9..63bee158cd8e 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -18,10 +18,10 @@ struct net_user_info {
18 int (*open)(void *); 18 int (*open)(void *);
19 void (*close)(int, void *); 19 void (*close)(int, void *);
20 void (*remove)(void *); 20 void (*remove)(void *);
21 int (*set_mtu)(int mtu, void *);
22 void (*add_address)(unsigned char *, unsigned char *, void *); 21 void (*add_address)(unsigned char *, unsigned char *, void *);
23 void (*delete_address)(unsigned char *, unsigned char *, void *); 22 void (*delete_address)(unsigned char *, unsigned char *, void *);
24 int max_packet; 23 int max_packet;
24 int mtu;
25}; 25};
26 26
27extern void ether_user_init(void *data, void *dev); 27extern void ether_user_init(void *data, void *dev);
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 542bcc58354c..04f11b9f1ac0 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -36,35 +36,24 @@ static void etap_init(struct net_device *dev, void *data)
36 printk("\n"); 36 printk("\n");
37} 37}
38 38
39static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) 39static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
40{ 40{
41 int len; 41 int len;
42 42
43 *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); 43 len = net_recvfrom(fd, skb_mac_header(skb),
44 if (*skb == NULL) 44 skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
45 return -ENOMEM;
46 len = net_recvfrom(fd, skb_mac_header(*skb),
47 (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
48 if (len <= 0) 45 if (len <= 0)
49 return len; 46 return(len);
50 skb_pull(*skb, 2); 47
48 skb_pull(skb, 2);
51 len -= 2; 49 len -= 2;
52 return len; 50 return len;
53} 51}
54 52
55static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 53static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
56{ 54{
57 if (skb_headroom(*skb) < 2) { 55 skb_push(skb, 2);
58 struct sk_buff *skb2; 56 return net_send(fd, skb->data, skb->len);
59
60 skb2 = skb_realloc_headroom(*skb, 2);
61 dev_kfree_skb(*skb);
62 if (skb2 == NULL)
63 return -ENOMEM;
64 *skb = skb2;
65 }
66 skb_push(*skb, 2);
67 return net_send(fd, (*skb)->data, (*skb)->len);
68} 57}
69 58
70const struct net_kern_info ethertap_kern_info = { 59const struct net_kern_info ethertap_kern_info = {
@@ -99,6 +88,7 @@ static struct transport ethertap_transport = {
99 .user = &ethertap_user_info, 88 .user = &ethertap_user_info,
100 .kern = &ethertap_kern_info, 89 .kern = &ethertap_kern_info,
101 .private_size = sizeof(struct ethertap_data), 90 .private_size = sizeof(struct ethertap_data),
91 .setup_size = sizeof(struct ethertap_init),
102}; 92};
103 93
104static int register_ethertap(void) 94static int register_ethertap(void)
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 29404b955f18..4ff553603449 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -222,11 +222,6 @@ static void etap_close(int fd, void *data)
222 pri->control_fd = -1; 222 pri->control_fd = -1;
223} 223}
224 224
225static int etap_set_mtu(int mtu, void *data)
226{
227 return mtu;
228}
229
230static void etap_add_addr(unsigned char *addr, unsigned char *netmask, 225static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
231 void *data) 226 void *data)
232{ 227{
@@ -254,8 +249,8 @@ const struct net_user_info ethertap_user_info = {
254 .open = etap_open, 249 .open = etap_open,
255 .close = etap_close, 250 .close = etap_close,
256 .remove = NULL, 251 .remove = NULL,
257 .set_mtu = etap_set_mtu,
258 .add_address = etap_add_addr, 252 .add_address = etap_add_addr,
259 .delete_address = etap_del_addr, 253 .delete_address = etap_del_addr,
260 .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP 254 .mtu = ETH_MAX_PACKET,
255 .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP,
261}; 256};
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 9ade1f892ac8..9d384807b077 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -35,20 +35,15 @@ static void tuntap_init(struct net_device *dev, void *data)
35 printk("\n"); 35 printk("\n");
36} 36}
37 37
38static int tuntap_read(int fd, struct sk_buff **skb, 38static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
39 struct uml_net_private *lp)
40{ 39{
41 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 40 return net_read(fd, skb_mac_header(skb),
42 if (*skb == NULL) 41 skb->dev->mtu + ETH_HEADER_OTHER);
43 return -ENOMEM;
44 return net_read(fd, skb_mac_header(*skb),
45 (*skb)->dev->mtu + ETH_HEADER_OTHER);
46} 42}
47 43
48static int tuntap_write(int fd, struct sk_buff **skb, 44static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
49 struct uml_net_private *lp)
50{ 45{
51 return net_write(fd, (*skb)->data, (*skb)->len); 46 return net_write(fd, skb->data, skb->len);
52} 47}
53 48
54const struct net_kern_info tuntap_kern_info = { 49const struct net_kern_info tuntap_kern_info = {
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 10714a413cfd..6c55d3c8ead8 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -18,8 +18,6 @@
18#include "tuntap.h" 18#include "tuntap.h"
19#include "user.h" 19#include "user.h"
20 20
21#define MAX_PACKET ETH_MAX_PACKET
22
23static int tuntap_user_init(void *data, void *dev) 21static int tuntap_user_init(void *data, void *dev)
24{ 22{
25 struct tuntap_data *pri = data; 23 struct tuntap_data *pri = data;
@@ -206,18 +204,13 @@ static void tuntap_close(int fd, void *data)
206 pri->fd = -1; 204 pri->fd = -1;
207} 205}
208 206
209static int tuntap_set_mtu(int mtu, void *data)
210{
211 return mtu;
212}
213
214const struct net_user_info tuntap_user_info = { 207const struct net_user_info tuntap_user_info = {
215 .init = tuntap_user_init, 208 .init = tuntap_user_init,
216 .open = tuntap_open, 209 .open = tuntap_open,
217 .close = tuntap_close, 210 .close = tuntap_close,
218 .remove = NULL, 211 .remove = NULL,
219 .set_mtu = tuntap_set_mtu,
220 .add_address = tuntap_add_addr, 212 .add_address = tuntap_add_addr,
221 .delete_address = tuntap_del_addr, 213 .delete_address = tuntap_del_addr,
222 .max_packet = MAX_PACKET 214 .mtu = ETH_MAX_PACKET,
215 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
223}; 216};