From b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0a Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Tue, 16 Oct 2007 01:27:31 -0700 Subject: 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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/drivers/ethertap_kern.c | 30 ++++++++++-------------------- arch/um/os-Linux/drivers/ethertap_user.c | 9 ++------- arch/um/os-Linux/drivers/tuntap_kern.c | 15 +++++---------- arch/um/os-Linux/drivers/tuntap_user.c | 11 ++--------- 4 files changed, 19 insertions(+), 46 deletions(-) (limited to 'arch/um/os-Linux/drivers') 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) printk("\n"); } -static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) +static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) { int len; - *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); - if (*skb == NULL) - return -ENOMEM; - len = net_recvfrom(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); + len = net_recvfrom(fd, skb_mac_header(skb), + skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP); if (len <= 0) - return len; - skb_pull(*skb, 2); + return(len); + + skb_pull(skb, 2); len -= 2; return len; } -static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) +static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - if (skb_headroom(*skb) < 2) { - struct sk_buff *skb2; - - skb2 = skb_realloc_headroom(*skb, 2); - dev_kfree_skb(*skb); - if (skb2 == NULL) - return -ENOMEM; - *skb = skb2; - } - skb_push(*skb, 2); - return net_send(fd, (*skb)->data, (*skb)->len); + skb_push(skb, 2); + return net_send(fd, skb->data, skb->len); } const struct net_kern_info ethertap_kern_info = { @@ -99,6 +88,7 @@ static struct transport ethertap_transport = { .user = ðertap_user_info, .kern = ðertap_kern_info, .private_size = sizeof(struct ethertap_data), + .setup_size = sizeof(struct ethertap_init), }; static 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) pri->control_fd = -1; } -static int etap_set_mtu(int mtu, void *data) -{ - return mtu; -} - static void etap_add_addr(unsigned char *addr, unsigned char *netmask, void *data) { @@ -254,8 +249,8 @@ const struct net_user_info ethertap_user_info = { .open = etap_open, .close = etap_close, .remove = NULL, - .set_mtu = etap_set_mtu, .add_address = etap_add_addr, .delete_address = etap_del_addr, - .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP, }; 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) printk("\n"); } -static int tuntap_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int tuntap_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_read(fd, skb_mac_header(*skb), - (*skb)->dev->mtu + ETH_HEADER_OTHER); + return net_read(fd, skb_mac_header(skb), + skb->dev->mtu + ETH_HEADER_OTHER); } -static int tuntap_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) +static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) { - return net_write(fd, (*skb)->data, (*skb)->len); + return net_write(fd, skb->data, skb->len); } const 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 @@ #include "tuntap.h" #include "user.h" -#define MAX_PACKET ETH_MAX_PACKET - static int tuntap_user_init(void *data, void *dev) { struct tuntap_data *pri = data; @@ -206,18 +204,13 @@ static void tuntap_close(int fd, void *data) pri->fd = -1; } -static int tuntap_set_mtu(int mtu, void *data) -{ - return mtu; -} - const struct net_user_info tuntap_user_info = { .init = tuntap_user_init, .open = tuntap_open, .close = tuntap_close, .remove = NULL, - .set_mtu = tuntap_set_mtu, .add_address = tuntap_add_addr, .delete_address = tuntap_del_addr, - .max_packet = MAX_PACKET + .mtu = ETH_MAX_PACKET, + .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, }; -- cgit v1.2.3