diff options
Diffstat (limited to 'net/batman-adv/bat_iv_ogm.c')
| -rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 512159bf607f..8323bced8e5b 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
| @@ -241,19 +241,19 @@ batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr) | |||
| 241 | size = bat_priv->num_ifaces * sizeof(uint8_t); | 241 | size = bat_priv->num_ifaces * sizeof(uint8_t); |
| 242 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); | 242 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); |
| 243 | if (!orig_node->bat_iv.bcast_own_sum) | 243 | if (!orig_node->bat_iv.bcast_own_sum) |
| 244 | goto free_bcast_own; | 244 | goto free_orig_node; |
| 245 | 245 | ||
| 246 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, | 246 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, |
| 247 | batadv_choose_orig, orig_node, | 247 | batadv_choose_orig, orig_node, |
| 248 | &orig_node->hash_entry); | 248 | &orig_node->hash_entry); |
| 249 | if (hash_added != 0) | 249 | if (hash_added != 0) |
| 250 | goto free_bcast_own; | 250 | goto free_orig_node; |
| 251 | 251 | ||
| 252 | return orig_node; | 252 | return orig_node; |
| 253 | 253 | ||
| 254 | free_bcast_own: | ||
| 255 | kfree(orig_node->bat_iv.bcast_own); | ||
| 256 | free_orig_node: | 254 | free_orig_node: |
| 255 | /* free twice, as batadv_orig_node_new sets refcount to 2 */ | ||
| 256 | batadv_orig_node_free_ref(orig_node); | ||
| 257 | batadv_orig_node_free_ref(orig_node); | 257 | batadv_orig_node_free_ref(orig_node); |
| 258 | 258 | ||
| 259 | return NULL; | 259 | return NULL; |
| @@ -266,7 +266,7 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, | |||
| 266 | struct batadv_orig_node *orig_neigh) | 266 | struct batadv_orig_node *orig_neigh) |
| 267 | { | 267 | { |
| 268 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 268 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
| 269 | struct batadv_neigh_node *neigh_node; | 269 | struct batadv_neigh_node *neigh_node, *tmp_neigh_node; |
| 270 | 270 | ||
| 271 | neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node); | 271 | neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node); |
| 272 | if (!neigh_node) | 272 | if (!neigh_node) |
| @@ -281,14 +281,24 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, | |||
| 281 | neigh_node->orig_node = orig_neigh; | 281 | neigh_node->orig_node = orig_neigh; |
| 282 | neigh_node->if_incoming = hard_iface; | 282 | neigh_node->if_incoming = hard_iface; |
| 283 | 283 | ||
| 284 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
| 285 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", | ||
| 286 | neigh_addr, orig_node->orig, hard_iface->net_dev->name); | ||
| 287 | |||
| 288 | spin_lock_bh(&orig_node->neigh_list_lock); | 284 | spin_lock_bh(&orig_node->neigh_list_lock); |
| 289 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | 285 | tmp_neigh_node = batadv_neigh_node_get(orig_node, hard_iface, |
| 286 | neigh_addr); | ||
| 287 | if (!tmp_neigh_node) { | ||
| 288 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); | ||
| 289 | } else { | ||
| 290 | kfree(neigh_node); | ||
| 291 | batadv_hardif_free_ref(hard_iface); | ||
| 292 | neigh_node = tmp_neigh_node; | ||
| 293 | } | ||
| 290 | spin_unlock_bh(&orig_node->neigh_list_lock); | 294 | spin_unlock_bh(&orig_node->neigh_list_lock); |
| 291 | 295 | ||
| 296 | if (!tmp_neigh_node) | ||
| 297 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | ||
| 298 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", | ||
| 299 | neigh_addr, orig_node->orig, | ||
| 300 | hard_iface->net_dev->name); | ||
| 301 | |||
| 292 | out: | 302 | out: |
| 293 | return neigh_node; | 303 | return neigh_node; |
| 294 | } | 304 | } |
