aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/translation-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r--net/batman-adv/translation-table.c60
1 files changed, 46 insertions, 14 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index feaf492b01ca..7e6df7a4964a 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -47,10 +47,12 @@
47#include "bridge_loop_avoidance.h" 47#include "bridge_loop_avoidance.h"
48#include "hard-interface.h" 48#include "hard-interface.h"
49#include "hash.h" 49#include "hash.h"
50#include "log.h"
50#include "multicast.h" 51#include "multicast.h"
51#include "originator.h" 52#include "originator.h"
52#include "packet.h" 53#include "packet.h"
53#include "soft-interface.h" 54#include "soft-interface.h"
55#include "tvlv.h"
54 56
55/* hash class keys */ 57/* hash class keys */
56static struct lock_class_key batadv_tt_local_hash_lock_class_key; 58static struct lock_class_key batadv_tt_local_hash_lock_class_key;
@@ -650,8 +652,10 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
650 652
651 /* increase the refcounter of the related vlan */ 653 /* increase the refcounter of the related vlan */
652 vlan = batadv_softif_vlan_get(bat_priv, vid); 654 vlan = batadv_softif_vlan_get(bat_priv, vid);
653 if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d", 655 if (!vlan) {
654 addr, BATADV_PRINT_VID(vid))) { 656 net_ratelimited_function(batadv_info, soft_iface,
657 "adding TT local entry %pM to non-existent VLAN %d\n",
658 addr, BATADV_PRINT_VID(vid));
655 kfree(tt_local); 659 kfree(tt_local);
656 tt_local = NULL; 660 tt_local = NULL;
657 goto out; 661 goto out;
@@ -691,7 +695,6 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
691 if (unlikely(hash_added != 0)) { 695 if (unlikely(hash_added != 0)) {
692 /* remove the reference for the hash */ 696 /* remove the reference for the hash */
693 batadv_tt_local_entry_put(tt_local); 697 batadv_tt_local_entry_put(tt_local);
694 batadv_softif_vlan_put(vlan);
695 goto out; 698 goto out;
696 } 699 }
697 700
@@ -995,7 +998,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
995 struct batadv_tt_local_entry *tt_local; 998 struct batadv_tt_local_entry *tt_local;
996 struct batadv_hard_iface *primary_if; 999 struct batadv_hard_iface *primary_if;
997 struct hlist_head *head; 1000 struct hlist_head *head;
998 unsigned short vid;
999 u32 i; 1001 u32 i;
1000 int last_seen_secs; 1002 int last_seen_secs;
1001 int last_seen_msecs; 1003 int last_seen_msecs;
@@ -1022,7 +1024,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
1022 tt_local = container_of(tt_common_entry, 1024 tt_local = container_of(tt_common_entry,
1023 struct batadv_tt_local_entry, 1025 struct batadv_tt_local_entry,
1024 common); 1026 common);
1025 vid = tt_common_entry->vid;
1026 last_seen_jiffies = jiffies - tt_local->last_seen; 1027 last_seen_jiffies = jiffies - tt_local->last_seen;
1027 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); 1028 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
1028 last_seen_secs = last_seen_msecs / 1000; 1029 last_seen_secs = last_seen_msecs / 1000;
@@ -1546,7 +1547,7 @@ batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1546 struct batadv_tt_global_entry *tt_global_entry) 1547 struct batadv_tt_global_entry *tt_global_entry)
1547{ 1548{
1548 struct batadv_neigh_node *router, *best_router = NULL; 1549 struct batadv_neigh_node *router, *best_router = NULL;
1549 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; 1550 struct batadv_algo_ops *bao = bat_priv->algo_ops;
1550 struct hlist_head *head; 1551 struct hlist_head *head;
1551 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL; 1552 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
1552 1553
@@ -1558,8 +1559,8 @@ batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1558 continue; 1559 continue;
1559 1560
1560 if (best_router && 1561 if (best_router &&
1561 bao->bat_neigh_cmp(router, BATADV_IF_DEFAULT, 1562 bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router,
1562 best_router, BATADV_IF_DEFAULT) <= 0) { 1563 BATADV_IF_DEFAULT) <= 0) {
1563 batadv_neigh_node_put(router); 1564 batadv_neigh_node_put(router);
1564 continue; 1565 continue;
1565 } 1566 }
@@ -2269,6 +2270,29 @@ static u32 batadv_tt_local_crc(struct batadv_priv *bat_priv,
2269 return crc; 2270 return crc;
2270} 2271}
2271 2272
2273/**
2274 * batadv_tt_req_node_release - free tt_req node entry
2275 * @ref: kref pointer of the tt req_node entry
2276 */
2277static void batadv_tt_req_node_release(struct kref *ref)
2278{
2279 struct batadv_tt_req_node *tt_req_node;
2280
2281 tt_req_node = container_of(ref, struct batadv_tt_req_node, refcount);
2282
2283 kfree(tt_req_node);
2284}
2285
2286/**
2287 * batadv_tt_req_node_put - decrement the tt_req_node refcounter and
2288 * possibly release it
2289 * @tt_req_node: tt_req_node to be free'd
2290 */
2291static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
2292{
2293 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
2294}
2295
2272static void batadv_tt_req_list_free(struct batadv_priv *bat_priv) 2296static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
2273{ 2297{
2274 struct batadv_tt_req_node *node; 2298 struct batadv_tt_req_node *node;
@@ -2278,7 +2302,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
2278 2302
2279 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2303 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2280 hlist_del_init(&node->list); 2304 hlist_del_init(&node->list);
2281 kfree(node); 2305 batadv_tt_req_node_put(node);
2282 } 2306 }
2283 2307
2284 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2308 spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2315,7 +2339,7 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
2315 if (batadv_has_timed_out(node->issued_at, 2339 if (batadv_has_timed_out(node->issued_at,
2316 BATADV_TT_REQUEST_TIMEOUT)) { 2340 BATADV_TT_REQUEST_TIMEOUT)) {
2317 hlist_del_init(&node->list); 2341 hlist_del_init(&node->list);
2318 kfree(node); 2342 batadv_tt_req_node_put(node);
2319 } 2343 }
2320 } 2344 }
2321 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2345 spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2347,9 +2371,11 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
2347 if (!tt_req_node) 2371 if (!tt_req_node)
2348 goto unlock; 2372 goto unlock;
2349 2373
2374 kref_init(&tt_req_node->refcount);
2350 ether_addr_copy(tt_req_node->addr, orig_node->orig); 2375 ether_addr_copy(tt_req_node->addr, orig_node->orig);
2351 tt_req_node->issued_at = jiffies; 2376 tt_req_node->issued_at = jiffies;
2352 2377
2378 kref_get(&tt_req_node->refcount);
2353 hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list); 2379 hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list);
2354unlock: 2380unlock:
2355 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2381 spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2613,13 +2639,19 @@ static bool batadv_send_tt_request(struct batadv_priv *bat_priv,
2613out: 2639out:
2614 if (primary_if) 2640 if (primary_if)
2615 batadv_hardif_put(primary_if); 2641 batadv_hardif_put(primary_if);
2642
2616 if (ret && tt_req_node) { 2643 if (ret && tt_req_node) {
2617 spin_lock_bh(&bat_priv->tt.req_list_lock); 2644 spin_lock_bh(&bat_priv->tt.req_list_lock);
2618 /* hlist_del_init() verifies tt_req_node still is in the list */ 2645 if (!hlist_unhashed(&tt_req_node->list)) {
2619 hlist_del_init(&tt_req_node->list); 2646 hlist_del_init(&tt_req_node->list);
2647 batadv_tt_req_node_put(tt_req_node);
2648 }
2620 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2649 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2621 kfree(tt_req_node);
2622 } 2650 }
2651
2652 if (tt_req_node)
2653 batadv_tt_req_node_put(tt_req_node);
2654
2623 kfree(tvlv_tt_data); 2655 kfree(tvlv_tt_data);
2624 return ret; 2656 return ret;
2625} 2657}
@@ -3055,7 +3087,7 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
3055 if (!batadv_compare_eth(node->addr, resp_src)) 3087 if (!batadv_compare_eth(node->addr, resp_src))
3056 continue; 3088 continue;
3057 hlist_del_init(&node->list); 3089 hlist_del_init(&node->list);
3058 kfree(node); 3090 batadv_tt_req_node_put(node);
3059 } 3091 }
3060 3092
3061 spin_unlock_bh(&bat_priv->tt.req_list_lock); 3093 spin_unlock_bh(&bat_priv->tt.req_list_lock);