aboutsummaryrefslogtreecommitdiff
path: root/arch/um/os-Linux/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/drivers')
-rw-r--r--arch/um/os-Linux/drivers/etap.h20
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c79
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c191
-rw-r--r--arch/um/os-Linux/drivers/tuntap.h17
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c62
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c149
6 files changed, 231 insertions, 287 deletions
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
index b84f6c4740f..54183a679fd 100644
--- a/arch/um/os-Linux/drivers/etap.h
+++ b/arch/um/os-Linux/drivers/etap.h
@@ -1,9 +1,12 @@
/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "net_user.h"
+#ifndef __DRIVERS_ETAP_H
+#define __DRIVERS_ETAP_H
+
+#include <net_user.h>
struct ethertap_data {
char *dev_name;
@@ -13,15 +16,6 @@ struct ethertap_data {
void *dev;
};
-extern struct net_user_info ethertap_user_info;
+extern const struct net_user_info ethertap_user_info;
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 6ae4b19d9f5..f424600a583 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -1,16 +1,15 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
-#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
-#include "net_kern.h"
-#include "net_user.h"
+#include <linux/init.h>
+#include <linux/netdevice.h>
#include "etap.h"
+#include <net_kern.h>
struct ethertap_init {
char *dev_name;
@@ -23,7 +22,7 @@ static void etap_init(struct net_device *dev, void *data)
struct ethertap_data *epri;
struct ethertap_init *init = data;
- pri = dev->priv;
+ pri = netdev_priv(dev);
epri = (struct ethertap_data *) pri->user;
epri->dev_name = init->dev_name;
epri->gate_addr = init->gate_addr;
@@ -31,41 +30,33 @@ static void etap_init(struct net_device *dev, void *data)
epri->control_fd = -1;
epri->dev = dev;
- printk("ethertap backend - %s", epri->dev_name);
+ printk(KERN_INFO "ethertap backend - %s", epri->dev_name);
if (epri->gate_addr != NULL)
- printk(", IP = %s", epri->gate_addr);
- printk("\n");
+ printk(KERN_CONT ", IP = %s", epri->gate_addr);
+ printk(KERN_CONT "\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.raw,
- (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
- if(len <= 0) return(len);
- skb_pull(*skb, 2);
+ len = net_recvfrom(fd, skb_mac_header(skb),
+ skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
+ if (len <= 0)
+ return(len);
+
+ skb_pull(skb, 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){
- 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);
}
-struct net_kern_info ethertap_kern_info = {
+const struct net_kern_info ethertap_kern_info = {
.init = etap_init,
.protocol = eth_protocol,
.read = etap_read,
@@ -79,15 +70,15 @@ int ethertap_setup(char *str, char **mac_out, void *data)
*init = ((struct ethertap_init)
{ .dev_name = NULL,
.gate_addr = NULL });
- if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
+ if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
&init->gate_addr))
- return(0);
- if(init->dev_name == NULL){
- printk("ethertap_setup : Missing tap device name\n");
- return(0);
+ return 0;
+ if (init->dev_name == NULL) {
+ printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
+ return 0;
}
- return(1);
+ return 1;
}
static struct transport ethertap_transport = {
@@ -97,23 +88,13 @@ static struct transport ethertap_transport = {
.user = &ethertap_user_info,
.kern = &ethertap_kern_info,
.private_size = sizeof(struct ethertap_data),
+ .setup_size = sizeof(struct ethertap_init),
};
static int register_ethertap(void)
{
register_transport(&ethertap_transport);
- return(1);
+ return 0;
}
-__initcall(register_ethertap);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+late_initcall(register_ethertap);
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 901b85e8a1c..b39b6696ac5 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
@@ -7,27 +8,23 @@
#include <stdio.h>
#include <unistd.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/errno.h>
+#include <errno.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
-#include <sys/un.h>
-#include <net/if.h>
-#include "user.h"
-#include "kern_util.h"
-#include "user_util.h"
-#include "net_user.h"
#include "etap.h"
-#include "os.h"
+#include <os.h>
+#include <net_user.h>
+#include <um_malloc.h>
#define MAX_PACKET ETH_MAX_PACKET
-void etap_user_init(void *data, void *dev)
+static int etap_user_init(void *data, void *dev)
{
struct ethertap_data *pri = data;
pri->dev = dev;
+ return 0;
}
struct addr_change {
@@ -40,20 +37,25 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
int fd)
{
struct addr_change change;
- void *output;
+ char *output;
int n;
change.what = op;
memcpy(change.addr, addr, sizeof(change.addr));
memcpy(change.netmask, netmask, sizeof(change.netmask));
- n = os_write_file(fd, &change, sizeof(change));
- if(n != sizeof(change))
- printk("etap_change - request failed, err = %d\n", -n);
- output = um_kmalloc(page_size());
- if(output == NULL)
- printk("etap_change : Failed to allocate output buffer\n");
- read_output(fd, output, page_size());
- if(output != NULL){
+ CATCH_EINTR(n = write(fd, &change, sizeof(change)));
+ if (n != sizeof(change)) {
+ printk(UM_KERN_ERR "etap_change - request failed, err = %d\n",
+ errno);
+ return;
+ }
+
+ output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
+ if (output == NULL)
+ printk(UM_KERN_ERR "etap_change : Failed to allocate output "
+ "buffer\n");
+ read_output(fd, output, UM_KERN_PAGE_SIZE);
+ if (output != NULL) {
printk("%s", output);
kfree(output);
}
@@ -82,27 +84,27 @@ static void etap_pre_exec(void *arg)
struct etap_pre_exec_data *data = arg;
dup2(data->control_remote, 1);
- os_close_file(data->data_me);
- os_close_file(data->control_me);
+ close(data->data_me);
+ close(data->control_me);
}
-static int etap_tramp(char *dev, char *gate, int control_me,
+static int etap_tramp(char *dev, char *gate, int control_me,
int control_remote, int data_me, int data_remote)
{
struct etap_pre_exec_data pe_data;
- int pid, status, err, n;
+ int pid, err, n;
char version_buf[sizeof("nnnnn\0")];
char data_fd_buf[sizeof("nnnnnn\0")];
char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
data_fd_buf, gate_buf, NULL };
- char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
+ char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
dev, data_fd_buf, NULL };
char **args, c;
sprintf(data_fd_buf, "%d", data_remote);
sprintf(version_buf, "%d", UML_NET_VERSION);
- if(gate != NULL){
+ if (gate != NULL) {
strcpy(gate_buf, gate);
args = setup_args;
}
@@ -112,26 +114,24 @@ static int etap_tramp(char *dev, char *gate, int control_me,
pe_data.control_remote = control_remote;
pe_data.control_me = control_me;
pe_data.data_me = data_me;
- pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
-
- if(pid < 0) err = pid;
- os_close_file(data_remote);
- os_close_file(control_remote);
- n = os_read_file(control_me, &c, sizeof(c));
- if(n != sizeof(c)){
- printk("etap_tramp : read of status failed, err = %d\n", -n);
- return(-EINVAL);
+ pid = run_helper(etap_pre_exec, &pe_data, args);
+
+ if (pid < 0)
+ err = pid;
+ close(data_remote);
+ close(control_remote);
+ CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
+ if (n != sizeof(c)) {
+ err = -errno;
+ printk(UM_KERN_ERR "etap_tramp : read of status failed, "
+ "err = %d\n", -err);
+ return err;
}
- if(c != 1){
- printk("etap_tramp : uml_net failed\n");
- err = -EINVAL;
- CATCH_EINTR(n = waitpid(pid, &status, 0));
- if(n < 0)
- err = -errno;
- else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
- printk("uml_net didn't exit with status 1\n");
+ if (c != 1) {
+ printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
+ err = helper_wait(pid);
}
- return(err);
+ return err;
}
static int etap_open(void *data)
@@ -141,42 +141,56 @@ static int etap_open(void *data)
int data_fds[2], control_fds[2], err, output_len;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err) return(err);
-
- err = os_pipe(data_fds, 0, 0);
- if(err < 0){
- printk("data os_pipe failed - err = %d\n", -err);
- return(err);
+ if (err)
+ return err;
+
+ err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
+ if (err) {
+ err = -errno;
+ printk(UM_KERN_ERR "etap_open - data socketpair failed - "
+ "err = %d\n", errno);
+ return err;
}
- err = os_pipe(control_fds, 1, 0);
- if(err < 0){
- printk("control os_pipe failed - err = %d\n", -err);
- return(err);
+ err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
+ if (err) {
+ err = -errno;
+ printk(UM_KERN_ERR "etap_open - control socketpair failed - "
+ "err = %d\n", errno);
+ goto out_close_data;
}
-
- err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
+
+ err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
- output_len = page_size();
- output = um_kmalloc(output_len);
+ output_len = UM_KERN_PAGE_SIZE;
+ output = uml_kmalloc(output_len, UM_GFP_KERNEL);
read_output(control_fds[0], output, output_len);
- if(output == NULL)
- printk("etap_open : failed to allocate output buffer\n");
+ if (output == NULL)
+ printk(UM_KERN_ERR "etap_open : failed to allocate output "
+ "buffer\n");
else {
printk("%s", output);
kfree(output);
}
- if(err < 0){
- printk("etap_tramp failed - err = %d\n", -err);
- return(err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err);
+ goto out_close_control;
}
pri->data_fd = data_fds[0];
pri->control_fd = control_fds[0];
iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
- return(data_fds[0]);
+ return data_fds[0];
+
+out_close_control:
+ close(control_fds[0]);
+ close(control_fds[1]);
+out_close_data:
+ close(data_fds[0]);
+ close(data_fds[1]);
+ return err;
}
static void etap_close(int fd, void *data)
@@ -184,56 +198,51 @@ static void etap_close(int fd, void *data)
struct ethertap_data *pri = data;
iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
- os_close_file(fd);
- os_shutdown_socket(pri->data_fd, 1, 1);
- os_close_file(pri->data_fd);
+ close(fd);
+
+ if (shutdown(pri->data_fd, SHUT_RDWR) < 0)
+ printk(UM_KERN_ERR "etap_close - shutdown data socket failed, "
+ "errno = %d\n", errno);
+
+ if (shutdown(pri->control_fd, SHUT_RDWR) < 0)
+ printk(UM_KERN_ERR "etap_close - shutdown control socket "
+ "failed, errno = %d\n", errno);
+
+ close(pri->data_fd);
pri->data_fd = -1;
- os_close_file(pri->control_fd);
+ close(pri->control_fd);
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)
{
struct ethertap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if(pri->control_fd == -1) return;
+ if (pri->control_fd == -1)
+ return;
etap_open_addr(addr, netmask, &pri->control_fd);
}
-static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
+static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct ethertap_data *pri = data;
- if(pri->control_fd == -1) return;
+ if (pri->control_fd == -1)
+ return;
+
etap_close_addr(addr, netmask, &pri->control_fd);
}
-struct net_user_info ethertap_user_info = {
+const struct net_user_info ethertap_user_info = {
.init = etap_user_init,
.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,
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
index 25d4a286881..7367354ac8d 100644
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ b/arch/um/os-Linux/drivers/tuntap.h
@@ -1,12 +1,12 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __UM_TUNTAP_H
#define __UM_TUNTAP_H
-#include "net_user.h"
+#include <net_user.h>
struct tuntap_data {
char *dev_name;
@@ -16,17 +16,6 @@ struct tuntap_data {
void *dev;
};
-extern struct net_user_info tuntap_user_info;
+extern const struct net_user_info tuntap_user_info;
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 4202b9ebad4..d9d56e5810f 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -1,16 +1,13 @@
-/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/stddef.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
-#include "linux/skbuff.h"
-#include "linux/init.h"
-#include "asm/errno.h"
-#include "net_kern.h"
-#include "net_user.h"
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <asm/errno.h>
+#include <net_kern.h>
#include "tuntap.h"
struct tuntap_init {
@@ -24,7 +21,7 @@ static void tuntap_init(struct net_device *dev, void *data)
struct tuntap_data *tpri;
struct tuntap_init *init = data;
- pri = dev->priv;
+ pri = netdev_priv(dev);
tpri = (struct tuntap_data *) pri->user;
tpri->dev_name = init->dev_name;
tpri->fixed_config = (init->dev_name != NULL);
@@ -32,28 +29,24 @@ static void tuntap_init(struct net_device *dev, void *data)
tpri->fd = -1;
tpri->dev = dev;
- printk("TUN/TAP backend - ");
+ printk(KERN_INFO "TUN/TAP backend - ");
if (tpri->gate_addr != NULL)
- printk("IP = %s", tpri->gate_addr);
- printk("\n");
+ printk(KERN_CONT "IP = %s", tpri->gate_addr);
+ printk(KERN_CONT "\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.raw,
- (*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);
}
-struct net_kern_info tuntap_kern_info = {
+const struct net_kern_info tuntap_kern_info = {
.init = tuntap_init,
.protocol = eth_protocol,
.read = tuntap_read,
@@ -67,11 +60,11 @@ int tuntap_setup(char *str, char **mac_out, void *data)
*init = ((struct tuntap_init)
{ .dev_name = NULL,
.gate_addr = NULL });
- if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
+ if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
&init->gate_addr))
- return(0);
+ return 0;
- return(1);
+ return 1;
}
static struct transport tuntap_transport = {
@@ -87,18 +80,7 @@ static struct transport tuntap_transport = {
static int register_tuntap(void)
{
register_transport(&tuntap_transport);
- return(1);
+ return 0;
}
-__initcall(register_tuntap);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+late_initcall(register_tuntap);
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 52945338b64..14126d9176a 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -1,34 +1,28 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
-#include <sys/wait.h>
+#include <string.h>
+#include <linux/if_tun.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <sys/un.h>
+#include <sys/wait.h>
#include <sys/uio.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <linux/if_tun.h>
-#include "net_user.h"
+#include <kern_util.h>
+#include <os.h>
#include "tuntap.h"
-#include "kern_util.h"
-#include "user_util.h"
-#include "user.h"
-#include "os.h"
-#define MAX_PACKET ETH_MAX_PACKET
-
-void tuntap_user_init(void *data, void *dev)
+static int tuntap_user_init(void *data, void *dev)
{
struct tuntap_data *pri = data;
pri->dev = dev;
+ return 0;
}
static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -37,7 +31,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
struct tuntap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if((pri->fd == -1) || pri->fixed_config) return;
+ if ((pri->fd == -1) || pri->fixed_config)
+ return;
open_addr(addr, netmask, pri->dev_name);
}
@@ -46,7 +41,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct tuntap_data *pri = data;
- if((pri->fd == -1) || pri->fixed_config) return;
+ if ((pri->fd == -1) || pri->fixed_config)
+ return;
close_addr(addr, netmask, pri->dev_name);
}
@@ -58,9 +54,9 @@ struct tuntap_pre_exec_data {
static void tuntap_pre_exec(void *arg)
{
struct tuntap_pre_exec_data *data = arg;
-
+
dup2(data->stdout, 1);
- os_close_file(data->close_me);
+ close(data->close_me);
}
static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
@@ -81,15 +77,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
data.stdout = remote;
data.close_me = me;
- pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
+ pid = run_helper(tuntap_pre_exec, &data, argv);
- if(pid < 0) return(-pid);
+ if (pid < 0)
+ return -pid;
- os_close_file(remote);
+ close(remote);
msg.msg_name = NULL;
msg.msg_namelen = 0;
- if(buffer != NULL){
+ if (buffer != NULL) {
iov = ((struct iovec) { buffer, buffer_len });
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
@@ -103,26 +100,29 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
msg.msg_flags = 0;
n = recvmsg(me, &msg, 0);
*used_out = n;
- if(n < 0){
+ if (n < 0) {
err = -errno;
- printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
- errno);
+ printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - "
+ "errno = %d\n", errno);
return err;
}
- CATCH_EINTR(waitpid(pid, NULL, 0));
+ helper_wait(pid);
cmsg = CMSG_FIRSTHDR(&msg);
- if(cmsg == NULL){
- printk("tuntap_open_tramp : didn't receive a message\n");
- return(-EINVAL);
+ if (cmsg == NULL) {
+ printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
+ "message\n");
+ return -EINVAL;
}
- if((cmsg->cmsg_level != SOL_SOCKET) ||
- (cmsg->cmsg_type != SCM_RIGHTS)){
- printk("tuntap_open_tramp : didn't receive a descriptor\n");
- return(-EINVAL);
+ if ((cmsg->cmsg_level != SOL_SOCKET) ||
+ (cmsg->cmsg_type != SCM_RIGHTS)) {
+ printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
+ "descriptor\n");
+ return -EINVAL;
}
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
- return(0);
+ os_set_exec_close(*fd_out);
+ return 0;
}
static int tuntap_open(void *data)
@@ -133,47 +133,52 @@ static int tuntap_open(void *data)
int err, fds[2], len, used;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err < 0)
- return(err);
-
- if(pri->fixed_config){
- pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
- if(pri->fd < 0){
- printk("Failed to open /dev/net/tun, err = %d\n",
- -pri->fd);
- return(pri->fd);
+ if (err < 0)
+ return err;
+
+ if (pri->fixed_config) {
+ pri->fd = os_open_file("/dev/net/tun",
+ of_cloexec(of_rdwr(OPENFLAGS())), 0);
+ if (pri->fd < 0) {
+ printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
+ "err = %d\n", -pri->fd);
+ return pri->fd;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
- if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
+ if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
err = -errno;
- printk("TUNSETIFF failed, errno = %d\n", errno);
- os_close_file(pri->fd);
+ printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
+ errno);
+ close(pri->fd);
return err;
}
}
else {
- err = os_pipe(fds, 0, 0);
- if(err < 0){
- printk("tuntap_open : os_pipe failed - err = %d\n",
- -err);
- return(err);
+ err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
+ if (err) {
+ err = -errno;
+ printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
+ "errno = %d\n", errno);
+ return err;
}
buffer = get_output_buffer(&len);
- if(buffer != NULL) len--;
+ if (buffer != NULL)
+ len--;
used = 0;
err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
fds[1], buffer, len, &used);
output = buffer;
- if(err < 0) {
+ if (err < 0) {
printk("%s", output);
free_output_buffer(buffer);
- printk("tuntap_open_tramp failed - err = %d\n", -err);
- return(err);
+ printk(UM_KERN_ERR "tuntap_open_tramp failed - "
+ "err = %d\n", -err);
+ return err;
}
pri->dev_name = uml_strdup(buffer);
@@ -181,46 +186,30 @@ static int tuntap_open(void *data)
printk("%s", output);
free_output_buffer(buffer);
- os_close_file(fds[0]);
+ close(fds[0]);
iter_addresses(pri->dev, open_addr, pri->dev_name);
}
- return(pri->fd);
+ return pri->fd;
}
static void tuntap_close(int fd, void *data)
{
struct tuntap_data *pri = data;
- if(!pri->fixed_config)
+ if (!pri->fixed_config)
iter_addresses(pri->dev, close_addr, pri->dev_name);
- os_close_file(fd);
+ close(fd);
pri->fd = -1;
}
-static int tuntap_set_mtu(int mtu, void *data)
-{
- return(mtu);
-}
-
-struct net_user_info tuntap_user_info = {
+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,
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */