b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] reorganized kernel interface patches (version 3)
@ 2010-03-24  4:52 Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 1/5] batman-adv: move originator interval setting from /proc to /sys Marek Lindner
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Marek Lindner @ 2010-03-24  4:52 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking


Hi,

since my last patches did not trigger too many complaints I went ahead and 
submitted them. This opens the way for the last series of patches which 
conclude the matter. All remaining /proc files have been eliminated and moved 
over to /sys. While doing so, I reworked the interface handling to satisfy an 
old feature request: interfaces can be added & removed on the fly.

On startup batman-adv will scan the system for available interfaces to create 
a "batman_adv" subfolder in their respective /sys/class/net folder, e.g.
eth0: /sys/class/net/eth0/batman_adv
This subfolder will contain the settings which are relevant for this 
interface. You can tell batman-adv to use an interface by writing "bat0" into 
the mesh_iface file:
echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface
or write "none" to deactivate it:
echo none > /sys/class/net/eth0/batman_adv/mesh_iface
Although only "bat0" is accepted at this point, the syntax already gears 
towards multiple virtual mesh support. Later you will be able to create/name 
your virtual meshes by writing into this file. Retrieve the interface status by 
simply reading its status file:
cat /sys/class/net/eth0/batman_adv/iface_status

Note: batman-adv will continuously observe the system's interfaces. Whenever 
new interfaces appear or disappear batman will update the /sys/class/net 
folders automatically. Also, batman-adv will make sure that incompatible 
interfaces (e.g. loopback, non-ethernet, etc) won't have the subfolder, hence 
can't be activated.

The batctl interface syntax had to be modified in order to cope with these 
changes. You can run:
batctl interface
to get the list of active interfaces and their status. To add or delete 
interfaces you can run:
batctl interface add|del eth0 eth1 ..

Since removing an active interface is a tricky thing where many operations can 
go wrong I expect some crashes/race conditions in the code. I tested it a 
while on multiple machines with multiple interfaces and it works for me but 
I'm sure there are more bugs to find. 

Regards,
Marek

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [B.A.T.M.A.N.] [PATCH 1/5] batman-adv: move originator interval setting from /proc to /sys
  2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
@ 2010-03-24  4:52 ` Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 2/5] batctl: follow the orig_interval move " Marek Lindner
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Lindner @ 2010-03-24  4:52 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batman-adv-kernelland/bat_sysfs.c |   47 +++++++++++++++++++++++
 batman-adv-kernelland/main.c      |    2 -
 batman-adv-kernelland/main.h      |    1 -
 batman-adv-kernelland/proc.c      |   75 -------------------------------------
 batman-adv-kernelland/proc.h      |    1 -
 batman-adv-kernelland/send.c      |    6 +-
 batman-adv-kernelland/types.h     |    1 +
 7 files changed, 51 insertions(+), 82 deletions(-)

diff --git a/batman-adv-kernelland/bat_sysfs.c b/batman-adv-kernelland/bat_sysfs.c
index e4685a7..58bf44e 100644
--- a/batman-adv-kernelland/bat_sysfs.c
+++ b/batman-adv-kernelland/bat_sysfs.c
@@ -251,17 +251,63 @@ static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr,
 	return gw_mode_set(bat_priv, buff, count);
 }
 
+static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr,
+				 char *buff)
+{
+	struct device *dev = to_dev(kobj->parent);
+	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+
+	return sprintf(buff, "status: %i\n",
+		       atomic_read(&bat_priv->orig_interval));
+}
+
+static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,
+				  char *buff, size_t count)
+{
+	struct device *dev = to_dev(kobj->parent);
+	struct net_device *net_dev = to_net_dev(dev);
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
+	unsigned long orig_interval_tmp;
+	int ret;
+
+	ret = strict_strtoul(buff, 10, &orig_interval_tmp);
+	if (ret) {
+		printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n",
+		       net_dev->name, buff);
+		return -EINVAL;
+	}
+
+	if (orig_interval_tmp <= JITTER * 2) {
+		printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n",
+		       orig_interval_tmp, JITTER * 2);
+		return -EINVAL;
+	}
+
+	if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp)
+		return count;
+
+	printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n",
+	       atomic_read(&bat_priv->orig_interval),
+	       orig_interval_tmp, net_dev->name);
+
+	atomic_set(&bat_priv->orig_interval, orig_interval_tmp);
+	return count;
+}
+
 static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
 		show_aggr_ogm, store_aggr_ogm);
 static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond);
 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
 static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
+static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
+		show_orig_interval, store_orig_interval);
 
 static struct bat_attribute *mesh_attrs[] = {
 	&bat_attr_aggregate_ogm,
 	&bat_attr_bonding,
 	&bat_attr_vis_mode,
 	&bat_attr_gw_mode,
+	&bat_attr_orig_interval,
 	NULL,
 };
 
@@ -345,6 +391,7 @@ int sysfs_add_meshif(struct net_device *dev)
 	atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
 	atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
 	atomic_set(&bat_priv->gw_class, 0);
+	atomic_set(&bat_priv->orig_interval, 1000);
 
 	bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
 						    batif_kobject);
diff --git a/batman-adv-kernelland/main.c b/batman-adv-kernelland/main.c
index cd53ced..b276e86 100644
--- a/batman-adv-kernelland/main.c
+++ b/batman-adv-kernelland/main.c
@@ -44,7 +44,6 @@ DEFINE_SPINLOCK(orig_hash_lock);
 DEFINE_SPINLOCK(forw_bat_list_lock);
 DEFINE_SPINLOCK(forw_bcast_list_lock);
 
-atomic_t originator_interval;
 atomic_t vis_interval;
 int16_t num_hna;
 int16_t num_ifs;
@@ -82,7 +81,6 @@ int init_module(void)
 
 	atomic_set(&module_state, MODULE_INACTIVE);
 
-	atomic_set(&originator_interval, 1000);
 	atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
 					 * for debugging now. */
 
diff --git a/batman-adv-kernelland/main.h b/batman-adv-kernelland/main.h
index d72f2c2..ddb0d6c 100644
--- a/batman-adv-kernelland/main.h
+++ b/batman-adv-kernelland/main.h
@@ -131,7 +131,6 @@ extern spinlock_t orig_hash_lock;
 extern spinlock_t forw_bat_list_lock;
 extern spinlock_t forw_bcast_list_lock;
 
-extern atomic_t originator_interval;
 extern atomic_t vis_interval;
 extern int16_t num_hna;
 extern int16_t num_ifs;
diff --git a/batman-adv-kernelland/proc.c b/batman-adv-kernelland/proc.c
index d2dfdd7..a8a1a67 100644
--- a/batman-adv-kernelland/proc.c
+++ b/batman-adv-kernelland/proc.c
@@ -32,7 +32,6 @@
 #include "gateway_client.h"
 
 static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
-static struct proc_dir_entry *proc_orig_interval_file;
 
 static int proc_interfaces_read(struct seq_file *seq, void *offset)
 {
@@ -124,57 +123,6 @@ end:
 	return count;
 }
 
-static int proc_orig_interval_read(struct seq_file *seq, void *offset)
-{
-	seq_printf(seq, "%i\n", atomic_read(&originator_interval));
-
-	return 0;
-}
-
-static ssize_t proc_orig_interval_write(struct file *file,
-					const char __user *buffer,
-					size_t count, loff_t *ppos)
-{
-	char *interval_string;
-	int not_copied = 0;
-	unsigned long originator_interval_tmp;
-	int retval;
-
-	interval_string = kmalloc(count, GFP_KERNEL);
-
-	if (!interval_string)
-		return -ENOMEM;
-
-	not_copied = copy_from_user(interval_string, buffer, count);
-	interval_string[count - not_copied - 1] = 0;
-
-	retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
-	if (retval) {
-		printk(KERN_ERR "batman-adv:New originator interval invalid\n");
-		goto end;
-	}
-
-	if (originator_interval_tmp <= JITTER * 2) {
-		printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n",
-		       originator_interval_tmp, JITTER * 2);
-		goto end;
-	}
-
-	printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n",
-	       atomic_read(&originator_interval), originator_interval_tmp);
-
-	atomic_set(&originator_interval, originator_interval_tmp);
-
-end:
-	kfree(interval_string);
-	return count;
-}
-
-static int proc_orig_interval_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_orig_interval_read, NULL);
-}
-
 static const struct file_operations proc_interfaces_fops = {
 	.owner		= THIS_MODULE,
 	.open		= proc_interfaces_open,
@@ -184,20 +132,8 @@ static const struct file_operations proc_interfaces_fops = {
 	.release	= single_release,
 };
 
-static const struct file_operations proc_orig_interval_fops = {
-	.owner		= THIS_MODULE,
-	.open		= proc_orig_interval_open,
-	.read		= seq_read,
-	.write		= proc_orig_interval_write,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
 void cleanup_procfs(void)
 {
-	if (proc_orig_interval_file)
-		remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir);
-
 	if (proc_interface_file)
 		remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
 
@@ -233,16 +169,5 @@ int setup_procfs(void)
 		return -EFAULT;
 	}
 
-	proc_orig_interval_file = create_proc_entry(PROC_FILE_ORIG_INTERVAL,
-						    S_IWUSR | S_IRUGO,
-						    proc_batman_dir);
-	if (proc_orig_interval_file) {
-		proc_orig_interval_file->proc_fops = &proc_orig_interval_fops;
-	} else {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIG_INTERVAL);
-		cleanup_procfs();
-		return -EFAULT;
-	}
-
 	return 0;
 }
diff --git a/batman-adv-kernelland/proc.h b/batman-adv-kernelland/proc.h
index 6a972a6..6f4f5b3 100644
--- a/batman-adv-kernelland/proc.h
+++ b/batman-adv-kernelland/proc.h
@@ -24,7 +24,6 @@
 
 #define PROC_ROOT_DIR "batman-adv"
 #define PROC_FILE_INTERFACES "interfaces"
-#define PROC_FILE_ORIG_INTERVAL "orig_interval"
 
 void cleanup_procfs(void);
 int setup_procfs(void);
diff --git a/batman-adv-kernelland/send.c b/batman-adv-kernelland/send.c
index 51011d4..b5a96f5 100644
--- a/batman-adv-kernelland/send.c
+++ b/batman-adv-kernelland/send.c
@@ -39,10 +39,10 @@ static uint8_t hop_penalty(const uint8_t tq)
 }
 
 /* when do we schedule our own packet to be sent */
-static unsigned long own_send_time(void)
+static unsigned long own_send_time(struct bat_priv *bat_priv)
 {
 	return jiffies +
-		(((atomic_read(&originator_interval) - JITTER +
+		(((atomic_read(&bat_priv->orig_interval) - JITTER +
 		   (random32() % 2*JITTER)) * HZ) / 1000);
 }
 
@@ -285,7 +285,7 @@ void schedule_own_packet(struct batman_if *batman_if)
 	atomic_inc(&batman_if->seqno);
 
 	slide_own_bcast_window(batman_if);
-	send_time = own_send_time();
+	send_time = own_send_time(bat_priv);
 	add_bat_packet_to_list(bat_priv,
 			       batman_if->packet_buff,
 			       batman_if->packet_len,
diff --git a/batman-adv-kernelland/types.h b/batman-adv-kernelland/types.h
index 98968b4..0794dfc 100644
--- a/batman-adv-kernelland/types.h
+++ b/batman-adv-kernelland/types.h
@@ -99,6 +99,7 @@ struct bat_priv {
 	atomic_t vis_mode;
 	atomic_t gw_mode;
 	atomic_t gw_class;
+	atomic_t orig_interval;
 	struct kobject *mesh_obj;
 };
 
-- 
1.7.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [B.A.T.M.A.N.] [PATCH 2/5] batctl: follow the orig_interval move to /sys
  2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 1/5] batman-adv: move originator interval setting from /proc to /sys Marek Lindner
@ 2010-03-24  4:52 ` Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 3/5] batman-adv: remove redundant pointer to originator interface Marek Lindner
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Lindner @ 2010-03-24  4:52 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batctl/main.c |    4 ++--
 batctl/proc.c |    7 -------
 batctl/proc.h |    2 --
 batctl/sys.c  |    7 +++++++
 batctl/sys.h  |    2 ++
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/batctl/main.c b/batctl/main.c
index a07e75b..da7fb4a 100644
--- a/batctl/main.c
+++ b/batctl/main.c
@@ -43,7 +43,7 @@ void print_usage(void) {
 	printf("commands:\n");
 	printf(" \tinterface|if   [none|interface]  \tdisplay or modify the interface settings\n");
 	printf(" \toriginators|o                    \tdisplay the originator table\n");
-	printf(" \tinterval|it    [orig_interval]   \tdisplay or modify the originator interval in ms\n");
+	printf(" \tinterval|it    [orig_interval]   \tdisplay or modify the originator interval (in ms)\n");
 	printf(" \tloglevel|ll    [level]           \tdisplay or modify the log level\n");
 	printf(" \tlog|l                            \tread the log produced by the kernel module\n");
 	printf(" \tgw_mode|gw     [mode]            \tdisplay or modify the gateway mode\n");
@@ -123,7 +123,7 @@ int main(int argc, char **argv)
 
 	} else if ((strcmp(argv[1], "interval") == 0) || (strcmp(argv[1], "it") == 0)) {
 
-		ret = handle_proc_setting(argc - 1, argv + 1, PROC_ORIG_INTERVAL, orig_interval_usage);
+		ret = handle_sys_setting(argc - 1, argv + 1, SYS_ORIG_INTERVAL, orig_interval_usage);
 
 	} else if ((strcmp(argv[1], "vis_mode") == 0) || (strcmp(argv[1], "vm") == 0)) {
 
diff --git a/batctl/proc.c b/batctl/proc.c
index 9f5c24f..192d4fb 100644
--- a/batctl/proc.c
+++ b/batctl/proc.c
@@ -68,13 +68,6 @@ int interface(int argc, char **argv)
 	return EXIT_SUCCESS;
 }
 
-void orig_interval_usage(void)
-{
-	printf("Usage: batctl [options] interval \n");
-	printf("options:\n");
-	printf(" \t -h print this help\n");
-}
-
 int handle_table(int argc, char **argv, char *file_path, void table_usage(void))
 {
 	int optchar, read_opt = USE_BAT_HOSTS;
diff --git a/batctl/proc.h b/batctl/proc.h
index 0b5a6f2..61d6058 100644
--- a/batctl/proc.h
+++ b/batctl/proc.h
@@ -21,10 +21,8 @@
 
 #define PROC_ROOT_PATH "/proc/net/batman-adv/"
 #define PROC_INTERFACES "interfaces"
-#define PROC_ORIG_INTERVAL "orig_interval"
 
 int interface(int argc, char **argv);
 
-void orig_interval_usage(void);
 int handle_table(int argc, char **argv, char *file_path, void table_usage(void));
 int handle_proc_setting(int argc, char **argv, char *file_path, void setting_usage(void));
diff --git a/batctl/sys.c b/batctl/sys.c
index 7d035d6..cd8979a 100644
--- a/batctl/sys.c
+++ b/batctl/sys.c
@@ -207,6 +207,13 @@ void vis_mode_usage(void)
 	printf(" \t -h print this help\n");
 }
 
+void orig_interval_usage(void)
+{
+	printf("Usage: batctl [options] interval \n");
+	printf("options:\n");
+	printf(" \t -h print this help\n");
+}
+
 int handle_sys_setting(int argc, char **argv, char *file_path, void setting_usage(void))
 {
 	int optchar, res;
diff --git a/batctl/sys.h b/batctl/sys.h
index 4f10cee..19d19f5 100644
--- a/batctl/sys.h
+++ b/batctl/sys.h
@@ -33,6 +33,7 @@
 #define SYS_GATEWAYS "gateways"
 #define SYS_VIS_MODE "vis_mode"
 #define SYS_VIS_DATA "vis_data"
+#define SYS_ORIG_INTERVAL "orig_interval"
 
 void originators_usage(void);
 void trans_local_usage(void);
@@ -42,6 +43,7 @@ void bonding_usage(void);
 void gw_mode_usage(void);
 void gateways_usage(void);
 void vis_mode_usage(void);
+void orig_interval_usage(void);
 int log_print(int argc, char **argv);
 int handle_loglevel(int argc, char **argv);
 int handle_sys_table(int argc, char **argv, char *file_path, void table_usage(void));
-- 
1.7.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [B.A.T.M.A.N.] [PATCH 3/5] batman-adv: remove redundant pointer to originator interface
  2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 1/5] batman-adv: move originator interval setting from /proc to /sys Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 2/5] batctl: follow the orig_interval move " Marek Lindner
@ 2010-03-24  4:52 ` Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 4/5] batman-adv: move /proc interface handling to /sys Marek Lindner
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Lindner @ 2010-03-24  4:52 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batman-adv-kernelland/device.c     |    2 +-
 batman-adv-kernelland/originator.c |    1 -
 batman-adv-kernelland/routing.c    |   14 +++-----------
 batman-adv-kernelland/types.h      |    1 -
 batman-adv-kernelland/vis.c        |   15 +++++++--------
 5 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/batman-adv-kernelland/device.c b/batman-adv-kernelland/device.c
index 484b2a1..a3e066a 100644
--- a/batman-adv-kernelland/device.c
+++ b/batman-adv-kernelland/device.c
@@ -260,7 +260,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
 	if (!orig_node->router)
 		goto unlock;
 
-	batman_if = orig_node->batman_if;
+	batman_if = orig_node->router->if_incoming;
 	memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 
 	spin_unlock_irqrestore(&orig_hash_lock, flags);
diff --git a/batman-adv-kernelland/originator.c b/batman-adv-kernelland/originator.c
index 1f607f4..dbc7cbf 100644
--- a/batman-adv-kernelland/originator.c
+++ b/batman-adv-kernelland/originator.c
@@ -139,7 +139,6 @@ struct orig_node *get_orig_node(uint8_t *addr)
 
 	memcpy(orig_node->orig, addr, ETH_ALEN);
 	orig_node->router = NULL;
-	orig_node->batman_if = NULL;
 	orig_node->hna_buff = NULL;
 
 	size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
diff --git a/batman-adv-kernelland/routing.c b/batman-adv-kernelland/routing.c
index 2e357bf..3168215 100644
--- a/batman-adv-kernelland/routing.c
+++ b/batman-adv-kernelland/routing.c
@@ -99,11 +99,6 @@ static void update_route(struct orig_node *orig_node,
 		bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr);
 	}
 
-	if (neigh_node != NULL)
-		orig_node->batman_if = neigh_node->if_incoming;
-	else
-		orig_node->batman_if = NULL;
-
 	orig_node->router = neigh_node;
 }
 
@@ -747,12 +742,11 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
 	ret = NET_RX_DROP;
 
 	if ((orig_node != NULL) &&
-	    (orig_node->batman_if != NULL) &&
 	    (orig_node->router != NULL)) {
 
 		/* don't lock while sending the packets ... we therefore
 		 * copy the required data before sending */
-		batman_if = orig_node->batman_if;
+		batman_if = orig_node->router->if_incoming;
 		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
@@ -809,12 +803,11 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
 	ret = NET_RX_DROP;
 
 	if ((orig_node != NULL) &&
-	    (orig_node->batman_if != NULL) &&
 	    (orig_node->router != NULL)) {
 
 		/* don't lock while sending the packets ... we therefore
 		 * copy the required data before sending */
-		batman_if = orig_node->batman_if;
+		batman_if = orig_node->router->if_incoming;
 		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
@@ -905,12 +898,11 @@ int recv_icmp_packet(struct sk_buff *skb)
 		     hash_find(orig_hash, icmp_packet->dst));
 
 	if ((orig_node != NULL) &&
-	    (orig_node->batman_if != NULL) &&
 	    (orig_node->router != NULL)) {
 
 		/* don't lock while sending the packets ... we therefore
 		 * copy the required data before sending */
-		batman_if = orig_node->batman_if;
+		batman_if = orig_node->router->if_incoming;
 		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
diff --git a/batman-adv-kernelland/types.h b/batman-adv-kernelland/types.h
index 0794dfc..de13c99 100644
--- a/batman-adv-kernelland/types.h
+++ b/batman-adv-kernelland/types.h
@@ -49,7 +49,6 @@ struct orig_node {               /* structure for orig_list maintaining nodes of
 	uint8_t orig[ETH_ALEN];
 	uint8_t primary_addr[ETH_ALEN];	/* hosts primary interface address */
 	struct neigh_node *router;
-	struct batman_if *batman_if;
 	TYPE_OF_WORD *bcast_own;
 	uint8_t *bcast_own_sum;
 	uint8_t tq_own;
diff --git a/batman-adv-kernelland/vis.c b/batman-adv-kernelland/vis.c
index 91849f4..a774de7 100644
--- a/batman-adv-kernelland/vis.c
+++ b/batman-adv-kernelland/vis.c
@@ -499,14 +499,14 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
 		if (orig_node->router != NULL
 			&& compare_orig(orig_node->router->addr,
 					orig_node->orig)
-			&& orig_node->batman_if
-			&& (orig_node->batman_if->if_active == IF_ACTIVE)
+			&& (orig_node->router->if_incoming->if_status ==
+								IF_ACTIVE)
 		    && orig_node->router->tq_avg > 0) {
 
 			/* fill one entry into buffer. */
 			entry = &entry_array[info->packet.entries];
 			memcpy(entry->src,
-			       orig_node->batman_if->net_dev->dev_addr,
+			     orig_node->router->if_incoming->net_dev->dev_addr,
 			       ETH_ALEN);
 			memcpy(entry->dest, orig_node->orig, ETH_ALEN);
 			entry->quality = orig_node->router->tq_avg;
@@ -574,8 +574,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
 		orig_node = hashit.bucket->data;
 
 		/* if it's a vis server and reachable, send it. */
-		if ((!orig_node) || (!orig_node->batman_if) ||
-		    (!orig_node->router))
+		if ((!orig_node) || (!orig_node->router))
 			continue;
 		if (!(orig_node->flags & VIS_SERVER))
 			continue;
@@ -585,7 +584,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
 			continue;
 
 		memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN);
-		batman_if = orig_node->batman_if;
+		batman_if = orig_node->router->if_incoming;
 		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
@@ -610,12 +609,12 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length)
 	orig_node = ((struct orig_node *)
 		     hash_find(orig_hash, info->packet.target_orig));
 
-	if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router))
+	if ((!orig_node) || (!orig_node->router))
 		goto out;
 
 	/* don't lock while sending the packets ... we therefore
 	 * copy the required data before sending */
-	batman_if = orig_node->batman_if;
+	batman_if = orig_node->router->if_incoming;
 	memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
 	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-- 
1.7.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [B.A.T.M.A.N.] [PATCH 4/5] batman-adv: move /proc interface handling to /sys
  2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
                   ` (2 preceding siblings ...)
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 3/5] batman-adv: remove redundant pointer to originator interface Marek Lindner
@ 2010-03-24  4:52 ` Marek Lindner
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 5/5] batctl: adapt batctl to new sysfs interface handling Marek Lindner
  2010-04-01 17:28 ` [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Linus Lüssing
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Lindner @ 2010-03-24  4:52 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Instead of having a single /proc file "interfaces" in which you have
to echo the wanted interface batman-adv will create a subfolder in each
suitable /sys/class/net folder. This subfolder contains files for the
interface specific settings. For example, mesh_iface to add/remove an
interface from a virtual mesh network (at the moment only bat0 is
supported).

Example:
echo bat0 > /sys/class/net/eth0/batman-adv/mesh_iface

to deactivate:
echo none > /sys/class/net/eth0/batman-adv/mesh_iface

Interfaces which are not compatible with batman-adv won't contain the
batman-adv folder, therefore can't be activated. Not supported are:
loopback, non-ethernet, non-ARP and virtual mesh network interfaces

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batman-adv-kernelland/Makefile.kbuild     |    2 +-
 batman-adv-kernelland/bat_sysfs.c         |  144 ++++++++
 batman-adv-kernelland/bat_sysfs.h         |    3 +
 batman-adv-kernelland/device.c            |    2 +-
 batman-adv-kernelland/gateway_client.c    |    9 +-
 batman-adv-kernelland/hard-interface.c    |  515 +++++++++++++++--------------
 batman-adv-kernelland/hard-interface.h    |   18 +-
 batman-adv-kernelland/main.c              |   21 +-
 batman-adv-kernelland/main.h              |    3 +-
 batman-adv-kernelland/originator.c        |  195 ++++++++++-
 batman-adv-kernelland/originator.h        |    2 +
 batman-adv-kernelland/proc.c              |  173 ----------
 batman-adv-kernelland/proc.h              |   30 --
 batman-adv-kernelland/routing.c           |    4 +-
 batman-adv-kernelland/send.c              |   51 +++-
 batman-adv-kernelland/send.h              |    2 +-
 batman-adv-kernelland/soft-interface.c    |    4 +-
 batman-adv-kernelland/translation-table.c |   14 +-
 batman-adv-kernelland/types.h             |    5 +-
 batman-adv-kernelland/vis.c               |    7 +-
 20 files changed, 668 insertions(+), 536 deletions(-)
 delete mode 100644 batman-adv-kernelland/proc.c
 delete mode 100644 batman-adv-kernelland/proc.h

diff --git a/batman-adv-kernelland/Makefile.kbuild b/batman-adv-kernelland/Makefile.kbuild
index c1f181a..e9b58b9 100644
--- a/batman-adv-kernelland/Makefile.kbuild
+++ b/batman-adv-kernelland/Makefile.kbuild
@@ -32,4 +32,4 @@ EXTRA_CFLAGS += -DREVISION_VERSION=\"r$(REVISION)\"
 endif
 
 obj-m += batman-adv.o
-batman-adv-objs := main.o proc.o bat_sysfs.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o gateway_common.o gateway_client.o $(shell [ "2" -eq "$(VERSION)" ] 2>&- && [ "6" -eq "$(PATCHLEVEL)" ] 2>&- && [ "$(SUBLEVEL)" -le "28" ] 2>&- && echo bat_printk.o)
+batman-adv-objs := main.o bat_sysfs.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o gateway_common.o gateway_client.o $(shell [ "2" -eq "$(VERSION)" ] 2>&- && [ "6" -eq "$(PATCHLEVEL)" ] 2>&- && [ "$(SUBLEVEL)" -le "28" ] 2>&- && echo bat_printk.o)
diff --git a/batman-adv-kernelland/bat_sysfs.c b/batman-adv-kernelland/bat_sysfs.c
index 58bf44e..4dffa00 100644
--- a/batman-adv-kernelland/bat_sysfs.c
+++ b/batman-adv-kernelland/bat_sysfs.c
@@ -38,6 +38,14 @@ struct bat_attribute {
 			 char *buf, size_t count);
 };
 
+struct hardif_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
+			 char *buf, size_t count);
+};
+
 #define BAT_ATTR(_name, _mode, _show, _store)	\
 struct bat_attribute bat_attr_##_name = {	\
 	.attr = {.name = __stringify(_name),	\
@@ -54,6 +62,14 @@ struct bin_attribute bat_attr_##_name = {		\
 	.write = _write,				\
 };
 
+#define HARDIF_ATTR(_name, _mode, _show, _store)	\
+struct hardif_attribute hardif_attr_##_name = {		\
+	.attr = {.name = __stringify(_name),		\
+		 .mode = _mode },			\
+	.show   = _show,				\
+	.store  = _store,				\
+};
+
 static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr,
 			     char *buff)
 {
@@ -392,6 +408,8 @@ int sysfs_add_meshif(struct net_device *dev)
 	atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
 	atomic_set(&bat_priv->gw_class, 0);
 	atomic_set(&bat_priv->orig_interval, 1000);
+	bat_priv->primary_if = NULL;
+	bat_priv->num_ifaces = 0;
 
 	bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
 						    batif_kobject);
@@ -452,3 +470,129 @@ void sysfs_del_meshif(struct net_device *dev)
 	kobject_put(bat_priv->mesh_obj);
 	bat_priv->mesh_obj = NULL;
 }
+
+static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
+			       char *buff)
+{
+	struct net_device *net_dev = to_net_dev(to_dev(kobj->parent));
+	struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+
+	if (!batman_if)
+		return 0;
+
+	return sprintf(buff, "status: %s\ncommands: none, bat0 \n",
+		       batman_if->if_status == IF_NOT_IN_USE ?
+							"none" : "bat0");
+}
+
+static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
+				char *buff, size_t count)
+{
+	struct net_device *net_dev = to_net_dev(to_dev(kobj->parent));
+	struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+	int status_tmp = -1;
+
+	if (!batman_if)
+		return count;
+
+	if (strncmp(buff, "none", 4) == 0)
+		status_tmp = IF_NOT_IN_USE;
+
+	if (strncmp(buff, "bat0", 4) == 0)
+		status_tmp = IF_I_WANT_YOU;
+
+	if (status_tmp < 0) {
+		if (buff[count - 1] == '\n')
+			buff[count - 1] = '\0';
+
+		printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n",
+		       buff);
+		return -EINVAL;
+	}
+
+	if ((batman_if->if_status == status_tmp) ||
+	    ((status_tmp == IF_I_WANT_YOU) &&
+	     (batman_if->if_status != IF_NOT_IN_USE)))
+		return count;
+
+	if (status_tmp == IF_I_WANT_YOU)
+		status_tmp = hardif_enable_interface(batman_if);
+	else
+		hardif_disable_interface(batman_if);
+
+	return (status_tmp < 0 ? status_tmp : count);
+}
+
+static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
+				 char *buff)
+{
+	struct net_device *net_dev = to_net_dev(to_dev(kobj->parent));
+	struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+
+	if (!batman_if)
+		return 0;
+
+	switch (batman_if->if_status) {
+	case IF_TO_BE_REMOVED:
+		return sprintf(buff, "disabling\n");
+	case IF_INACTIVE:
+		return sprintf(buff, "inactive\n");
+	case IF_ACTIVE:
+		return sprintf(buff, "active\n");
+	case IF_TO_BE_ACTIVATED:
+		return sprintf(buff, "enabling\n");
+	case IF_NOT_IN_USE:
+	default:
+		return sprintf(buff, "not in use\n");
+	}
+}
+
+static HARDIF_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
+		   show_mesh_iface, store_mesh_iface);
+static HARDIF_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
+
+static struct hardif_attribute *batman_attrs[] = {
+	&hardif_attr_mesh_iface,
+	&hardif_attr_iface_status,
+	NULL,
+};
+
+int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
+{
+	struct kobject *hardif_kobject = &dev->dev.kobj;
+	struct hardif_attribute **hardif_attr;
+	int err;
+
+	*hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR,
+						    hardif_kobject);
+
+	if (!*hardif_obj) {
+		printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
+		       dev->name, SYSFS_IF_BAT_SUBDIR);
+		goto out;
+	}
+
+	for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) {
+		err = sysfs_create_file(*hardif_obj, &((*hardif_attr)->attr));
+		if (err) {
+			printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
+			       dev->name, SYSFS_IF_BAT_SUBDIR,
+			       ((*hardif_attr)->attr).name);
+			goto rem_attr;
+		}
+	}
+
+	return 0;
+
+rem_attr:
+	for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr)
+		sysfs_remove_file(*hardif_obj, &((*hardif_attr)->attr));
+out:
+	return -ENOMEM;
+}
+
+void sysfs_del_hardif(struct kobject **hardif_obj)
+{
+	kobject_put(*hardif_obj);
+	*hardif_obj = NULL;
+}
diff --git a/batman-adv-kernelland/bat_sysfs.h b/batman-adv-kernelland/bat_sysfs.h
index 671ebd1..e189341 100644
--- a/batman-adv-kernelland/bat_sysfs.h
+++ b/batman-adv-kernelland/bat_sysfs.h
@@ -21,6 +21,9 @@
 
 
 #define SYSFS_IF_MESH_SUBDIR "mesh"
+#define SYSFS_IF_BAT_SUBDIR "batman_adv"
 
 int sysfs_add_meshif(struct net_device *dev);
 void sysfs_del_meshif(struct net_device *dev);
+int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
+void sysfs_del_hardif(struct kobject **hardif_obj);
diff --git a/batman-adv-kernelland/device.c b/batman-adv-kernelland/device.c
index a3e066a..f011430 100644
--- a/batman-adv-kernelland/device.c
+++ b/batman-adv-kernelland/device.c
@@ -268,7 +268,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
 	if (!batman_if)
 		goto dst_unreach;
 
-	if (batman_if->if_active != IF_ACTIVE)
+	if (batman_if->if_status != IF_ACTIVE)
 		goto dst_unreach;
 
 	memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN);
diff --git a/batman-adv-kernelland/gateway_client.c b/batman-adv-kernelland/gateway_client.c
index 29a4783..0e619dd 100644
--- a/batman-adv-kernelland/gateway_client.c
+++ b/batman-adv-kernelland/gateway_client.c
@@ -337,12 +337,13 @@ static int _write_buffer_text(unsigned char *buff, int bytes_written,
 int gw_client_fill_buffer_text(struct net_device *net_dev, char *buff,
 			       size_t count, loff_t off)
 {
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct gw_node *gw_node;
 	size_t hdr_len, tmp_len;
 	int bytes_written = 0, gw_count = 0;
 
 	rcu_read_lock();
-	if (list_empty(&if_list)) {
+	if (!bat_priv->primary_if) {
 		rcu_read_unlock();
 
 		if (off == 0)
@@ -353,7 +354,7 @@ int gw_client_fill_buffer_text(struct net_device *net_dev, char *buff,
 		return 0;
 	}
 
-	if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
+	if (bat_priv->primary_if->if_status != IF_ACTIVE) {
 		rcu_read_unlock();
 
 		if (off == 0)
@@ -368,8 +369,8 @@ int gw_client_fill_buffer_text(struct net_device *net_dev, char *buff,
 			  "      %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n",
 			  "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
 			  "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
-			  ((struct batman_if *)if_list.next)->dev,
-			  ((struct batman_if *)if_list.next)->addr_str,
+			  bat_priv->primary_if->dev,
+			  bat_priv->primary_if->addr_str,
 			  net_dev->name);
 	rcu_read_unlock();
 
diff --git a/batman-adv-kernelland/hard-interface.c b/batman-adv-kernelland/hard-interface.c
index 0eb861b..64307fc 100644
--- a/batman-adv-kernelland/hard-interface.c
+++ b/batman-adv-kernelland/hard-interface.c
@@ -25,23 +25,22 @@
 #include "send.h"
 #include "translation-table.h"
 #include "routing.h"
+#include "bat_sysfs.h"
+#include "originator.h"
 #include "hash.h"
 #include "compat.h"
 
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-
-static char avail_ifs;
-static char active_ifs;
+#include <linux/if_arp.h>
 
-static void hardif_free_interface(struct rcu_head *rcu);
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
 
-static struct batman_if *get_batman_if_by_name(char *name)
+struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev)
 {
 	struct batman_if *batman_if;
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		if (strncmp(batman_if->dev, name, IFNAMSIZ) == 0)
+		if (batman_if->net_dev == net_dev)
 			goto out;
 	}
 
@@ -52,23 +51,90 @@ out:
 	return batman_if;
 }
 
-int hardif_min_mtu(void)
+static int is_valid_iface(struct net_device *net_dev)
+{
+	if (net_dev->flags & IFF_LOOPBACK)
+		return 0;
+
+	if (net_dev->type != ARPHRD_ETHER)
+		return 0;
+
+	if (net_dev->addr_len != ETH_ALEN)
+		return 0;
+
+	/* no batman over batman */
+#ifdef HAVE_NET_DEVICE_OPS
+	if (net_dev->netdev_ops->ndo_start_xmit == interface_tx)
+		return 0;
+#else
+	if (net_dev->hard_start_xmit == interface_tx)
+		return 0;
+#endif
+
+	/* Device is being bridged */
+	/* if (net_dev->br_port != NULL)
+		return 0; */
+
+	return 1;
+}
+
+static struct batman_if *get_active_batman_if(void)
 {
 	struct batman_if *batman_if;
-	/* allow big frames if all devices are capable to do so
-	 * (have MTU > 1500 + BAT_HEADER_LEN) */
-	int min_mtu = ETH_DATA_LEN;
 
+	/* TODO: should check interfaces belonging to bat_priv */
 	rcu_read_lock();
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		if ((batman_if->if_active == IF_ACTIVE) ||
-		    (batman_if->if_active == IF_TO_BE_ACTIVATED))
-			min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
-				      min_mtu);
+		if (batman_if->if_status == IF_ACTIVE)
+			goto out;
 	}
+
+	batman_if = NULL;
+
+out:
 	rcu_read_unlock();
+	return batman_if;
+}
 
-	return min_mtu;
+static void set_primary_if(struct bat_priv *bat_priv,
+			   struct batman_if *batman_if)
+{
+	struct batman_packet *batman_packet;
+
+	bat_priv->primary_if = batman_if;
+
+	if (!bat_priv->primary_if)
+		return;
+
+	set_main_if_addr(batman_if->net_dev->dev_addr);
+
+	batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+	batman_packet->flags = PRIMARIES_FIRST_HOP;
+	batman_packet->ttl = TTL;
+
+	/***
+	 * hacky trick to make sure that we send the HNA information via
+	 * our new primary interface
+	 */
+	atomic_set(&hna_local_changed, 1);
+}
+
+static bool hardif_is_iface_up(struct batman_if *batman_if)
+{
+	if (batman_if->net_dev->flags & IFF_UP)
+		return true;
+
+	return false;
+}
+
+static void update_mac_addresses(struct batman_if *batman_if)
+{
+	addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
+
+	memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
+	       batman_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender,
+	       batman_if->net_dev->dev_addr, ETH_ALEN);
 }
 
 static void check_known_mac_addr(uint8_t *addr)
@@ -77,8 +143,8 @@ static void check_known_mac_addr(uint8_t *addr)
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		if ((batman_if->if_active != IF_ACTIVE) &&
-		    (batman_if->if_active != IF_TO_BE_ACTIVATED))
+		if ((batman_if->if_status != IF_ACTIVE) &&
+		    (batman_if->if_status != IF_TO_BE_ACTIVATED))
 			continue;
 
 		if (!compare_orig(batman_if->net_dev->dev_addr, addr))
@@ -91,6 +157,25 @@ static void check_known_mac_addr(uint8_t *addr)
 	rcu_read_unlock();
 }
 
+int hardif_min_mtu(void)
+{
+	struct batman_if *batman_if;
+	/* allow big frames if all devices are capable to do so
+	 * (have MTU > 1500 + BAT_HEADER_LEN) */
+	int min_mtu = ETH_DATA_LEN;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if ((batman_if->if_status == IF_ACTIVE) ||
+		    (batman_if->if_status == IF_TO_BE_ACTIVATED))
+			min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
+				      min_mtu);
+	}
+	rcu_read_unlock();
+
+	return min_mtu;
+}
+
 /* adjusts the MTU if a new interface with a smaller MTU appeared. */
 void update_min_mtu(void)
 {
@@ -101,322 +186,246 @@ void update_min_mtu(void)
 		soft_device->mtu = min_mtu;
 }
 
-/* checks if the interface is up. (returns 1 if it is) */
-static int hardif_is_interface_up(char *dev)
+static void hardif_activate_interface(struct bat_priv *bat_priv,
+				      struct batman_if *batman_if)
 {
-	struct net_device *net_dev;
+	if (batman_if->if_status != IF_INACTIVE)
+		return;
 
-	/**
-	 * if we already have an interface in our interface list and
-	 * the current interface is not the primary interface and
-	 * the primary interface is not up and
-	 * the primary interface has never been up - don't activate any
-	 * secondary interface !
-	 */
+	dev_hold(batman_if->net_dev);
 
-	rcu_read_lock();
-	if ((!list_empty(&if_list)) &&
-	    strncmp(((struct batman_if *)if_list.next)->dev, dev, IFNAMSIZ) &&
-	    !(((struct batman_if *)if_list.next)->if_active == IF_ACTIVE) &&
-	    !(((struct batman_if *)if_list.next)->if_active == IF_TO_BE_ACTIVATED) &&
-	    (!main_if_was_up())) {
-		rcu_read_unlock();
-		goto end;
-	}
-	rcu_read_unlock();
+	update_mac_addresses(batman_if);
+	batman_if->if_status = IF_TO_BE_ACTIVATED;
 
-#ifdef __NET_NET_NAMESPACE_H
-	net_dev = dev_get_by_name(&init_net, dev);
-#else
-	net_dev = dev_get_by_name(dev);
-#endif
-	if (!net_dev)
-		goto end;
+	/**
+	 * the first active interface becomes our primary interface or
+	 * the next active interface after the old primay interface was removed
+	 */
+	if (!bat_priv->primary_if)
+		set_primary_if(bat_priv, batman_if);
 
-	if (!(net_dev->flags & IFF_UP))
-		goto failure;
+	printk(KERN_INFO "batman-adv:Interface activated: %s\n",
+	       batman_if->dev);
 
-	dev_put(net_dev);
-	return 1;
+	if (atomic_read(&module_state) == MODULE_INACTIVE)
+		activate_module();
 
-failure:
-	dev_put(net_dev);
-end:
-	return 0;
+	update_min_mtu();
+	return;
 }
 
-/* deactivates the interface. */
-void hardif_deactivate_interface(struct batman_if *batman_if)
+static void hardif_deactivate_interface(struct batman_if *batman_if)
 {
-	if (batman_if->if_active != IF_ACTIVE)
+	if ((batman_if->if_status != IF_ACTIVE) &&
+	   (batman_if->if_status != IF_TO_BE_ACTIVATED))
 		return;
 
-	/**
-	 * batman_if->net_dev has been acquired by dev_get_by_name() in
-	 * proc_interfaces_write() and has to be unreferenced.
-	 */
-
-	if (batman_if->net_dev)
-		dev_put(batman_if->net_dev);
+	dev_put(batman_if->net_dev);
 
-	batman_if->if_active = IF_INACTIVE;
-	active_ifs--;
+	batman_if->if_status = IF_INACTIVE;
 
 	printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
-		  batman_if->dev);
+	       batman_if->dev);
+
+	update_min_mtu();
 }
 
-/* (re)activate given interface. */
-static void hardif_activate_interface(struct batman_if *batman_if)
+int hardif_enable_interface(struct batman_if *batman_if)
 {
-	if (batman_if->if_active != IF_INACTIVE)
-		return;
-
-#ifdef __NET_NET_NAMESPACE_H
-	batman_if->net_dev = dev_get_by_name(&init_net, batman_if->dev);
-#else
-	batman_if->net_dev = dev_get_by_name(batman_if->dev);
-#endif
-	if (!batman_if->net_dev)
-		goto dev_err;
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+	struct batman_packet *batman_packet;
 
-	check_known_mac_addr(batman_if->net_dev->dev_addr);
+	if (batman_if->if_status != IF_NOT_IN_USE)
+		goto out;
 
-	addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
+	batman_if->packet_len = BAT_PACKET_LEN;
+	batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
 
-	memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
-	       batman_if->net_dev->dev_addr, ETH_ALEN);
-	memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender,
-	       batman_if->net_dev->dev_addr, ETH_ALEN);
+	if (!batman_if->packet_buff) {
+		printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n",
+		       batman_if->dev);
+		goto err;
+	}
 
-	batman_if->if_active = IF_TO_BE_ACTIVATED;
-	active_ifs++;
+	batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+	batman_packet->packet_type = BAT_PACKET;
+	batman_packet->version = COMPAT_VERSION;
+	batman_packet->flags = 0;
+	batman_packet->ttl = 2;
+	batman_packet->tq = TQ_MAX_VALUE;
+	batman_packet->num_hna = 0;
 
-	/* save the mac address if it is our primary interface */
-	if (batman_if->if_num == 0)
-		set_main_if_addr(batman_if->net_dev->dev_addr);
+	batman_if->if_num = bat_priv->num_ifaces;
+	bat_priv->num_ifaces++;
+	batman_if->if_status = IF_INACTIVE;
+	orig_hash_add_if(batman_if, bat_priv->num_ifaces);
 
-	printk(KERN_INFO "batman-adv:Interface activated: %s\n",
-		  batman_if->dev);
+	atomic_set(&batman_if->seqno, 1);
+	printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev);
 
-	return;
+	if (hardif_is_iface_up(batman_if))
+		hardif_activate_interface(bat_priv, batman_if);
+	else
+		printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
 
-dev_err:
-	batman_if->net_dev = NULL;
-}
+	/* begin scheduling originator messages on that interface */
+	schedule_own_packet(batman_if);
 
-static void hardif_free_interface(struct rcu_head *rcu)
-{
-	struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu);
+out:
+	return 0;
 
-	kfree(batman_if->packet_buff);
-	kfree(batman_if->dev);
-	kfree(batman_if);
+err:
+	return -ENOMEM;
 }
 
-/**
- * called by
- *  - echo '' > /proc/.../interfaces
- *  - modprobe -r batman-adv-core
- */
-/* removes and frees all interfaces */
-void hardif_remove_interfaces(void)
+void hardif_disable_interface(struct batman_if *batman_if)
 {
-	struct batman_if *batman_if = NULL;
-
-	avail_ifs = 0;
-
-	/* no lock needed - we don't delete somewhere else */
-	list_for_each_entry(batman_if, &if_list, list) {
-
-		list_del_rcu(&batman_if->list);
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 
-		/* first deactivate interface */
-		if (batman_if->if_active != IF_INACTIVE)
-			hardif_deactivate_interface(batman_if);
-
-		call_rcu(&batman_if->rcu, hardif_free_interface);
-	}
-}
-
-static int resize_orig(struct orig_node *orig_node, int if_num)
-{
-	void *data_ptr;
+	if (batman_if->if_status == IF_ACTIVE)
+		hardif_deactivate_interface(batman_if);
 
-	data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
-			   GFP_ATOMIC);
-	if (!data_ptr) {
-		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
-		return -1;
-	}
+	if (batman_if->if_status != IF_INACTIVE)
+		return;
 
-	memcpy(data_ptr, orig_node->bcast_own,
-	       if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS);
-	kfree(orig_node->bcast_own);
-	orig_node->bcast_own = data_ptr;
+	printk(KERN_INFO "batman-adv:Removing interface: %s\n", batman_if->dev);
+	bat_priv->num_ifaces--;
+	orig_hash_del_if(batman_if, bat_priv->num_ifaces);
 
-	data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
-	if (!data_ptr) {
-		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
-		return -1;
-	}
+	if (batman_if == bat_priv->primary_if)
+		set_primary_if(bat_priv, get_active_batman_if());
 
-	memcpy(data_ptr, orig_node->bcast_own_sum, if_num * sizeof(uint8_t));
-	kfree(orig_node->bcast_own_sum);
-	orig_node->bcast_own_sum = data_ptr;
+	kfree(batman_if->packet_buff);
+	batman_if->packet_buff = NULL;
+	batman_if->if_status = IF_NOT_IN_USE;
 
-	return 0;
+	if ((atomic_read(&module_state) == MODULE_ACTIVE) &&
+	    (bat_priv->num_ifaces == 0))
+		deactivate_module();
 }
 
-
-/* adds an interface the interface list and activate it, if possible */
-int hardif_add_interface(char *dev, int if_num)
+static struct batman_if *hardif_add_interface(struct net_device *net_dev)
 {
 	struct batman_if *batman_if;
-	struct batman_packet *batman_packet;
-	struct orig_node *orig_node;
-	unsigned long flags;
-	HASHIT(hashit);
+	int ret;
 
-	batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
+	ret = is_valid_iface(net_dev);
+	if (ret != 1)
+		goto out;
 
+	batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
 	if (!batman_if) {
-		printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev);
-		return -1;
-	}
-
-	batman_if->net_dev = NULL;
-
-	if ((if_num == 0) && (num_hna > 0))
-		batman_if->packet_len = BAT_PACKET_LEN + num_hna * ETH_ALEN;
-	else
-		batman_if->packet_len = BAT_PACKET_LEN;
-
-	batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
-
-	if (!batman_if->packet_buff) {
-		printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev);
+		printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n",
+		       net_dev->name);
 		goto out;
 	}
 
-	batman_if->if_num = if_num;
-	batman_if->dev = dev;
-	batman_if->if_active = IF_INACTIVE;
-	INIT_RCU_HEAD(&batman_if->rcu);
+	batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
+	if (!batman_if->dev)
+		goto free_if;
 
-	printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev);
-	avail_ifs++;
+	ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev);
+	if (ret)
+		goto free_dev;
 
+	batman_if->if_num = -1;
+	batman_if->net_dev = net_dev;
+	batman_if->if_status = IF_NOT_IN_USE;
+	INIT_RCU_HEAD(&batman_if->rcu);
 	INIT_LIST_HEAD(&batman_if->list);
 
-	batman_packet = (struct batman_packet *)(batman_if->packet_buff);
-	batman_packet->packet_type = BAT_PACKET;
-	batman_packet->version = COMPAT_VERSION;
-	batman_packet->flags = batman_if->if_num > 0 ?
-			0x00 : PRIMARIES_FIRST_HOP;
-	batman_packet->ttl = batman_if->if_num > 0 ? 2 : TTL;
-	batman_packet->tq = TQ_MAX_VALUE;
-	batman_packet->num_hna = 0;
-
-	if (batman_if->packet_len != BAT_PACKET_LEN) {
-		unsigned char *hna_buff;
-		int hna_len;
-
-		hna_buff = batman_if->packet_buff + BAT_PACKET_LEN;
-		hna_len = batman_if->packet_len - BAT_PACKET_LEN;
-		batman_packet->num_hna = hna_local_fill_buffer(hna_buff,
-							       hna_len);
-	}
-
-	atomic_set(&batman_if->seqno, 1);
+	check_known_mac_addr(batman_if->net_dev->dev_addr);
+	list_add_tail_rcu(&batman_if->list, &if_list);
+	return batman_if;
 
-	/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
-	 * if_num */
-	spin_lock_irqsave(&orig_hash_lock, flags);
+free_dev:
+	kfree(batman_if->dev);
+free_if:
+	kfree(batman_if);
+out:
+	return NULL;
+}
 
-	while (hash_iterate(orig_hash, &hashit)) {
-		orig_node = hashit.bucket->data;
-		if (resize_orig(orig_node, if_num) == -1) {
-			spin_unlock_irqrestore(&orig_hash_lock, flags);
-			goto out;
-		}
-	}
+static void hardif_free_interface(struct rcu_head *rcu)
+{
+	struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu);
 
-	spin_unlock_irqrestore(&orig_hash_lock, flags);
+	/* delete all references to this batman_if */
+	purge_orig(NULL);
+	purge_outstanding_packets(batman_if);
 
-	if (!hardif_is_interface_up(batman_if->dev))
-		printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
-	else
-		hardif_activate_interface(batman_if);
+	kfree(batman_if->dev);
+	kfree(batman_if);
+}
 
-	list_add_tail_rcu(&batman_if->list, &if_list);
+static void hardif_remove_interface(struct batman_if *batman_if)
+{
+	/* first deactivate interface */
+	if (batman_if->if_status != IF_NOT_IN_USE)
+		hardif_disable_interface(batman_if);
 
-	/* begin sending originator messages on that interface */
-	schedule_own_packet(batman_if);
-	return 1;
+	if (batman_if->if_status != IF_NOT_IN_USE)
+		return;
 
-out:
-	kfree(batman_if->packet_buff);
-	kfree(batman_if);
-	kfree(dev);
-	return -1;
+	batman_if->if_status = IF_TO_BE_REMOVED;
+	list_del_rcu(&batman_if->list);
+	sysfs_del_hardif(&batman_if->hardif_obj);
+	call_rcu(&batman_if->rcu, hardif_free_interface);
 }
 
-char hardif_get_active_if_num(void)
+void hardif_remove_interfaces(void)
 {
-	return active_ifs;
+	struct batman_if *batman_if, *batman_if_tmp;
+
+	list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list)
+		hardif_remove_interface(batman_if);
 }
 
 static int hard_if_event(struct notifier_block *this,
-			    unsigned long event, void *ptr)
+			 unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *)ptr;
-	struct batman_if *batman_if = get_batman_if_by_name(dev->name);
+	struct net_device *net_dev = (struct net_device *)ptr;
+	struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+
+	if (!batman_if)
+		batman_if = hardif_add_interface(net_dev);
 
 	if (!batman_if)
 		goto out;
 
 	switch (event) {
+	case NETDEV_REGISTER:
+		break;
+	case NETDEV_UP:
+		hardif_activate_interface(bat_priv, batman_if);
+		break;
 	case NETDEV_GOING_DOWN:
 	case NETDEV_DOWN:
-	case NETDEV_UNREGISTER:
 		hardif_deactivate_interface(batman_if);
 		break;
-	case NETDEV_UP:
-		hardif_activate_interface(batman_if);
-		if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
-		    (hardif_get_active_if_num() > 0)) {
-			activate_module();
-		}
+	case NETDEV_UNREGISTER:
+		hardif_remove_interface(batman_if);
+		break;
+	case NETDEV_CHANGENAME:
+		break;
+	case NETDEV_CHANGEADDR:
+		check_known_mac_addr(batman_if->net_dev->dev_addr);
+		update_mac_addresses(batman_if);
+		if (batman_if == bat_priv->primary_if)
+			set_primary_if(bat_priv, batman_if);
 		break;
-	/* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
 	default:
 		break;
 	};
 
-	update_min_mtu();
-
 out:
 	return NOTIFY_DONE;
 }
 
-/* find batman interface by netdev. assumes rcu_read_lock on */
-static struct batman_if *find_batman_if(struct net_device *dev)
-{
-	struct batman_if *batman_if;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		if (batman_if->net_dev == dev) {
-			rcu_read_unlock();
-			return batman_if;
-		}
-	}
-	rcu_read_unlock();
-	return NULL;
-}
-
-
 /* receive a packet with the batman ethertype coming on a hard
  * interface */
 int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
@@ -445,12 +454,12 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 				|| !skb_mac_header(skb)))
 		goto err_free;
 
-	batman_if = find_batman_if(skb->dev);
+	batman_if = get_batman_if_by_netdev(skb->dev);
 	if (!batman_if)
 		goto err_free;
 
 	/* discard frames on not active interfaces */
-	if (batman_if->if_active != IF_ACTIVE)
+	if (batman_if->if_status != IF_ACTIVE)
 		goto err_free;
 
 	stats = (struct net_device_stats *)dev_get_stats(skb->dev);
diff --git a/batman-adv-kernelland/hard-interface.h b/batman-adv-kernelland/hard-interface.h
index 4100a27..1e5fc3e 100644
--- a/batman-adv-kernelland/hard-interface.h
+++ b/batman-adv-kernelland/hard-interface.h
@@ -19,19 +19,19 @@
  *
  */
 
-#define IF_INACTIVE 0
-#define IF_ACTIVE 1
-/* #define IF_TO_BE_DEACTIVATED 2 - not needed anymore */
-#define IF_TO_BE_ACTIVATED 3
+#define IF_NOT_IN_USE 0
+#define IF_TO_BE_REMOVED 1
+#define IF_INACTIVE 2
+#define IF_ACTIVE 3
+#define IF_TO_BE_ACTIVATED 4
+#define IF_I_WANT_YOU 5
 
 extern struct notifier_block hard_if_notifier;
 
+struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev);
+int hardif_enable_interface(struct batman_if *batman_if);
+void hardif_disable_interface(struct batman_if *batman_if);
 void hardif_remove_interfaces(void);
-int hardif_add_interface(char *dev, int if_num);
-void hardif_deactivate_interface(struct batman_if *batman_if);
-char hardif_get_active_if_num(void);
-void hardif_check_interfaces_status(void);
-void hardif_check_interfaces_status_wq(struct work_struct *work);
 int batman_skb_recv(struct sk_buff *skb,
 				struct net_device *dev,
 				struct packet_type *ptype,
diff --git a/batman-adv-kernelland/main.c b/batman-adv-kernelland/main.c
index b276e86..b98fd83 100644
--- a/batman-adv-kernelland/main.c
+++ b/batman-adv-kernelland/main.c
@@ -20,7 +20,6 @@
  */
 
 #include "main.h"
-#include "proc.h"
 #include "bat_sysfs.h"
 #include "routing.h"
 #include "send.h"
@@ -46,7 +45,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
 
 atomic_t vis_interval;
 int16_t num_hna;
-int16_t num_ifs;
 
 struct net_device *soft_device;
 
@@ -91,10 +89,6 @@ int init_module(void)
 	if (!bat_event_workqueue)
 		return -ENOMEM;
 
-	retval = setup_procfs();
-	if (retval < 0)
-		return retval;
-
 	bat_device_init();
 
 	/* initialize layer 2 interface */
@@ -137,7 +131,10 @@ end:
 
 void cleanup_module(void)
 {
-	shutdown_module();
+	deactivate_module();
+
+	unregister_netdevice_notifier(&hard_if_notifier);
+	hardif_remove_interfaces();
 
 	if (soft_device) {
 		sysfs_del_meshif(soft_device);
@@ -147,9 +144,6 @@ void cleanup_module(void)
 
 	dev_remove_pack(&batman_adv_packet_type);
 
-	unregister_netdevice_notifier(&hard_if_notifier);
-	cleanup_procfs();
-
 	destroy_workqueue(bat_event_workqueue);
 	bat_event_workqueue = NULL;
 }
@@ -180,17 +174,17 @@ void activate_module(void)
 
 err:
 	printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n");
-	shutdown_module();
+	deactivate_module();
 end:
 	return;
 }
 
 /* shuts down the whole module.*/
-void shutdown_module(void)
+void deactivate_module(void)
 {
 	atomic_set(&module_state, MODULE_DEACTIVATING);
 
-	purge_outstanding_packets();
+	purge_outstanding_packets(NULL);
 	flush_workqueue(bat_event_workqueue);
 
 	vis_quit();
@@ -206,7 +200,6 @@ void shutdown_module(void)
 	synchronize_net();
 	bat_device_destroy();
 
-	hardif_remove_interfaces();
 	synchronize_rcu();
 	atomic_set(&module_state, MODULE_INACTIVE);
 }
diff --git a/batman-adv-kernelland/main.h b/batman-adv-kernelland/main.h
index ddb0d6c..5dcbf03 100644
--- a/batman-adv-kernelland/main.h
+++ b/batman-adv-kernelland/main.h
@@ -133,7 +133,6 @@ extern spinlock_t forw_bcast_list_lock;
 
 extern atomic_t vis_interval;
 extern int16_t num_hna;
-extern int16_t num_ifs;
 
 extern struct net_device *soft_device;
 
@@ -142,7 +141,7 @@ extern atomic_t module_state;
 extern struct workqueue_struct *bat_event_workqueue;
 
 void activate_module(void);
-void shutdown_module(void);
+void deactivate_module(void);
 void inc_module_count(void);
 void dec_module_count(void);
 int addr_to_string(char *buff, uint8_t *addr);
diff --git a/batman-adv-kernelland/originator.c b/batman-adv-kernelland/originator.c
index dbc7cbf..d04bac4 100644
--- a/batman-adv-kernelland/originator.c
+++ b/batman-adv-kernelland/originator.c
@@ -120,6 +120,8 @@ void free_orig_node(void *data)
  * address if it does not exits */
 struct orig_node *get_orig_node(uint8_t *addr)
 {
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct orig_node *orig_node;
 	struct hashtable_t *swaphash;
 	int size;
@@ -141,13 +143,13 @@ struct orig_node *get_orig_node(uint8_t *addr)
 	orig_node->router = NULL;
 	orig_node->hna_buff = NULL;
 
-	size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
+	size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS;
 
 	orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
 	if (!orig_node->bcast_own)
 		goto free_orig_node;
 
-	size = num_ifs * sizeof(uint8_t);
+	size = bat_priv->num_ifaces * sizeof(uint8_t);
 	orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
 	if (!orig_node->bcast_own_sum)
 		goto free_bcast_own;
@@ -184,16 +186,25 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
 
 	*best_neigh_node = NULL;
 
-
 	/* for all neighbors towards this originator ... */
 	list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
 		neigh_node = list_entry(list_pos, struct neigh_node, list);
 
-		if (time_after(jiffies,
+		if ((time_after(jiffies,
 			       (neigh_node->last_valid +
-				((PURGE_TIMEOUT * HZ) / 1000)))) {
-
-			bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ));
+				((PURGE_TIMEOUT * HZ) / 1000)))) ||
+		    (neigh_node->if_incoming->if_status ==
+						IF_TO_BE_REMOVED)) {
+
+			if (neigh_node->if_incoming->if_status ==
+							IF_TO_BE_REMOVED)
+				bat_dbg(DBG_BATMAN, "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n",
+					orig_node->orig, neigh_node->addr,
+					neigh_node->if_incoming->dev);
+			else
+				bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n",
+					orig_node->orig, neigh_node->addr,
+					(neigh_node->last_valid / HZ));
 
 			neigh_purged = true;
 			list_del(list_pos);
@@ -257,13 +268,18 @@ void purge_orig(struct work_struct *work)
 
 	gw_node_purge_deleted();
 	gw_election();
-	start_purge_timer();
+
+	/* if work == NULL we were not called by the timer
+	 * and thus do not need to re-arm the timer */
+	if (work)
+		start_purge_timer();
 }
 
 ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 			      size_t count, loff_t off)
 {
 	HASHIT(hashit);
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct orig_node *orig_node;
 	struct neigh_node *neigh_node;
 	size_t hdr_len, tmp_len;
@@ -271,10 +287,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 	unsigned long flags;
 	char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
 
-	rcu_read_lock();
-	if (list_empty(&if_list)) {
-		rcu_read_unlock();
-
+	if (!bat_priv->primary_if) {
 		if (off == 0)
 			return sprintf(buff,
 				       "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
@@ -283,9 +296,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 		return 0;
 	}
 
-	if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
-		rcu_read_unlock();
-
+	if (bat_priv->primary_if->if_status != IF_ACTIVE) {
 		if (off == 0)
 			return sprintf(buff,
 				       "BATMAN mesh %s disabled - primary interface not active\n",
@@ -294,12 +305,12 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 		return 0;
 	}
 
+	rcu_read_lock();
 	hdr_len = sprintf(buff,
 		   "  %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n",
 		   "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
 		   "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
-		   ((struct batman_if *)if_list.next)->dev,
-		   ((struct batman_if *)if_list.next)->addr_str,
+		   bat_priv->primary_if->dev, bat_priv->primary_if->addr_str,
 		   net_dev->name);
 	rcu_read_unlock();
 
@@ -357,3 +368,153 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 
 	return bytes_written;
 }
+
+static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
+{
+	void *data_ptr;
+
+	data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS,
+			   GFP_ATOMIC);
+	if (!data_ptr) {
+		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
+		return -1;
+	}
+
+	memcpy(data_ptr, orig_node->bcast_own,
+	       (max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS);
+	kfree(orig_node->bcast_own);
+	orig_node->bcast_own = data_ptr;
+
+	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
+	if (!data_ptr) {
+		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
+		return -1;
+	}
+
+	memcpy(data_ptr, orig_node->bcast_own_sum,
+	       (max_if_num - 1) * sizeof(uint8_t));
+	kfree(orig_node->bcast_own_sum);
+	orig_node->bcast_own_sum = data_ptr;
+
+	return 0;
+}
+
+int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
+{
+	struct orig_node *orig_node;
+	HASHIT(hashit);
+
+	/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
+	 * if_num */
+	spin_lock(&orig_hash_lock);
+
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
+
+		if (orig_node_add_if(orig_node, max_if_num) == -1)
+			goto err;
+	}
+
+	spin_unlock(&orig_hash_lock);
+	return 0;
+
+err:
+	spin_unlock(&orig_hash_lock);
+	return -ENOMEM;
+}
+
+static int orig_node_del_if(struct orig_node *orig_node,
+		     int max_if_num, int del_if_num)
+{
+	void *data_ptr = NULL;
+	int chunk_size;
+
+	/* last interface was removed */
+	if (max_if_num == 0)
+		goto free_bcast_own;
+
+	chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS;
+	data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
+	if (!data_ptr) {
+		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
+		return -1;
+	}
+
+	/* copy first part */
+	memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size);
+
+	/* copy second part */
+	memcpy(data_ptr,
+	       orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
+	       (max_if_num - del_if_num) * chunk_size);
+
+free_bcast_own:
+	kfree(orig_node->bcast_own);
+	orig_node->bcast_own = data_ptr;
+
+	if (max_if_num == 0)
+		goto free_own_sum;
+
+	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
+	if (!data_ptr) {
+		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
+		return -1;
+	}
+
+	memcpy(data_ptr, orig_node->bcast_own_sum,
+	       del_if_num * sizeof(uint8_t));
+
+	memcpy(data_ptr,
+	       orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)),
+	       (max_if_num - del_if_num) * sizeof(uint8_t));
+
+free_own_sum:
+	kfree(orig_node->bcast_own_sum);
+	orig_node->bcast_own_sum = data_ptr;
+
+	return 0;
+}
+
+int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
+{
+	struct batman_if *batman_if_tmp;
+	struct orig_node *orig_node;
+	HASHIT(hashit);
+	int ret;
+
+	/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
+	 * if_num */
+	spin_lock(&orig_hash_lock);
+
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
+
+		ret = orig_node_del_if(orig_node, max_if_num,
+				       batman_if->if_num);
+
+		if (ret == -1)
+			goto err;
+	}
+
+	/* renumber remaining batman interfaces _inside_ of orig_hash_lock */
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if_tmp, &if_list, list) {
+		if (batman_if_tmp->if_status == IF_NOT_IN_USE)
+			continue;
+
+		if (batman_if == batman_if_tmp)
+			continue;
+
+		if (batman_if_tmp->if_num > batman_if->if_num)
+			batman_if_tmp->if_num--;
+	}
+	rcu_read_unlock();
+
+	batman_if->if_num = -1;
+	spin_unlock(&orig_hash_lock);
+	return 0;
+
+err:
+	spin_unlock(&orig_hash_lock);
+	return -ENOMEM;
+}
diff --git a/batman-adv-kernelland/originator.h b/batman-adv-kernelland/originator.h
index 745b4b0..afbc7c0 100644
--- a/batman-adv-kernelland/originator.h
+++ b/batman-adv-kernelland/originator.h
@@ -30,3 +30,5 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
 		uint8_t *neigh, struct batman_if *if_incoming);
 ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 			      size_t count, loff_t off);
+int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
+int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
diff --git a/batman-adv-kernelland/proc.c b/batman-adv-kernelland/proc.c
deleted file mode 100644
index a8a1a67..0000000
--- a/batman-adv-kernelland/proc.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#include "main.h"
-#include "proc.h"
-#include "routing.h"
-#include "translation-table.h"
-#include "hard-interface.h"
-#include "types.h"
-#include "hash.h"
-#include "vis.h"
-#include "compat.h"
-#include "gateway_common.h"
-#include "gateway_client.h"
-
-static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
-
-static int proc_interfaces_read(struct seq_file *seq, void *offset)
-{
-	struct batman_if *batman_if;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		seq_printf(seq, "[%8s] %s %s \n",
-			   (batman_if->if_active == IF_ACTIVE ?
-			    "active" : "inactive"),
-			   batman_if->dev,
-			   (batman_if->if_active == IF_ACTIVE ?
-			    batman_if->addr_str : " "));
-	}
-	rcu_read_unlock();
-
-	return 0;
-}
-
-static int proc_interfaces_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_interfaces_read, NULL);
-}
-
-static ssize_t proc_interfaces_write(struct file *instance,
-				     const char __user *userbuffer,
-				     size_t count, loff_t *data)
-{
-	char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
-	int not_copied = 0, if_num = 0, add_success;
-	struct batman_if *batman_if = NULL;
-
-	if_string = kmalloc(count, GFP_KERNEL);
-
-	if (!if_string)
-		return -ENOMEM;
-
-	if (count > IFNAMSIZ - 1) {
-		printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
-		goto end;
-	}
-
-	not_copied = copy_from_user(if_string, userbuffer, count);
-	if_string[count - not_copied - 1] = 0;
-
-	colon_ptr = strchr(if_string, ':');
-	if (colon_ptr)
-		*colon_ptr = 0;
-
-	if (!colon_ptr) {
-		cr_ptr = strchr(if_string, '\n');
-		if (cr_ptr)
-			*cr_ptr = 0;
-	}
-
-	if (strlen(if_string) == 0) {
-		shutdown_module();
-		num_ifs = 0;
-		goto end;
-	}
-
-	/* add interface */
-	rcu_read_lock();
-	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		if (strncmp(batman_if->dev, if_string, count) == 0) {
-			printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string);
-			rcu_read_unlock();
-			goto end;
-
-		}
-
-		if_num++;
-	}
-	rcu_read_unlock();
-
-	add_success = hardif_add_interface(if_string, if_num);
-	if (add_success < 0)
-		goto end;
-
-	num_ifs = if_num + 1;
-
-	if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
-	    (hardif_get_active_if_num() > 0))
-		activate_module();
-
-	return count;
-end:
-	kfree(if_string);
-	return count;
-}
-
-static const struct file_operations proc_interfaces_fops = {
-	.owner		= THIS_MODULE,
-	.open		= proc_interfaces_open,
-	.read		= seq_read,
-	.write		= proc_interfaces_write,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-void cleanup_procfs(void)
-{
-	if (proc_interface_file)
-		remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
-
-	if (proc_batman_dir)
-#ifdef __NET_NET_NAMESPACE_H
-		remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net);
-#else
-		remove_proc_entry(PROC_ROOT_DIR, proc_net);
-#endif
-}
-
-int setup_procfs(void)
-{
-#ifdef __NET_NET_NAMESPACE_H
-	proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, init_net.proc_net);
-#else
-	proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, proc_net);
-#endif
-
-	if (!proc_batman_dir) {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s' folder failed\n", PROC_ROOT_DIR);
-		return -EFAULT;
-	}
-
-	proc_interface_file = create_proc_entry(PROC_FILE_INTERFACES,
-						S_IWUSR | S_IRUGO,
-						proc_batman_dir);
-	if (proc_interface_file) {
-		proc_interface_file->proc_fops = &proc_interfaces_fops;
-	} else {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_INTERFACES);
-		cleanup_procfs();
-		return -EFAULT;
-	}
-
-	return 0;
-}
diff --git a/batman-adv-kernelland/proc.h b/batman-adv-kernelland/proc.h
deleted file mode 100644
index 6f4f5b3..0000000
--- a/batman-adv-kernelland/proc.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#define PROC_ROOT_DIR "batman-adv"
-#define PROC_FILE_INTERFACES "interfaces"
-
-void cleanup_procfs(void);
-int setup_procfs(void);
-
diff --git a/batman-adv-kernelland/routing.c b/batman-adv-kernelland/routing.c
index 3168215..dbe27ad 100644
--- a/batman-adv-kernelland/routing.c
+++ b/batman-adv-kernelland/routing.c
@@ -207,7 +207,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node,
 	batman_packet->tq = ((batman_packet->tq *
 			      orig_neigh_node->tq_own *
 			      orig_neigh_node->tq_asym_penalty) /
-			     (TQ_MAX_VALUE *	 TQ_MAX_VALUE));
+			     (TQ_MAX_VALUE * TQ_MAX_VALUE));
 
 	bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
 		orig_node->orig, orig_neigh_node->orig, total_count,
@@ -514,7 +514,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 		batman_packet->version, has_directlink_flag);
 
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		if (batman_if->if_active != IF_ACTIVE)
+		if (batman_if->if_status != IF_ACTIVE)
 			continue;
 
 		if (compare_orig(ethhdr->h_source,
diff --git a/batman-adv-kernelland/send.c b/batman-adv-kernelland/send.c
index b5a96f5..684bf1d 100644
--- a/batman-adv-kernelland/send.c
+++ b/batman-adv-kernelland/send.c
@@ -60,7 +60,7 @@ int send_skb_packet(struct sk_buff *skb,
 {
 	struct ethhdr *ethhdr;
 
-	if (batman_if->if_active != IF_ACTIVE)
+	if (batman_if->if_status != IF_ACTIVE)
 		goto send_skb_err;
 
 	if (unlikely(!batman_if->net_dev))
@@ -126,7 +126,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 	int16_t buff_pos;
 	struct batman_packet *batman_packet;
 
-	if (batman_if->if_active != IF_ACTIVE)
+	if (batman_if->if_status != IF_ACTIVE)
 		return;
 
 	packet_num = buff_pos = 0;
@@ -184,7 +184,7 @@ static void send_packet(struct forw_packet *forw_packet)
 		return;
 	}
 
-	if (forw_packet->if_incoming->if_active != IF_ACTIVE)
+	if (forw_packet->if_incoming->if_status != IF_ACTIVE)
 		return;
 
 	/* multihomed peer assumed */
@@ -245,7 +245,13 @@ void schedule_own_packet(struct batman_if *batman_if)
 	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	unsigned long send_time;
 	struct batman_packet *batman_packet;
-	int vis_server = atomic_read(&bat_priv->vis_mode);
+	int vis_server;
+
+	if ((batman_if->if_status == IF_NOT_IN_USE) ||
+	    (batman_if->if_status == IF_TO_BE_REMOVED))
+		return;
+
+	vis_server = atomic_read(&bat_priv->vis_mode);
 
 	/**
 	 * the interface gets activated here to avoid race conditions between
@@ -254,11 +260,12 @@ void schedule_own_packet(struct batman_if *batman_if)
 	 * outdated packets (especially uninitialized mac addresses) in the
 	 * packet queue
 	 */
-	if (batman_if->if_active == IF_TO_BE_ACTIVATED)
-		batman_if->if_active = IF_ACTIVE;
+	if (batman_if->if_status == IF_TO_BE_ACTIVATED)
+		batman_if->if_status = IF_ACTIVE;
 
 	/* if local hna has changed and interface is a primary interface */
-	if ((atomic_read(&hna_local_changed)) && (batman_if->if_num == 0))
+	if ((atomic_read(&hna_local_changed)) &&
+	    (batman_if == bat_priv->primary_if))
 		rebuild_batman_packet(batman_if);
 
 	/**
@@ -366,6 +373,9 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
 	unsigned long flags;
 	INIT_HLIST_NODE(&forw_packet->list);
 
+	if (forw_packet->if_incoming->if_status == IF_TO_BE_REMOVED)
+		return;
+
 	/* add new packet to packet list */
 	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_add_head(&forw_packet->list, &forw_bcast_list);
@@ -433,7 +443,8 @@ void send_outstanding_bcast_packet(struct work_struct *work)
 	/* if we still have some more bcasts to send and we are not shutting
 	 * down */
 	if ((forw_packet->num_packets < 3) &&
-	    (atomic_read(&module_state) != MODULE_DEACTIVATING))
+	    (atomic_read(&module_state) != MODULE_DEACTIVATING) &&
+	    (forw_packet->if_incoming->if_status != IF_TO_BE_REMOVED))
 		_add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
 	else
 		forw_packet_free(forw_packet);
@@ -465,19 +476,31 @@ void send_outstanding_bat_packet(struct work_struct *work)
 	forw_packet_free(forw_packet);
 }
 
-void purge_outstanding_packets(void)
+void purge_outstanding_packets(struct batman_if *batman_if)
 {
 	struct forw_packet *forw_packet;
 	struct hlist_node *tmp_node, *safe_tmp_node;
 	unsigned long flags;
 
-	bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
+	if (batman_if)
+		bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n",
+			batman_if->dev);
+	else
+		bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
 
 	/* free bcast list */
 	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
 				  &forw_bcast_list, list) {
 
+		/**
+		 * if purge_outstanding_packets() was called with an argmument
+		 * we delete only packets belonging to the given interface
+		 */
+		if ((batman_if) &&
+		    (forw_packet->if_incoming != batman_if))
+			continue;
+
 		spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 		/**
@@ -494,6 +517,14 @@ void purge_outstanding_packets(void)
 	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
 				  &forw_bat_list, list) {
 
+		/**
+		 * if purge_outstanding_packets() was called with an argmument
+		 * we delete only packets belonging to the given interface
+		 */
+		if ((batman_if) &&
+		    (forw_packet->if_incoming != batman_if))
+			continue;
+
 		spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 
 		/**
diff --git a/batman-adv-kernelland/send.h b/batman-adv-kernelland/send.h
index b2ddf63..b84a470 100644
--- a/batman-adv-kernelland/send.h
+++ b/batman-adv-kernelland/send.h
@@ -36,4 +36,4 @@ void schedule_forward_packet(struct orig_node *orig_node,
 void add_bcast_packet_to_list(struct sk_buff *skb);
 void send_outstanding_bcast_packet(struct work_struct *work);
 void send_outstanding_bat_packet(struct work_struct *work);
-void purge_outstanding_packets(void);
+void purge_outstanding_packets(struct batman_if *batman_if);
diff --git a/batman-adv-kernelland/soft-interface.c b/batman-adv-kernelland/soft-interface.c
index d2c7864..a36d3de 100644
--- a/batman-adv-kernelland/soft-interface.c
+++ b/batman-adv-kernelland/soft-interface.c
@@ -176,8 +176,6 @@ int interface_change_mtu(struct net_device *dev, int new_mtu)
 	return 0;
 }
 
-
-
 int interface_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct unicast_packet *unicast_packet;
@@ -263,7 +261,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-		if (batman_if->if_active != IF_ACTIVE)
+		if (batman_if->if_status != IF_ACTIVE)
 			goto dropped;
 
 		if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
diff --git a/batman-adv-kernelland/translation-table.c b/batman-adv-kernelland/translation-table.c
index bab6d7e..d63f0b8 100644
--- a/batman-adv-kernelland/translation-table.c
+++ b/batman-adv-kernelland/translation-table.c
@@ -160,16 +160,14 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
 int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
 			       size_t count, loff_t off)
 {
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct hna_local_entry *hna_local_entry;
 	HASHIT(hashit);
 	int bytes_written = 0;
 	unsigned long flags;
 	size_t hdr_len;
 
-	rcu_read_lock();
-	if (list_empty(&if_list)) {
-		rcu_read_unlock();
-
+	if (!bat_priv->primary_if) {
 		if (off == 0)
 			return sprintf(buff,
 				       "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
@@ -177,7 +175,6 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
 
 		return 0;
 	}
-	rcu_read_unlock();
 
 	hdr_len = sprintf(buff,
 			  "Locally retrieved addresses (from %s) announced via HNA:\n",
@@ -377,16 +374,14 @@ void hna_global_add_orig(struct orig_node *orig_node,
 int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
 				size_t count, loff_t off)
 {
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct hna_global_entry *hna_global_entry;
 	HASHIT(hashit);
 	int bytes_written = 0;
 	unsigned long flags;
 	size_t hdr_len;
 
-	rcu_read_lock();
-	if (list_empty(&if_list)) {
-		rcu_read_unlock();
-
+	if (!bat_priv->primary_if) {
 		if (off == 0)
 			return sprintf(buff,
 				       "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
@@ -394,7 +389,6 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
 
 		return 0;
 	}
-	rcu_read_unlock();
 
 	hdr_len = sprintf(buff,
 			  "Globally announced HNAs received via the mesh %s (translation table):\n",
diff --git a/batman-adv-kernelland/types.h b/batman-adv-kernelland/types.h
index de13c99..737db7c 100644
--- a/batman-adv-kernelland/types.h
+++ b/batman-adv-kernelland/types.h
@@ -36,12 +36,13 @@ struct batman_if {
 	struct list_head list;
 	int16_t if_num;
 	char *dev;
-	char if_active;
+	char if_status;
 	char addr_str[ETH_STR_LEN];
 	struct net_device *net_dev;
 	atomic_t seqno;
 	unsigned char *packet_buff;
 	int packet_len;
+	struct kobject *hardif_obj;
 	struct rcu_head rcu;
 };
 
@@ -99,6 +100,8 @@ struct bat_priv {
 	atomic_t gw_mode;
 	atomic_t gw_class;
 	atomic_t orig_interval;
+	char num_ifaces;
+	struct batman_if *primary_if;
 	struct kobject *mesh_obj;
 };
 
diff --git a/batman-adv-kernelland/vis.c b/batman-adv-kernelland/vis.c
index a774de7..3144439 100644
--- a/batman-adv-kernelland/vis.c
+++ b/batman-adv-kernelland/vis.c
@@ -174,13 +174,10 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
 	unsigned long flags;
 	int vis_server = atomic_read(&bat_priv->vis_mode);
 
-	rcu_read_lock();
-	if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
-		rcu_read_unlock();
+	if ((!bat_priv->primary_if) ||
+	    (vis_server == VIS_TYPE_CLIENT_UPDATE))
 		return 0;
-	}
 
-	rcu_read_unlock();
 	hdr_len = 0;
 
 	spin_lock_irqsave(&vis_hash_lock, flags);
-- 
1.7.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [B.A.T.M.A.N.] [PATCH 5/5] batctl: adapt batctl to new sysfs interface handling
  2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
                   ` (3 preceding siblings ...)
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 4/5] batman-adv: move /proc interface handling to /sys Marek Lindner
@ 2010-03-24  4:52 ` Marek Lindner
  2010-04-01 17:28 ` [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Linus Lüssing
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Lindner @ 2010-03-24  4:52 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 batctl/Makefile     |    4 +-
 batctl/functions.c  |    3 +-
 batctl/functions.h  |    1 +
 batctl/main.c       |    3 +-
 batctl/man/batctl.8 |    6 +--
 batctl/proc.c       |  114 -------------------------------------------------
 batctl/proc.h       |   28 ------------
 batctl/sys.c        |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++
 batctl/sys.h        |    4 ++
 9 files changed, 130 insertions(+), 151 deletions(-)
 delete mode 100644 batctl/proc.c
 delete mode 100644 batctl/proc.h

diff --git a/batctl/Makefile b/batctl/Makefile
index 595b996..db375f7 100644
--- a/batctl/Makefile
+++ b/batctl/Makefile
@@ -39,8 +39,8 @@ SRC_FILES = "\(\.c\)\|\(\.h\)\|\(Makefile\)\|\(INSTALL\)\|\(LIESMICH\)\|\(README
 EXTRA_MODULES_C := bisect.c
 EXTRA_MODULES_H := bisect.h
 
-SRC_C = main.c bat-hosts.c functions.c proc.c sys.c ping.c traceroute.c tcpdump.c list-batman.c hash.c vis.c $(EXTRA_MODULES_C)
-SRC_H = main.h bat-hosts.h functions.h proc.h sys.h ping.h traceroute.h tcpdump.h list-batman.h hash.h allocate.h vis.h $(EXTRA_MODULES_H)
+SRC_C = main.c bat-hosts.c functions.c sys.c ping.c traceroute.c tcpdump.c list-batman.c hash.c vis.c $(EXTRA_MODULES_C)
+SRC_H = main.h bat-hosts.h functions.h sys.h ping.h traceroute.h tcpdump.h list-batman.h hash.h allocate.h vis.h $(EXTRA_MODULES_H)
 SRC_O = $(SRC_C:.c=.o)
 
 PACKAGE_NAME = batctl
diff --git a/batctl/functions.c b/batctl/functions.c
index a7f4b77..7d8be51 100644
--- a/batctl/functions.c
+++ b/batctl/functions.c
@@ -164,7 +164,8 @@ open:
 	fp = fopen(full_path, "r");
 
 	if (!fp) {
-		printf("Error - can't open file '%s': %s\n", full_path, strerror(errno));
+		if (!(read_opt & SILENCE_ERRORS))
+			printf("Error - can't open file '%s': %s\n", full_path, strerror(errno));
 		goto out;
 	}
 
diff --git a/batctl/functions.h b/batctl/functions.h
index 3756392..63740d2 100644
--- a/batctl/functions.h
+++ b/batctl/functions.h
@@ -48,4 +48,5 @@ enum {
 	LOG_MODE = 0x08,
 	USE_READ_BUFF = 0x10,
 	SEARCH_ARGS = 0x20,
+	SILENCE_ERRORS = 0x40,
 };
diff --git a/batctl/main.c b/batctl/main.c
index da7fb4a..1cabcdd 100644
--- a/batctl/main.c
+++ b/batctl/main.c
@@ -29,7 +29,6 @@
 #include <string.h>
 
 #include "main.h"
-#include "proc.h"
 #include "sys.h"
 #include "ping.h"
 #include "traceroute.h"
@@ -41,7 +40,7 @@
 void print_usage(void) {
 	printf("Usage: batctl [options] commands \n");
 	printf("commands:\n");
-	printf(" \tinterface|if   [none|interface]  \tdisplay or modify the interface settings\n");
+	printf(" \tinterface|if   [add|del iface(s)]\tdisplay or modify the interface settings\n");
 	printf(" \toriginators|o                    \tdisplay the originator table\n");
 	printf(" \tinterval|it    [orig_interval]   \tdisplay or modify the originator interval (in ms)\n");
 	printf(" \tloglevel|ll    [level]           \tdisplay or modify the log level\n");
diff --git a/batctl/man/batctl.8 b/batctl/man/batctl.8
index 43af853..ad165bf 100644
--- a/batctl/man/batctl.8
+++ b/batctl/man/batctl.8
@@ -53,10 +53,8 @@ protocol.
 .br
 .TP
 .I \fBcommands:
-.IP "\fBinterface\fP|\fBif\fP     [\fBnone\fP|\fBinterface\fP]"
-If no parameter is given the current interface settings are displayed
-otherwise the parameter(s) are added as new interfaces. Use the "none"
-keyword to deactivate all interfaces.
+.IP "\fBinterface\fP|\fBif\fP     [\fBadd\fP|\fBdel iface(s)\fP]"
+If no parameter is given or the first parameter is neither "add" nor "del" the current interface settings are displayed. In order to add or delete interfaces specify "add" or "del" as first argument and append the interface names you wish to add or delete.
 .br
 .IP "\fBoriginators\fP|\fBo\fP    [\fB\-b\fP][\fB\-n\fP]"
 Once started batctl will display the list of announced gateways in the network. Use the "\-w" option to let batctl refresh the list every second. If "\-n" is given batctl will not replace the MAC addresses with bat\-host names in the output.
diff --git a/batctl/proc.c b/batctl/proc.c
deleted file mode 100644
index 192d4fb..0000000
--- a/batctl/proc.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner <lindner_marek@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-
-#include <sys/time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "main.h"
-#include "proc.h"
-#include "functions.h"
-
-static void interface_usage(void)
-{
-	printf("Usage: batctl interface [options] [none|interface] \n");
-	printf("options:\n");
-	printf(" \t -h print this help\n");
-}
-
-int interface(int argc, char **argv)
-{
-	int i, res, optchar;
-
-	while ((optchar = getopt(argc, argv, "h")) != -1) {
-		switch (optchar) {
-		case 'h':
-			interface_usage();
-			return EXIT_SUCCESS;
-		default:
-			interface_usage();
-			return EXIT_FAILURE;
-		}
-	}
-
-	if (argc == 1)
-		return read_file(PROC_ROOT_PATH, PROC_INTERFACES, SINGLE_READ);
-
-	for (i = 1; i < argc; i++) {
-		if (strcmp(argv[i], "none") == 0)
-			res = write_file(PROC_ROOT_PATH, PROC_INTERFACES, "", NULL);
-		else
-			res = write_file(PROC_ROOT_PATH, PROC_INTERFACES, argv[i], NULL);
-
-		if (res != EXIT_SUCCESS)
-			return res;
-	}
-
-	return EXIT_SUCCESS;
-}
-
-int handle_table(int argc, char **argv, char *file_path, void table_usage(void))
-{
-	int optchar, read_opt = USE_BAT_HOSTS;
-
-	while ((optchar = getopt(argc, argv, "hnw")) != -1) {
-		switch (optchar) {
-		case 'h':
-			table_usage();
-			return EXIT_SUCCESS;
-		case 'n':
-			read_opt &= ~USE_BAT_HOSTS;
-			break;
-		case 'w':
-			read_opt |= CLR_CONT_READ;
-			break;
-		default:
-			table_usage();
-			return EXIT_FAILURE;
-		}
-	}
-
-	return read_file(PROC_ROOT_PATH, file_path, read_opt);
-}
-
-int handle_proc_setting(int argc, char **argv, char *file_path, void setting_usage(void))
-{
-	int optchar;
-
-	while ((optchar = getopt(argc, argv, "h")) != -1) {
-		switch (optchar) {
-		case 'h':
-			setting_usage();
-			return EXIT_SUCCESS;
-		default:
-			setting_usage();
-			return EXIT_FAILURE;
-		}
-	}
-
-	if (argc == 1)
-		return read_file(PROC_ROOT_PATH, file_path, SINGLE_READ);
-
-	return write_file(PROC_ROOT_PATH, file_path, argv[1], NULL);
-}
diff --git a/batctl/proc.h b/batctl/proc.h
deleted file mode 100644
index 61d6058..0000000
--- a/batctl/proc.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner <lindner_marek@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#define PROC_ROOT_PATH "/proc/net/batman-adv/"
-#define PROC_INTERFACES "interfaces"
-
-int interface(int argc, char **argv);
-
-int handle_table(int argc, char **argv, char *file_path, void table_usage(void));
-int handle_proc_setting(int argc, char **argv, char *file_path, void setting_usage(void));
diff --git a/batctl/sys.c b/batctl/sys.c
index cd8979a..1b0b784 100644
--- a/batctl/sys.c
+++ b/batctl/sys.c
@@ -25,11 +25,129 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 #include "main.h"
 #include "sys.h"
 #include "functions.h"
 
+#define PATH_BUFF_LEN 200
+
+static void interface_usage(void)
+{
+	printf("Usage: batctl interface [options] [add|del iface(s)] \n");
+	printf("options:\n");
+	printf(" \t -h print this help\n");
+}
+
+static int print_interfaces(void)
+{
+	DIR *iface_base_dir;
+	struct dirent *iface_dir;
+	char *path_buff;
+	int res;
+
+	path_buff = malloc(PATH_BUFF_LEN);
+	if (!path_buff) {
+		printf("Error - could not allocate path buffer: out of memory ?\n");
+		goto err;
+	}
+
+	iface_base_dir = opendir(SYS_IFACE_PATH);
+	if (!iface_base_dir) {
+		printf("Error - the directory '%s' could not be read: %s\n",
+		       SYS_IFACE_PATH, strerror(errno));
+		printf("Is the batman-adv module loaded and sysfs mounted ?\n");
+		goto err_buff;
+	}
+
+	while ((iface_dir = readdir(iface_base_dir)) != NULL) {
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name);
+		res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS);
+		if (res != EXIT_SUCCESS)
+			continue;
+
+		if (line_ptr[strlen(line_ptr) - 1] == '\n')
+			line_ptr[strlen(line_ptr) - 1] = '\0';
+
+		if (strcmp(line_ptr, "status: none") == 0)
+			goto free_line;
+
+		free(line_ptr);
+		line_ptr = NULL;
+
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name);
+		res = read_file("", path_buff, SINGLE_READ | USE_READ_BUFF | SILENCE_ERRORS);
+		if (res != EXIT_SUCCESS) {
+			printf("<error reading status>\n");
+			continue;
+		}
+
+		printf("%s: %s", iface_dir->d_name, line_ptr);
+
+free_line:
+		free(line_ptr);
+		line_ptr = NULL;
+	}
+
+	free(path_buff);
+	closedir(iface_base_dir);
+	return EXIT_SUCCESS;
+
+err_buff:
+	free(path_buff);
+err:
+	return EXIT_FAILURE;
+}
+
+int interface(int argc, char **argv)
+{
+	char *path_buff;
+	int i, res, optchar;
+
+	while ((optchar = getopt(argc, argv, "h")) != -1) {
+		switch (optchar) {
+		case 'h':
+			interface_usage();
+			return EXIT_SUCCESS;
+		default:
+			interface_usage();
+			return EXIT_FAILURE;
+		}
+	}
+
+	if ((argc == 1) ||
+	    ((strcmp(argv[1], "add") != 0) &&
+	    (strcmp(argv[1], "del") != 0)))
+		return print_interfaces();
+
+	path_buff = malloc(PATH_BUFF_LEN);
+	if (!path_buff) {
+		printf("Error - could not allocate path buffer: out of memory ?\n");
+		goto err;
+	}
+
+	for (i = 2; i < argc; i++) {
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, argv[i]);
+
+		if (strcmp(argv[1], "add") == 0)
+			res = write_file("", path_buff, "bat0", NULL);
+		else
+			res = write_file("", path_buff, "none", NULL);
+
+		if (res != EXIT_SUCCESS)
+			goto err_buff;
+	}
+
+	free(path_buff);
+	return EXIT_SUCCESS;
+
+err_buff:
+	free(path_buff);
+err:
+	return EXIT_FAILURE;
+}
 
 static void log_usage(void)
 {
diff --git a/batctl/sys.h b/batctl/sys.h
index 19d19f5..6d78622 100644
--- a/batctl/sys.h
+++ b/batctl/sys.h
@@ -34,6 +34,9 @@
 #define SYS_VIS_MODE "vis_mode"
 #define SYS_VIS_DATA "vis_data"
 #define SYS_ORIG_INTERVAL "orig_interval"
+#define SYS_IFACE_PATH "/sys/class/net"
+#define SYS_MESH_IFACE_FMT SYS_IFACE_PATH"/%s/batman_adv/mesh_iface"
+#define SYS_IFACE_STATUS_FMT SYS_IFACE_PATH"/%s/batman_adv/iface_status"
 
 void originators_usage(void);
 void trans_local_usage(void);
@@ -45,6 +48,7 @@ void gateways_usage(void);
 void vis_mode_usage(void);
 void orig_interval_usage(void);
 int log_print(int argc, char **argv);
+int interface(int argc, char **argv);
 int handle_loglevel(int argc, char **argv);
 int handle_sys_table(int argc, char **argv, char *file_path, void table_usage(void));
 int handle_sys_setting(int argc, char **argv, char *file_path, void setting_usage(void));
-- 
1.7.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [B.A.T.M.A.N.] reorganized kernel interface patches (version 3)
  2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
                   ` (4 preceding siblings ...)
  2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 5/5] batctl: adapt batctl to new sysfs interface handling Marek Lindner
@ 2010-04-01 17:28 ` Linus Lüssing
  2010-04-03  9:44   ` Marek Lindner
  5 siblings, 1 reply; 9+ messages in thread
From: Linus Lüssing @ 2010-04-01 17:28 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking


[-- Attachment #1.1: Type: text/plain, Size: 575 bytes --]

Hi Marek,

had a look at your patches and found a bug which causes a kernel panic
(see attachement). I can reproduce this with the following veeery
complicated routine :):
---
ifconfig bat0 down && ifconfig bat0 up
---

The adding and deleting of mesh-port interfaces seems to work fine,
the new, more dynamic interface is awesome :). And I just was
wondering if you forgot about adding something like "batctl if del
all" or did you schedule this for another patch?

Also some additional abbrevations for add/del would be nice (just
"a" and "d" for instance).

Cheers, Linus

[-- Attachment #1.2: 2010-0401-1838-syspatches.log --]
[-- Type: text/plain, Size: 10080 bytes --]

└─(18:09:%)─> picocom /dev/ttyUSB0                                                                                                           <─(Thu,Apr01)─┘
picocom v1.4

port is        : /dev/ttyUSB0
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
escape is      : C-a
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : ascii_xfr -s -v -l10
receive_cmd is : rz -vv

Terminal ready
+Warning: IP address 192.168.1.1 in use
Ethernet eth0: MAC address 00:22:b0:98:87:de
IP: 192.168.1.1/255.255.255.0, Gateway: 0.0.0.0
Default server: 192.168.1.2

RedBoot(tm) bootstrap and debug environment [ROMRAM]
production release, version "2.1.3" - built 18:43:19, Sep 20 2007

Platform: ap61 (Atheros WiSOC)
Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Copyright (C) 2007, NewMedia-NET GmbH.

Board: DLINK DIR-300
RAM: 0x80000000-0x81000000, [0x80040580-0x80fe1000] available
FLASH: 0xbfc00000 - 0xbfff0000, 64 blocks of 0x00010000 bytes each.
== Executing boot script in 5.000 seconds - enter ^C to abort
DD-WRT> fis load -l vmlinux.bin.l7
�����������Image loaded from 0x80041000-0x802c2200
DD-WRT> exec
Now booting linux kernel:
 Base address 0x80030000 Entry 0x80041000
 Cmdline :
Linux version 2.6.30.10 (linus@Linus-Debian) (gcc version 4.3.3 (GCC) ) #25 Thu Apr 1 14:30:45 CEST 2010
CPU revision is: 00019064 (MIPS 4KEc)
Determined physical RAM map:
 memory: 01000000 @ 00000000 (usable)
Initrd not found or empty - disabling initrd
Zone PFN ranges:
  Normal   0x00000000 -> 0x00001000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00001000
Built 1 zonelists in Zone order, mobility grouping off.  Total pages: 4064
Kernel command line: console=ttyS0,9600 rootfstype=squashfs,jffs2
Primary instruction cache 16kB, VIPT, 4-way, linesize 16 bytes.
Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 16 bytes
NR_IRQS:128
PID hash table entries: 64 (order: 6, 256 bytes)
console [ttyS0] enabled
Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory: 13324k/16384k available (1985k kernel code, 3060k reserved, 452k data, 128k init, 0k highmem)
Calibrating delay loop... 183.50 BogoMIPS (lpj=917504)
Mount-cache hash table entries: 512
net_namespace: 732 bytes
NET: Registered protocol family 16
bio: create slab <bio-0> at 0
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 512 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 512 bind 512)
TCP reno registered
NET: Registered protocol family 1
Radio config found at offset 0xf8(0x1f8)
squashfs: version 4.0 (2009/01/31) Phillip Lougher
Registering mini_fo version $Id$
JFFS2 version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
msgmni has been set to 26
io scheduler noop registered
io scheduler deadline registered (default)
gpiodev: gpio device registered with major 254
gpiodev: gpio platform device registered with access mask FFFFFFFF
Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
serial8250: ttyS0 at MMIO 0xb1100003 (irq = 37) is a 16550A
eth0: Atheros AR231x: 00:22:b0:98:87:de, irq 4
ar231x_eth_mii: probed
eth0: attached PHY driver [IC+ IP175C] (mii_bus:phy_addr=0:00)
cmdlinepart partition parsing not available
Searching for RedBoot partition table in spiflash at offset 0x3d0000
Searching for RedBoot partition table in spiflash at offset 0x3e0000
6 RedBoot partitions found on MTD device spiflash
Creating 6 MTD partitions on "spiflash":
0x000000000000-0x000000030000 : "RedBoot"
0x000000030000-0x0000002f0000 : "rootfs"
mtd: partition "rootfs" set to be root filesystem
mtd: partition "rootfs_data" created automatically, ofs=230000, len=C0000
0x000000230000-0x0000002f0000 : "rootfs_data"
0x0000002f0000-0x0000003d0000 : "vmlinux.bin.l7"
0x0000003e0000-0x0000003ef000 : "FIS directory"
0x0000003ef000-0x0000003f0000 : "RedBoot config"
0x0000003f0000-0x000000400000 : "boardconfig"
TCP westwood registered
NET: Registered protocol family 17
Bridge firewalling registered
802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>
All bugs added by David S. Miller <davem@redhat.com>
VFS: Mounted root (squashfs filesystem) readonly on device 31:1.
Freeing unused kernel memory: 128k freed
Please be patient, while OpenWrt loads ...
- preinit -
Press Press f<ENTER> to enter failsafe mode
- regular preinit -
jffs2 not ready yet; using ramdisk
mini_fo: using base directory: /
mini_fo: using storage directory: /tmp/root
- init -

Please press Enter to activate this console. NET: Registered protocol family 10
lo: Disabled Privacy Extensions
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
device eth0.1 entered promiscuous mode
device eth0 entered promiscuous mode
br-mesh: port 1(eth0.1) entering forwarding state
ip_tables: (C) 2000-2006 Netfilter Core Team
Ebtables v2.0 registered
ip6_tables: (C) 2000-2006 Netfilter Core Team
batman-adv:B.A.T.M.A.N. advanced 0.3.0-alpha r1611 (compatibility version 9) loaded
ath_hal: module license 'Proprietary' taints kernel.
Disabling lock debugging due to kernel taint
ath_hal: 2009-05-08 (AR5212, AR5312, RF5111, RF5112, RF2316, RF2317, REGOPS_FUNC, TX_DESC_SWAP, XR)
device eth0.4 entered promiscuous mode
br-wan_vpn: port 1(eth0.4) entering forwarding state
br-wan_vpn: starting userspace STP failed, starting kernel STP
ath_ahb: trunk
wlan: trunk
wlan: mac acl policy registered
ath_rate_minstrel: Minstrel automatic rate control algorithm 1.2 (trunk)
ath_rate_minstrel: look around rate set to 10%
ath_rate_minstrel: EWMA rolloff level set to 75%
ath_rate_minstrel: max segment size in the mrr set to 6000 us
Atheros HAL provided by OpenWrt, DD-WRT and MakSat Technologies
wifi0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
wifi0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: turboG rates: 6Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
wifi0: H/W encryption support: WEP AES AES_CCM TKIP
ath_ahb: wifi0: Atheros 2317 WiSoC REV1: mem=0xb0000000, irq=3
IRQ 3/wifi0: IRQF_DISABLED is not guaranteed on shared IRQs
device bat0 entered promiscuous mode
br-mesh: port 2(bat0) entering forwarding state
device ath0 entered promiscuous mode
br-mesh: port 3(ath0) entering forwarding state
device ath0 left promiscuous mode
br-mesh: port 3(ath0) entering disabled state
device ath0 entered promiscuous mode
br-mesh: port 3(ath0) entering forwarding state
device ath1 entered promiscuous mode
br-wan_vpn: topology change detected, propagating
br-wan_vpn: port 2(ath1) entering forwarding state
device ath1 left promiscuous mode
br-wan_vpn: port 2(ath1) entering disabled state
device ath1 entered promiscuous mode
br-wan_vpn: topology change detected, propagating
br-wan_vpn: port 2(ath1) entering forwarding state
br-wan_vpn: port 2(ath1) entering disabled state
br-wan_vpn: port 1(eth0.4) entering disabled state
br-wan_vpn: topology change detected, propagating
br-wan_vpn: port 2(ath1) entering forwarding state
br-wan_vpn: topology change detected, propagating
br-wan_vpn: port 1(eth0.4) entering forwarding state
br-mesh: port 3(ath0) entering disabled state
br-mesh: port 2(bat0) entering disabled state
br-mesh: port 1(eth0.1) entering disabled state
br-mesh: port 3(ath0) entering forwarding state
br-mesh: port 2(bat0) entering forwarding state
br-mesh: port 1(eth0.1) entering forwarding state
batman-adv:Adding interface: ath2
batman-adv:Interface activated: ath2
CPU 0 Unable to handle kernel paging request at virtual address 00000011, epc == 80bd1524, ra == 80bd3ec4
Oops[#1]:
Cpu 0
$ 0   : 00000000 10009c00 00000001 80c2a4a0
$ 4   : 80e9b300 00000001 00000000 80e21020
$ 8   : 00000000 00000000 00000000 00000000
$12   : 00000000 00000000 802d0000 00000000
$16   : 80e21008 809fe2c0 80f33e20 809fe000
$20   : 8096dd80 0000006e ffffffff 80290000
$24   : 00000000 80bd3ddc
$28   : 8057a000 8057bcb0 80279490 80bd3ec4
Hi    : 00000064
Lo    : 00af485a
epc   : 80bd1524 purge_outstanding_packets+0x21c/0x300 [batman_adv]
    Tainted: P
ra    : 80bd3ec4 interface_tx+0xe8/0x294 [batman_adv]
Status: 10009c03    KERNEL EXL IE
Cause : 10800008
BadVA : 00000011
PrId  : 00019064 (MIPS 4KEc)
Modules linked in: ath_ahb ath_hal(P) batman_adv ip6t_REJECT ip6t_LOG ip6t_rt ip6t_hbh ip6t_mh ip6t_ipv6header ip6t_frag ip6t_eui64 ip6t_ah ip6table_raw ip6_queue ip6table_mangle ip6table_filter ip6_tables ebt_redirect ebt_mark ebt_vlan ebt_stp ebt_pkttype ebt_mark_m ebt_limit ebt_among ebt_802_3 ebtable_nat ebtable_filter ebtable_broute ebtables xt_quota xt_pkttype xt_physdev ipt_REJECT xt_TCPMSS ipt_LOG xt_multiport xt_mac xt_limit iptable_mangle iptable_filter ip_tables xt_tcpudp x_tables tun ipv6
Process dropbearkey (pid: 1090, threadinfo=8057a000, task=80343988, tls=00000000)
Stack : 80f33e20 8057bcf4 80e21012 809fe2c0 80f33e20 80e21008 809fe2c0 80bd3ec4
        0000000a 80a82e98 809fe000 00000005 80bc9800 801d2c40 80bc9800 80bc9800
        00000001 80f33e20 809fe000 8096dd80 ffffa89e ffffffff 80290000 801c6310
        80f33e20 80f33e20 80bcb800 802d4ac0 8096dd80 00000000 80f33e20 809fe000
        802d4ac0 80e21050 00000003 00000004 80bcb800 801b3e08 00000000 00000060
        ...
Call Trace:
[<80bd1524>] purge_outstanding_packets+0x21c/0x300 [batman_adv]
[<80bd3ec4>] interface_tx+0xe8/0x294 [batman_adv]
[<801c6310>] __qdisc_run+0x118/0x2cc
[<801b3e08>] dev_queue_xmit+0x298/0x3dc
[<80a8615c>] ip6_output+0xcd4/0x103c [ipv6]
[<80aa2934>] ipv6_chk_mcast_addr+0xe18/0x1620 [ipv6]


Code: 8c82004c  ac800000  ac800004 <80430010> 24020001  00808021  10620030  00a08821  40056000
Kernel panic - not syncing: Fatal exception in interrupt


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [B.A.T.M.A.N.] reorganized kernel interface patches (version 3)
  2010-04-01 17:28 ` [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Linus Lüssing
@ 2010-04-03  9:44   ` Marek Lindner
  2010-04-05 20:47     ` Marek Lindner
  0 siblings, 1 reply; 9+ messages in thread
From: Marek Lindner @ 2010-04-03  9:44 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking


Hey,

thanks a lot for testing and your feedback!

> had a look at your patches and found a bug which causes a kernel panic
> (see attachement). I can reproduce this with the following veeery
> complicated routine :):
> ---
> ifconfig bat0 down && ifconfig bat0 up
> ---

I tried that but it does not crash at my end. Maybe you did more than you 
think to provoke this crash ? In my test setup I have 2 nodes with 3 
interfaces each. I ran your command several times without seeing any odd 
behaviour.


> The adding and deleting of mesh-port interfaces seems to work fine,
> the new, more dynamic interface is awesome :). And I just was
> wondering if you forgot about adding something like "batctl if del
> all" or did you schedule this for another patch?

Actually, a "delete all" was not on my agenda.


> Also some additional abbrevations for add/del would be nice (just
> "a" and "d" for instance).

Should be no problem - I'll add it before submitting the patches.

Regards,
Marek

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [B.A.T.M.A.N.] reorganized kernel interface patches (version 3)
  2010-04-03  9:44   ` Marek Lindner
@ 2010-04-05 20:47     ` Marek Lindner
  0 siblings, 0 replies; 9+ messages in thread
From: Marek Lindner @ 2010-04-05 20:47 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Saturday 03 April 2010 17:44:28 Marek Lindner wrote:
> I tried that but it does not crash at my end. Maybe you did more than you
> think to provoke this crash ? In my test setup I have 2 nodes with 3
> interfaces each. I ran your command several times without seeing any odd
> behaviour.

Ok, we found the bug and fixed it.
The sysfs changes are complete now and can be found in the trunk.

Regards,
Marek

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-04-05 20:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-24  4:52 [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Marek Lindner
2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 1/5] batman-adv: move originator interval setting from /proc to /sys Marek Lindner
2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 2/5] batctl: follow the orig_interval move " Marek Lindner
2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 3/5] batman-adv: remove redundant pointer to originator interface Marek Lindner
2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 4/5] batman-adv: move /proc interface handling to /sys Marek Lindner
2010-03-24  4:52 ` [B.A.T.M.A.N.] [PATCH 5/5] batctl: adapt batctl to new sysfs interface handling Marek Lindner
2010-04-01 17:28 ` [B.A.T.M.A.N.] reorganized kernel interface patches (version 3) Linus Lüssing
2010-04-03  9:44   ` Marek Lindner
2010-04-05 20:47     ` Marek Lindner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).