Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b53f35a8 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

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: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent cd1ae0e4
Loading
Loading
Loading
Loading
+5 −10
Original line number Diff line number Diff line
@@ -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);
}

+2 −9
Original line number Diff line number Diff line
@@ -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,
};
+5 −8
Original line number Diff line number Diff line
@@ -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);
}

+2 −9
Original line number Diff line number Diff line
@@ -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,
};
+8 −34
Original line number Diff line number Diff line
@@ -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)
Loading