On Sunday 13 January 2013 17:51:03 Marek Lindner wrote:
> From: Sven Eckelmann <[email protected]>
> 
> The sysfs configuration interface of batman-adv to add/remove slaves of an
> soft-iface is not deadlock free and doesn't follow the currently common way
> to modify slaves of an interface.
> 
> An additional configuration interface though rtnl_link is introduced which
> provides easy device adding/removing with tools like "ip":
> $ ip link set dev eth0 master bat0
> $ ip link set dev eth0 nomaster
> 
> Signed-off-by: Sven Eckelmann <[email protected]>
> ---


Master setting is missing. This is necessary on current kernels to use 
"nomaster" of ip. Also reference counting is br0ken. An example patch is added 
(just to explain things... it will not apply directly).

Kind regards,
        Sven
diff --git a/hard-interface.c b/hard-interface.c
index 5e2655d..c5c7f13 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -349,9 +349,16 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
 	hard_iface->soft_iface = soft_iface;
 	bat_priv = netdev_priv(hard_iface->soft_iface);
 
+	ret = netdev_set_master(hard_iface->net_dev, hard_iface->soft_iface);
+	if (ret) {
+		batadv_err(hard_iface->soft_iface,
+			   "Device %s failed to set master\n", iface_name);
+		goto err_dev;
+	}
+
 	ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface);
 	if (ret < 0)
-		goto err_dev;
+		goto err_enable;
 
 	hard_iface->if_num = bat_priv->num_ifaces;
 	bat_priv->num_ifaces++;
@@ -361,7 +368,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
 		bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
 		bat_priv->num_ifaces--;
 		hard_iface->if_status = BATADV_IF_NOT_IN_USE;
-		goto err_dev;
+		goto err_enable;
 	}
 
 	hard_iface->batman_adv_ptype.type = ethertype;
@@ -400,6 +407,8 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
 out:
 	return 0;
 
+err_enable:
+	netdev_set_master(hard_iface->net_dev, NULL);
 err_dev:
 	dev_put(soft_iface);
 err:
@@ -450,6 +459,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
 		batadv_softif_destroy(hard_iface->soft_iface, NULL);
 
 	hard_iface->soft_iface = NULL;
+	netdev_set_master(hard_iface->net_dev, NULL);
 	batadv_hardif_free_ref(hard_iface);
 
 out:
diff --git a/soft-interface.c b/soft-interface.c
index 3cafe50..54eb2a9 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -486,12 +486,15 @@ static int batadv_add_slave(struct net_device *dev,
 			    struct net_device *slave_dev)
 {
 	struct batadv_hard_iface *hard_iface;
+	int ret;
 
 	hard_iface = batadv_hardif_get_by_netdev(slave_dev);
 	if (!hard_iface || hard_iface->soft_iface != NULL)
 		return -EINVAL;
 
-	return batadv_hardif_enable_interface(hard_iface, dev->name);
+	ret = batadv_hardif_enable_interface(hard_iface, dev->name);
+	batadv_hardif_free_ref(hard_iface);
+	return ret;
 }
 
 /**
@@ -509,6 +512,7 @@ static int batadv_del_slave(struct net_device *dev,
 		return -EINVAL;
 
 	batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP);
+	batadv_hardif_free_ref(hard_iface);
 	return 0;
 }
 

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to