summaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-10-16 10:27:31 +0200
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 18:43:08 +0200
commitb53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0a (patch)
tree50e19688753650e27b1f7fc1d48eb8683666e6b7 /arch/um/drivers
parentuml: network formatting (diff)
downloadlinux-b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0a.tar.xz
linux-b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0a.zip
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/drivers')
-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
13 files changed, 53 insertions, 133 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)
printk("\n");
}
-static int daemon_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if (*skb == NULL)
- return -ENOMEM;
- return net_recvfrom(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER);
+ return net_recvfrom(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
}
-static int daemon_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return daemon_user_write(fd, (*skb)->data, (*skb)->len,
+ return daemon_user_write(fd, skb->data, skb->len,
(struct daemon_data *) &lp->user);
}
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 @@
#include "um_malloc.h"
#include "user.h"
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
-
enum request_type { REQ_NEW_CONTROL };
#define SWITCH_MAGIC 0xfeedface
@@ -184,18 +182,13 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
-static int daemon_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info daemon_user_info = {
.init = daemon_user_init,
.open = daemon_open,
.close = NULL,
.remove = daemon_remove,
- .set_mtu = daemon_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
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)
dpri->addr, dpri->port, dpri->ttl);
}
-static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if (*skb == NULL)
- return -ENOMEM;
- return net_recvfrom(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER);
+ return net_recvfrom(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
}
-static int mcast_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return mcast_user_write(fd, (*skb)->data, (*skb)->len,
+ return mcast_user_write(fd, skb->data, skb->len,
(struct mcast_data *) &lp->user);
}
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 @@
#include "um_malloc.h"
#include "user.h"
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
-
static struct sockaddr_in *new_addr(char *addr, unsigned short port)
{
struct sockaddr_in *sin;
@@ -154,18 +152,13 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
-static int mcast_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info mcast_user_info = {
.init = mcast_user_init,
.open = mcast_open,
.close = mcast_close,
.remove = mcast_remove,
- .set_mtu = mcast_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
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)
struct sk_buff *skb;
/* If we can't allocate memory, try again next round. */
- skb = dev_alloc_skb(dev->mtu);
+ skb = dev_alloc_skb(lp->max_packet);
if (skb == NULL) {
lp->stats.rx_dropped++;
return 0;
}
skb->dev = dev;
- skb_put(skb, dev->mtu);
+ skb_put(skb, lp->max_packet);
skb_reset_mac_header(skb);
- pkt_len = (*lp->read)(lp->fd, &skb, lp);
+ pkt_len = (*lp->read)(lp->fd, skb, lp);
if (pkt_len > 0) {
skb_trim(skb, pkt_len);
@@ -178,7 +178,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- len = (*lp->write)(lp->fd, &skb, lp);
+ len = (*lp->write)(lp->fd, skb, lp);
if (len == skb->len) {
lp->stats.tx_packets++;
@@ -240,22 +240,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr)
static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
{
- struct uml_net_private *lp = dev->priv;
- int err = 0;
-
- spin_lock_irq(&lp->lock);
-
- new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
- if (new_mtu < 0) {
- err = new_mtu;
- goto out;
- }
-
dev->mtu = new_mtu;
- out:
- spin_unlock_irq(&lp->lock);
- return err;
+ return 0;
}
static void uml_net_get_drvinfo(struct net_device *dev,
@@ -427,6 +414,7 @@ static void eth_configure(int n, void *init, char *mac,
.dev = dev,
.fd = -1,
.mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
+ .max_packet = transport->user->max_packet,
.protocol = transport->kern->protocol,
.open = transport->user->open,
.close = transport->user->close,
@@ -434,8 +422,7 @@ static void eth_configure(int n, void *init, char *mac,
.read = transport->kern->read,
.write = transport->kern->write,
.add_address = transport->user->add_address,
- .delete_address = transport->user->delete_address,
- .set_mtu = transport->user->set_mtu });
+ .delete_address = transport->user->delete_address });
init_timer(&lp->tl);
spin_lock_init(&lp->lock);
@@ -447,7 +434,7 @@ static void eth_configure(int n, void *init, char *mac,
goto out_unregister;
set_ether_mac(dev, device->mac);
- dev->mtu = transport->user->max_packet;
+ dev->mtu = transport->user->mtu;
dev->open = uml_net_open;
dev->hard_start_xmit = uml_net_start_xmit;
dev->stop = uml_net_close;
@@ -807,19 +794,6 @@ static void close_devices(void)
__uml_exitcall(close_devices);
-struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
-{
- if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
- struct sk_buff *skb2;
-
- skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
- dev_kfree_skb(skb);
- skb = skb2;
- }
- if (skb != NULL) skb_put(skb, extra);
- return skb;
-}
-
void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
void *),
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)
printk("pcap backend, host interface %s\n", ppri->host_if);
}
-static int pcap_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if (*skb == NULL)
- return -ENOMEM;
-
- return pcap_user_read(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER,
+ return pcap_user_read(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER,
(struct pcap_data *) &lp->user);
}
-static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
return -EPERM;
}
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 @@
#include "um_malloc.h"
#include "user.h"
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
-
#define PCAP_FD(p) (*(int *)(p))
static int pcap_user_init(void *data, void *dev)
@@ -23,7 +21,8 @@ static int pcap_user_init(void *data, void *dev)
pcap_t *p;
char errors[PCAP_ERRBUF_SIZE];
- p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
+ p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
+ pri->promisc, 0, errors);
if (p == NULL) {
printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
"'%s'\n", errors);
@@ -133,8 +132,8 @@ const struct net_user_info pcap_user_info = {
.open = pcap_open,
.close = NULL,
.remove = pcap_remove,
- .set_mtu = NULL,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
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)
return htons(ETH_P_IP);
}
-static int slip_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
+ return slip_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
(struct slip_data *) &lp->user);
}
-static int slip_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return slip_user_write(fd, (*skb)->data, (*skb)->len,
+ return slip_user_write(fd, skb->data, skb->len,
(struct slip_data *) &lp->user);
}
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)
return slip_proto_write(fd, buf, len, &pri->slip);
}
-static int slip_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
@@ -260,8 +255,8 @@ const struct net_user_info slip_user_info = {
.open = slip_open,
.close = slip_close,
.remove = NULL,
- .set_mtu = slip_set_mtu,
.add_address = slip_add_addr,
.delete_address = slip_del_addr,
- .max_packet = BUF_SIZE
+ .mtu = BUF_SIZE,
+ .max_packet = BUF_SIZE,
};
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)
return htons(ETH_P_IP);
}
-static int slirp_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
- (struct slirp_data *) &lp->user);
+ return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
+ (struct slirp_data *) &lp->user);
}
-static int slirp_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return slirp_user_write(fd, (*skb)->data, (*skb)->len,
- (struct slirp_data *) &lp->user);
+ return slirp_user_write(fd, skb->data, skb->len,
+ (struct slirp_data *) &lp->user);
}
const 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)
return slip_proto_write(fd, buf, len, &pri->slip);
}
-static int slirp_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info slirp_user_info = {
.init = slirp_user_init,
.open = slirp_open,
.close = slirp_close,
.remove = NULL,
- .set_mtu = slirp_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = BUF_SIZE
+ .mtu = BUF_SIZE,
+ .max_packet = BUF_SIZE,
};
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)
printk("\n");
}
-static int vde_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
struct vde_data *pri = (struct vde_data *) &lp->user;
- if (pri->conn != NULL) {
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if (*skb == NULL)
- return -ENOMEM;
-
- return vde_user_read(pri->conn, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER);
- }
+ if (pri->conn != NULL)
+ return vde_user_read(pri->conn, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
printk(KERN_ERR "vde_read - we have no VDECONN to read from");
return -EBADF;
}
-static int vde_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
struct vde_data *pri = (struct vde_data *) &lp->user;
if (pri->conn != NULL)
- return vde_user_write((void *)pri->conn, (*skb)->data,
- (*skb)->len);
+ return vde_user_write((void *)pri->conn, skb->data,
+ skb->len);
printk(KERN_ERR "vde_write - we have no VDECONN to write to");
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 @@
#include "user.h"
#include "vde.h"
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
-
static int vde_user_init(void *data, void *dev)
{
struct vde_data *pri = data;
@@ -65,20 +63,15 @@ static void vde_remove(void *data)
printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove");
}
-static int vde_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info vde_user_info = {
.init = vde_user_init,
.open = vde_user_open,
.close = NULL,
.remove = vde_remove,
- .set_mtu = vde_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)