]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/batman-adv/soft-interface.c
Merge tag 'late-mvebu-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[karo-tx-linux.git] / net / batman-adv / soft-interface.c
index 6b548fde8e0435fece3a67f9ea0f94a1f8aae693..2711e870f557d43ac6bbd4180a7f239a27fb850a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
+/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
  *
  * Marek Lindner, Simon Wunderlich
  *
@@ -124,7 +124,6 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
                batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
        }
 
-       dev->addr_assign_type &= ~NET_ADDR_RANDOM;
        return 0;
 }
 
@@ -181,7 +180,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
                goto dropped;
 
        /* Register the client MAC in the transtable */
-       batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
+       if (!is_multicast_ether_addr(ethhdr->h_source))
+               batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
 
        /* don't accept stp packets. STP does not help in meshes.
         * better use the bridge loop avoidance ...
@@ -449,6 +449,30 @@ static void batadv_interface_setup(struct net_device *dev)
        memset(priv, 0, sizeof(*priv));
 }
 
+/**
+ * batadv_softif_destroy_finish - cleans up the remains of a softif
+ * @work: work queue item
+ *
+ * Free the parts of the soft interface which can not be removed under
+ * rtnl lock (to prevent deadlock situations).
+ */
+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();
+}
+
 struct net_device *batadv_softif_create(const char *name)
 {
        struct net_device *soft_iface;
@@ -463,6 +487,8 @@ struct net_device *batadv_softif_create(const char *name)
                goto out;
 
        bat_priv = netdev_priv(soft_iface);
+       bat_priv->soft_iface = soft_iface;
+       INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish);
 
        /* batadv_interface_stats() needs to be available as soon as
         * register_netdevice() has been called
@@ -480,7 +506,9 @@ struct net_device *batadv_softif_create(const char *name)
 
        atomic_set(&bat_priv->aggregated_ogms, 1);
        atomic_set(&bat_priv->bonding, 0);
+#ifdef CONFIG_BATMAN_ADV_BLA
        atomic_set(&bat_priv->bridge_loop_avoidance, 0);
+#endif
 #ifdef CONFIG_BATMAN_ADV_DAT
        atomic_set(&bat_priv->distributed_arp_table, 1);
 #endif
@@ -491,7 +519,9 @@ struct net_device *batadv_softif_create(const char *name)
        atomic_set(&bat_priv->gw_bandwidth, 41);
        atomic_set(&bat_priv->orig_interval, 1000);
        atomic_set(&bat_priv->hop_penalty, 30);
+#ifdef CONFIG_BATMAN_ADV_DEBUG
        atomic_set(&bat_priv->log_level, 0);
+#endif
        atomic_set(&bat_priv->fragmentation, 1);
        atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
        atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
@@ -547,10 +577,10 @@ out:
 
 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);
+       queue_work(batadv_event_workqueue, &bat_priv->cleanup_work);
 }
 
 int batadv_softif_is_valid(const struct net_device *net_dev)
@@ -581,10 +611,10 @@ static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static void batadv_get_drvinfo(struct net_device *dev,
                               struct ethtool_drvinfo *info)
 {
-       strcpy(info->driver, "B.A.T.M.A.N. advanced");
-       strcpy(info->version, BATADV_SOURCE_VERSION);
-       strcpy(info->fw_version, "N/A");
-       strcpy(info->bus_info, "batman");
+       strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver));
+       strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version));
+       strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
+       strlcpy(info->bus_info, "batman", sizeof(info->bus_info));
 }
 
 static u32 batadv_get_msglevel(struct net_device *dev)