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:
parent
cd1ae0e49b
commit
b53f35a809
@ -39,20 +39,15 @@ static void daemon_init(struct net_device *dev, void *data)
|
|||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int daemon_read(int fd, struct sk_buff **skb,
|
static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
struct uml_net_private *lp)
|
|
||||||
{
|
{
|
||||||
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
return net_recvfrom(fd, skb_mac_header(skb),
|
||||||
if (*skb == NULL)
|
skb->dev->mtu + ETH_HEADER_OTHER);
|
||||||
return -ENOMEM;
|
|
||||||
return net_recvfrom(fd, skb_mac_header(*skb),
|
|
||||||
(*skb)->dev->mtu + ETH_HEADER_OTHER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int daemon_write(int fd, struct sk_buff **skb,
|
static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
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);
|
(struct daemon_data *) &lp->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
|
||||||
|
|
||||||
enum request_type { REQ_NEW_CONTROL };
|
enum request_type { REQ_NEW_CONTROL };
|
||||||
|
|
||||||
#define SWITCH_MAGIC 0xfeedface
|
#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));
|
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 = {
|
const struct net_user_info daemon_user_info = {
|
||||||
.init = daemon_user_init,
|
.init = daemon_user_init,
|
||||||
.open = daemon_open,
|
.open = daemon_open,
|
||||||
.close = NULL,
|
.close = NULL,
|
||||||
.remove = daemon_remove,
|
.remove = daemon_remove,
|
||||||
.set_mtu = daemon_set_mtu,
|
|
||||||
.add_address = NULL,
|
.add_address = NULL,
|
||||||
.delete_address = NULL,
|
.delete_address = NULL,
|
||||||
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
|
.mtu = ETH_MAX_PACKET,
|
||||||
|
.max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
|
||||||
};
|
};
|
||||||
|
@ -39,18 +39,15 @@ static void mcast_init(struct net_device *dev, void *data)
|
|||||||
dpri->addr, dpri->port, dpri->ttl);
|
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);
|
return net_recvfrom(fd, skb_mac_header(skb),
|
||||||
if (*skb == NULL)
|
skb->dev->mtu + ETH_HEADER_OTHER);
|
||||||
return -ENOMEM;
|
|
||||||
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);
|
(struct mcast_data *) &lp->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
|
||||||
|
|
||||||
static struct sockaddr_in *new_addr(char *addr, unsigned short port)
|
static struct sockaddr_in *new_addr(char *addr, unsigned short port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sin;
|
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));
|
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 = {
|
const struct net_user_info mcast_user_info = {
|
||||||
.init = mcast_user_init,
|
.init = mcast_user_init,
|
||||||
.open = mcast_open,
|
.open = mcast_open,
|
||||||
.close = mcast_close,
|
.close = mcast_close,
|
||||||
.remove = mcast_remove,
|
.remove = mcast_remove,
|
||||||
.set_mtu = mcast_set_mtu,
|
|
||||||
.add_address = NULL,
|
.add_address = NULL,
|
||||||
.delete_address = NULL,
|
.delete_address = NULL,
|
||||||
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
|
.mtu = ETH_MAX_PACKET,
|
||||||
|
.max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
|
||||||
};
|
};
|
||||||
|
@ -41,16 +41,16 @@ static int uml_net_rx(struct net_device *dev)
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
/* If we can't allocate memory, try again next round. */
|
/* 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) {
|
if (skb == NULL) {
|
||||||
lp->stats.rx_dropped++;
|
lp->stats.rx_dropped++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
skb_put(skb, dev->mtu);
|
skb_put(skb, lp->max_packet);
|
||||||
skb_reset_mac_header(skb);
|
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) {
|
if (pkt_len > 0) {
|
||||||
skb_trim(skb, pkt_len);
|
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);
|
spin_lock_irqsave(&lp->lock, flags);
|
||||||
|
|
||||||
len = (*lp->write)(lp->fd, &skb, lp);
|
len = (*lp->write)(lp->fd, skb, lp);
|
||||||
|
|
||||||
if (len == skb->len) {
|
if (len == skb->len) {
|
||||||
lp->stats.tx_packets++;
|
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)
|
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;
|
dev->mtu = new_mtu;
|
||||||
|
|
||||||
out:
|
return 0;
|
||||||
spin_unlock_irq(&lp->lock);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uml_net_get_drvinfo(struct net_device *dev,
|
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,
|
.dev = dev,
|
||||||
.fd = -1,
|
.fd = -1,
|
||||||
.mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
|
.mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
.max_packet = transport->user->max_packet,
|
||||||
.protocol = transport->kern->protocol,
|
.protocol = transport->kern->protocol,
|
||||||
.open = transport->user->open,
|
.open = transport->user->open,
|
||||||
.close = transport->user->close,
|
.close = transport->user->close,
|
||||||
@ -434,8 +422,7 @@ static void eth_configure(int n, void *init, char *mac,
|
|||||||
.read = transport->kern->read,
|
.read = transport->kern->read,
|
||||||
.write = transport->kern->write,
|
.write = transport->kern->write,
|
||||||
.add_address = transport->user->add_address,
|
.add_address = transport->user->add_address,
|
||||||
.delete_address = transport->user->delete_address,
|
.delete_address = transport->user->delete_address });
|
||||||
.set_mtu = transport->user->set_mtu });
|
|
||||||
|
|
||||||
init_timer(&lp->tl);
|
init_timer(&lp->tl);
|
||||||
spin_lock_init(&lp->lock);
|
spin_lock_init(&lp->lock);
|
||||||
@ -447,7 +434,7 @@ static void eth_configure(int n, void *init, char *mac,
|
|||||||
goto out_unregister;
|
goto out_unregister;
|
||||||
|
|
||||||
set_ether_mac(dev, device->mac);
|
set_ether_mac(dev, device->mac);
|
||||||
dev->mtu = transport->user->max_packet;
|
dev->mtu = transport->user->mtu;
|
||||||
dev->open = uml_net_open;
|
dev->open = uml_net_open;
|
||||||
dev->hard_start_xmit = uml_net_start_xmit;
|
dev->hard_start_xmit = uml_net_start_xmit;
|
||||||
dev->stop = uml_net_close;
|
dev->stop = uml_net_close;
|
||||||
@ -807,19 +794,6 @@ static void close_devices(void)
|
|||||||
|
|
||||||
__uml_exitcall(close_devices);
|
__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 iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
|
||||||
void *),
|
void *),
|
||||||
void *arg)
|
void *arg)
|
||||||
|
@ -31,19 +31,14 @@ void pcap_init(struct net_device *dev, void *data)
|
|||||||
printk("pcap backend, host interface %s\n", ppri->host_if);
|
printk("pcap backend, host interface %s\n", ppri->host_if);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcap_read(int fd, struct sk_buff **skb,
|
static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
struct uml_net_private *lp)
|
|
||||||
{
|
{
|
||||||
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
return pcap_user_read(fd, skb_mac_header(skb),
|
||||||
if (*skb == NULL)
|
skb->dev->mtu + ETH_HEADER_OTHER,
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return pcap_user_read(fd, skb_mac_header(*skb),
|
|
||||||
(*skb)->dev->mtu + ETH_HEADER_OTHER,
|
|
||||||
(struct pcap_data *) &lp->user);
|
(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;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
|
||||||
|
|
||||||
#define PCAP_FD(p) (*(int *)(p))
|
#define PCAP_FD(p) (*(int *)(p))
|
||||||
|
|
||||||
static int pcap_user_init(void *data, void *dev)
|
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;
|
pcap_t *p;
|
||||||
char errors[PCAP_ERRBUF_SIZE];
|
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) {
|
if (p == NULL) {
|
||||||
printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
|
printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
|
||||||
"'%s'\n", errors);
|
"'%s'\n", errors);
|
||||||
@ -133,8 +132,8 @@ const struct net_user_info pcap_user_info = {
|
|||||||
.open = pcap_open,
|
.open = pcap_open,
|
||||||
.close = NULL,
|
.close = NULL,
|
||||||
.remove = pcap_remove,
|
.remove = pcap_remove,
|
||||||
.set_mtu = NULL,
|
|
||||||
.add_address = NULL,
|
.add_address = NULL,
|
||||||
.delete_address = NULL,
|
.delete_address = NULL,
|
||||||
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
|
.mtu = ETH_MAX_PACKET,
|
||||||
|
.max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
|
||||||
};
|
};
|
||||||
|
@ -47,17 +47,15 @@ static unsigned short slip_protocol(struct sk_buff *skbuff)
|
|||||||
return htons(ETH_P_IP);
|
return htons(ETH_P_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slip_read(int fd, struct sk_buff **skb,
|
static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
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);
|
(struct slip_data *) &lp->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slip_write(int fd, struct sk_buff **skb,
|
static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
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);
|
(struct slip_data *) &lp->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
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,
|
static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@ -260,8 +255,8 @@ const struct net_user_info slip_user_info = {
|
|||||||
.open = slip_open,
|
.open = slip_open,
|
||||||
.close = slip_close,
|
.close = slip_close,
|
||||||
.remove = NULL,
|
.remove = NULL,
|
||||||
.set_mtu = slip_set_mtu,
|
|
||||||
.add_address = slip_add_addr,
|
.add_address = slip_add_addr,
|
||||||
.delete_address = slip_del_addr,
|
.delete_address = slip_del_addr,
|
||||||
.max_packet = BUF_SIZE
|
.mtu = BUF_SIZE,
|
||||||
|
.max_packet = BUF_SIZE,
|
||||||
};
|
};
|
||||||
|
@ -52,18 +52,16 @@ static unsigned short slirp_protocol(struct sk_buff *skbuff)
|
|||||||
return htons(ETH_P_IP);
|
return htons(ETH_P_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slirp_read(int fd, struct sk_buff **skb,
|
static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
struct uml_net_private *lp)
|
|
||||||
{
|
{
|
||||||
return slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
|
return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
|
||||||
(struct slirp_data *) &lp->user);
|
(struct slirp_data *) &lp->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slirp_write(int fd, struct sk_buff **skb,
|
static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
struct uml_net_private *lp)
|
|
||||||
{
|
{
|
||||||
return slirp_user_write(fd, (*skb)->data, (*skb)->len,
|
return slirp_user_write(fd, skb->data, skb->len,
|
||||||
(struct slirp_data *) &lp->user);
|
(struct slirp_data *) &lp->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct net_kern_info slirp_kern_info = {
|
const struct net_kern_info slirp_kern_info = {
|
||||||
|
@ -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);
|
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 = {
|
const struct net_user_info slirp_user_info = {
|
||||||
.init = slirp_user_init,
|
.init = slirp_user_init,
|
||||||
.open = slirp_open,
|
.open = slirp_open,
|
||||||
.close = slirp_close,
|
.close = slirp_close,
|
||||||
.remove = NULL,
|
.remove = NULL,
|
||||||
.set_mtu = slirp_set_mtu,
|
|
||||||
.add_address = NULL,
|
.add_address = NULL,
|
||||||
.delete_address = NULL,
|
.delete_address = NULL,
|
||||||
.max_packet = BUF_SIZE
|
.mtu = BUF_SIZE,
|
||||||
|
.max_packet = BUF_SIZE,
|
||||||
};
|
};
|
||||||
|
@ -36,30 +36,25 @@ static void vde_init(struct net_device *dev, void *data)
|
|||||||
printk("\n");
|
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;
|
struct vde_data *pri = (struct vde_data *) &lp->user;
|
||||||
|
|
||||||
if (pri->conn != NULL) {
|
if (pri->conn != NULL)
|
||||||
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
return vde_user_read(pri->conn, skb_mac_header(skb),
|
||||||
if (*skb == NULL)
|
skb->dev->mtu + ETH_HEADER_OTHER);
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
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");
|
printk(KERN_ERR "vde_read - we have no VDECONN to read from");
|
||||||
return -EBADF;
|
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;
|
struct vde_data *pri = (struct vde_data *) &lp->user;
|
||||||
|
|
||||||
if (pri->conn != NULL)
|
if (pri->conn != NULL)
|
||||||
return vde_user_write((void *)pri->conn, (*skb)->data,
|
return vde_user_write((void *)pri->conn, skb->data,
|
||||||
(*skb)->len);
|
skb->len);
|
||||||
|
|
||||||
printk(KERN_ERR "vde_write - we have no VDECONN to write to");
|
printk(KERN_ERR "vde_write - we have no VDECONN to write to");
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "vde.h"
|
#include "vde.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
|
||||||
|
|
||||||
static int vde_user_init(void *data, void *dev)
|
static int vde_user_init(void *data, void *dev)
|
||||||
{
|
{
|
||||||
struct vde_data *pri = data;
|
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");
|
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 = {
|
const struct net_user_info vde_user_info = {
|
||||||
.init = vde_user_init,
|
.init = vde_user_init,
|
||||||
.open = vde_user_open,
|
.open = vde_user_open,
|
||||||
.close = NULL,
|
.close = NULL,
|
||||||
.remove = vde_remove,
|
.remove = vde_remove,
|
||||||
.set_mtu = vde_set_mtu,
|
|
||||||
.add_address = NULL,
|
.add_address = NULL,
|
||||||
.delete_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)
|
void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -30,24 +30,24 @@ struct uml_net_private {
|
|||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
int fd;
|
int fd;
|
||||||
unsigned char mac[ETH_ALEN];
|
unsigned char mac[ETH_ALEN];
|
||||||
|
int max_packet;
|
||||||
unsigned short (*protocol)(struct sk_buff *);
|
unsigned short (*protocol)(struct sk_buff *);
|
||||||
int (*open)(void *);
|
int (*open)(void *);
|
||||||
void (*close)(int, void *);
|
void (*close)(int, void *);
|
||||||
void (*remove)(void *);
|
void (*remove)(void *);
|
||||||
int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
|
int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
|
||||||
int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
|
int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
|
||||||
|
|
||||||
void (*add_address)(unsigned char *, unsigned char *, void *);
|
void (*add_address)(unsigned char *, unsigned char *, void *);
|
||||||
void (*delete_address)(unsigned char *, unsigned char *, void *);
|
void (*delete_address)(unsigned char *, unsigned char *, void *);
|
||||||
int (*set_mtu)(int mtu, void *);
|
|
||||||
char user[0];
|
char user[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct net_kern_info {
|
struct net_kern_info {
|
||||||
void (*init)(struct net_device *, void *);
|
void (*init)(struct net_device *, void *);
|
||||||
unsigned short (*protocol)(struct sk_buff *);
|
unsigned short (*protocol)(struct sk_buff *);
|
||||||
int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
|
int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
|
||||||
int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
|
int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct transport {
|
struct transport {
|
||||||
@ -62,7 +62,6 @@ struct transport {
|
|||||||
|
|
||||||
extern struct net_device *ether_init(int);
|
extern struct net_device *ether_init(int);
|
||||||
extern unsigned short ether_protocol(struct sk_buff *);
|
extern unsigned short ether_protocol(struct sk_buff *);
|
||||||
extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
|
|
||||||
extern int tap_setup_common(char *str, char *type, char **dev_name,
|
extern int tap_setup_common(char *str, char *type, char **dev_name,
|
||||||
char **mac_out, char **gate_addr);
|
char **mac_out, char **gate_addr);
|
||||||
extern void register_transport(struct transport *new);
|
extern void register_transport(struct transport *new);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -18,10 +18,10 @@ struct net_user_info {
|
|||||||
int (*open)(void *);
|
int (*open)(void *);
|
||||||
void (*close)(int, void *);
|
void (*close)(int, void *);
|
||||||
void (*remove)(void *);
|
void (*remove)(void *);
|
||||||
int (*set_mtu)(int mtu, void *);
|
|
||||||
void (*add_address)(unsigned char *, unsigned char *, void *);
|
void (*add_address)(unsigned char *, unsigned char *, void *);
|
||||||
void (*delete_address)(unsigned char *, unsigned char *, void *);
|
void (*delete_address)(unsigned char *, unsigned char *, void *);
|
||||||
int max_packet;
|
int max_packet;
|
||||||
|
int mtu;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void ether_user_init(void *data, void *dev);
|
extern void ether_user_init(void *data, void *dev);
|
||||||
|
@ -36,35 +36,24 @@ static void etap_init(struct net_device *dev, void *data)
|
|||||||
printk("\n");
|
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;
|
int len;
|
||||||
|
|
||||||
*skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
|
len = net_recvfrom(fd, skb_mac_header(skb),
|
||||||
if (*skb == NULL)
|
skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
|
||||||
return -ENOMEM;
|
|
||||||
len = net_recvfrom(fd, skb_mac_header(*skb),
|
|
||||||
(*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return len;
|
return(len);
|
||||||
skb_pull(*skb, 2);
|
|
||||||
|
skb_pull(skb, 2);
|
||||||
len -= 2;
|
len -= 2;
|
||||||
return len;
|
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) {
|
skb_push(skb, 2);
|
||||||
struct sk_buff *skb2;
|
return net_send(fd, skb->data, skb->len);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct net_kern_info ethertap_kern_info = {
|
const struct net_kern_info ethertap_kern_info = {
|
||||||
@ -99,6 +88,7 @@ static struct transport ethertap_transport = {
|
|||||||
.user = ðertap_user_info,
|
.user = ðertap_user_info,
|
||||||
.kern = ðertap_kern_info,
|
.kern = ðertap_kern_info,
|
||||||
.private_size = sizeof(struct ethertap_data),
|
.private_size = sizeof(struct ethertap_data),
|
||||||
|
.setup_size = sizeof(struct ethertap_init),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int register_ethertap(void)
|
static int register_ethertap(void)
|
||||||
|
@ -222,11 +222,6 @@ static void etap_close(int fd, void *data)
|
|||||||
pri->control_fd = -1;
|
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,
|
static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@ -254,8 +249,8 @@ const struct net_user_info ethertap_user_info = {
|
|||||||
.open = etap_open,
|
.open = etap_open,
|
||||||
.close = etap_close,
|
.close = etap_close,
|
||||||
.remove = NULL,
|
.remove = NULL,
|
||||||
.set_mtu = etap_set_mtu,
|
|
||||||
.add_address = etap_add_addr,
|
.add_address = etap_add_addr,
|
||||||
.delete_address = etap_del_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,
|
||||||
};
|
};
|
||||||
|
@ -35,20 +35,15 @@ static void tuntap_init(struct net_device *dev, void *data)
|
|||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tuntap_read(int fd, struct sk_buff **skb,
|
static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
struct uml_net_private *lp)
|
|
||||||
{
|
{
|
||||||
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
return net_read(fd, skb_mac_header(skb),
|
||||||
if (*skb == NULL)
|
skb->dev->mtu + ETH_HEADER_OTHER);
|
||||||
return -ENOMEM;
|
|
||||||
return net_read(fd, skb_mac_header(*skb),
|
|
||||||
(*skb)->dev->mtu + ETH_HEADER_OTHER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tuntap_write(int fd, struct sk_buff **skb,
|
static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||||
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 = {
|
const struct net_kern_info tuntap_kern_info = {
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
#include "tuntap.h"
|
#include "tuntap.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET ETH_MAX_PACKET
|
|
||||||
|
|
||||||
static int tuntap_user_init(void *data, void *dev)
|
static int tuntap_user_init(void *data, void *dev)
|
||||||
{
|
{
|
||||||
struct tuntap_data *pri = data;
|
struct tuntap_data *pri = data;
|
||||||
@ -206,18 +204,13 @@ static void tuntap_close(int fd, void *data)
|
|||||||
pri->fd = -1;
|
pri->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tuntap_set_mtu(int mtu, void *data)
|
|
||||||
{
|
|
||||||
return mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct net_user_info tuntap_user_info = {
|
const struct net_user_info tuntap_user_info = {
|
||||||
.init = tuntap_user_init,
|
.init = tuntap_user_init,
|
||||||
.open = tuntap_open,
|
.open = tuntap_open,
|
||||||
.close = tuntap_close,
|
.close = tuntap_close,
|
||||||
.remove = NULL,
|
.remove = NULL,
|
||||||
.set_mtu = tuntap_set_mtu,
|
|
||||||
.add_address = tuntap_add_addr,
|
.add_address = tuntap_add_addr,
|
||||||
.delete_address = tuntap_del_addr,
|
.delete_address = tuntap_del_addr,
|
||||||
.max_packet = MAX_PACKET
|
.mtu = ETH_MAX_PACKET,
|
||||||
|
.max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user