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>
This commit is contained in:
Jeff Dike
2007-10-16 01:27:31 -07:00
committed by Linus Torvalds
parent cd1ae0e49b
commit b53f35a809
19 changed files with 80 additions and 188 deletions

View File

@@ -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)