]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/batman-adv/originator.c
batman-adv: remove obsolete deleted attribute for gateway node
[karo-tx-linux.git] / net / batman-adv / originator.c
index 018b7495ad844cdf4f97f1590455bc205cdf3d71..d6d9809fee661591c3bcbe077b4ed60ebebf2319 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/list.h>
 #include <linux/lockdep.h>
 #include <linux/netdevice.h>
+#include <linux/rculist.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -70,7 +71,7 @@ batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
        struct batadv_orig_node_vlan *vlan = NULL, *tmp;
 
        rcu_read_lock();
-       list_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
+       hlist_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
                if (tmp->vid != vid)
                        continue;
 
@@ -118,7 +119,7 @@ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
        atomic_set(&vlan->refcount, 2);
        vlan->vid = vid;
 
-       list_add_rcu(&vlan->list, &orig_node->vlan_list);
+       hlist_add_head_rcu(&vlan->list, &orig_node->vlan_list);
 
 out:
        spin_unlock_bh(&orig_node->vlan_list_lock);
@@ -452,15 +453,24 @@ out:
  */
 struct batadv_neigh_node *
 batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
-                     const uint8_t *neigh_addr,
-                     struct batadv_orig_node *orig_node)
+                     const u8 *neigh_addr, struct batadv_orig_node *orig_node)
 {
        struct batadv_neigh_node *neigh_node;
 
+       neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
+       if (neigh_node)
+               goto out;
+
        neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
        if (!neigh_node)
                goto out;
 
+       if (!atomic_inc_not_zero(&hard_iface->refcount)) {
+               kfree(neigh_node);
+               neigh_node = NULL;
+               goto out;
+       }
+
        INIT_HLIST_NODE(&neigh_node->list);
        INIT_HLIST_HEAD(&neigh_node->ifinfo_list);
        spin_lock_init(&neigh_node->ifinfo_lock);
@@ -472,6 +482,14 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
        /* extra reference for return */
        atomic_set(&neigh_node->refcount, 2);
 
+       spin_lock_bh(&orig_node->neigh_list_lock);
+       hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
+       spin_unlock_bh(&orig_node->neigh_list_lock);
+
+       batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv,
+                  "Creating new neighbor %pM for orig_node %pM on interface %s\n",
+                  neigh_addr, orig_node->orig, hard_iface->net_dev->name);
+
 out:
        return neigh_node;
 }
@@ -489,7 +507,7 @@ out:
 struct batadv_neigh_node *
 batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
                      const struct batadv_hard_iface *hard_iface,
-                     const uint8_t *addr)
+                     const u8 *addr)
 {
        struct batadv_neigh_node *tmp_neigh_node, *res = NULL;
 
@@ -624,7 +642,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
        struct hlist_head *head;
        spinlock_t *list_lock; /* spinlock to protect write access */
        struct batadv_orig_node *orig_node;
-       uint32_t i;
+       u32 i;
 
        if (!hash)
                return;
@@ -659,7 +677,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
  * Returns the newly created object or NULL on failure.
  */
 struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
-                                             const uint8_t *addr)
+                                             const u8 *addr)
 {
        struct batadv_orig_node *orig_node;
        struct batadv_orig_node_vlan *vlan;
@@ -674,7 +692,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
                return NULL;
 
        INIT_HLIST_HEAD(&orig_node->neigh_list);
-       INIT_LIST_HEAD(&orig_node->vlan_list);
+       INIT_HLIST_HEAD(&orig_node->vlan_list);
        INIT_HLIST_HEAD(&orig_node->ifinfo_list);
        spin_lock_init(&orig_node->bcast_seqno_lock);
        spin_lock_init(&orig_node->neigh_list_lock);
@@ -696,8 +714,13 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
        orig_node->last_seen = jiffies;
        reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
        orig_node->bcast_seqno_reset = reset_time;
+
 #ifdef CONFIG_BATMAN_ADV_MCAST
        orig_node->mcast_flags = BATADV_NO_FLAGS;
+       INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node);
+       INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node);
+       INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node);
+       spin_lock_init(&orig_node->mcast_handler_lock);
 #endif
 
        /* create a vlan object for the "untagged" LAN */
@@ -976,7 +999,7 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
        struct hlist_head *head;
        spinlock_t *list_lock; /* spinlock to protect write access */
        struct batadv_orig_node *orig_node;
-       uint32_t i;
+       u32 i;
 
        if (!hash)
                return;
@@ -1005,7 +1028,6 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
                spin_unlock_bh(list_lock);
        }
 
-       batadv_gw_node_purge(bat_priv);
        batadv_gw_election(bat_priv);
 }
 
@@ -1110,7 +1132,7 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
        struct batadv_hashtable *hash = bat_priv->orig_hash;
        struct hlist_head *head;
        struct batadv_orig_node *orig_node;
-       uint32_t i;
+       u32 i;
        int ret;
 
        /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
@@ -1147,7 +1169,7 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
        struct batadv_hard_iface *hard_iface_tmp;
        struct batadv_orig_node *orig_node;
        struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
-       uint32_t i;
+       u32 i;
        int ret;
 
        /* resize all orig nodes because orig_node->bcast_own(_sum) depend on