[B.A.T.M.A.N.] batman-adv: Unable to add interface in LXC

2012-12-30 Thread Pau Koning
I am running LXC (SID) under Debian SID and the current git version of
batman-adv (v3.7-rc7-1325-gaf5d4f7) +batctl (v2012.4.0-30-ga395164).
But it fails to add any of my interfaces and non-batman-adv interfaces
can be created without problems

# ip link
13: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast
state UP mode DEFAULT qlen 1000
link/ether 00:ff:aa:00:00:01 brd ff:ff:ff:ff:ff:ff
15: lo: LOOPBACK,UP,LOWER_UP mtu 16436 qdisc noqueue state UNKNOWN
mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# batctl if add eth0
Error - can't open file '/sys/class/net/eth0/batman_adv/mesh_iface':
Read-only file system
# ls -l /sys/class/net/eth0/batman_adv/mesh_iface
-rw-r--r-- 1 root root 4096 Dec 30 18:26
/sys/class/net/eth0/batman_adv/mesh_iface
# id
uid=0(root) gid=0(root) groups=0(root)
# ip link add dev br0 type bridge
# ip link set dev eth0 master br0
# ip link
18: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast
master br0 state UP mode DEFAULT qlen 1000
link/ether 00:ff:aa:00:00:01 brd ff:ff:ff:ff:ff:ff
20: lo: LOOPBACK,UP,LOWER_UP mtu 16436 qdisc noqueue state UNKNOWN
mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
21: br0: BROADCAST,MULTICAST mtu 1500 qdisc noop state DOWN mode DEFAULT
link/ether 00:ff:aa:00:00:01 brd ff:ff:ff:ff:ff:ff


[B.A.T.M.A.N.] [PATCH] batman-adv: postpone sysfs removal when unregistering

2012-12-30 Thread Simon Wunderlich
When processing the unregister notify for a hard interface, removing
the sysfs files may lead to a circular deadlock (rtnl mutex -
s_active).

To overcome this problem, postpone the sysfs removal in a worker.

Reported-by: Sasha Levin sasha.le...@oracle.com
Reported-by: Sven Eckelmann s...@narfation.org
Signed-off-by: Simon Wunderlich s...@hrz.tu-chemnitz.de
---
Changes from RFCv1:
 * use work_struct properly, instead of delayed_work
 * postpone for softifs as well as for hardifs

Postponing the sysfs removal for the hardif unregister is easier than
other alternatives involving deferring. This should bring us to the
same level to the bridge code, which also messes with sysfs in the
notifier processing function, and uses rtnl_trylock when called
from within sysfs.

As far as I could understand the net/core code, only the unregister
case is the critical one, so the original bug should hopefully be
fixed.
---
 hard-interface.c |   16 ++--
 soft-interface.c |   26 +++---
 types.h  |3 +++
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/hard-interface.c b/hard-interface.c
index f1d37cd..eb3a12d 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -506,6 +506,17 @@ out:
return NULL;
 }
 
+static void batadv_hardif_remove_interface_finish(struct work_struct *work)
+{
+   struct batadv_hard_iface *hard_iface;
+
+   hard_iface = container_of(work, struct batadv_hard_iface,
+ cleanup_work);
+
+   batadv_sysfs_del_hardif(hard_iface-hardif_obj);
+   batadv_hardif_free_ref(hard_iface);
+}
+
 static void batadv_hardif_remove_interface(struct batadv_hard_iface 
*hard_iface)
 {
ASSERT_RTNL();
@@ -518,8 +529,9 @@ static void batadv_hardif_remove_interface(struct 
batadv_hard_iface *hard_iface)
return;
 
hard_iface-if_status = BATADV_IF_TO_BE_REMOVED;
-   batadv_sysfs_del_hardif(hard_iface-hardif_obj);
-   batadv_hardif_free_ref(hard_iface);
+   INIT_WORK(hard_iface-cleanup_work,
+ batadv_hardif_remove_interface_finish);
+   queue_work(batadv_event_workqueue, hard_iface-cleanup_work);
 }
 
 void batadv_hardif_remove_interfaces(void)
diff --git a/soft-interface.c b/soft-interface.c
index a8eb963..b8a307b 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -464,6 +464,7 @@ struct net_device *batadv_softif_create(const char *name)
goto out;
 
bat_priv = netdev_priv(soft_iface);
+   bat_priv-soft_iface = soft_iface;
 
/* batadv_interface_stats() needs to be available as soon as
 * register_netdevice() has been called
@@ -550,12 +551,31 @@ out:
return NULL;
 }
 
+static void batadv_softif_destroy_finish(struct work_struct *work)
+{
+   struct batadv_priv *bat_priv;
+   struct net_device *soft_iface;
+
+   bat_priv = container_of(work, struct batadv_priv,
+   cleanup_work);
+   soft_iface = bat_priv-soft_iface;
+
+   batadv_debugfs_del_meshif(soft_iface);
+   batadv_sysfs_del_meshif(soft_iface);
+
+   rtnl_lock();
+   unregister_netdevice(soft_iface);
+   rtnl_unlock();
+}
+
 void batadv_softif_destroy(struct net_device *soft_iface)
 {
-   batadv_debugfs_del_meshif(soft_iface);
-   batadv_sysfs_del_meshif(soft_iface);
+   struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+
batadv_mesh_free(soft_iface);
-   unregister_netdevice(soft_iface);
+
+   INIT_WORK(bat_priv-cleanup_work, batadv_softif_destroy_finish);
+   queue_work(batadv_event_workqueue, bat_priv-cleanup_work);
 }
 
 int batadv_softif_is_valid(const struct net_device *net_dev)
diff --git a/types.h b/types.h
index d8061ac..a9800ee 100644
--- a/types.h
+++ b/types.h
@@ -63,6 +63,7 @@ struct batadv_hard_iface {
struct net_device *soft_iface;
struct rcu_head rcu;
struct batadv_hard_iface_bat_iv bat_iv;
+   struct work_struct cleanup_work;
 };
 
 /**
@@ -266,6 +267,7 @@ struct batadv_priv_dat {
 
 struct batadv_priv {
atomic_t mesh_state;
+   struct net_device *soft_iface;
struct net_device_stats stats;
uint64_t __percpu *bat_counters; /* Per cpu counters */
atomic_t aggregated_ogms;   /* boolean */
@@ -302,6 +304,7 @@ struct batadv_priv {
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
spinlock_t forw_bcast_list_lock; /* protects forw_bcast_list */
struct delayed_work orig_work;
+   struct work_struct cleanup_work;
struct batadv_hard_iface __rcu *primary_if;  /* rcu protected pointer */
struct batadv_algo_ops *bat_algo_ops;
 #ifdef CONFIG_BATMAN_ADV_BLA
-- 
1.7.10.4



[B.A.T.M.A.N.] Unterstanding gateway-mode - why does node have a sticky gateway

2012-12-30 Thread Jan Lühr
Hello,

I started using batman-adv's gateway mode. Sadly, I ran into some trouble - A 
client is connected to two gateways via vpn (fastd):
# batctl gw_mode
client (selection class: 1)

# batctl gwl
  Gateway  (#/255)   Nexthop [outgoingIF]: gw_class ... 
[B.A.T.M.A.N. adv 2012.4.0, MainIF/MAC: wlan0-1/f6:ec:38:e9:72:35 (bat0)]
   6a:4b:93:de:00:84 (255) 6a:4b:93:de:00:84 [  mesh-vpn]: 207 - 48MBit/48MBit
= aa:31:0e:4a:0f:1d (254) aa:31:0e:4a:0f:1d [  mesh-vpn]:  39 - 
1024KBit/1024KBit

# batctl o
[B.A.T.M.A.N. adv 2012.4.0, MainIF/MAC: wlan0-1/f6:ec:38:e9:72:35 (bat0)]
  Originator  last-seen (#/255)   Nexthop [outgoingIF]:   Potential 
nexthops ...
aa:31:0e:4a:0f:1d0.500s   (255) aa:31:0e:4a:0f:1d [  mesh-vpn]: 
aa:31:0e:4a:0f:1d (255)
6a:4b:93:de:00:840.940s   (255) 6a:4b:93:de:00:84 [  mesh-vpn]: 
6a:4b:93:de:00:84 (255)

The client should use 6a:4b:93:de:00:84 as a gatway, since it provides much 
higher data rates - however, it is stuck at aa:31:0e:4a:0f:1d.
Why is that? How can I make the client choosing 6a:4b:93:de:00:84?

Thanks in advance,
Keep smiling
yanosz