diff options
| author | Jeff Dike <jdike@addtoit.com> | 2007-10-16 04:27:31 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:08 -0400 |
| commit | b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0a (patch) | |
| tree | 50e19688753650e27b1f7fc1d48eb8683666e6b7 | |
| parent | cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085 (diff) | |
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>
| -rw-r--r-- | arch/um/drivers/daemon_kern.c | 15 | ||||
| -rw-r--r-- | arch/um/drivers/daemon_user.c | 11 | ||||
| -rw-r--r-- | arch/um/drivers/mcast_kern.c | 13 | ||||
| -rw-r--r-- | arch/um/drivers/mcast_user.c | 11 | ||||
| -rw-r--r-- | arch/um/drivers/net_kern.c | 42 | ||||
| -rw-r--r-- | arch/um/drivers/pcap_kern.c | 13 | ||||
| -rw-r--r-- | arch/um/drivers/pcap_user.c | 9 | ||||
| -rw-r--r-- | arch/um/drivers/slip_kern.c | 10 | ||||
| -rw-r--r-- | arch/um/drivers/slip_user.c | 9 | ||||
| -rw-r--r-- | arch/um/drivers/slirp_kern.c | 14 | ||||
| -rw-r--r-- | arch/um/drivers/slirp_user.c | 9 | ||||
| -rw-r--r-- | arch/um/drivers/vde_kern.c | 19 | ||||
| -rw-r--r-- | arch/um/drivers/vde_user.c | 11 | ||||
| -rw-r--r-- | arch/um/include/net_kern.h | 13 | ||||
| -rw-r--r-- | arch/um/include/net_user.h | 4 | ||||
| -rw-r--r-- | arch/um/os-Linux/drivers/ethertap_kern.c | 30 | ||||
| -rw-r--r-- | arch/um/os-Linux/drivers/ethertap_user.c | 9 | ||||
| -rw-r--r-- | arch/um/os-Linux/drivers/tuntap_kern.c | 15 | ||||
| -rw-r--r-- | arch/um/os-Linux/drivers/tuntap_user.c | 11 |
19 files changed, 80 insertions, 188 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) | |||
| 39 | printk("\n"); | 39 | printk("\n"); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static int daemon_read(int fd, struct sk_buff **skb, | 42 | static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 43 | struct uml_net_private *lp) | ||
| 44 | { | 43 | { |
| 45 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | 44 | return net_recvfrom(fd, skb_mac_header(skb), |
| 46 | if (*skb == NULL) | 45 | skb->dev->mtu + ETH_HEADER_OTHER); |
| 47 | return -ENOMEM; | ||
| 48 | return net_recvfrom(fd, skb_mac_header(*skb), | ||
| 49 | (*skb)->dev->mtu + ETH_HEADER_OTHER); | ||
| 50 | } | 46 | } |
| 51 | 47 | ||
| 52 | static int daemon_write(int fd, struct sk_buff **skb, | 48 | static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 53 | struct uml_net_private *lp) | ||
| 54 | { | 49 | { |
| 55 | return daemon_user_write(fd, (*skb)->data, (*skb)->len, | 50 | return daemon_user_write(fd, skb->data, skb->len, |
| 56 | (struct daemon_data *) &lp->user); | 51 | (struct daemon_data *) &lp->user); |
| 57 | } | 52 | } |
| 58 | 53 | ||
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 @@ | |||
| 19 | #include "um_malloc.h" | 19 | #include "um_malloc.h" |
| 20 | #include "user.h" | 20 | #include "user.h" |
| 21 | 21 | ||
| 22 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | ||
| 23 | |||
| 24 | enum request_type { REQ_NEW_CONTROL }; | 22 | enum request_type { REQ_NEW_CONTROL }; |
| 25 | 23 | ||
| 26 | #define SWITCH_MAGIC 0xfeedface | 24 | #define SWITCH_MAGIC 0xfeedface |
| @@ -184,18 +182,13 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) | |||
| 184 | return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); | 182 | return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); |
| 185 | } | 183 | } |
| 186 | 184 | ||
| 187 | static int daemon_set_mtu(int mtu, void *data) | ||
| 188 | { | ||
| 189 | return mtu; | ||
| 190 | } | ||
| 191 | |||
| 192 | const struct net_user_info daemon_user_info = { | 185 | const struct net_user_info daemon_user_info = { |
| 193 | .init = daemon_user_init, | 186 | .init = daemon_user_init, |
| 194 | .open = daemon_open, | 187 | .open = daemon_open, |
| 195 | .close = NULL, | 188 | .close = NULL, |
| 196 | .remove = daemon_remove, | 189 | .remove = daemon_remove, |
| 197 | .set_mtu = daemon_set_mtu, | ||
| 198 | .add_address = NULL, | 190 | .add_address = NULL, |
| 199 | .delete_address = NULL, | 191 | .delete_address = NULL, |
| 200 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | 192 | .mtu = ETH_MAX_PACKET, |
| 193 | .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, | ||
| 201 | }; | 194 | }; |
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) | |||
| 39 | dpri->addr, dpri->port, dpri->ttl); | 39 | dpri->addr, dpri->port, dpri->ttl); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 42 | static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 43 | { | 43 | { |
| 44 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | 44 | return net_recvfrom(fd, skb_mac_header(skb), |
| 45 | if (*skb == NULL) | 45 | skb->dev->mtu + ETH_HEADER_OTHER); |
| 46 | return -ENOMEM; | ||
| 47 | return net_recvfrom(fd, skb_mac_header(*skb), | ||
| 48 | (*skb)->dev->mtu + ETH_HEADER_OTHER); | ||
| 49 | } | 46 | } |
| 50 | 47 | ||
| 51 | static int mcast_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 48 | static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 52 | { | 49 | { |
| 53 | return mcast_user_write(fd, (*skb)->data, (*skb)->len, | 50 | return mcast_user_write(fd, skb->data, skb->len, |
| 54 | (struct mcast_data *) &lp->user); | 51 | (struct mcast_data *) &lp->user); |
| 55 | } | 52 | } |
| 56 | 53 | ||
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 @@ | |||
| 20 | #include "um_malloc.h" | 20 | #include "um_malloc.h" |
| 21 | #include "user.h" | 21 | #include "user.h" |
| 22 | 22 | ||
| 23 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | ||
| 24 | |||
| 25 | static struct sockaddr_in *new_addr(char *addr, unsigned short port) | 23 | static struct sockaddr_in *new_addr(char *addr, unsigned short port) |
| 26 | { | 24 | { |
| 27 | struct sockaddr_in *sin; | 25 | struct sockaddr_in *sin; |
| @@ -154,18 +152,13 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) | |||
| 154 | return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); | 152 | return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); |
| 155 | } | 153 | } |
| 156 | 154 | ||
| 157 | static int mcast_set_mtu(int mtu, void *data) | ||
| 158 | { | ||
| 159 | return mtu; | ||
| 160 | } | ||
| 161 | |||
| 162 | const struct net_user_info mcast_user_info = { | 155 | const struct net_user_info mcast_user_info = { |
| 163 | .init = mcast_user_init, | 156 | .init = mcast_user_init, |
| 164 | .open = mcast_open, | 157 | .open = mcast_open, |
| 165 | .close = mcast_close, | 158 | .close = mcast_close, |
| 166 | .remove = mcast_remove, | 159 | .remove = mcast_remove, |
| 167 | .set_mtu = mcast_set_mtu, | ||
| 168 | .add_address = NULL, | 160 | .add_address = NULL, |
| 169 | .delete_address = NULL, | 161 | .delete_address = NULL, |
| 170 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | 162 | .mtu = ETH_MAX_PACKET, |
| 163 | .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, | ||
| 171 | }; | 164 | }; |
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) | |||
| 41 | struct sk_buff *skb; | 41 | struct sk_buff *skb; |
| 42 | 42 | ||
| 43 | /* If we can't allocate memory, try again next round. */ | 43 | /* If we can't allocate memory, try again next round. */ |
| 44 | skb = dev_alloc_skb(dev->mtu); | 44 | skb = dev_alloc_skb(lp->max_packet); |
| 45 | if (skb == NULL) { | 45 | if (skb == NULL) { |
| 46 | lp->stats.rx_dropped++; | 46 | lp->stats.rx_dropped++; |
| 47 | return 0; | 47 | return 0; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | skb->dev = dev; | 50 | skb->dev = dev; |
| 51 | skb_put(skb, dev->mtu); | 51 | skb_put(skb, lp->max_packet); |
| 52 | skb_reset_mac_header(skb); | 52 | skb_reset_mac_header(skb); |
| 53 | pkt_len = (*lp->read)(lp->fd, &skb, lp); | 53 | pkt_len = (*lp->read)(lp->fd, skb, lp); |
| 54 | 54 | ||
| 55 | if (pkt_len > 0) { | 55 | if (pkt_len > 0) { |
| 56 | skb_trim(skb, pkt_len); | 56 | skb_trim(skb, pkt_len); |
| @@ -178,7 +178,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 178 | 178 | ||
| 179 | spin_lock_irqsave(&lp->lock, flags); | 179 | spin_lock_irqsave(&lp->lock, flags); |
| 180 | 180 | ||
| 181 | len = (*lp->write)(lp->fd, &skb, lp); | 181 | len = (*lp->write)(lp->fd, skb, lp); |
| 182 | 182 | ||
| 183 | if (len == skb->len) { | 183 | if (len == skb->len) { |
| 184 | lp->stats.tx_packets++; | 184 | lp->stats.tx_packets++; |
| @@ -240,22 +240,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr) | |||
| 240 | 240 | ||
| 241 | static int uml_net_change_mtu(struct net_device *dev, int new_mtu) | 241 | static int uml_net_change_mtu(struct net_device *dev, int new_mtu) |
| 242 | { | 242 | { |
| 243 | struct uml_net_private *lp = dev->priv; | ||
| 244 | int err = 0; | ||
| 245 | |||
| 246 | spin_lock_irq(&lp->lock); | ||
| 247 | |||
| 248 | new_mtu = (*lp->set_mtu)(new_mtu, &lp->user); | ||
| 249 | if (new_mtu < 0) { | ||
| 250 | err = new_mtu; | ||
| 251 | goto out; | ||
| 252 | } | ||
| 253 | |||
| 254 | dev->mtu = new_mtu; | 243 | dev->mtu = new_mtu; |
| 255 | 244 | ||
| 256 | out: | 245 | return 0; |
| 257 | spin_unlock_irq(&lp->lock); | ||
| 258 | return err; | ||
| 259 | } | 246 | } |
| 260 | 247 | ||
| 261 | static void uml_net_get_drvinfo(struct net_device *dev, | 248 | static void uml_net_get_drvinfo(struct net_device *dev, |
| @@ -427,6 +414,7 @@ static void eth_configure(int n, void *init, char *mac, | |||
| 427 | .dev = dev, | 414 | .dev = dev, |
| 428 | .fd = -1, | 415 | .fd = -1, |
| 429 | .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, | 416 | .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, |
| 417 | .max_packet = transport->user->max_packet, | ||
| 430 | .protocol = transport->kern->protocol, | 418 | .protocol = transport->kern->protocol, |
| 431 | .open = transport->user->open, | 419 | .open = transport->user->open, |
| 432 | .close = transport->user->close, | 420 | .close = transport->user->close, |
| @@ -434,8 +422,7 @@ static void eth_configure(int n, void *init, char *mac, | |||
| 434 | .read = transport->kern->read, | 422 | .read = transport->kern->read, |
| 435 | .write = transport->kern->write, | 423 | .write = transport->kern->write, |
| 436 | .add_address = transport->user->add_address, | 424 | .add_address = transport->user->add_address, |
| 437 | .delete_address = transport->user->delete_address, | 425 | .delete_address = transport->user->delete_address }); |
| 438 | .set_mtu = transport->user->set_mtu }); | ||
| 439 | 426 | ||
| 440 | init_timer(&lp->tl); | 427 | init_timer(&lp->tl); |
| 441 | spin_lock_init(&lp->lock); | 428 | spin_lock_init(&lp->lock); |
| @@ -447,7 +434,7 @@ static void eth_configure(int n, void *init, char *mac, | |||
| 447 | goto out_unregister; | 434 | goto out_unregister; |
| 448 | 435 | ||
| 449 | set_ether_mac(dev, device->mac); | 436 | set_ether_mac(dev, device->mac); |
| 450 | dev->mtu = transport->user->max_packet; | 437 | dev->mtu = transport->user->mtu; |
| 451 | dev->open = uml_net_open; | 438 | dev->open = uml_net_open; |
| 452 | dev->hard_start_xmit = uml_net_start_xmit; | 439 | dev->hard_start_xmit = uml_net_start_xmit; |
| 453 | dev->stop = uml_net_close; | 440 | dev->stop = uml_net_close; |
| @@ -807,19 +794,6 @@ static void close_devices(void) | |||
| 807 | 794 | ||
| 808 | __uml_exitcall(close_devices); | 795 | __uml_exitcall(close_devices); |
| 809 | 796 | ||
| 810 | struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) | ||
| 811 | { | ||
| 812 | if ((skb != NULL) && (skb_tailroom(skb) < extra)) { | ||
| 813 | struct sk_buff *skb2; | ||
| 814 | |||
| 815 | skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC); | ||
| 816 | dev_kfree_skb(skb); | ||
| 817 | skb = skb2; | ||
| 818 | } | ||
| 819 | if (skb != NULL) skb_put(skb, extra); | ||
| 820 | return skb; | ||
| 821 | } | ||
| 822 | |||
| 823 | void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, | 797 | void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, |
| 824 | void *), | 798 | void *), |
| 825 | void *arg) | 799 | 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) | |||
| 31 | printk("pcap backend, host interface %s\n", ppri->host_if); | 31 | printk("pcap backend, host interface %s\n", ppri->host_if); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | static int pcap_read(int fd, struct sk_buff **skb, | 34 | static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 35 | struct uml_net_private *lp) | ||
| 36 | { | 35 | { |
| 37 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | 36 | return pcap_user_read(fd, skb_mac_header(skb), |
| 38 | if (*skb == NULL) | 37 | skb->dev->mtu + ETH_HEADER_OTHER, |
| 39 | return -ENOMEM; | ||
| 40 | |||
| 41 | return pcap_user_read(fd, skb_mac_header(*skb), | ||
| 42 | (*skb)->dev->mtu + ETH_HEADER_OTHER, | ||
| 43 | (struct pcap_data *) &lp->user); | 38 | (struct pcap_data *) &lp->user); |
| 44 | } | 39 | } |
| 45 | 40 | ||
| 46 | static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 41 | static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 47 | { | 42 | { |
| 48 | return -EPERM; | 43 | return -EPERM; |
| 49 | } | 44 | } |
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 @@ | |||
| 13 | #include "um_malloc.h" | 13 | #include "um_malloc.h" |
| 14 | #include "user.h" | 14 | #include "user.h" |
| 15 | 15 | ||
| 16 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | ||
| 17 | |||
| 18 | #define PCAP_FD(p) (*(int *)(p)) | 16 | #define PCAP_FD(p) (*(int *)(p)) |
| 19 | 17 | ||
| 20 | static int pcap_user_init(void *data, void *dev) | 18 | static int pcap_user_init(void *data, void *dev) |
| @@ -23,7 +21,8 @@ static int pcap_user_init(void *data, void *dev) | |||
| 23 | pcap_t *p; | 21 | pcap_t *p; |
| 24 | char errors[PCAP_ERRBUF_SIZE]; | 22 | char errors[PCAP_ERRBUF_SIZE]; |
| 25 | 23 | ||
| 26 | p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); | 24 | p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER, |
| 25 | pri->promisc, 0, errors); | ||
| 27 | if (p == NULL) { | 26 | if (p == NULL) { |
| 28 | printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - " | 27 | printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - " |
| 29 | "'%s'\n", errors); | 28 | "'%s'\n", errors); |
| @@ -133,8 +132,8 @@ const struct net_user_info pcap_user_info = { | |||
| 133 | .open = pcap_open, | 132 | .open = pcap_open, |
| 134 | .close = NULL, | 133 | .close = NULL, |
| 135 | .remove = pcap_remove, | 134 | .remove = pcap_remove, |
| 136 | .set_mtu = NULL, | ||
| 137 | .add_address = NULL, | 135 | .add_address = NULL, |
| 138 | .delete_address = NULL, | 136 | .delete_address = NULL, |
| 139 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | 137 | .mtu = ETH_MAX_PACKET, |
| 138 | .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, | ||
| 140 | }; | 139 | }; |
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) | |||
| 47 | return htons(ETH_P_IP); | 47 | return htons(ETH_P_IP); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static int slip_read(int fd, struct sk_buff **skb, | 50 | static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 51 | struct uml_net_private *lp) | ||
| 52 | { | 51 | { |
| 53 | return slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, | 52 | return slip_user_read(fd, skb_mac_header(skb), skb->dev->mtu, |
| 54 | (struct slip_data *) &lp->user); | 53 | (struct slip_data *) &lp->user); |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | static int slip_write(int fd, struct sk_buff **skb, | 56 | static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 58 | struct uml_net_private *lp) | ||
| 59 | { | 57 | { |
| 60 | return slip_user_write(fd, (*skb)->data, (*skb)->len, | 58 | return slip_user_write(fd, skb->data, skb->len, |
| 61 | (struct slip_data *) &lp->user); | 59 | (struct slip_data *) &lp->user); |
| 62 | } | 60 | } |
| 63 | 61 | ||
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) | |||
| 230 | return slip_proto_write(fd, buf, len, &pri->slip); | 230 | return slip_proto_write(fd, buf, len, &pri->slip); |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | static int slip_set_mtu(int mtu, void *data) | ||
| 234 | { | ||
| 235 | return mtu; | ||
| 236 | } | ||
| 237 | |||
| 238 | static void slip_add_addr(unsigned char *addr, unsigned char *netmask, | 233 | static void slip_add_addr(unsigned char *addr, unsigned char *netmask, |
| 239 | void *data) | 234 | void *data) |
| 240 | { | 235 | { |
| @@ -260,8 +255,8 @@ const struct net_user_info slip_user_info = { | |||
| 260 | .open = slip_open, | 255 | .open = slip_open, |
| 261 | .close = slip_close, | 256 | .close = slip_close, |
| 262 | .remove = NULL, | 257 | .remove = NULL, |
| 263 | .set_mtu = slip_set_mtu, | ||
| 264 | .add_address = slip_add_addr, | 258 | .add_address = slip_add_addr, |
| 265 | .delete_address = slip_del_addr, | 259 | .delete_address = slip_del_addr, |
| 266 | .max_packet = BUF_SIZE | 260 | .mtu = BUF_SIZE, |
| 261 | .max_packet = BUF_SIZE, | ||
| 267 | }; | 262 | }; |
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) | |||
| 52 | return htons(ETH_P_IP); | 52 | return htons(ETH_P_IP); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static int slirp_read(int fd, struct sk_buff **skb, | 55 | static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 56 | struct uml_net_private *lp) | ||
| 57 | { | 56 | { |
| 58 | return slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, | 57 | return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu, |
| 59 | (struct slirp_data *) &lp->user); | 58 | (struct slirp_data *) &lp->user); |
| 60 | } | 59 | } |
| 61 | 60 | ||
| 62 | static int slirp_write(int fd, struct sk_buff **skb, | 61 | static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 63 | struct uml_net_private *lp) | ||
| 64 | { | 62 | { |
| 65 | return slirp_user_write(fd, (*skb)->data, (*skb)->len, | 63 | return slirp_user_write(fd, skb->data, skb->len, |
| 66 | (struct slirp_data *) &lp->user); | 64 | (struct slirp_data *) &lp->user); |
| 67 | } | 65 | } |
| 68 | 66 | ||
| 69 | const struct net_kern_info slirp_kern_info = { | 67 | 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) | |||
| 124 | return slip_proto_write(fd, buf, len, &pri->slip); | 124 | return slip_proto_write(fd, buf, len, &pri->slip); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static int slirp_set_mtu(int mtu, void *data) | ||
| 128 | { | ||
| 129 | return mtu; | ||
| 130 | } | ||
| 131 | |||
| 132 | const struct net_user_info slirp_user_info = { | 127 | const struct net_user_info slirp_user_info = { |
| 133 | .init = slirp_user_init, | 128 | .init = slirp_user_init, |
| 134 | .open = slirp_open, | 129 | .open = slirp_open, |
| 135 | .close = slirp_close, | 130 | .close = slirp_close, |
| 136 | .remove = NULL, | 131 | .remove = NULL, |
| 137 | .set_mtu = slirp_set_mtu, | ||
| 138 | .add_address = NULL, | 132 | .add_address = NULL, |
| 139 | .delete_address = NULL, | 133 | .delete_address = NULL, |
| 140 | .max_packet = BUF_SIZE | 134 | .mtu = BUF_SIZE, |
| 135 | .max_packet = BUF_SIZE, | ||
| 141 | }; | 136 | }; |
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) | |||
| 36 | printk("\n"); | 36 | printk("\n"); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static int vde_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 39 | static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 40 | { | 40 | { |
| 41 | struct vde_data *pri = (struct vde_data *) &lp->user; | 41 | struct vde_data *pri = (struct vde_data *) &lp->user; |
| 42 | 42 | ||
| 43 | if (pri->conn != NULL) { | 43 | if (pri->conn != NULL) |
| 44 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | 44 | return vde_user_read(pri->conn, skb_mac_header(skb), |
| 45 | if (*skb == NULL) | 45 | skb->dev->mtu + ETH_HEADER_OTHER); |
| 46 | return -ENOMEM; | ||
| 47 | |||
| 48 | return vde_user_read(pri->conn, skb_mac_header(*skb), | ||
| 49 | (*skb)->dev->mtu + ETH_HEADER_OTHER); | ||
| 50 | } | ||
| 51 | 46 | ||
| 52 | printk(KERN_ERR "vde_read - we have no VDECONN to read from"); | 47 | printk(KERN_ERR "vde_read - we have no VDECONN to read from"); |
| 53 | return -EBADF; | 48 | return -EBADF; |
| 54 | } | 49 | } |
| 55 | 50 | ||
| 56 | static int vde_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 51 | static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 57 | { | 52 | { |
| 58 | struct vde_data *pri = (struct vde_data *) &lp->user; | 53 | struct vde_data *pri = (struct vde_data *) &lp->user; |
| 59 | 54 | ||
| 60 | if (pri->conn != NULL) | 55 | if (pri->conn != NULL) |
| 61 | return vde_user_write((void *)pri->conn, (*skb)->data, | 56 | return vde_user_write((void *)pri->conn, skb->data, |
| 62 | (*skb)->len); | 57 | skb->len); |
| 63 | 58 | ||
| 64 | printk(KERN_ERR "vde_write - we have no VDECONN to write to"); | 59 | printk(KERN_ERR "vde_write - we have no VDECONN to write to"); |
| 65 | return -EBADF; | 60 | 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 @@ | |||
| 12 | #include "user.h" | 12 | #include "user.h" |
| 13 | #include "vde.h" | 13 | #include "vde.h" |
| 14 | 14 | ||
| 15 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | ||
| 16 | |||
| 17 | static int vde_user_init(void *data, void *dev) | 15 | static int vde_user_init(void *data, void *dev) |
| 18 | { | 16 | { |
| 19 | struct vde_data *pri = data; | 17 | struct vde_data *pri = data; |
| @@ -65,20 +63,15 @@ static void vde_remove(void *data) | |||
| 65 | printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove"); | 63 | printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove"); |
| 66 | } | 64 | } |
| 67 | 65 | ||
| 68 | static int vde_set_mtu(int mtu, void *data) | ||
| 69 | { | ||
| 70 | return mtu; | ||
| 71 | } | ||
| 72 | |||
| 73 | const struct net_user_info vde_user_info = { | 66 | const struct net_user_info vde_user_info = { |
| 74 | .init = vde_user_init, | 67 | .init = vde_user_init, |
| 75 | .open = vde_user_open, | 68 | .open = vde_user_open, |
| 76 | .close = NULL, | 69 | .close = NULL, |
| 77 | .remove = vde_remove, | 70 | .remove = vde_remove, |
| 78 | .set_mtu = vde_set_mtu, | ||
| 79 | .add_address = NULL, | 71 | .add_address = NULL, |
| 80 | .delete_address = NULL, | 72 | .delete_address = NULL, |
| 81 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | 73 | .mtu = ETH_MAX_PACKET, |
| 74 | .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, | ||
| 82 | }; | 75 | }; |
| 83 | 76 | ||
| 84 | void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) | 77 | void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) |
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h index 9237056b9103..d843c7924a7c 100644 --- a/arch/um/include/net_kern.h +++ b/arch/um/include/net_kern.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
| 3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| @@ -30,24 +30,24 @@ struct uml_net_private { | |||
| 30 | struct work_struct work; | 30 | struct work_struct work; |
| 31 | int fd; | 31 | int fd; |
| 32 | unsigned char mac[ETH_ALEN]; | 32 | unsigned char mac[ETH_ALEN]; |
| 33 | int max_packet; | ||
| 33 | unsigned short (*protocol)(struct sk_buff *); | 34 | unsigned short (*protocol)(struct sk_buff *); |
| 34 | int (*open)(void *); | 35 | int (*open)(void *); |
| 35 | void (*close)(int, void *); | 36 | void (*close)(int, void *); |
| 36 | void (*remove)(void *); | 37 | void (*remove)(void *); |
| 37 | int (*read)(int, struct sk_buff **skb, struct uml_net_private *); | 38 | int (*read)(int, struct sk_buff *skb, struct uml_net_private *); |
| 38 | int (*write)(int, struct sk_buff **skb, struct uml_net_private *); | 39 | int (*write)(int, struct sk_buff *skb, struct uml_net_private *); |
| 39 | 40 | ||
| 40 | void (*add_address)(unsigned char *, unsigned char *, void *); | 41 | void (*add_address)(unsigned char *, unsigned char *, void *); |
| 41 | void (*delete_address)(unsigned char *, unsigned char *, void *); | 42 | void (*delete_address)(unsigned char *, unsigned char *, void *); |
| 42 | int (*set_mtu)(int mtu, void *); | ||
| 43 | char user[0]; | 43 | char user[0]; |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | struct net_kern_info { | 46 | struct net_kern_info { |
| 47 | void (*init)(struct net_device *, void *); | 47 | void (*init)(struct net_device *, void *); |
| 48 | unsigned short (*protocol)(struct sk_buff *); | 48 | unsigned short (*protocol)(struct sk_buff *); |
| 49 | int (*read)(int, struct sk_buff **skb, struct uml_net_private *); | 49 | int (*read)(int, struct sk_buff *skb, struct uml_net_private *); |
| 50 | int (*write)(int, struct sk_buff **skb, struct uml_net_private *); | 50 | int (*write)(int, struct sk_buff *skb, struct uml_net_private *); |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | struct transport { | 53 | struct transport { |
| @@ -62,7 +62,6 @@ struct transport { | |||
| 62 | 62 | ||
| 63 | extern struct net_device *ether_init(int); | 63 | extern struct net_device *ether_init(int); |
| 64 | extern unsigned short ether_protocol(struct sk_buff *); | 64 | extern unsigned short ether_protocol(struct sk_buff *); |
| 65 | extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); | ||
| 66 | extern int tap_setup_common(char *str, char *type, char **dev_name, | 65 | extern int tap_setup_common(char *str, char *type, char **dev_name, |
| 67 | char **mac_out, char **gate_addr); | 66 | char **mac_out, char **gate_addr); |
| 68 | extern void register_transport(struct transport *new); | 67 | extern void register_transport(struct transport *new); |
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index cfe7c50634b9..63bee158cd8e 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
| 3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| @@ -18,10 +18,10 @@ struct net_user_info { | |||
| 18 | int (*open)(void *); | 18 | int (*open)(void *); |
| 19 | void (*close)(int, void *); | 19 | void (*close)(int, void *); |
| 20 | void (*remove)(void *); | 20 | void (*remove)(void *); |
| 21 | int (*set_mtu)(int mtu, void *); | ||
| 22 | void (*add_address)(unsigned char *, unsigned char *, void *); | 21 | void (*add_address)(unsigned char *, unsigned char *, void *); |
| 23 | void (*delete_address)(unsigned char *, unsigned char *, void *); | 22 | void (*delete_address)(unsigned char *, unsigned char *, void *); |
| 24 | int max_packet; | 23 | int max_packet; |
| 24 | int mtu; | ||
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | extern void ether_user_init(void *data, void *dev); | 27 | extern void ether_user_init(void *data, void *dev); |
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) | |||
| 36 | printk("\n"); | 36 | printk("\n"); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 39 | static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 40 | { | 40 | { |
| 41 | int len; | 41 | int len; |
| 42 | 42 | ||
| 43 | *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); | 43 | len = net_recvfrom(fd, skb_mac_header(skb), |
| 44 | if (*skb == NULL) | 44 | skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP); |
| 45 | return -ENOMEM; | ||
| 46 | len = net_recvfrom(fd, skb_mac_header(*skb), | ||
| 47 | (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); | ||
| 48 | if (len <= 0) | 45 | if (len <= 0) |
| 49 | return len; | 46 | return(len); |
| 50 | skb_pull(*skb, 2); | 47 | |
| 48 | skb_pull(skb, 2); | ||
| 51 | len -= 2; | 49 | len -= 2; |
| 52 | return len; | 50 | return len; |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) | 53 | static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 56 | { | 54 | { |
| 57 | if (skb_headroom(*skb) < 2) { | 55 | skb_push(skb, 2); |
| 58 | struct sk_buff *skb2; | 56 | return net_send(fd, skb->data, skb->len); |
| 59 | |||
| 60 | skb2 = skb_realloc_headroom(*skb, 2); | ||
| 61 | dev_kfree_skb(*skb); | ||
| 62 | if (skb2 == NULL) | ||
| 63 | return -ENOMEM; | ||
| 64 | *skb = skb2; | ||
| 65 | } | ||
| 66 | skb_push(*skb, 2); | ||
| 67 | return net_send(fd, (*skb)->data, (*skb)->len); | ||
| 68 | } | 57 | } |
| 69 | 58 | ||
| 70 | const struct net_kern_info ethertap_kern_info = { | 59 | const struct net_kern_info ethertap_kern_info = { |
| @@ -99,6 +88,7 @@ static struct transport ethertap_transport = { | |||
| 99 | .user = ðertap_user_info, | 88 | .user = ðertap_user_info, |
| 100 | .kern = ðertap_kern_info, | 89 | .kern = ðertap_kern_info, |
| 101 | .private_size = sizeof(struct ethertap_data), | 90 | .private_size = sizeof(struct ethertap_data), |
| 91 | .setup_size = sizeof(struct ethertap_init), | ||
| 102 | }; | 92 | }; |
| 103 | 93 | ||
| 104 | static int register_ethertap(void) | 94 | 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) | |||
| 222 | pri->control_fd = -1; | 222 | pri->control_fd = -1; |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | static int etap_set_mtu(int mtu, void *data) | ||
| 226 | { | ||
| 227 | return mtu; | ||
| 228 | } | ||
| 229 | |||
| 230 | static void etap_add_addr(unsigned char *addr, unsigned char *netmask, | 225 | static void etap_add_addr(unsigned char *addr, unsigned char *netmask, |
| 231 | void *data) | 226 | void *data) |
| 232 | { | 227 | { |
| @@ -254,8 +249,8 @@ const struct net_user_info ethertap_user_info = { | |||
| 254 | .open = etap_open, | 249 | .open = etap_open, |
| 255 | .close = etap_close, | 250 | .close = etap_close, |
| 256 | .remove = NULL, | 251 | .remove = NULL, |
| 257 | .set_mtu = etap_set_mtu, | ||
| 258 | .add_address = etap_add_addr, | 252 | .add_address = etap_add_addr, |
| 259 | .delete_address = etap_del_addr, | 253 | .delete_address = etap_del_addr, |
| 260 | .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP | 254 | .mtu = ETH_MAX_PACKET, |
| 255 | .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP, | ||
| 261 | }; | 256 | }; |
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) | |||
| 35 | printk("\n"); | 35 | printk("\n"); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | static int tuntap_read(int fd, struct sk_buff **skb, | 38 | static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 39 | struct uml_net_private *lp) | ||
| 40 | { | 39 | { |
| 41 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | 40 | return net_read(fd, skb_mac_header(skb), |
| 42 | if (*skb == NULL) | 41 | skb->dev->mtu + ETH_HEADER_OTHER); |
| 43 | return -ENOMEM; | ||
| 44 | return net_read(fd, skb_mac_header(*skb), | ||
| 45 | (*skb)->dev->mtu + ETH_HEADER_OTHER); | ||
| 46 | } | 42 | } |
| 47 | 43 | ||
| 48 | static int tuntap_write(int fd, struct sk_buff **skb, | 44 | static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) |
| 49 | struct uml_net_private *lp) | ||
| 50 | { | 45 | { |
| 51 | return net_write(fd, (*skb)->data, (*skb)->len); | 46 | return net_write(fd, skb->data, skb->len); |
| 52 | } | 47 | } |
| 53 | 48 | ||
| 54 | const struct net_kern_info tuntap_kern_info = { | 49 | 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 @@ | |||
| 18 | #include "tuntap.h" | 18 | #include "tuntap.h" |
| 19 | #include "user.h" | 19 | #include "user.h" |
| 20 | 20 | ||
| 21 | #define MAX_PACKET ETH_MAX_PACKET | ||
| 22 | |||
| 23 | static int tuntap_user_init(void *data, void *dev) | 21 | static int tuntap_user_init(void *data, void *dev) |
| 24 | { | 22 | { |
| 25 | struct tuntap_data *pri = data; | 23 | struct tuntap_data *pri = data; |
| @@ -206,18 +204,13 @@ static void tuntap_close(int fd, void *data) | |||
| 206 | pri->fd = -1; | 204 | pri->fd = -1; |
| 207 | } | 205 | } |
| 208 | 206 | ||
| 209 | static int tuntap_set_mtu(int mtu, void *data) | ||
| 210 | { | ||
| 211 | return mtu; | ||
| 212 | } | ||
| 213 | |||
| 214 | const struct net_user_info tuntap_user_info = { | 207 | const struct net_user_info tuntap_user_info = { |
| 215 | .init = tuntap_user_init, | 208 | .init = tuntap_user_init, |
| 216 | .open = tuntap_open, | 209 | .open = tuntap_open, |
| 217 | .close = tuntap_close, | 210 | .close = tuntap_close, |
| 218 | .remove = NULL, | 211 | .remove = NULL, |
| 219 | .set_mtu = tuntap_set_mtu, | ||
| 220 | .add_address = tuntap_add_addr, | 212 | .add_address = tuntap_add_addr, |
| 221 | .delete_address = tuntap_del_addr, | 213 | .delete_address = tuntap_del_addr, |
| 222 | .max_packet = MAX_PACKET | 214 | .mtu = ETH_MAX_PACKET, |
| 215 | .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER, | ||
| 223 | }; | 216 | }; |
