aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/translation-table.c
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2011-11-02 15:26:45 -0400
committerSven Eckelmann <sven@narfation.org>2011-11-20 07:08:36 -0500
commit80b3f58cf416770ae89b30734d252d641a56d289 (patch)
tree2ec071472dd768a3e867fe12e003c7bc3026eee5 /net/batman-adv/translation-table.c
parent697f25314a923f75deef0d3b10991dd103f59d93 (diff)
batman-adv: check return value for hash_add()
if hash_add() fails, we should remove the structure to avoid memory leaks. Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Acked-by: Antonio Quartulli <ordex@autistici.org> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r--net/batman-adv/translation-table.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index f6bbd6423def..cc87acf02431 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -190,6 +190,7 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
190 struct bat_priv *bat_priv = netdev_priv(soft_iface); 190 struct bat_priv *bat_priv = netdev_priv(soft_iface);
191 struct tt_local_entry *tt_local_entry = NULL; 191 struct tt_local_entry *tt_local_entry = NULL;
192 struct tt_global_entry *tt_global_entry = NULL; 192 struct tt_global_entry *tt_global_entry = NULL;
193 int hash_added;
193 194
194 tt_local_entry = tt_local_hash_find(bat_priv, addr); 195 tt_local_entry = tt_local_hash_find(bat_priv, addr);
195 196
@@ -217,6 +218,16 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
217 if (compare_eth(addr, soft_iface->dev_addr)) 218 if (compare_eth(addr, soft_iface->dev_addr))
218 tt_local_entry->common.flags |= TT_CLIENT_NOPURGE; 219 tt_local_entry->common.flags |= TT_CLIENT_NOPURGE;
219 220
221 hash_added = hash_add(bat_priv->tt_local_hash, compare_tt, choose_orig,
222 &tt_local_entry->common,
223 &tt_local_entry->common.hash_entry);
224
225 if (unlikely(hash_added != 0)) {
226 /* remove the reference for the hash */
227 tt_local_entry_free_ref(tt_local_entry);
228 goto out;
229 }
230
220 tt_local_event(bat_priv, addr, tt_local_entry->common.flags); 231 tt_local_event(bat_priv, addr, tt_local_entry->common.flags);
221 232
222 /* The local entry has to be marked as NEW to avoid to send it in 233 /* The local entry has to be marked as NEW to avoid to send it in
@@ -224,9 +235,6 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
224 * (consistency check) */ 235 * (consistency check) */
225 tt_local_entry->common.flags |= TT_CLIENT_NEW; 236 tt_local_entry->common.flags |= TT_CLIENT_NEW;
226 237
227 hash_add(bat_priv->tt_local_hash, compare_tt, choose_orig,
228 &tt_local_entry->common, &tt_local_entry->common.hash_entry);
229
230 /* remove address from global hash if present */ 238 /* remove address from global hash if present */
231 tt_global_entry = tt_global_hash_find(bat_priv, addr); 239 tt_global_entry = tt_global_hash_find(bat_priv, addr);
232 240
@@ -499,6 +507,7 @@ int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
499 struct tt_global_entry *tt_global_entry; 507 struct tt_global_entry *tt_global_entry;
500 struct orig_node *orig_node_tmp; 508 struct orig_node *orig_node_tmp;
501 int ret = 0; 509 int ret = 0;
510 int hash_added;
502 511
503 tt_global_entry = tt_global_hash_find(bat_priv, tt_addr); 512 tt_global_entry = tt_global_hash_find(bat_priv, tt_addr);
504 513
@@ -518,9 +527,15 @@ int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
518 tt_global_entry->ttvn = ttvn; 527 tt_global_entry->ttvn = ttvn;
519 tt_global_entry->roam_at = 0; 528 tt_global_entry->roam_at = 0;
520 529
521 hash_add(bat_priv->tt_global_hash, compare_tt, 530 hash_added = hash_add(bat_priv->tt_global_hash, compare_tt,
522 choose_orig, &tt_global_entry->common, 531 choose_orig, &tt_global_entry->common,
523 &tt_global_entry->common.hash_entry); 532 &tt_global_entry->common.hash_entry);
533
534 if (unlikely(hash_added != 0)) {
535 /* remove the reference for the hash */
536 tt_global_entry_free_ref(tt_global_entry);
537 goto out_remove;
538 }
524 atomic_inc(&orig_node->tt_size); 539 atomic_inc(&orig_node->tt_size);
525 } else { 540 } else {
526 if (tt_global_entry->orig_node != orig_node) { 541 if (tt_global_entry->orig_node != orig_node) {
@@ -543,6 +558,7 @@ int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
543 "Creating new global tt entry: %pM (via %pM)\n", 558 "Creating new global tt entry: %pM (via %pM)\n",
544 tt_global_entry->common.addr, orig_node->orig); 559 tt_global_entry->common.addr, orig_node->orig);
545 560
561out_remove:
546 /* remove address from local hash if present */ 562 /* remove address from local hash if present */
547 tt_local_remove(bat_priv, tt_global_entry->common.addr, 563 tt_local_remove(bat_priv, tt_global_entry->common.addr,
548 "global tt received", roaming); 564 "global tt received", roaming);