diff -Naur -X exclude-files ac_cur/arch/um/drivers/daemon.h ac/arch/um/drivers/daemon.h --- ac_cur/arch/um/drivers/daemon.h Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/daemon.h Sun Aug 5 13:15:16 2001 @@ -22,7 +22,6 @@ extern int daemon_user_set_mac(struct daemon_data *pri, unsigned char *hwaddr, int len); -extern void daemon_setup(char *str, struct uml_net *dev); extern int daemon_user_read(int fd, void *buf, int len, struct daemon_data *data); extern int daemon_user_write(int fd, void *buf, int len, diff -Naur -X exclude-files ac_cur/arch/um/drivers/daemon_kern.c ac/arch/um/drivers/daemon_kern.c --- ac_cur/arch/um/drivers/daemon_kern.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/daemon_kern.c Sun Aug 5 13:15:16 2001 @@ -11,6 +11,7 @@ #include "net_kern.h" #include "net_user.h" #include "daemon.h" +#include "daemon_kern.h" struct daemon_data daemon_priv[MAX_UML_NETDEV] = { [ 0 ... MAX_UML_NETDEV - 1 ] = diff -Naur -X exclude-files ac_cur/arch/um/drivers/daemon_kern.h ac/arch/um/drivers/daemon_kern.h --- ac_cur/arch/um/drivers/daemon_kern.h Wed Dec 31 19:00:00 1969 +++ ac/arch/um/drivers/daemon_kern.h Sun Aug 5 13:24:06 2001 @@ -0,0 +1,8 @@ +#ifndef __UM_DAEMON_KERN_H +#define __UM_DAEMON_KERN_H + +#include "net_kern.h" + +extern void daemon_setup(char *arg, struct uml_net *dev); + +#endif diff -Naur -X exclude-files ac_cur/arch/um/drivers/daemon_user.c ac/arch/um/drivers/daemon_user.c --- ac_cur/arch/um/drivers/daemon_user.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/daemon_user.c Sun Aug 5 13:15:16 2001 @@ -83,6 +83,10 @@ if(!pri->hw_setup){ pri->hwaddr[0] = 0xfe; pri->hwaddr[1] = 0xfd; + pri->hwaddr[2] = 0x0; + pri->hwaddr[3] = 0x0; + pri->hwaddr[4] = 0x0; + pri->hwaddr[5] = 0x0; dev_ip_addr(pri->dev, addr, &pri->hwaddr[2]); set_ether_mac(pri->dev, pri->hwaddr); } diff -Naur -X exclude-files ac_cur/arch/um/drivers/etap.h ac/arch/um/drivers/etap.h --- ac_cur/arch/um/drivers/etap.h Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/etap.h Sun Aug 5 13:15:16 2001 @@ -15,7 +15,6 @@ }; extern struct net_user_info ethertap_user_info; -extern void ethertap_setup(char *str, struct uml_net *dev); extern int etap_user_write(int fd, void *buf, int len, struct ethertap_data *pri); extern int etap_user_read(int fd, void *buf, int len, diff -Naur -X exclude-files ac_cur/arch/um/drivers/etap_kern.h ac/arch/um/drivers/etap_kern.h --- ac_cur/arch/um/drivers/etap_kern.h Wed Dec 31 19:00:00 1969 +++ ac/arch/um/drivers/etap_kern.h Sun Aug 5 13:24:06 2001 @@ -0,0 +1,8 @@ +#ifndef __UM_ETHERTAP_KERN_H +#define __UM_ETHERTAP_KERN_H + +#include "net_kern.h" + +extern void ethertap_setup(char *arg, struct uml_net *dev); + +#endif diff -Naur -X exclude-files ac_cur/arch/um/drivers/ethertap_kern.c ac/arch/um/drivers/ethertap_kern.c --- ac_cur/arch/um/drivers/ethertap_kern.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/ethertap_kern.c Sun Aug 5 13:15:16 2001 @@ -11,6 +11,7 @@ #include "net_kern.h" #include "net_user.h" #include "etap.h" +#include "etap_kern.h" struct ethertap_setup { char *dev_name; diff -Naur -X exclude-files ac_cur/arch/um/drivers/ethertap_user.c ac/arch/um/drivers/ethertap_user.c --- ac_cur/arch/um/drivers/ethertap_user.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/ethertap_user.c Sun Aug 5 13:15:16 2001 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -89,8 +90,15 @@ int fds[2]; char addr[sizeof("255.255.255.255\0")], ether[6]; - if((pri->gate_addr != NULL) || !pri->hw_setup) + if((pri->gate_addr != NULL) || !pri->hw_setup){ + ether[0] = 0xfe; + ether[1] = 0xfd; + ether[2] = 0x0; + ether[3] = 0x0; + ether[4] = 0x0; + ether[5] = 0x0; dev_ip_addr(pri->dev, addr, ðer[2]); + } if(pri->gate_addr != NULL){ int uml_addr[4], tap_addr[4]; if(sscanf(addr, "%d.%d.%d.%d", ¨_addr[0], ¨_addr[1], diff -Naur -X exclude-files ac_cur/arch/um/drivers/mcast.h ac/arch/um/drivers/mcast.h --- ac_cur/arch/um/drivers/mcast.h Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/mcast.h Sun Aug 5 13:15:16 2001 @@ -19,7 +19,6 @@ extern int mcast_user_set_mac(struct mcast_data *pri, unsigned char *hwaddr, int len); -extern void mcast_setup(char *str, struct uml_net *dev); extern int mcast_user_read(int fd, void *buf, int len, struct mcast_data *data); extern int mcast_user_write(int fd, void *buf, int len, diff -Naur -X exclude-files ac_cur/arch/um/drivers/mcast_kern.c ac/arch/um/drivers/mcast_kern.c --- ac_cur/arch/um/drivers/mcast_kern.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/mcast_kern.c Sun Aug 5 13:15:16 2001 @@ -19,6 +19,7 @@ #include "net_kern.h" #include "net_user.h" #include "mcast.h" +#include "mcast_kern.h" struct mcast_data mcast_priv[MAX_UML_NETDEV] = { [ 0 ... MAX_UML_NETDEV - 1 ] = diff -Naur -X exclude-files ac_cur/arch/um/drivers/mcast_kern.h ac/arch/um/drivers/mcast_kern.h --- ac_cur/arch/um/drivers/mcast_kern.h Wed Dec 31 19:00:00 1969 +++ ac/arch/um/drivers/mcast_kern.h Sun Aug 5 13:24:06 2001 @@ -0,0 +1,8 @@ +#ifndef __UM_MCAST_KERN_H +#define __UM_MCAST_KERN_H + +#include "net_kern.h" + +extern void mcast_setup(char *arg, struct uml_net *dev); + +#endif diff -Naur -X exclude-files ac_cur/arch/um/drivers/mcast_user.c ac/arch/um/drivers/mcast_user.c --- ac_cur/arch/um/drivers/mcast_user.c Sat Aug 4 22:01:55 2001 +++ ac/arch/um/drivers/mcast_user.c Sun Aug 5 13:15:16 2001 @@ -60,6 +60,10 @@ if(!pri->hw_setup){ pri->hwaddr[0] = 0xfe; pri->hwaddr[1] = 0xfd; + pri->hwaddr[2] = 0x0; + pri->hwaddr[3] = 0x0; + pri->hwaddr[4] = 0x0; + pri->hwaddr[5] = 0x0; dev_ip_addr(pri->dev, addr, &pri->hwaddr[2]); set_ether_mac(pri->dev, pri->hwaddr); } diff -Naur -X exclude-files ac_cur/arch/um/drivers/mconsole_kern.c ac/arch/um/drivers/mconsole_kern.c --- ac_cur/arch/um/drivers/mconsole_kern.c Sat Aug 4 22:10:18 2001 +++ ac/arch/um/drivers/mconsole_kern.c Sun Aug 5 13:40:18 2001 @@ -37,7 +37,7 @@ LIST_HEAD(mc_requests); -void mc_tasklet(unsigned long unused) +void mc_task_proc(void *unused) { struct mconsole_entry *req; unsigned long flags; @@ -55,7 +55,10 @@ } while(!done); } -DECLARE_TASKLET(mconsole_tasklet, mc_tasklet, 0); +struct tq_struct mconsole_task = { + routine: mc_task_proc, + data: NULL +}; void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -73,7 +76,7 @@ list_add(&new->list, &mc_requests); } } - tasklet_schedule(&mconsole_tasklet); + schedule_task(&mconsole_task); reactivate_fd(fd); } diff -Naur -X exclude-files ac_cur/arch/um/drivers/net_kern.c ac/arch/um/drivers/net_kern.c --- ac_cur/arch/um/drivers/net_kern.c Sat Aug 4 22:02:06 2001 +++ ac/arch/um/drivers/net_kern.c Sun Aug 5 13:18:55 2001 @@ -15,26 +15,34 @@ #include "linux/etherdevice.h" #include "linux/list.h" #include "linux/inetdevice.h" +#include "linux/ctype.h" #include "user_util.h" +#include "kern_util.h" #include "net_kern.h" #include "net_user.h" #include "slip.h" +#include "slip_kern.h" #include "etap.h" +#include "etap_kern.h" #include "daemon.h" +#include "daemon_kern.h" #include "mcast.h" +#include "mcast_kern.h" +#include "mconsole_kern.h" LIST_HEAD(opened); struct uml_net devices[MAX_UML_NETDEV] = { [ 0 ... MAX_UML_NETDEV - 1 ] = { + dev: NULL, user: NULL, kern: NULL, private_size: 0, } }; -static int eth_setup(char *str) +static int eth_setup_common(char *str, int *index_out) { char *end; int n; @@ -54,34 +62,46 @@ return(1); } str++; + if(devices[n].dev != NULL){ + printk(KERN_ERR "eth_setup: Device %d already configured\n", + n); + return(1); + } + if(index_out) *index_out = n; #ifdef CONFIG_UML_NET_ETHERTAP if(!strncmp(str, "ethertap", strlen("ethertap"))){ ethertap_setup(&str[strlen("ethertap")], &devices[n]); - return(1); + return(0); } #endif #ifdef CONFIG_UML_NET_DAEMON if(!strncmp(str, "daemon", strlen("daemon"))){ daemon_setup(&str[strlen("daemon")], &devices[n]); - return(1); + return(0); } #endif #ifdef CONFIG_UML_NET_SLIP if(!strncmp(str, "slip", strlen("slip"))){ slip_setup(&str[strlen("slip")], &devices[n]); - return(1); + return(0); } #endif #ifdef CONFIG_UML_NET_MCAST if(!strncmp(str, "mcast", strlen("mcast"))){ mcast_setup(&str[strlen("mcast")], &devices[n]); - return(1); + return(0); } #endif printk(KERN_ERR "Unknown transport in eth_setup : %s\n", str); return(1); } +static int eth_setup(char *str) +{ + eth_setup_common(str, NULL); + return(1); +} + __setup("eth", eth_setup); int ndev = 0; @@ -297,57 +317,117 @@ #endif } -int __init uml_net_probe(void) +static int eth_configure(struct uml_net *device, int n) { struct net_device *dev; struct uml_net_private *lp; - int i; - for(i = 0; i < sizeof(devices)/sizeof(devices[0]); i++){ - if(devices[i].user == NULL) continue; - devices[i].private_size += sizeof(struct uml_net_private) + - sizeof(((struct uml_net_private *) 0)->user); - printk("Netdevice %d : ", i); - dev = (*devices[i].kern->init)(devices[i].private_size, - devices[i].transport_index); - - if (dev == NULL) - return -ENOMEM; - - dev->mtu = devices[i].user->max_packet; - dev->open = uml_net_open; - dev->hard_start_xmit = uml_net_start_xmit; - dev->stop = uml_net_close; - dev->get_stats = uml_net_get_stats; - dev->set_multicast_list = uml_net_set_multicast_list; - dev->tx_timeout = uml_net_tx_timeout; - dev->set_mac_address = uml_net_set_mac; - dev->change_mtu = uml_net_change_mtu; - dev->do_ioctl = uml_net_ioctl; - dev->watchdog_timeo = (HZ >> 1); - dev->irq = UM_ETH_IRQ; - - lp = dev->priv; - spin_lock_init(&lp->lock); - init_timer(&lp->tl); - lp->tl.function = uml_net_user_timer_expire; - lp->list = ((struct list_head) LIST_HEAD_INIT(lp->list)); - memset(&lp->stats, 0, sizeof(lp->stats)); - lp->fd = -1; - lp->protocol = devices[i].kern->protocol; - lp->set_mac = devices[i].kern->set_mac; - lp->open = devices[i].user->open; - lp->close = devices[i].user->close; - lp->read = devices[i].kern->read; - lp->write = devices[i].kern->write; - lp->set_mtu = devices[i].user->set_mtu; + device->private_size += sizeof(struct uml_net_private) + + sizeof(((struct uml_net_private *) 0)->user); + printk(KERN_INFO "Netdevice %d : ", n); + dev = (*device->kern->init)(device->private_size, + device->transport_index); + device->dev = dev; + + if (dev == NULL){ + printk(KERN_ERR "eth_configure: Out of memory on device %d\n", + n); + return(1); + } + + dev->mtu = device->user->max_packet; + dev->open = uml_net_open; + dev->hard_start_xmit = uml_net_start_xmit; + dev->stop = uml_net_close; + dev->get_stats = uml_net_get_stats; + dev->set_multicast_list = uml_net_set_multicast_list; + dev->tx_timeout = uml_net_tx_timeout; + dev->set_mac_address = uml_net_set_mac; + dev->change_mtu = uml_net_change_mtu; + dev->do_ioctl = uml_net_ioctl; + dev->watchdog_timeo = (HZ >> 1); + dev->irq = UM_ETH_IRQ; + + lp = dev->priv; + spin_lock_init(&lp->lock); + init_timer(&lp->tl); + lp->tl.function = uml_net_user_timer_expire; + lp->list = ((struct list_head) LIST_HEAD_INIT(lp->list)); + memset(&lp->stats, 0, sizeof(lp->stats)); + lp->fd = -1; + lp->protocol = device->kern->protocol; + lp->set_mac = device->kern->set_mac; + lp->open = device->user->open; + lp->close = device->user->close; + lp->read = device->kern->read; + lp->write = device->kern->write; + lp->set_mtu = device->user->set_mtu; - if(devices[i].user->init) - (*devices[i].user->init)(&lp->user, dev); + if(device->user->init) + (*device->user->init)(&lp->user, dev); + return(0); +} + +int __init uml_net_probe(void) +{ + int i; + + for(i = 0; i < sizeof(devices)/sizeof(devices[0]); i++){ + if(devices[i].user == NULL) continue; + eth_configure(&devices[i], i); + } + return(0); +} + +static int net_config(char *str) +{ + int err, n; + + str = uml_strdup(str); + if(str == NULL){ + printk(KERN_ERR "net_config failed to strdup string\n"); + return(1); + } + err = eth_setup_common(str, &n); + if(err){ + kfree(str); + return(err); } + err = eth_configure(&devices[n], n); + return(err); +} + +static int net_remove(char *str) +{ + struct net_device *dev; + struct uml_net_private *lp; + int n; + + if(!isdigit(*str)) return(-1); + n = *str - '0'; + if(devices[n].dev == NULL) return(0); + dev = devices[n].dev; + lp = dev->priv; + if(lp->fd > 0) return(-1); + unregister_netdev(dev); + devices[n].dev = NULL; + return(0); +} + +static struct mc_device net_mc = { + name: "eth", + config: net_config, + remove: net_remove, +}; + +int net_mc_init(void) +{ + mconsole_register_dev(&net_mc); return(0); } +__initcall(net_mc_init); + static void close_devices(void) { struct list_head *ele; @@ -389,9 +469,16 @@ { struct net_device *dev = d; struct in_device *ip = dev->ip_ptr; - struct in_ifaddr *in = ip->ifa_list; - u32 addr = in->ifa_address; + struct in_ifaddr *in; + u32 addr; + if(ip == NULL){ + printk(KERN_WARNING "dev_ip_addr - device not assigned an " + "IP address\n"); + return; + } + in = ip->ifa_list; + addr = in->ifa_address; sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, (addr >> 16) & 0xff, addr >> 24); if(bin_buf){ diff -Naur -X exclude-files ac_cur/arch/um/drivers/net_kern.h ac/arch/um/drivers/net_kern.h --- ac_cur/arch/um/drivers/net_kern.h Sun Aug 5 13:01:39 2001 +++ ac/arch/um/drivers/net_kern.h Sun Aug 5 13:24:06 2001 @@ -8,6 +8,14 @@ #define MAX_UML_NETDEV (16) +struct uml_net { + struct net_device *dev; + struct net_user_info *user; + struct net_kern_info *kern; + int private_size; + int transport_index; +}; + struct uml_net_private { spinlock_t lock; diff -Naur -X exclude-files ac_cur/arch/um/drivers/net_user.h ac/arch/um/drivers/net_user.h --- ac_cur/arch/um/drivers/net_user.h Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/net_user.h Sun Aug 5 13:15:16 2001 @@ -6,13 +6,6 @@ #define ETH_HEADER_OTHER (14) #define ETH_MAX_PACKET (1500) -struct uml_net { - struct net_user_info *user; - struct net_kern_info *kern; - int private_size; - int transport_index; -}; - struct net_user_info { void (*init)(void *, void *); int (*open)(void *); diff -Naur -X exclude-files ac_cur/arch/um/drivers/slip.h ac/arch/um/drivers/slip.h --- ac_cur/arch/um/drivers/slip.h Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/slip.h Sun Aug 5 13:15:16 2001 @@ -16,7 +16,6 @@ extern struct net_user_info slip_user_info; extern int set_umn_addr(int fd, char *addr, char *ptp_addr); -extern void slip_setup(char *arg, struct uml_net *dev); extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); diff -Naur -X exclude-files ac_cur/arch/um/drivers/slip_kern.c ac/arch/um/drivers/slip_kern.c --- ac_cur/arch/um/drivers/slip_kern.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/slip_kern.c Sun Aug 5 13:15:16 2001 @@ -6,6 +6,7 @@ #include "net_user.h" #include "kern.h" #include "slip.h" +#include "slip_kern.h" struct slip_data slip_priv[MAX_UML_NETDEV] = { [ 0 ... MAX_UML_NETDEV - 1 ] = diff -Naur -X exclude-files ac_cur/arch/um/drivers/slip_kern.h ac/arch/um/drivers/slip_kern.h --- ac_cur/arch/um/drivers/slip_kern.h Wed Dec 31 19:00:00 1969 +++ ac/arch/um/drivers/slip_kern.h Sun Aug 5 13:24:06 2001 @@ -0,0 +1,8 @@ +#ifndef __UM_SLIP_KERN_H +#define __UM_SLIP_KERN_H + +#include "net_kern.h" + +extern void slip_setup(char *arg, struct uml_net *dev); + +#endif diff -Naur -X exclude-files ac_cur/arch/um/drivers/slip_user.c ac/arch/um/drivers/slip_user.c --- ac_cur/arch/um/drivers/slip_user.c Sat Aug 4 22:01:03 2001 +++ ac/arch/um/drivers/slip_user.c Sun Aug 5 13:15:16 2001 @@ -1,7 +1,9 @@ #include +#include #include #include #include +#include #include #include #include diff -Naur -X exclude-files ac_cur/arch/um/include/kern_util.h ac/arch/um/include/kern_util.h --- ac_cur/arch/um/include/kern_util.h Sat Aug 4 22:01:03 2001 +++ ac/arch/um/include/kern_util.h Sun Aug 5 13:36:17 2001 @@ -119,6 +119,7 @@ extern void handling_signal(void *t); extern int config_gdb(char *str); extern int remove_gdb(void); +extern char *uml_strdup(char *string); #endif /* diff -Naur -X exclude-files ac_cur/arch/um/kernel/process_kern.c ac/arch/um/kernel/process_kern.c --- ac_cur/arch/um/kernel/process_kern.c Sat Aug 4 22:10:18 2001 +++ ac/arch/um/kernel/process_kern.c Sun Aug 5 13:36:30 2001 @@ -802,6 +802,16 @@ return(ROUND_DOWN(addr)); } +char *uml_strdup(char *string) +{ + char *new; + + new = kmalloc(strlen(string) + 1, GFP_KERNEL); + if(new == NULL) return(NULL); + strcpy(new, string); + return(new); +} + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically