uml: network formatting
Style and other non-functional changes in the UML networking code, including include tidying style violations copyright updates printks getting severities userspace code calling libc directly rather than using the os_* wrappers There's also a exit path cleanup in the pcap driver. 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:
committed by
Linus Torvalds
parent
1a80521990
commit
cd1ae0e49b
@@ -1,8 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __DAEMON_H__
|
||||||
|
#define __DAEMON_H__
|
||||||
|
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
|
|
||||||
#define SWITCH_VERSION 3
|
#define SWITCH_VERSION 3
|
||||||
@@ -23,13 +26,4 @@ extern const struct net_user_info daemon_user_info;
|
|||||||
extern int daemon_user_write(int fd, void *buf, int len,
|
extern int daemon_user_write(int fd, void *buf, int len,
|
||||||
struct daemon_data *pri);
|
struct daemon_data *pri);
|
||||||
|
|
||||||
/*
|
#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:
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
||||||
* James Leu (jleu@mindspring.net).
|
* 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.
|
* Copyright (C) 2001 by various other people who didn't put their name here.
|
||||||
* Licensed under the GPL.
|
* Licensed under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/kernel.h"
|
|
||||||
#include "linux/init.h"
|
#include "linux/init.h"
|
||||||
#include "linux/netdevice.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/etherdevice.h"
|
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
|
|
||||||
struct daemon_init {
|
struct daemon_init {
|
||||||
@@ -45,16 +43,17 @@ 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);
|
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
||||||
if(*skb == NULL) return(-ENOMEM);
|
if (*skb == NULL)
|
||||||
return(net_recvfrom(fd, skb_mac_header(*skb),
|
return -ENOMEM;
|
||||||
(*skb)->dev->mtu + ETH_HEADER_OTHER));
|
return net_recvfrom(fd, skb_mac_header(*skb),
|
||||||
|
(*skb)->dev->mtu + ETH_HEADER_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int daemon_write(int fd, struct sk_buff **skb,
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_kern_info daemon_kern_info = {
|
static const struct net_kern_info daemon_kern_info = {
|
||||||
@@ -75,11 +74,11 @@ static int daemon_setup(char *str, char **mac_out, void *data)
|
|||||||
|
|
||||||
remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
|
remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
|
||||||
NULL);
|
NULL);
|
||||||
if(remain != NULL)
|
if (remain != NULL)
|
||||||
printk(KERN_WARNING "daemon_setup : Ignoring data socket "
|
printk(KERN_WARNING "daemon_setup : Ignoring data socket "
|
||||||
"specification\n");
|
"specification\n");
|
||||||
|
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct transport daemon_transport = {
|
static struct transport daemon_transport = {
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
||||||
* James Leu (jleu@mindspring.net).
|
* James Leu (jleu@mindspring.net).
|
||||||
* Copyright (C) 2001 by various other people who didn't put their name here.
|
* Copyright (C) 2001 by various other people who didn't put their name here.
|
||||||
* Licensed under the GPL.
|
* Licensed under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "net_user.h"
|
#include <sys/un.h>
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "kern_util.h"
|
#include "net_user.h"
|
||||||
#include "user.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
||||||
|
|
||||||
@@ -36,8 +37,9 @@ static struct sockaddr_un *new_addr(void *name, int len)
|
|||||||
struct sockaddr_un *sun;
|
struct sockaddr_un *sun;
|
||||||
|
|
||||||
sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
|
sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
|
||||||
if(sun == NULL){
|
if (sun == NULL) {
|
||||||
printk("new_addr: allocation of sockaddr_un failed\n");
|
printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
|
||||||
|
"failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sun->sun_family = AF_UNIX;
|
sun->sun_family = AF_UNIX;
|
||||||
@@ -54,38 +56,39 @@ static int connect_to_switch(struct daemon_data *pri)
|
|||||||
int fd, n, err;
|
int fd, n, err;
|
||||||
|
|
||||||
pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
|
pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if(pri->control < 0){
|
if (pri->control < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("daemon_open : control socket failed, errno = %d\n",
|
printk(UM_KERN_ERR "daemon_open : control socket failed, "
|
||||||
-err);
|
"errno = %d\n", -err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(connect(pri->control, (struct sockaddr *) ctl_addr,
|
if (connect(pri->control, (struct sockaddr *) ctl_addr,
|
||||||
sizeof(*ctl_addr)) < 0){
|
sizeof(*ctl_addr)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("daemon_open : control connect failed, errno = %d\n",
|
printk(UM_KERN_ERR "daemon_open : control connect failed, "
|
||||||
-err);
|
"errno = %d\n", -err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||||
if(fd < 0){
|
if (fd < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("daemon_open : data socket failed, errno = %d\n",
|
printk(UM_KERN_ERR "daemon_open : data socket failed, "
|
||||||
-err);
|
"errno = %d\n", -err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
|
if (bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("daemon_open : data bind failed, errno = %d\n",
|
printk(UM_KERN_ERR "daemon_open : data bind failed, "
|
||||||
-err);
|
"errno = %d\n", -err);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
|
sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
|
||||||
if(sun == NULL){
|
if (sun == NULL) {
|
||||||
printk("new_addr: allocation of sockaddr_un failed\n");
|
printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
|
||||||
|
"failed\n");
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
@@ -94,18 +97,18 @@ static int connect_to_switch(struct daemon_data *pri)
|
|||||||
req.version = SWITCH_VERSION;
|
req.version = SWITCH_VERSION;
|
||||||
req.type = REQ_NEW_CONTROL;
|
req.type = REQ_NEW_CONTROL;
|
||||||
req.sock = *local_addr;
|
req.sock = *local_addr;
|
||||||
n = os_write_file(pri->control, &req, sizeof(req));
|
n = write(pri->control, &req, sizeof(req));
|
||||||
if(n != sizeof(req)){
|
if (n != sizeof(req)) {
|
||||||
printk("daemon_open : control setup request failed, err = %d\n",
|
printk(UM_KERN_ERR "daemon_open : control setup request "
|
||||||
-n);
|
"failed, err = %d\n", -errno);
|
||||||
err = -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = os_read_file(pri->control, sun, sizeof(*sun));
|
n = read(pri->control, sun, sizeof(*sun));
|
||||||
if(n != sizeof(*sun)){
|
if (n != sizeof(*sun)) {
|
||||||
printk("daemon_open : read of data socket failed, err = %d\n",
|
printk(UM_KERN_ERR "daemon_open : read of data socket failed, "
|
||||||
-n);
|
"err = %d\n", -errno);
|
||||||
err = -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
@@ -116,9 +119,9 @@ static int connect_to_switch(struct daemon_data *pri)
|
|||||||
out_free:
|
out_free:
|
||||||
kfree(sun);
|
kfree(sun);
|
||||||
out_close:
|
out_close:
|
||||||
os_close_file(fd);
|
close(fd);
|
||||||
out:
|
out:
|
||||||
os_close_file(pri->control);
|
close(pri->control);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +135,7 @@ static int daemon_user_init(void *data, void *dev)
|
|||||||
int usecs;
|
int usecs;
|
||||||
} name;
|
} name;
|
||||||
|
|
||||||
if(!strcmp(pri->sock_type, "unix"))
|
if (!strcmp(pri->sock_type, "unix"))
|
||||||
pri->ctl_addr = new_addr(pri->ctl_sock,
|
pri->ctl_addr = new_addr(pri->ctl_sock,
|
||||||
strlen(pri->ctl_sock) + 1);
|
strlen(pri->ctl_sock) + 1);
|
||||||
name.zero = 0;
|
name.zero = 0;
|
||||||
@@ -142,7 +145,7 @@ static int daemon_user_init(void *data, void *dev)
|
|||||||
pri->local_addr = new_addr(&name, sizeof(name));
|
pri->local_addr = new_addr(&name, sizeof(name));
|
||||||
pri->dev = dev;
|
pri->dev = dev;
|
||||||
pri->fd = connect_to_switch(pri);
|
pri->fd = connect_to_switch(pri);
|
||||||
if(pri->fd < 0){
|
if (pri->fd < 0) {
|
||||||
kfree(pri->local_addr);
|
kfree(pri->local_addr);
|
||||||
pri->local_addr = NULL;
|
pri->local_addr = NULL;
|
||||||
return pri->fd;
|
return pri->fd;
|
||||||
@@ -161,9 +164,9 @@ static void daemon_remove(void *data)
|
|||||||
{
|
{
|
||||||
struct daemon_data *pri = data;
|
struct daemon_data *pri = data;
|
||||||
|
|
||||||
os_close_file(pri->fd);
|
close(pri->fd);
|
||||||
pri->fd = -1;
|
pri->fd = -1;
|
||||||
os_close_file(pri->control);
|
close(pri->control);
|
||||||
pri->control = -1;
|
pri->control = -1;
|
||||||
|
|
||||||
kfree(pri->data_addr);
|
kfree(pri->data_addr);
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_MCAST_H
|
||||||
|
#define __DRIVERS_MCAST_H
|
||||||
|
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
|
|
||||||
struct mcast_data {
|
struct mcast_data {
|
||||||
@@ -18,13 +21,4 @@ extern const struct net_user_info mcast_user_info;
|
|||||||
extern int mcast_user_write(int fd, void *buf, int len,
|
extern int mcast_user_write(int fd, void *buf, int len,
|
||||||
struct mcast_data *pri);
|
struct mcast_data *pri);
|
||||||
|
|
||||||
/*
|
#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:
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* user-mode-linux networking multicast transport
|
* user-mode-linux networking multicast transport
|
||||||
* Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
|
* Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
*
|
*
|
||||||
* based on the existing uml-networking code, which is
|
* based on the existing uml-networking code, which is
|
||||||
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
||||||
@@ -10,15 +11,10 @@
|
|||||||
* Licensed under the GPL.
|
* Licensed under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/kernel.h"
|
|
||||||
#include "linux/init.h"
|
#include "linux/init.h"
|
||||||
#include "linux/netdevice.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/etherdevice.h"
|
|
||||||
#include "linux/in.h"
|
|
||||||
#include "linux/inet.h"
|
|
||||||
#include "net_kern.h"
|
|
||||||
#include "net_user.h"
|
|
||||||
#include "mcast.h"
|
#include "mcast.h"
|
||||||
|
#include "net_kern.h"
|
||||||
|
|
||||||
struct mcast_init {
|
struct mcast_init {
|
||||||
char *addr;
|
char *addr;
|
||||||
@@ -39,23 +35,20 @@ static void mcast_init(struct net_device *dev, void *data)
|
|||||||
dpri->ttl = init->ttl;
|
dpri->ttl = init->ttl;
|
||||||
dpri->dev = dev;
|
dpri->dev = dev;
|
||||||
|
|
||||||
printk("mcast backend ");
|
printk("mcast backend multicast address: %s:%u, TTL:%u\n",
|
||||||
printk("multicast address: %s:%u, TTL:%u ",
|
|
||||||
dpri->addr, dpri->port, dpri->ttl);
|
dpri->addr, dpri->port, dpri->ttl);
|
||||||
|
|
||||||
printk("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
||||||
if(*skb == NULL) return(-ENOMEM);
|
if (*skb == NULL)
|
||||||
return(net_recvfrom(fd, skb_mac_header(*skb),
|
return -ENOMEM;
|
||||||
(*skb)->dev->mtu + ETH_HEADER_OTHER));
|
return net_recvfrom(fd, skb_mac_header(*skb),
|
||||||
|
(*skb)->dev->mtu + ETH_HEADER_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mcast_write(int fd, struct sk_buff **skb,
|
static int mcast_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
|
||||||
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);
|
||||||
@@ -81,34 +74,34 @@ int mcast_setup(char *str, char **mac_out, void *data)
|
|||||||
|
|
||||||
remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
|
remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
|
||||||
NULL);
|
NULL);
|
||||||
if(remain != NULL){
|
if (remain != NULL) {
|
||||||
printk(KERN_ERR "mcast_setup - Extra garbage on "
|
printk(KERN_ERR "mcast_setup - Extra garbage on "
|
||||||
"specification : '%s'\n", remain);
|
"specification : '%s'\n", remain);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(port_str != NULL){
|
if (port_str != NULL) {
|
||||||
init->port = simple_strtoul(port_str, &last, 10);
|
init->port = simple_strtoul(port_str, &last, 10);
|
||||||
if((*last != '\0') || (last == port_str)){
|
if ((*last != '\0') || (last == port_str)) {
|
||||||
printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
|
printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
|
||||||
port_str);
|
port_str);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ttl_str != NULL){
|
if (ttl_str != NULL) {
|
||||||
init->ttl = simple_strtoul(ttl_str, &last, 10);
|
init->ttl = simple_strtoul(ttl_str, &last, 10);
|
||||||
if((*last != '\0') || (last == ttl_str)){
|
if ((*last != '\0') || (last == ttl_str)) {
|
||||||
printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
|
printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
|
||||||
ttl_str);
|
ttl_str);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
|
printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
|
||||||
init->port, init->ttl);
|
init->port, init->ttl);
|
||||||
|
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct transport mcast_transport = {
|
static struct transport mcast_transport = {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* user-mode-linux networking multicast transport
|
* user-mode-linux networking multicast transport
|
||||||
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
|
* Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
|
||||||
*
|
*
|
||||||
* based on the existing uml-networking code, which is
|
* based on the existing uml-networking code, which is
|
||||||
@@ -11,18 +12,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <errno.h>
|
||||||
#include <sys/un.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include "net_user.h"
|
|
||||||
#include "mcast.h"
|
#include "mcast.h"
|
||||||
#include "kern_util.h"
|
#include "net_user.h"
|
||||||
#include "user.h"
|
|
||||||
#include "os.h"
|
|
||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
||||||
|
|
||||||
@@ -31,8 +27,9 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
|
|||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
|
sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
|
||||||
if(sin == NULL){
|
if (sin == NULL) {
|
||||||
printk("new_addr: allocation of sockaddr_in failed\n");
|
printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
|
||||||
|
"failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
@@ -71,17 +68,17 @@ static int mcast_open(void *data)
|
|||||||
|
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (fd < 0){
|
if (fd < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("mcast_open : data socket failed, errno = %d\n",
|
printk(UM_KERN_ERR "mcast_open : data socket failed, "
|
||||||
errno);
|
"errno = %d\n", errno);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
|
printk(UM_KERN_ERR "mcast_open: SO_REUSEADDR failed, "
|
||||||
errno);
|
"errno = %d\n", errno);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,23 +86,24 @@ static int mcast_open(void *data)
|
|||||||
if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
|
if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
|
||||||
sizeof(pri->ttl)) < 0) {
|
sizeof(pri->ttl)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
|
printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_TTL failed, "
|
||||||
errno);
|
"error = %d\n", errno);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set LOOP, so data does get fed back to local sockets */
|
/* set LOOP, so data does get fed back to local sockets */
|
||||||
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
|
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
|
printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_LOOP failed, "
|
||||||
errno);
|
"error = %d\n", errno);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bind socket to mcast address */
|
/* bind socket to mcast address */
|
||||||
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
|
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("mcast_open : data bind failed, errno = %d\n", errno);
|
printk(UM_KERN_ERR "mcast_open : data bind failed, "
|
||||||
|
"errno = %d\n", errno);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,19 +113,19 @@ static int mcast_open(void *data)
|
|||||||
if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
|
if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
|
||||||
&mreq, sizeof(mreq)) < 0) {
|
&mreq, sizeof(mreq)) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
|
printk(UM_KERN_ERR "mcast_open: IP_ADD_MEMBERSHIP failed, "
|
||||||
errno);
|
"error = %d\n", errno);
|
||||||
printk("There appears not to be a multicast-capable network "
|
printk(UM_KERN_ERR "There appears not to be a multicast-"
|
||||||
"interface on the host.\n");
|
"capable network interface on the host.\n");
|
||||||
printk("eth0 should be configured in order to use the "
|
printk(UM_KERN_ERR "eth0 should be configured in order to use "
|
||||||
"multicast transport.\n");
|
"the multicast transport.\n");
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
out_close:
|
out_close:
|
||||||
os_close_file(fd);
|
close(fd);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -142,11 +140,11 @@ static void mcast_close(int fd, void *data)
|
|||||||
mreq.imr_interface.s_addr = 0;
|
mreq.imr_interface.s_addr = 0;
|
||||||
if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
|
if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
|
||||||
&mreq, sizeof(mreq)) < 0) {
|
&mreq, sizeof(mreq)) < 0) {
|
||||||
printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
|
printk(UM_KERN_ERR "mcast_open: IP_DROP_MEMBERSHIP failed, "
|
||||||
errno);
|
"error = %d\n", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
os_close_file(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
|
int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
|
||||||
|
|||||||
@@ -1,33 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
||||||
* James Leu (jleu@mindspring.net).
|
* James Leu (jleu@mindspring.net).
|
||||||
* Copyright (C) 2001 by various other people who didn't put their name here.
|
* Copyright (C) 2001 by various other people who didn't put their name here.
|
||||||
* Licensed under the GPL.
|
* Licensed under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/kernel.h"
|
#include <linux/bootmem.h>
|
||||||
#include "linux/netdevice.h"
|
#include <linux/etherdevice.h>
|
||||||
#include "linux/rtnetlink.h"
|
#include <linux/ethtool.h>
|
||||||
#include "linux/skbuff.h"
|
#include <linux/inetdevice.h>
|
||||||
#include "linux/socket.h"
|
#include <linux/init.h>
|
||||||
#include "linux/spinlock.h"
|
#include <linux/list.h>
|
||||||
#include "linux/module.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/init.h"
|
#include <linux/platform_device.h>
|
||||||
#include "linux/etherdevice.h"
|
#include <linux/rtnetlink.h>
|
||||||
#include "linux/list.h"
|
#include <linux/skbuff.h>
|
||||||
#include "linux/inetdevice.h"
|
#include <linux/spinlock.h>
|
||||||
#include "linux/ctype.h"
|
#include "init.h"
|
||||||
#include "linux/bootmem.h"
|
#include "irq_kern.h"
|
||||||
#include "linux/ethtool.h"
|
#include "irq_user.h"
|
||||||
#include "linux/platform_device.h"
|
#include "mconsole_kern.h"
|
||||||
#include "asm/uaccess.h"
|
|
||||||
#include "kern_util.h"
|
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
#include "mconsole_kern.h"
|
|
||||||
#include "init.h"
|
|
||||||
#include "irq_user.h"
|
|
||||||
#include "irq_kern.h"
|
|
||||||
|
|
||||||
static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
|
static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
|
||||||
{
|
{
|
||||||
@@ -84,12 +79,12 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
|
|||||||
struct uml_net_private *lp = dev->priv;
|
struct uml_net_private *lp = dev->priv;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if(!netif_running(dev))
|
if (!netif_running(dev))
|
||||||
return(IRQ_NONE);
|
return IRQ_NONE;
|
||||||
|
|
||||||
spin_lock(&lp->lock);
|
spin_lock(&lp->lock);
|
||||||
while((err = uml_net_rx(dev)) > 0) ;
|
while ((err = uml_net_rx(dev)) > 0) ;
|
||||||
if(err < 0) {
|
if (err < 0) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"Device '%s' read returned %d, shutting it down\n",
|
"Device '%s' read returned %d, shutting it down\n",
|
||||||
dev->name, err);
|
dev->name, err);
|
||||||
@@ -115,20 +110,20 @@ static int uml_net_open(struct net_device *dev)
|
|||||||
struct uml_net_private *lp = dev->priv;
|
struct uml_net_private *lp = dev->priv;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if(lp->fd >= 0){
|
if (lp->fd >= 0) {
|
||||||
err = -ENXIO;
|
err = -ENXIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
lp->fd = (*lp->open)(&lp->user);
|
lp->fd = (*lp->open)(&lp->user);
|
||||||
if(lp->fd < 0){
|
if (lp->fd < 0) {
|
||||||
err = lp->fd;
|
err = lp->fd;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
|
err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
|
||||||
IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
|
IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
|
||||||
if(err != 0){
|
if (err != 0) {
|
||||||
printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
|
printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
|
||||||
err = -ENETUNREACH;
|
err = -ENETUNREACH;
|
||||||
goto out_close;
|
goto out_close;
|
||||||
@@ -141,7 +136,7 @@ static int uml_net_open(struct net_device *dev)
|
|||||||
* is full when we get here. In this case, new data is never queued,
|
* is full when we get here. In this case, new data is never queued,
|
||||||
* SIGIOs never arrive, and the net never works.
|
* SIGIOs never arrive, and the net never works.
|
||||||
*/
|
*/
|
||||||
while((err = uml_net_rx(dev)) > 0) ;
|
while ((err = uml_net_rx(dev)) > 0) ;
|
||||||
|
|
||||||
spin_lock(&opened_lock);
|
spin_lock(&opened_lock);
|
||||||
list_add(&lp->list, &opened);
|
list_add(&lp->list, &opened);
|
||||||
@@ -149,7 +144,7 @@ static int uml_net_open(struct net_device *dev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
out_close:
|
out_close:
|
||||||
if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
|
if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
|
||||||
lp->fd = -1;
|
lp->fd = -1;
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
@@ -162,7 +157,7 @@ static int uml_net_close(struct net_device *dev)
|
|||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
if(lp->close != NULL)
|
if (lp->close != NULL)
|
||||||
(*lp->close)(lp->fd, &lp->user);
|
(*lp->close)(lp->fd, &lp->user);
|
||||||
lp->fd = -1;
|
lp->fd = -1;
|
||||||
|
|
||||||
@@ -185,7 +180,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
|
|
||||||
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++;
|
||||||
lp->stats.tx_bytes += skb->len;
|
lp->stats.tx_bytes += skb->len;
|
||||||
dev->trans_start = jiffies;
|
dev->trans_start = jiffies;
|
||||||
@@ -194,7 +189,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
/* this is normally done in the interrupt when tx finishes */
|
/* this is normally done in the interrupt when tx finishes */
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
else if(len == 0){
|
else if (len == 0) {
|
||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
lp->stats.tx_dropped++;
|
lp->stats.tx_dropped++;
|
||||||
}
|
}
|
||||||
@@ -218,8 +213,10 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
|
|||||||
|
|
||||||
static void uml_net_set_multicast_list(struct net_device *dev)
|
static void uml_net_set_multicast_list(struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (dev->flags & IFF_PROMISC) return;
|
if (dev->flags & IFF_PROMISC)
|
||||||
else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
|
return;
|
||||||
|
else if (dev->mc_count)
|
||||||
|
dev->flags |= IFF_ALLMULTI;
|
||||||
else dev->flags &= ~IFF_ALLMULTI;
|
else dev->flags &= ~IFF_ALLMULTI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +246,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
|
|||||||
spin_lock_irq(&lp->lock);
|
spin_lock_irq(&lp->lock);
|
||||||
|
|
||||||
new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
|
new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
|
||||||
if(new_mtu < 0){
|
if (new_mtu < 0) {
|
||||||
err = new_mtu;
|
err = new_mtu;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -288,13 +285,13 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name)
|
|||||||
char *end;
|
char *end;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(str == NULL)
|
if (str == NULL)
|
||||||
goto random;
|
goto random;
|
||||||
|
|
||||||
for(i=0;i<6;i++){
|
for (i = 0;i < 6; i++) {
|
||||||
addr[i] = simple_strtoul(str, &end, 16);
|
addr[i] = simple_strtoul(str, &end, 16);
|
||||||
if((end == str) ||
|
if ((end == str) ||
|
||||||
((*end != ':') && (*end != ',') && (*end != '\0'))){
|
((*end != ':') && (*end != ',') && (*end != '\0'))) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"setup_etheraddr: failed to parse '%s' "
|
"setup_etheraddr: failed to parse '%s' "
|
||||||
"as an ethernet address\n", str);
|
"as an ethernet address\n", str);
|
||||||
@@ -349,7 +346,7 @@ static void net_device_release(struct device *dev)
|
|||||||
struct net_device *netdev = device->dev;
|
struct net_device *netdev = device->dev;
|
||||||
struct uml_net_private *lp = netdev->priv;
|
struct uml_net_private *lp = netdev->priv;
|
||||||
|
|
||||||
if(lp->remove != NULL)
|
if (lp->remove != NULL)
|
||||||
(*lp->remove)(&lp->user);
|
(*lp->remove)(&lp->user);
|
||||||
list_del(&device->list);
|
list_del(&device->list);
|
||||||
kfree(device);
|
kfree(device);
|
||||||
@@ -413,7 +410,7 @@ static void eth_configure(int n, void *init, char *mac,
|
|||||||
device->pdev.name = DRIVER_NAME;
|
device->pdev.name = DRIVER_NAME;
|
||||||
device->pdev.dev.release = net_device_release;
|
device->pdev.dev.release = net_device_release;
|
||||||
device->pdev.dev.driver_data = device;
|
device->pdev.dev.driver_data = device;
|
||||||
if(platform_device_register(&device->pdev))
|
if (platform_device_register(&device->pdev))
|
||||||
goto out_free_netdev;
|
goto out_free_netdev;
|
||||||
SET_NETDEV_DEV(dev,&device->pdev.dev);
|
SET_NETDEV_DEV(dev,&device->pdev.dev);
|
||||||
|
|
||||||
@@ -493,9 +490,9 @@ static struct uml_net *find_device(int n)
|
|||||||
struct list_head *ele;
|
struct list_head *ele;
|
||||||
|
|
||||||
spin_lock(&devices_lock);
|
spin_lock(&devices_lock);
|
||||||
list_for_each(ele, &devices){
|
list_for_each(ele, &devices) {
|
||||||
device = list_entry(ele, struct uml_net, list);
|
device = list_entry(ele, struct uml_net, list);
|
||||||
if(device->index == n)
|
if (device->index == n)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
device = NULL;
|
device = NULL;
|
||||||
@@ -511,19 +508,19 @@ static int eth_parse(char *str, int *index_out, char **str_out,
|
|||||||
int n, err = -EINVAL;;
|
int n, err = -EINVAL;;
|
||||||
|
|
||||||
n = simple_strtoul(str, &end, 0);
|
n = simple_strtoul(str, &end, 0);
|
||||||
if(end == str){
|
if (end == str) {
|
||||||
*error_out = "Bad device number";
|
*error_out = "Bad device number";
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = end;
|
str = end;
|
||||||
if(*str != '='){
|
if (*str != '=') {
|
||||||
*error_out = "Expected '=' after device number";
|
*error_out = "Expected '=' after device number";
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
str++;
|
str++;
|
||||||
if(find_device(n)){
|
if (find_device(n)) {
|
||||||
*error_out = "Device already configured";
|
*error_out = "Device already configured";
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -551,20 +548,20 @@ static int check_transport(struct transport *transport, char *eth, int n,
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = strlen(transport->name);
|
len = strlen(transport->name);
|
||||||
if(strncmp(eth, transport->name, len))
|
if (strncmp(eth, transport->name, len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
eth += len;
|
eth += len;
|
||||||
if(*eth == ',')
|
if (*eth == ',')
|
||||||
eth++;
|
eth++;
|
||||||
else if(*eth != '\0')
|
else if (*eth != '\0')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*init_out = kmalloc(transport->setup_size, GFP_KERNEL);
|
*init_out = kmalloc(transport->setup_size, GFP_KERNEL);
|
||||||
if(*init_out == NULL)
|
if (*init_out == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if(!transport->setup(eth, mac_out, *init_out)){
|
if (!transport->setup(eth, mac_out, *init_out)) {
|
||||||
kfree(*init_out);
|
kfree(*init_out);
|
||||||
*init_out = NULL;
|
*init_out = NULL;
|
||||||
}
|
}
|
||||||
@@ -584,13 +581,13 @@ void register_transport(struct transport *new)
|
|||||||
list_add(&new->list, &transports);
|
list_add(&new->list, &transports);
|
||||||
spin_unlock(&transports_lock);
|
spin_unlock(&transports_lock);
|
||||||
|
|
||||||
list_for_each_safe(ele, next, ð_cmd_line){
|
list_for_each_safe(ele, next, ð_cmd_line) {
|
||||||
eth = list_entry(ele, struct eth_init, list);
|
eth = list_entry(ele, struct eth_init, list);
|
||||||
match = check_transport(new, eth->init, eth->index, &init,
|
match = check_transport(new, eth->init, eth->index, &init,
|
||||||
&mac);
|
&mac);
|
||||||
if(!match)
|
if (!match)
|
||||||
continue;
|
continue;
|
||||||
else if(init != NULL){
|
else if (init != NULL) {
|
||||||
eth_configure(eth->index, init, mac, new);
|
eth_configure(eth->index, init, mac, new);
|
||||||
kfree(init);
|
kfree(init);
|
||||||
}
|
}
|
||||||
@@ -607,11 +604,11 @@ static int eth_setup_common(char *str, int index)
|
|||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
spin_lock(&transports_lock);
|
spin_lock(&transports_lock);
|
||||||
list_for_each(ele, &transports){
|
list_for_each(ele, &transports) {
|
||||||
transport = list_entry(ele, struct transport, list);
|
transport = list_entry(ele, struct transport, list);
|
||||||
if(!check_transport(transport, str, index, &init, &mac))
|
if (!check_transport(transport, str, index, &init, &mac))
|
||||||
continue;
|
continue;
|
||||||
if(init != NULL){
|
if (init != NULL) {
|
||||||
eth_configure(index, init, mac, transport);
|
eth_configure(index, init, mac, transport);
|
||||||
kfree(init);
|
kfree(init);
|
||||||
}
|
}
|
||||||
@@ -630,15 +627,15 @@ static int __init eth_setup(char *str)
|
|||||||
int n, err;
|
int n, err;
|
||||||
|
|
||||||
err = eth_parse(str, &n, &str, &error);
|
err = eth_parse(str, &n, &str, &error);
|
||||||
if(err){
|
if (err) {
|
||||||
printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n",
|
printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n",
|
||||||
str, error);
|
str, error);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = alloc_bootmem(sizeof(*new));
|
new = alloc_bootmem(sizeof(*new));
|
||||||
if (new == NULL){
|
if (new == NULL) {
|
||||||
printk("eth_init : alloc_bootmem failed\n");
|
printk(KERN_ERR "eth_init : alloc_bootmem failed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,21 +658,21 @@ static int net_config(char *str, char **error_out)
|
|||||||
int n, err;
|
int n, err;
|
||||||
|
|
||||||
err = eth_parse(str, &n, &str, error_out);
|
err = eth_parse(str, &n, &str, error_out);
|
||||||
if(err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* This string is broken up and the pieces used by the underlying
|
/* This string is broken up and the pieces used by the underlying
|
||||||
* driver. So, it is freed only if eth_setup_common fails.
|
* driver. So, it is freed only if eth_setup_common fails.
|
||||||
*/
|
*/
|
||||||
str = kstrdup(str, GFP_KERNEL);
|
str = kstrdup(str, GFP_KERNEL);
|
||||||
if(str == NULL){
|
if (str == NULL) {
|
||||||
*error_out = "net_config failed to strdup string";
|
*error_out = "net_config failed to strdup string";
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
err = !eth_setup_common(str, n);
|
err = !eth_setup_common(str, n);
|
||||||
if(err)
|
if (err)
|
||||||
kfree(str);
|
kfree(str);
|
||||||
return(err);
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int net_id(char **str, int *start_out, int *end_out)
|
static int net_id(char **str, int *start_out, int *end_out)
|
||||||
@@ -684,7 +681,7 @@ static int net_id(char **str, int *start_out, int *end_out)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = simple_strtoul(*str, &end, 0);
|
n = simple_strtoul(*str, &end, 0);
|
||||||
if((*end != '\0') || (end == *str))
|
if ((*end != '\0') || (end == *str))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*start_out = n;
|
*start_out = n;
|
||||||
@@ -700,12 +697,12 @@ static int net_remove(int n, char **error_out)
|
|||||||
struct uml_net_private *lp;
|
struct uml_net_private *lp;
|
||||||
|
|
||||||
device = find_device(n);
|
device = find_device(n);
|
||||||
if(device == NULL)
|
if (device == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
dev = device->dev;
|
dev = device->dev;
|
||||||
lp = dev->priv;
|
lp = dev->priv;
|
||||||
if(lp->fd > 0)
|
if (lp->fd > 0)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
platform_device_unregister(&device->pdev);
|
platform_device_unregister(&device->pdev);
|
||||||
@@ -731,13 +728,13 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
|
|||||||
void (*proc)(unsigned char *, unsigned char *, void *);
|
void (*proc)(unsigned char *, unsigned char *, void *);
|
||||||
unsigned char addr_buf[4], netmask_buf[4];
|
unsigned char addr_buf[4], netmask_buf[4];
|
||||||
|
|
||||||
if(dev->open != uml_net_open)
|
if (dev->open != uml_net_open)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
lp = dev->priv;
|
lp = dev->priv;
|
||||||
|
|
||||||
proc = NULL;
|
proc = NULL;
|
||||||
switch (event){
|
switch (event) {
|
||||||
case NETDEV_UP:
|
case NETDEV_UP:
|
||||||
proc = lp->add_address;
|
proc = lp->add_address;
|
||||||
break;
|
break;
|
||||||
@@ -745,7 +742,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
|
|||||||
proc = lp->delete_address;
|
proc = lp->delete_address;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(proc != NULL){
|
if (proc != NULL) {
|
||||||
memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
|
memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
|
||||||
memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
|
memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
|
||||||
(*proc)(addr_buf, netmask_buf, &lp->user);
|
(*proc)(addr_buf, netmask_buf, &lp->user);
|
||||||
@@ -773,13 +770,13 @@ static int uml_net_init(void)
|
|||||||
* addresses which have already been set up get handled properly.
|
* addresses which have already been set up get handled properly.
|
||||||
*/
|
*/
|
||||||
spin_lock(&opened_lock);
|
spin_lock(&opened_lock);
|
||||||
list_for_each(ele, &opened){
|
list_for_each(ele, &opened) {
|
||||||
lp = list_entry(ele, struct uml_net_private, list);
|
lp = list_entry(ele, struct uml_net_private, list);
|
||||||
ip = lp->dev->ip_ptr;
|
ip = lp->dev->ip_ptr;
|
||||||
if(ip == NULL)
|
if (ip == NULL)
|
||||||
continue;
|
continue;
|
||||||
in = ip->ifa_list;
|
in = ip->ifa_list;
|
||||||
while(in != NULL){
|
while (in != NULL) {
|
||||||
uml_inetaddr_event(NULL, NETDEV_UP, in);
|
uml_inetaddr_event(NULL, NETDEV_UP, in);
|
||||||
in = in->ifa_next;
|
in = in->ifa_next;
|
||||||
}
|
}
|
||||||
@@ -797,12 +794,12 @@ static void close_devices(void)
|
|||||||
struct uml_net_private *lp;
|
struct uml_net_private *lp;
|
||||||
|
|
||||||
spin_lock(&opened_lock);
|
spin_lock(&opened_lock);
|
||||||
list_for_each(ele, &opened){
|
list_for_each(ele, &opened) {
|
||||||
lp = list_entry(ele, struct uml_net_private, list);
|
lp = list_entry(ele, struct uml_net_private, list);
|
||||||
free_irq(lp->dev->irq, lp->dev);
|
free_irq(lp->dev->irq, lp->dev);
|
||||||
if((lp->close != NULL) && (lp->fd >= 0))
|
if ((lp->close != NULL) && (lp->fd >= 0))
|
||||||
(*lp->close)(lp->fd, &lp->user);
|
(*lp->close)(lp->fd, &lp->user);
|
||||||
if(lp->remove != NULL)
|
if (lp->remove != NULL)
|
||||||
(*lp->remove)(&lp->user);
|
(*lp->remove)(&lp->user);
|
||||||
}
|
}
|
||||||
spin_unlock(&opened_lock);
|
spin_unlock(&opened_lock);
|
||||||
@@ -812,15 +809,15 @@ __uml_exitcall(close_devices);
|
|||||||
|
|
||||||
struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
|
struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
|
||||||
{
|
{
|
||||||
if((skb != NULL) && (skb_tailroom(skb) < extra)){
|
if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
|
||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
|
|
||||||
skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
|
skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
skb = skb2;
|
skb = skb2;
|
||||||
}
|
}
|
||||||
if(skb != NULL) skb_put(skb, extra);
|
if (skb != NULL) skb_put(skb, extra);
|
||||||
return(skb);
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
|
void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
|
||||||
@@ -832,9 +829,9 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
|
|||||||
struct in_ifaddr *in;
|
struct in_ifaddr *in;
|
||||||
unsigned char address[4], netmask[4];
|
unsigned char address[4], netmask[4];
|
||||||
|
|
||||||
if(ip == NULL) return;
|
if (ip == NULL) return;
|
||||||
in = ip->ifa_list;
|
in = ip->ifa_list;
|
||||||
while(in != NULL){
|
while (in != NULL) {
|
||||||
memcpy(address, &in->ifa_address, sizeof(address));
|
memcpy(address, &in->ifa_address, sizeof(address));
|
||||||
memcpy(netmask, &in->ifa_mask, sizeof(netmask));
|
memcpy(netmask, &in->ifa_mask, sizeof(netmask));
|
||||||
(*cb)(address, netmask, arg);
|
(*cb)(address, netmask, arg);
|
||||||
@@ -849,15 +846,15 @@ int dev_netmask(void *d, void *m)
|
|||||||
struct in_ifaddr *in;
|
struct in_ifaddr *in;
|
||||||
__be32 *mask_out = m;
|
__be32 *mask_out = m;
|
||||||
|
|
||||||
if(ip == NULL)
|
if (ip == NULL)
|
||||||
return(1);
|
return 1;
|
||||||
|
|
||||||
in = ip->ifa_list;
|
in = ip->ifa_list;
|
||||||
if(in == NULL)
|
if (in == NULL)
|
||||||
return(1);
|
return 1;
|
||||||
|
|
||||||
*mask_out = in->ifa_mask;
|
*mask_out = in->ifa_mask;
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *get_output_buffer(int *len_out)
|
void *get_output_buffer(int *len_out)
|
||||||
@@ -865,7 +862,7 @@ void *get_output_buffer(int *len_out)
|
|||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
ret = (void *) __get_free_pages(GFP_KERNEL, 0);
|
ret = (void *) __get_free_pages(GFP_KERNEL, 0);
|
||||||
if(ret) *len_out = PAGE_SIZE;
|
if (ret) *len_out = PAGE_SIZE;
|
||||||
else *len_out = 0;
|
else *len_out = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -881,16 +878,16 @@ int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
|
|||||||
char *remain;
|
char *remain;
|
||||||
|
|
||||||
remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
|
remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
|
||||||
if(remain != NULL){
|
if (remain != NULL) {
|
||||||
printk("tap_setup_common - Extra garbage on specification : "
|
printk(KERN_ERR "tap_setup_common - Extra garbage on "
|
||||||
"'%s'\n", remain);
|
"specification : '%s'\n", remain);
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short eth_protocol(struct sk_buff *skb)
|
unsigned short eth_protocol(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return(eth_type_trans(skb, skb->dev));
|
return eth_type_trans(skb, skb->dev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,32 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include "user.h"
|
|
||||||
#include "kern_util.h"
|
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
|
#include "kern_constants.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
#include "kern_constants.h"
|
#include "user.h"
|
||||||
|
|
||||||
int tap_open_common(void *dev, char *gate_addr)
|
int tap_open_common(void *dev, char *gate_addr)
|
||||||
{
|
{
|
||||||
int tap_addr[4];
|
int tap_addr[4];
|
||||||
|
|
||||||
if(gate_addr == NULL)
|
if (gate_addr == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
|
if (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
|
||||||
&tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
|
&tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4) {
|
||||||
printk("Invalid tap IP address - '%s'\n", gate_addr);
|
printk(UM_KERN_ERR "Invalid tap IP address - '%s'\n",
|
||||||
|
gate_addr);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -38,15 +36,15 @@ void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
|
|||||||
{
|
{
|
||||||
int tap_addr[4];
|
int tap_addr[4];
|
||||||
|
|
||||||
if((gate_addr != NULL) &&
|
if ((gate_addr != NULL) &&
|
||||||
(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
|
(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
|
||||||
&tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
|
&tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
|
||||||
(eth_addr[0] == tap_addr[0]) &&
|
(eth_addr[0] == tap_addr[0]) &&
|
||||||
(eth_addr[1] == tap_addr[1]) &&
|
(eth_addr[1] == tap_addr[1]) &&
|
||||||
(eth_addr[2] == tap_addr[2]) &&
|
(eth_addr[2] == tap_addr[2]) &&
|
||||||
(eth_addr[3] == tap_addr[3])){
|
(eth_addr[3] == tap_addr[3])) {
|
||||||
printk("The tap IP address and the UML eth IP address"
|
printk(UM_KERN_ERR "The tap IP address and the UML eth IP "
|
||||||
" must be different\n");
|
"address must be different\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,24 +55,28 @@ void read_output(int fd, char *output, int len)
|
|||||||
char c;
|
char c;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
if(output == NULL){
|
if (output == NULL) {
|
||||||
output = &c;
|
output = &c;
|
||||||
len = sizeof(c);
|
len = sizeof(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
*output = '\0';
|
*output = '\0';
|
||||||
ret = os_read_file(fd, &remain, sizeof(remain));
|
ret = read(fd, &remain, sizeof(remain));
|
||||||
|
|
||||||
if (ret != sizeof(remain)) {
|
if (ret != sizeof(remain)) {
|
||||||
|
if (ret < 0)
|
||||||
|
ret = -errno;
|
||||||
expected = sizeof(remain);
|
expected = sizeof(remain);
|
||||||
str = "length";
|
str = "length";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(remain != 0){
|
while (remain != 0) {
|
||||||
expected = (remain < len) ? remain : len;
|
expected = (remain < len) ? remain : len;
|
||||||
ret = os_read_file(fd, output, expected);
|
ret = read(fd, output, expected);
|
||||||
if (ret != expected) {
|
if (ret != expected) {
|
||||||
|
if (ret < 0)
|
||||||
|
ret = -errno;
|
||||||
str = "data";
|
str = "data";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -85,20 +87,22 @@ void read_output(int fd, char *output, int len)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
printk("read_output - read of %s failed, errno = %d\n", str, -ret);
|
printk(UM_KERN_ERR "read_output - read of %s failed, "
|
||||||
|
"errno = %d\n", str, -ret);
|
||||||
else
|
else
|
||||||
printk("read_output - read of %s failed, read only %d of %d bytes\n", str, ret, expected);
|
printk(UM_KERN_ERR "read_output - read of %s failed, read only "
|
||||||
|
"%d of %d bytes\n", str, ret, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_read(int fd, void *buf, int len)
|
int net_read(int fd, void *buf, int len)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = os_read_file(fd, buf, len);
|
n = read(fd, buf, len);
|
||||||
|
|
||||||
if(n == -EAGAIN)
|
if ((n < 0) && (errno == EAGAIN))
|
||||||
return 0;
|
return 0;
|
||||||
else if(n == 0)
|
else if (n == 0)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -108,12 +112,12 @@ int net_recvfrom(int fd, void *buf, int len)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL));
|
CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL));
|
||||||
if(n < 0){
|
if (n < 0) {
|
||||||
if(errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
else if(n == 0)
|
else if (n == 0)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -122,11 +126,11 @@ int net_write(int fd, void *buf, int len)
|
|||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = os_write_file(fd, buf, len);
|
n = write(fd, buf, len);
|
||||||
|
|
||||||
if(n == -EAGAIN)
|
if ((n < 0) && (errno == EAGAIN))
|
||||||
return 0;
|
return 0;
|
||||||
else if(n == 0)
|
else if (n == 0)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -136,12 +140,12 @@ int net_send(int fd, void *buf, int len)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
CATCH_EINTR(n = send(fd, buf, len, 0));
|
CATCH_EINTR(n = send(fd, buf, len, 0));
|
||||||
if(n < 0){
|
if (n < 0) {
|
||||||
if(errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
else if(n == 0)
|
else if (n == 0)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -152,12 +156,12 @@ int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
|
|||||||
|
|
||||||
CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
|
CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
|
||||||
sock_len));
|
sock_len));
|
||||||
if(n < 0){
|
if (n < 0) {
|
||||||
if(errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
else if(n == 0)
|
else if (n == 0)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -171,7 +175,7 @@ static void change_pre_exec(void *arg)
|
|||||||
{
|
{
|
||||||
struct change_pre_exec_data *data = arg;
|
struct change_pre_exec_data *data = arg;
|
||||||
|
|
||||||
os_close_file(data->close_me);
|
close(data->close_me);
|
||||||
dup2(data->stdout, 1);
|
dup2(data->stdout, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +185,9 @@ static int change_tramp(char **argv, char *output, int output_len)
|
|||||||
struct change_pre_exec_data pe_data;
|
struct change_pre_exec_data pe_data;
|
||||||
|
|
||||||
err = os_pipe(fds, 1, 0);
|
err = os_pipe(fds, 1, 0);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("change_tramp - pipe failed, err = %d\n", -err);
|
printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n",
|
||||||
|
-err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
pe_data.close_me = fds[0];
|
pe_data.close_me = fds[0];
|
||||||
@@ -192,8 +197,8 @@ static int change_tramp(char **argv, char *output, int output_len)
|
|||||||
if (pid > 0) /* Avoid hang as we won't get data in failure case. */
|
if (pid > 0) /* Avoid hang as we won't get data in failure case. */
|
||||||
read_output(fds[0], output, output_len);
|
read_output(fds[0], output, output_len);
|
||||||
|
|
||||||
os_close_file(fds[0]);
|
close(fds[0]);
|
||||||
os_close_file(fds[1]);
|
close(fds[1]);
|
||||||
|
|
||||||
if (pid > 0)
|
if (pid > 0)
|
||||||
CATCH_EINTR(err = waitpid(pid, NULL, 0));
|
CATCH_EINTR(err = waitpid(pid, NULL, 0));
|
||||||
@@ -218,13 +223,14 @@ static void change(char *dev, char *what, unsigned char *addr,
|
|||||||
|
|
||||||
output_len = UM_KERN_PAGE_SIZE;
|
output_len = UM_KERN_PAGE_SIZE;
|
||||||
output = kmalloc(output_len, UM_GFP_KERNEL);
|
output = kmalloc(output_len, UM_GFP_KERNEL);
|
||||||
if(output == NULL)
|
if (output == NULL)
|
||||||
printk("change : failed to allocate output buffer\n");
|
printk(UM_KERN_ERR "change : failed to allocate output "
|
||||||
|
"buffer\n");
|
||||||
|
|
||||||
pid = change_tramp(argv, output, output_len);
|
pid = change_tramp(argv, output, output_len);
|
||||||
if(pid < 0) return;
|
if (pid < 0) return;
|
||||||
|
|
||||||
if(output != NULL){
|
if (output != NULL) {
|
||||||
printk("%s", output);
|
printk("%s", output);
|
||||||
kfree(output);
|
kfree(output);
|
||||||
}
|
}
|
||||||
@@ -246,13 +252,13 @@ char *split_if_spec(char *str, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, str);
|
va_start(ap, str);
|
||||||
while((arg = va_arg(ap, char **)) != NULL){
|
while ((arg = va_arg(ap, char **)) != NULL) {
|
||||||
if(*str == '\0')
|
if (*str == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
end = strchr(str, ',');
|
end = strchr(str, ',');
|
||||||
if(end != str)
|
if (end != str)
|
||||||
*arg = str;
|
*arg = str;
|
||||||
if(end == NULL)
|
if (end == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
*end++ = '\0';
|
*end++ = '\0';
|
||||||
str = end;
|
str = end;
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/init.h"
|
#include "linux/init.h"
|
||||||
#include "linux/netdevice.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/etherdevice.h"
|
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
|
||||||
#include "pcap_user.h"
|
#include "pcap_user.h"
|
||||||
|
|
||||||
struct pcap_init {
|
struct pcap_init {
|
||||||
@@ -37,7 +35,7 @@ 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);
|
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
||||||
if(*skb == NULL)
|
if (*skb == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return pcap_user_read(fd, skb_mac_header(*skb),
|
return pcap_user_read(fd, skb_mac_header(*skb),
|
||||||
@@ -71,28 +69,29 @@ int pcap_setup(char *str, char **mac_out, void *data)
|
|||||||
|
|
||||||
remain = split_if_spec(str, &host_if, &init->filter,
|
remain = split_if_spec(str, &host_if, &init->filter,
|
||||||
&options[0], &options[1], mac_out, NULL);
|
&options[0], &options[1], mac_out, NULL);
|
||||||
if(remain != NULL){
|
if (remain != NULL) {
|
||||||
printk(KERN_ERR "pcap_setup - Extra garbage on "
|
printk(KERN_ERR "pcap_setup - Extra garbage on "
|
||||||
"specification : '%s'\n", remain);
|
"specification : '%s'\n", remain);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(host_if != NULL)
|
if (host_if != NULL)
|
||||||
init->host_if = host_if;
|
init->host_if = host_if;
|
||||||
|
|
||||||
for(i = 0; i < ARRAY_SIZE(options); i++){
|
for (i = 0; i < ARRAY_SIZE(options); i++) {
|
||||||
if(options[i] == NULL)
|
if (options[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
if(!strcmp(options[i], "promisc"))
|
if (!strcmp(options[i], "promisc"))
|
||||||
init->promisc = 1;
|
init->promisc = 1;
|
||||||
else if(!strcmp(options[i], "nopromisc"))
|
else if (!strcmp(options[i], "nopromisc"))
|
||||||
init->promisc = 0;
|
init->promisc = 0;
|
||||||
else if(!strcmp(options[i], "optimize"))
|
else if (!strcmp(options[i], "optimize"))
|
||||||
init->optimize = 1;
|
init->optimize = 1;
|
||||||
else if(!strcmp(options[i], "nooptimize"))
|
else if (!strcmp(options[i], "nooptimize"))
|
||||||
init->optimize = 0;
|
init->optimize = 0;
|
||||||
else {
|
else {
|
||||||
printk("pcap_setup : bad option - '%s'\n", options[i]);
|
printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
|
||||||
|
options[i]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
|
#include <string.h>
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
#include "pcap_user.h"
|
#include "pcap_user.h"
|
||||||
#include "user.h"
|
|
||||||
#include "um_malloc.h"
|
|
||||||
#include "kern_constants.h"
|
#include "kern_constants.h"
|
||||||
|
#include "um_malloc.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
||||||
|
|
||||||
@@ -26,7 +24,7 @@ static int pcap_user_init(void *data, void *dev)
|
|||||||
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, MAX_PACKET, 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);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -43,18 +41,19 @@ static int pcap_open(void *data)
|
|||||||
__u32 netmask;
|
__u32 netmask;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if(pri->pcap == NULL)
|
if (pri->pcap == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if(pri->filter != NULL){
|
if (pri->filter != NULL) {
|
||||||
err = dev_netmask(pri->dev, &netmask);
|
err = dev_netmask(pri->dev, &netmask);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
|
printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
pri->compiled = kmalloc(sizeof(struct bpf_program), UM_GFP_KERNEL);
|
pri->compiled = kmalloc(sizeof(struct bpf_program),
|
||||||
if(pri->compiled == NULL){
|
UM_GFP_KERNEL);
|
||||||
|
if (pri->compiled == NULL) {
|
||||||
printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
|
printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -62,31 +61,35 @@ static int pcap_open(void *data)
|
|||||||
err = pcap_compile(pri->pcap,
|
err = pcap_compile(pri->pcap,
|
||||||
(struct bpf_program *) pri->compiled,
|
(struct bpf_program *) pri->compiled,
|
||||||
pri->filter, pri->optimize, netmask);
|
pri->filter, pri->optimize, netmask);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
|
printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
|
||||||
"'%s'\n", pcap_geterr(pri->pcap));
|
"'%s'\n", pcap_geterr(pri->pcap));
|
||||||
return -EIO;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pcap_setfilter(pri->pcap, pri->compiled);
|
err = pcap_setfilter(pri->pcap, pri->compiled);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
|
printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
|
||||||
"failed - '%s'\n", pcap_geterr(pri->pcap));
|
"failed - '%s'\n", pcap_geterr(pri->pcap));
|
||||||
return -EIO;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PCAP_FD(pri->pcap);
|
return PCAP_FD(pri->pcap);
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(pri->compiled);
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcap_remove(void *data)
|
static void pcap_remove(void *data)
|
||||||
{
|
{
|
||||||
struct pcap_data *pri = data;
|
struct pcap_data *pri = data;
|
||||||
|
|
||||||
if(pri->compiled != NULL)
|
if (pri->compiled != NULL)
|
||||||
pcap_freecode(pri->compiled);
|
pcap_freecode(pri->compiled);
|
||||||
|
|
||||||
if(pri->pcap != NULL)
|
if (pri->pcap != NULL)
|
||||||
pcap_close(pri->pcap);
|
pcap_close(pri->pcap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,12 +118,12 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
|
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
|
||||||
if(n < 0){
|
if (n < 0) {
|
||||||
printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
|
printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
|
||||||
pcap_geterr(pri->pcap));
|
pcap_geterr(pri->pcap));
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
else if(n == 0)
|
else if (n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return hdata.len;
|
return hdata.len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#include "linux/kernel.h"
|
/*
|
||||||
#include "linux/stddef.h"
|
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
#include "linux/init.h"
|
* Licensed under the GPL.
|
||||||
#include "linux/netdevice.h"
|
*/
|
||||||
#include "linux/if_arp.h"
|
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
|
||||||
#include "kern.h"
|
|
||||||
#include "slip.h"
|
#include "slip.h"
|
||||||
|
|
||||||
struct slip_init {
|
struct slip_init {
|
||||||
@@ -43,21 +44,21 @@ void slip_init(struct net_device *dev, void *data)
|
|||||||
|
|
||||||
static unsigned short slip_protocol(struct sk_buff *skbuff)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct net_kern_info slip_kern_info = {
|
const struct net_kern_info slip_kern_info = {
|
||||||
@@ -71,12 +72,11 @@ static int slip_setup(char *str, char **mac_out, void *data)
|
|||||||
{
|
{
|
||||||
struct slip_init *init = data;
|
struct slip_init *init = data;
|
||||||
|
|
||||||
*init = ((struct slip_init)
|
*init = ((struct slip_init) { .gate_addr = NULL });
|
||||||
{ .gate_addr = NULL });
|
|
||||||
|
|
||||||
if(str[0] != '\0')
|
if (str[0] != '\0')
|
||||||
init->gate_addr = str;
|
init->gate_addr = str;
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct transport slip_transport = {
|
static struct transport slip_transport = {
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
|
* Licensed under the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/termios.h>
|
#include <sys/termios.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/signal.h>
|
|
||||||
#include "kern_util.h"
|
|
||||||
#include "user.h"
|
|
||||||
#include "net_user.h"
|
|
||||||
#include "slip.h"
|
|
||||||
#include "slip_common.h"
|
|
||||||
#include "os.h"
|
|
||||||
#include "um_malloc.h"
|
|
||||||
#include "kern_constants.h"
|
#include "kern_constants.h"
|
||||||
|
#include "net_user.h"
|
||||||
|
#include "os.h"
|
||||||
|
#include "slip.h"
|
||||||
|
#include "um_malloc.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
static int slip_user_init(void *data, void *dev)
|
static int slip_user_init(void *data, void *dev)
|
||||||
{
|
{
|
||||||
@@ -31,8 +32,9 @@ static int set_up_tty(int fd)
|
|||||||
struct termios tios;
|
struct termios tios;
|
||||||
|
|
||||||
if (tcgetattr(fd, &tios) < 0) {
|
if (tcgetattr(fd, &tios) < 0) {
|
||||||
printk("could not get initial terminal attributes\n");
|
printk(UM_KERN_ERR "could not get initial terminal "
|
||||||
return(-1);
|
"attributes\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
|
tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
|
||||||
@@ -48,10 +50,10 @@ static int set_up_tty(int fd)
|
|||||||
cfsetispeed(&tios, B38400);
|
cfsetispeed(&tios, B38400);
|
||||||
|
|
||||||
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
|
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
|
||||||
printk("failed to set terminal attributes\n");
|
printk(UM_KERN_ERR "failed to set terminal attributes\n");
|
||||||
return(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct slip_pre_exec_data {
|
struct slip_pre_exec_data {
|
||||||
@@ -64,9 +66,11 @@ static void slip_pre_exec(void *arg)
|
|||||||
{
|
{
|
||||||
struct slip_pre_exec_data *data = arg;
|
struct slip_pre_exec_data *data = arg;
|
||||||
|
|
||||||
if(data->stdin >= 0) dup2(data->stdin, 0);
|
if (data->stdin >= 0)
|
||||||
|
dup2(data->stdin, 0);
|
||||||
dup2(data->stdout, 1);
|
dup2(data->stdout, 1);
|
||||||
if(data->close_me >= 0) os_close_file(data->close_me);
|
if (data->close_me >= 0)
|
||||||
|
close(data->close_me);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slip_tramp(char **argv, int fd)
|
static int slip_tramp(char **argv, int fd)
|
||||||
@@ -76,8 +80,9 @@ static int slip_tramp(char **argv, int fd)
|
|||||||
int status, pid, fds[2], err, output_len;
|
int status, pid, fds[2], err, output_len;
|
||||||
|
|
||||||
err = os_pipe(fds, 1, 0);
|
err = os_pipe(fds, 1, 0);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("slip_tramp : pipe failed, err = %d\n", -err);
|
printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
|
||||||
|
-err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,41 +91,42 @@ static int slip_tramp(char **argv, int fd)
|
|||||||
pe_data.stdout = fds[1];
|
pe_data.stdout = fds[1];
|
||||||
pe_data.close_me = fds[0];
|
pe_data.close_me = fds[0];
|
||||||
err = run_helper(slip_pre_exec, &pe_data, argv);
|
err = run_helper(slip_pre_exec, &pe_data, argv);
|
||||||
if(err < 0)
|
if (err < 0)
|
||||||
goto out_close;
|
goto out_close;
|
||||||
pid = err;
|
pid = err;
|
||||||
|
|
||||||
output_len = UM_KERN_PAGE_SIZE;
|
output_len = UM_KERN_PAGE_SIZE;
|
||||||
output = kmalloc(output_len, UM_GFP_KERNEL);
|
output = kmalloc(output_len, UM_GFP_KERNEL);
|
||||||
if(output == NULL){
|
if (output == NULL) {
|
||||||
printk("slip_tramp : failed to allocate output buffer\n");
|
printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
|
||||||
|
"buffer\n");
|
||||||
os_kill_process(pid, 1);
|
os_kill_process(pid, 1);
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_close_file(fds[1]);
|
close(fds[1]);
|
||||||
read_output(fds[0], output, output_len);
|
read_output(fds[0], output, output_len);
|
||||||
printk("%s", output);
|
printk("%s", output);
|
||||||
|
|
||||||
CATCH_EINTR(err = waitpid(pid, &status, 0));
|
CATCH_EINTR(err = waitpid(pid, &status, 0));
|
||||||
if(err < 0)
|
if (err < 0)
|
||||||
err = errno;
|
err = errno;
|
||||||
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
|
else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
|
||||||
printk("'%s' didn't exit with status 0\n", argv[0]);
|
printk(UM_KERN_ERR "'%s' didn't exit with status 0\n", argv[0]);
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
}
|
}
|
||||||
else err = 0;
|
else err = 0;
|
||||||
|
|
||||||
os_close_file(fds[0]);
|
close(fds[0]);
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
kfree(output);
|
kfree(output);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out_close:
|
out_close:
|
||||||
os_close_file(fds[0]);
|
close(fds[0]);
|
||||||
os_close_file(fds[1]);
|
close(fds[1]);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -135,55 +141,59 @@ static int slip_open(void *data)
|
|||||||
int sfd, mfd, err;
|
int sfd, mfd, err;
|
||||||
|
|
||||||
err = get_pty();
|
err = get_pty();
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("slip-open : Failed to open pty, err = %d\n", -err);
|
printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
|
||||||
|
-err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mfd = err;
|
mfd = err;
|
||||||
|
|
||||||
err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
|
err = open(ptsname(mfd), O_RDWR, 0);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("Couldn't open tty for slip line, err = %d\n", -err);
|
printk(UM_KERN_ERR "Couldn't open tty for slip line, "
|
||||||
|
"err = %d\n", -err);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
sfd = err;
|
sfd = err;
|
||||||
|
|
||||||
if(set_up_tty(sfd))
|
if (set_up_tty(sfd))
|
||||||
goto out_close2;
|
goto out_close2;
|
||||||
|
|
||||||
pri->slave = sfd;
|
pri->slave = sfd;
|
||||||
pri->slip.pos = 0;
|
pri->slip.pos = 0;
|
||||||
pri->slip.esc = 0;
|
pri->slip.esc = 0;
|
||||||
if(pri->gate_addr != NULL){
|
if (pri->gate_addr != NULL) {
|
||||||
sprintf(version_buf, "%d", UML_NET_VERSION);
|
sprintf(version_buf, "%d", UML_NET_VERSION);
|
||||||
strcpy(gate_buf, pri->gate_addr);
|
strcpy(gate_buf, pri->gate_addr);
|
||||||
|
|
||||||
err = slip_tramp(argv, sfd);
|
err = slip_tramp(argv, sfd);
|
||||||
|
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("slip_tramp failed - err = %d\n", -err);
|
printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
|
||||||
|
-err);
|
||||||
goto out_close2;
|
goto out_close2;
|
||||||
}
|
}
|
||||||
err = os_get_ifname(pri->slave, pri->name);
|
err = os_get_ifname(pri->slave, pri->name);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("get_ifname failed, err = %d\n", -err);
|
printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
|
||||||
|
-err);
|
||||||
goto out_close2;
|
goto out_close2;
|
||||||
}
|
}
|
||||||
iter_addresses(pri->dev, open_addr, pri->name);
|
iter_addresses(pri->dev, open_addr, pri->name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err = os_set_slip(sfd);
|
err = os_set_slip(sfd);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("Failed to set slip discipline encapsulation - "
|
printk(UM_KERN_ERR "Failed to set slip discipline "
|
||||||
"err = %d\n", -err);
|
"encapsulation - err = %d\n", -err);
|
||||||
goto out_close2;
|
goto out_close2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(mfd);
|
return mfd;
|
||||||
out_close2:
|
out_close2:
|
||||||
os_close_file(sfd);
|
close(sfd);
|
||||||
out_close:
|
out_close:
|
||||||
os_close_file(mfd);
|
close(mfd);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -196,17 +206,17 @@ static void slip_close(int fd, void *data)
|
|||||||
NULL };
|
NULL };
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if(pri->gate_addr != NULL)
|
if (pri->gate_addr != NULL)
|
||||||
iter_addresses(pri->dev, close_addr, pri->name);
|
iter_addresses(pri->dev, close_addr, pri->name);
|
||||||
|
|
||||||
sprintf(version_buf, "%d", UML_NET_VERSION);
|
sprintf(version_buf, "%d", UML_NET_VERSION);
|
||||||
|
|
||||||
err = slip_tramp(argv, pri->slave);
|
err = slip_tramp(argv, pri->slave);
|
||||||
|
|
||||||
if(err != 0)
|
if (err != 0)
|
||||||
printk("slip_tramp failed - errno = %d\n", -err);
|
printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
|
||||||
os_close_file(fd);
|
close(fd);
|
||||||
os_close_file(pri->slave);
|
close(pri->slave);
|
||||||
pri->slave = -1;
|
pri->slave = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +232,7 @@ int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
|
|||||||
|
|
||||||
static int slip_set_mtu(int mtu, void *data)
|
static int slip_set_mtu(int mtu, void *data)
|
||||||
{
|
{
|
||||||
return(mtu);
|
return mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
|
static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
|
||||||
@@ -230,7 +240,8 @@ static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
|
|||||||
{
|
{
|
||||||
struct slip_data *pri = data;
|
struct slip_data *pri = data;
|
||||||
|
|
||||||
if(pri->slave < 0) return;
|
if (pri->slave < 0)
|
||||||
|
return;
|
||||||
open_addr(addr, netmask, pri->name);
|
open_addr(addr, netmask, pri->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +250,8 @@ static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
|
|||||||
{
|
{
|
||||||
struct slip_data *pri = data;
|
struct slip_data *pri = data;
|
||||||
|
|
||||||
if(pri->slave < 0) return;
|
if (pri->slave < 0)
|
||||||
|
return;
|
||||||
close_addr(addr, netmask, pri->name);
|
close_addr(addr, netmask, pri->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
#include "linux/kernel.h"
|
/*
|
||||||
#include "linux/stddef.h"
|
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
|
* Licensed under the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/if_arp.h>
|
||||||
#include "linux/init.h"
|
#include "linux/init.h"
|
||||||
#include "linux/netdevice.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/if_arp.h"
|
#include <linux/string.h>
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
#include "kern.h"
|
|
||||||
#include "slirp.h"
|
#include "slirp.h"
|
||||||
|
|
||||||
struct slirp_init {
|
struct slirp_init {
|
||||||
@@ -39,29 +42,28 @@ void slirp_init(struct net_device *dev, void *data)
|
|||||||
dev->tx_queue_len = 256;
|
dev->tx_queue_len = 256;
|
||||||
dev->flags = IFF_NOARP;
|
dev->flags = IFF_NOARP;
|
||||||
printk("SLIRP backend - command line:");
|
printk("SLIRP backend - command line:");
|
||||||
for(i=0;spri->argw.argv[i]!=NULL;i++) {
|
for (i = 0; spri->argw.argv[i] != NULL; i++)
|
||||||
printk(" '%s'",spri->argw.argv[i]);
|
printk(" '%s'",spri->argw.argv[i]);
|
||||||
}
|
|
||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short slirp_protocol(struct sk_buff *skbuff)
|
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 = {
|
||||||
@@ -76,31 +78,32 @@ static int slirp_setup(char *str, char **mac_out, void *data)
|
|||||||
struct slirp_init *init = data;
|
struct slirp_init *init = data;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|
||||||
*init = ((struct slirp_init)
|
*init = ((struct slirp_init) { .argw = { { "slirp", NULL } } });
|
||||||
{ .argw = { { "slirp", NULL } } });
|
|
||||||
|
|
||||||
str = split_if_spec(str, mac_out, NULL);
|
str = split_if_spec(str, mac_out, NULL);
|
||||||
|
|
||||||
if(str == NULL) { /* no command line given after MAC addr */
|
if (str == NULL) /* no command line given after MAC addr */
|
||||||
return(1);
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(i>=SLIRP_MAX_ARGS-1) {
|
if (i >= SLIRP_MAX_ARGS - 1) {
|
||||||
printk("slirp_setup: truncating slirp arguments\n");
|
printk(KERN_WARNING "slirp_setup: truncating slirp "
|
||||||
|
"arguments\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
init->argw.argv[i++] = str;
|
init->argw.argv[i++] = str;
|
||||||
while(*str && *str!=',') {
|
while(*str && *str!=',') {
|
||||||
if(*str=='_') *str=' ';
|
if (*str == '_')
|
||||||
|
*str=' ';
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
if(*str!=',')
|
if (*str != ',')
|
||||||
break;
|
break;
|
||||||
*str++='\0';
|
*str++ = '\0';
|
||||||
} while(1);
|
} while (1);
|
||||||
init->argw.argv[i]=NULL;
|
|
||||||
return(1);
|
init->argw.argv[i] = NULL;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct transport slirp_transport = {
|
static struct transport slirp_transport = {
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
#include <stdio.h>
|
/*
|
||||||
#include <stdlib.h>
|
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
|
* Licensed under the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/signal.h>
|
#include "kern_constants.h"
|
||||||
#include "kern_util.h"
|
|
||||||
#include "user.h"
|
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
#include "slirp.h"
|
|
||||||
#include "slip_common.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "slirp.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
static int slirp_user_init(void *data, void *dev)
|
static int slirp_user_init(void *data, void *dev)
|
||||||
{
|
{
|
||||||
@@ -31,8 +30,10 @@ static void slirp_pre_exec(void *arg)
|
|||||||
{
|
{
|
||||||
struct slirp_pre_exec_data *data = arg;
|
struct slirp_pre_exec_data *data = arg;
|
||||||
|
|
||||||
if(data->stdin != -1) dup2(data->stdin, 0);
|
if (data->stdin != -1)
|
||||||
if(data->stdout != -1) dup2(data->stdout, 1);
|
dup2(data->stdin, 0);
|
||||||
|
if (data->stdout != -1)
|
||||||
|
dup2(data->stdout, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slirp_tramp(char **argv, int fd)
|
static int slirp_tramp(char **argv, int fd)
|
||||||
@@ -44,7 +45,7 @@ static int slirp_tramp(char **argv, int fd)
|
|||||||
pe_data.stdout = fd;
|
pe_data.stdout = fd;
|
||||||
pid = run_helper(slirp_pre_exec, &pe_data, argv);
|
pid = run_helper(slirp_pre_exec, &pe_data, argv);
|
||||||
|
|
||||||
return(pid);
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slirp_open(void *data)
|
static int slirp_open(void *data)
|
||||||
@@ -53,12 +54,12 @@ static int slirp_open(void *data)
|
|||||||
int fds[2], pid, err;
|
int fds[2], pid, err;
|
||||||
|
|
||||||
err = os_pipe(fds, 1, 1);
|
err = os_pipe(fds, 1, 1);
|
||||||
if(err)
|
if (err)
|
||||||
return(err);
|
return err;
|
||||||
|
|
||||||
err = slirp_tramp(pri->argw.argv, fds[1]);
|
err = slirp_tramp(pri->argw.argv, fds[1]);
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("slirp_tramp failed - errno = %d\n", -err);
|
printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
pid = err;
|
pid = err;
|
||||||
@@ -68,10 +69,10 @@ static int slirp_open(void *data)
|
|||||||
pri->slip.esc = 0;
|
pri->slip.esc = 0;
|
||||||
pri->pid = err;
|
pri->pid = err;
|
||||||
|
|
||||||
return(fds[0]);
|
return fds[0];
|
||||||
out:
|
out:
|
||||||
os_close_file(fds[0]);
|
close(fds[0]);
|
||||||
os_close_file(fds[1]);
|
close(fds[1]);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,31 +81,33 @@ static void slirp_close(int fd, void *data)
|
|||||||
struct slirp_data *pri = data;
|
struct slirp_data *pri = data;
|
||||||
int status,err;
|
int status,err;
|
||||||
|
|
||||||
os_close_file(fd);
|
close(fd);
|
||||||
os_close_file(pri->slave);
|
close(pri->slave);
|
||||||
|
|
||||||
pri->slave = -1;
|
pri->slave = -1;
|
||||||
|
|
||||||
if(pri->pid<1) {
|
if (pri->pid<1) {
|
||||||
printk("slirp_close: no child process to shut down\n");
|
printk(UM_KERN_ERR "slirp_close: no child process to shut "
|
||||||
|
"down\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if(kill(pri->pid, SIGHUP)<0) {
|
if (kill(pri->pid, SIGHUP)<0) {
|
||||||
printk("slirp_close: sending hangup to %d failed (%d)\n",
|
printk(UM_KERN_ERR "slirp_close: sending hangup to %d failed "
|
||||||
pri->pid, errno);
|
"(%d)\n", pri->pid, errno);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
|
CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
|
||||||
if(err < 0) {
|
if (err < 0) {
|
||||||
printk("slirp_close: waitpid returned %d\n", errno);
|
printk(UM_KERN_ERR "slirp_close: waitpid returned %d\n", errno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(err == 0) {
|
if (err == 0) {
|
||||||
printk("slirp_close: process %d has not exited\n", pri->pid);
|
printk(UM_KERN_ERR "slirp_close: process %d has not exited\n",
|
||||||
|
pri->pid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +126,7 @@ int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
|
|||||||
|
|
||||||
static int slirp_set_mtu(int mtu, void *data)
|
static int slirp_set_mtu(int mtu, void *data)
|
||||||
{
|
{
|
||||||
return(mtu);
|
return mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct net_user_info slirp_user_info = {
|
const struct net_user_info slirp_user_info = {
|
||||||
|
|||||||
@@ -7,10 +7,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/kernel.h"
|
|
||||||
#include "linux/init.h"
|
#include "linux/init.h"
|
||||||
#include "linux/netdevice.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/etherdevice.h"
|
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
#include "vde.h"
|
#include "vde.h"
|
||||||
@@ -30,12 +28,12 @@ static void vde_init(struct net_device *dev, void *data)
|
|||||||
vpri->conn = NULL;
|
vpri->conn = NULL;
|
||||||
vpri->dev = dev;
|
vpri->dev = dev;
|
||||||
|
|
||||||
printk(KERN_INFO "vde backend - %s, ", vpri->vde_switch ?
|
printk("vde backend - %s, ", vpri->vde_switch ?
|
||||||
vpri->vde_switch : "(default socket)");
|
vpri->vde_switch : "(default socket)");
|
||||||
|
|
||||||
vde_init_libstuff(vpri, init);
|
vde_init_libstuff(vpri, init);
|
||||||
|
|
||||||
printk(KERN_INFO "\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)
|
||||||
|
|||||||
@@ -3,15 +3,13 @@
|
|||||||
* Licensed under the GPL.
|
* Licensed under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <libvdeplug.h>
|
#include <libvdeplug.h>
|
||||||
#include "net_user.h"
|
|
||||||
#include "kern_util.h"
|
|
||||||
#include "kern_constants.h"
|
#include "kern_constants.h"
|
||||||
#include "user.h"
|
#include "net_user.h"
|
||||||
#include "os.h"
|
|
||||||
#include "um_malloc.h"
|
#include "um_malloc.h"
|
||||||
|
#include "user.h"
|
||||||
#include "vde.h"
|
#include "vde.h"
|
||||||
|
|
||||||
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_ETAP_H
|
||||||
|
#define __DRIVERS_ETAP_H
|
||||||
|
|
||||||
#include "net_user.h"
|
#include "net_user.h"
|
||||||
|
|
||||||
struct ethertap_data {
|
struct ethertap_data {
|
||||||
@@ -15,13 +18,4 @@ struct ethertap_data {
|
|||||||
|
|
||||||
extern const struct net_user_info ethertap_user_info;
|
extern const struct net_user_info ethertap_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:
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -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).
|
* 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.
|
* Copyright (C) 2001 by various other people who didn't put their name here.
|
||||||
* Licensed under the GPL.
|
* Licensed under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/init.h"
|
#include "linux/init.h"
|
||||||
#include "linux/netdevice.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/etherdevice.h"
|
|
||||||
#include "net_kern.h"
|
|
||||||
#include "net_user.h"
|
|
||||||
#include "etap.h"
|
#include "etap.h"
|
||||||
|
#include "net_kern.h"
|
||||||
|
|
||||||
struct ethertap_init {
|
struct ethertap_init {
|
||||||
char *dev_name;
|
char *dev_name;
|
||||||
@@ -42,27 +41,30 @@ 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);
|
*skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
|
||||||
if(*skb == NULL) return(-ENOMEM);
|
if (*skb == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
len = net_recvfrom(fd, skb_mac_header(*skb),
|
len = net_recvfrom(fd, skb_mac_header(*skb),
|
||||||
(*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
|
(*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
|
||||||
if(len <= 0) return(len);
|
if (len <= 0)
|
||||||
|
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){
|
if (skb_headroom(*skb) < 2) {
|
||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
|
|
||||||
skb2 = skb_realloc_headroom(*skb, 2);
|
skb2 = skb_realloc_headroom(*skb, 2);
|
||||||
dev_kfree_skb(*skb);
|
dev_kfree_skb(*skb);
|
||||||
if (skb2 == NULL) return(-ENOMEM);
|
if (skb2 == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
*skb = skb2;
|
*skb = skb2;
|
||||||
}
|
}
|
||||||
skb_push(*skb, 2);
|
skb_push(*skb, 2);
|
||||||
return(net_send(fd, (*skb)->data, (*skb)->len));
|
return net_send(fd, (*skb)->data, (*skb)->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct net_kern_info ethertap_kern_info = {
|
const struct net_kern_info ethertap_kern_info = {
|
||||||
@@ -79,15 +81,15 @@ int ethertap_setup(char *str, char **mac_out, void *data)
|
|||||||
*init = ((struct ethertap_init)
|
*init = ((struct ethertap_init)
|
||||||
{ .dev_name = NULL,
|
{ .dev_name = NULL,
|
||||||
.gate_addr = 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))
|
&init->gate_addr))
|
||||||
return(0);
|
return 0;
|
||||||
if(init->dev_name == NULL){
|
if (init->dev_name == NULL) {
|
||||||
printk("ethertap_setup : Missing tap device name\n");
|
printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct transport ethertap_transport = {
|
static struct transport ethertap_transport = {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
|
||||||
* James Leu (jleu@mindspring.net).
|
* James Leu (jleu@mindspring.net).
|
||||||
* Copyright (C) 2001 by various other people who didn't put their name here.
|
* Copyright (C) 2001 by various other people who didn't put their name here.
|
||||||
@@ -7,20 +8,16 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stddef.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <string.h>
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/un.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include "user.h"
|
|
||||||
#include "kern_util.h"
|
|
||||||
#include "net_user.h"
|
|
||||||
#include "etap.h"
|
#include "etap.h"
|
||||||
#include "os.h"
|
|
||||||
#include "um_malloc.h"
|
|
||||||
#include "kern_constants.h"
|
#include "kern_constants.h"
|
||||||
|
#include "os.h"
|
||||||
|
#include "net_user.h"
|
||||||
|
#include "um_malloc.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET ETH_MAX_PACKET
|
#define MAX_PACKET ETH_MAX_PACKET
|
||||||
|
|
||||||
@@ -49,16 +46,18 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
|
|||||||
memcpy(change.addr, addr, sizeof(change.addr));
|
memcpy(change.addr, addr, sizeof(change.addr));
|
||||||
memcpy(change.netmask, netmask, sizeof(change.netmask));
|
memcpy(change.netmask, netmask, sizeof(change.netmask));
|
||||||
CATCH_EINTR(n = write(fd, &change, sizeof(change)));
|
CATCH_EINTR(n = write(fd, &change, sizeof(change)));
|
||||||
if(n != sizeof(change)){
|
if (n != sizeof(change)) {
|
||||||
printk("etap_change - request failed, err = %d\n", errno);
|
printk(UM_KERN_ERR "etap_change - request failed, err = %d\n",
|
||||||
|
errno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
|
output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
|
||||||
if(output == NULL)
|
if (output == NULL)
|
||||||
printk("etap_change : Failed to allocate output buffer\n");
|
printk(UM_KERN_ERR "etap_change : Failed to allocate output "
|
||||||
|
"buffer\n");
|
||||||
read_output(fd, output, UM_KERN_PAGE_SIZE);
|
read_output(fd, output, UM_KERN_PAGE_SIZE);
|
||||||
if(output != NULL){
|
if (output != NULL) {
|
||||||
printk("%s", output);
|
printk("%s", output);
|
||||||
kfree(output);
|
kfree(output);
|
||||||
}
|
}
|
||||||
@@ -107,7 +106,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
|
|||||||
|
|
||||||
sprintf(data_fd_buf, "%d", data_remote);
|
sprintf(data_fd_buf, "%d", data_remote);
|
||||||
sprintf(version_buf, "%d", UML_NET_VERSION);
|
sprintf(version_buf, "%d", UML_NET_VERSION);
|
||||||
if(gate != NULL){
|
if (gate != NULL) {
|
||||||
strcpy(gate_buf, gate);
|
strcpy(gate_buf, gate);
|
||||||
args = setup_args;
|
args = setup_args;
|
||||||
}
|
}
|
||||||
@@ -119,24 +118,26 @@ static int etap_tramp(char *dev, char *gate, int control_me,
|
|||||||
pe_data.data_me = data_me;
|
pe_data.data_me = data_me;
|
||||||
pid = run_helper(etap_pre_exec, &pe_data, args);
|
pid = run_helper(etap_pre_exec, &pe_data, args);
|
||||||
|
|
||||||
if(pid < 0)
|
if (pid < 0)
|
||||||
err = pid;
|
err = pid;
|
||||||
close(data_remote);
|
close(data_remote);
|
||||||
close(control_remote);
|
close(control_remote);
|
||||||
CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
|
CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
|
||||||
if(n != sizeof(c)){
|
if (n != sizeof(c)) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("etap_tramp : read of status failed, err = %d\n", -err);
|
printk(UM_KERN_ERR "etap_tramp : read of status failed, "
|
||||||
|
"err = %d\n", -err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if(c != 1){
|
if (c != 1) {
|
||||||
printk("etap_tramp : uml_net failed\n");
|
printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
CATCH_EINTR(n = waitpid(pid, &status, 0));
|
CATCH_EINTR(n = waitpid(pid, &status, 0));
|
||||||
if(n < 0)
|
if (n < 0)
|
||||||
err = -errno;
|
err = -errno;
|
||||||
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
|
else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
|
||||||
printk("uml_net didn't exit with status 1\n");
|
printk(UM_KERN_ERR "uml_net didn't exit with "
|
||||||
|
"status 1\n");
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -148,22 +149,22 @@ static int etap_open(void *data)
|
|||||||
int data_fds[2], control_fds[2], err, output_len;
|
int data_fds[2], control_fds[2], err, output_len;
|
||||||
|
|
||||||
err = tap_open_common(pri->dev, pri->gate_addr);
|
err = tap_open_common(pri->dev, pri->gate_addr);
|
||||||
if(err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
|
err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
|
||||||
if(err){
|
if (err) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("etap_open - data socketpair failed - err = %d\n",
|
printk(UM_KERN_ERR "etap_open - data socketpair failed - "
|
||||||
errno);
|
"err = %d\n", errno);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
|
err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
|
||||||
if(err){
|
if (err) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("etap_open - control socketpair failed - err = %d\n",
|
printk(UM_KERN_ERR "etap_open - control socketpair failed - "
|
||||||
errno);
|
"err = %d\n", errno);
|
||||||
goto out_close_data;
|
goto out_close_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,15 +174,16 @@ static int etap_open(void *data)
|
|||||||
output = kmalloc(output_len, UM_GFP_KERNEL);
|
output = kmalloc(output_len, UM_GFP_KERNEL);
|
||||||
read_output(control_fds[0], output, output_len);
|
read_output(control_fds[0], output, output_len);
|
||||||
|
|
||||||
if(output == NULL)
|
if (output == NULL)
|
||||||
printk("etap_open : failed to allocate output buffer\n");
|
printk(UM_KERN_ERR "etap_open : failed to allocate output "
|
||||||
|
"buffer\n");
|
||||||
else {
|
else {
|
||||||
printk("%s", output);
|
printk("%s", output);
|
||||||
kfree(output);
|
kfree(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(err < 0){
|
if (err < 0) {
|
||||||
printk("etap_tramp failed - err = %d\n", -err);
|
printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err);
|
||||||
goto out_close_control;
|
goto out_close_control;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,14 +208,14 @@ static void etap_close(int fd, void *data)
|
|||||||
iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
|
iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if(shutdown(pri->data_fd, SHUT_RDWR) < 0)
|
if (shutdown(pri->data_fd, SHUT_RDWR) < 0)
|
||||||
printk("etap_close - shutdown data socket failed, errno = %d\n",
|
printk(UM_KERN_ERR "etap_close - shutdown data socket failed, "
|
||||||
errno);
|
|
||||||
|
|
||||||
if(shutdown(pri->control_fd, SHUT_RDWR) < 0)
|
|
||||||
printk("etap_close - shutdown control socket failed, "
|
|
||||||
"errno = %d\n", errno);
|
"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);
|
close(pri->data_fd);
|
||||||
pri->data_fd = -1;
|
pri->data_fd = -1;
|
||||||
close(pri->control_fd);
|
close(pri->control_fd);
|
||||||
@@ -231,7 +233,7 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
|
|||||||
struct ethertap_data *pri = data;
|
struct ethertap_data *pri = data;
|
||||||
|
|
||||||
tap_check_ips(pri->gate_addr, addr);
|
tap_check_ips(pri->gate_addr, addr);
|
||||||
if(pri->control_fd == -1)
|
if (pri->control_fd == -1)
|
||||||
return;
|
return;
|
||||||
etap_open_addr(addr, netmask, &pri->control_fd);
|
etap_open_addr(addr, netmask, &pri->control_fd);
|
||||||
}
|
}
|
||||||
@@ -241,7 +243,7 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
|
|||||||
{
|
{
|
||||||
struct ethertap_data *pri = data;
|
struct ethertap_data *pri = data;
|
||||||
|
|
||||||
if(pri->control_fd == -1)
|
if (pri->control_fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
etap_close_addr(addr, netmask, &pri->control_fd);
|
etap_close_addr(addr, netmask, &pri->control_fd);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -19,14 +19,3 @@ struct tuntap_data {
|
|||||||
extern const struct net_user_info tuntap_user_info;
|
extern const struct net_user_info tuntap_user_info;
|
||||||
|
|
||||||
#endif
|
#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:
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -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
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/stddef.h"
|
#include <linux/netdevice.h>
|
||||||
#include "linux/netdevice.h"
|
#include <linux/init.h>
|
||||||
#include "linux/etherdevice.h"
|
#include <linux/skbuff.h>
|
||||||
#include "linux/skbuff.h"
|
#include <asm/errno.h>
|
||||||
#include "linux/init.h"
|
|
||||||
#include "asm/errno.h"
|
|
||||||
#include "net_kern.h"
|
#include "net_kern.h"
|
||||||
#include "net_user.h"
|
|
||||||
#include "tuntap.h"
|
#include "tuntap.h"
|
||||||
|
|
||||||
struct tuntap_init {
|
struct tuntap_init {
|
||||||
@@ -42,15 +39,16 @@ 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);
|
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
|
||||||
if(*skb == NULL) return(-ENOMEM);
|
if (*skb == NULL)
|
||||||
return(net_read(fd, skb_mac_header(*skb),
|
return -ENOMEM;
|
||||||
(*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,
|
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 = {
|
||||||
@@ -67,11 +65,11 @@ int tuntap_setup(char *str, char **mac_out, void *data)
|
|||||||
*init = ((struct tuntap_init)
|
*init = ((struct tuntap_init)
|
||||||
{ .dev_name = NULL,
|
{ .dev_name = NULL,
|
||||||
.gate_addr = 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))
|
&init->gate_addr))
|
||||||
return(0);
|
return 0;
|
||||||
|
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct transport tuntap_transport = {
|
static struct transport tuntap_transport = {
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
#include "net_user.h"
|
#include <net/if.h>
|
||||||
#include "tuntap.h"
|
#include <sys/ioctl.h>
|
||||||
#include "kern_util.h"
|
#include <sys/socket.h>
|
||||||
#include "user.h"
|
#include <sys/wait.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include "kern_constants.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "tuntap.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
#define MAX_PACKET ETH_MAX_PACKET
|
#define MAX_PACKET ETH_MAX_PACKET
|
||||||
|
|
||||||
@@ -37,7 +34,7 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
|
|||||||
struct tuntap_data *pri = data;
|
struct tuntap_data *pri = data;
|
||||||
|
|
||||||
tap_check_ips(pri->gate_addr, addr);
|
tap_check_ips(pri->gate_addr, addr);
|
||||||
if((pri->fd == -1) || pri->fixed_config)
|
if ((pri->fd == -1) || pri->fixed_config)
|
||||||
return;
|
return;
|
||||||
open_addr(addr, netmask, pri->dev_name);
|
open_addr(addr, netmask, pri->dev_name);
|
||||||
}
|
}
|
||||||
@@ -47,7 +44,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
|
|||||||
{
|
{
|
||||||
struct tuntap_data *pri = data;
|
struct tuntap_data *pri = data;
|
||||||
|
|
||||||
if((pri->fd == -1) || pri->fixed_config)
|
if ((pri->fd == -1) || pri->fixed_config)
|
||||||
return;
|
return;
|
||||||
close_addr(addr, netmask, pri->dev_name);
|
close_addr(addr, netmask, pri->dev_name);
|
||||||
}
|
}
|
||||||
@@ -85,14 +82,14 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
|
|||||||
|
|
||||||
pid = run_helper(tuntap_pre_exec, &data, argv);
|
pid = run_helper(tuntap_pre_exec, &data, argv);
|
||||||
|
|
||||||
if(pid < 0)
|
if (pid < 0)
|
||||||
return -pid;
|
return -pid;
|
||||||
|
|
||||||
close(remote);
|
close(remote);
|
||||||
|
|
||||||
msg.msg_name = NULL;
|
msg.msg_name = NULL;
|
||||||
msg.msg_namelen = 0;
|
msg.msg_namelen = 0;
|
||||||
if(buffer != NULL){
|
if (buffer != NULL) {
|
||||||
iov = ((struct iovec) { buffer, buffer_len });
|
iov = ((struct iovec) { buffer, buffer_len });
|
||||||
msg.msg_iov = &iov;
|
msg.msg_iov = &iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
@@ -106,22 +103,24 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
|
|||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
n = recvmsg(me, &msg, 0);
|
n = recvmsg(me, &msg, 0);
|
||||||
*used_out = n;
|
*used_out = n;
|
||||||
if(n < 0){
|
if (n < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
|
printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - "
|
||||||
errno);
|
"errno = %d\n", errno);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
CATCH_EINTR(waitpid(pid, NULL, 0));
|
CATCH_EINTR(waitpid(pid, NULL, 0));
|
||||||
|
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
if(cmsg == NULL){
|
if (cmsg == NULL) {
|
||||||
printk("tuntap_open_tramp : didn't receive a message\n");
|
printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
|
||||||
|
"message\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if((cmsg->cmsg_level != SOL_SOCKET) ||
|
if ((cmsg->cmsg_level != SOL_SOCKET) ||
|
||||||
(cmsg->cmsg_type != SCM_RIGHTS)){
|
(cmsg->cmsg_type != SCM_RIGHTS)) {
|
||||||
printk("tuntap_open_tramp : didn't receive a descriptor\n");
|
printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
|
||||||
|
"descriptor\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
|
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
|
||||||
@@ -137,38 +136,39 @@ static int tuntap_open(void *data)
|
|||||||
int err, fds[2], len, used;
|
int err, fds[2], len, used;
|
||||||
|
|
||||||
err = tap_open_common(pri->dev, pri->gate_addr);
|
err = tap_open_common(pri->dev, pri->gate_addr);
|
||||||
if(err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if(pri->fixed_config){
|
if (pri->fixed_config) {
|
||||||
pri->fd = os_open_file("/dev/net/tun",
|
pri->fd = os_open_file("/dev/net/tun",
|
||||||
of_cloexec(of_rdwr(OPENFLAGS())), 0);
|
of_cloexec(of_rdwr(OPENFLAGS())), 0);
|
||||||
if(pri->fd < 0){
|
if (pri->fd < 0) {
|
||||||
printk("Failed to open /dev/net/tun, err = %d\n",
|
printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
|
||||||
-pri->fd);
|
"err = %d\n", -pri->fd);
|
||||||
return pri->fd;
|
return pri->fd;
|
||||||
}
|
}
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||||
strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
|
strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
|
||||||
if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
|
if (ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("TUNSETIFF failed, errno = %d\n", errno);
|
printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
|
||||||
|
errno);
|
||||||
close(pri->fd);
|
close(pri->fd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
|
err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
|
||||||
if(err){
|
if (err) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
printk("tuntap_open : socketpair failed - errno = %d\n",
|
printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
|
||||||
errno);
|
"errno = %d\n", errno);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = get_output_buffer(&len);
|
buffer = get_output_buffer(&len);
|
||||||
if(buffer != NULL)
|
if (buffer != NULL)
|
||||||
len--;
|
len--;
|
||||||
used = 0;
|
used = 0;
|
||||||
|
|
||||||
@@ -176,10 +176,11 @@ static int tuntap_open(void *data)
|
|||||||
fds[1], buffer, len, &used);
|
fds[1], buffer, len, &used);
|
||||||
|
|
||||||
output = buffer;
|
output = buffer;
|
||||||
if(err < 0) {
|
if (err < 0) {
|
||||||
printk("%s", output);
|
printk("%s", output);
|
||||||
free_output_buffer(buffer);
|
free_output_buffer(buffer);
|
||||||
printk("tuntap_open_tramp failed - err = %d\n", -err);
|
printk(UM_KERN_ERR "tuntap_open_tramp failed - "
|
||||||
|
"err = %d\n", -err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +200,7 @@ static void tuntap_close(int fd, void *data)
|
|||||||
{
|
{
|
||||||
struct tuntap_data *pri = data;
|
struct tuntap_data *pri = data;
|
||||||
|
|
||||||
if(!pri->fixed_config)
|
if (!pri->fixed_config)
|
||||||
iter_addresses(pri->dev, close_addr, pri->dev_name);
|
iter_addresses(pri->dev, close_addr, pri->dev_name);
|
||||||
close(fd);
|
close(fd);
|
||||||
pri->fd = -1;
|
pri->fd = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user