Commit 1605d0d6 authored by Marek Lindner's avatar Marek Lindner
Browse files

batman-adv: increase refcount in create_neighbor to be consistent

parent 7b36e8ee
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -94,7 +94,9 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
	memcpy(neigh_node->addr, neigh, ETH_ALEN);
	neigh_node->orig_node = orig_neigh_node;
	neigh_node->if_incoming = if_incoming;
	atomic_set(&neigh_node->refcount, 1);

	/* 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);
+27 −36
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
				struct batman_if *if_incoming)
{
	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
	struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
	struct hlist_node *node;
	unsigned char total_count;
	uint8_t orig_eq_count, neigh_rq_count, tq_own;
@@ -161,27 +161,27 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
		hlist_for_each_entry_rcu(tmp_neigh_node, node,
					 &orig_node->neigh_list, list) {

			if (compare_eth(tmp_neigh_node->addr,
					orig_neigh_node->orig) &&
			    (tmp_neigh_node->if_incoming == if_incoming))
			if (!compare_eth(tmp_neigh_node->addr,
					 orig_neigh_node->orig))
				continue;

			if (tmp_neigh_node->if_incoming != if_incoming)
				continue;

			if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
				continue;

			neigh_node = tmp_neigh_node;
		}
		rcu_read_unlock();

		if (!neigh_node)
			neigh_node = create_neighbor(orig_node,
						     orig_neigh_node,
						     orig_neigh_node->orig,
						     if_incoming);
		/* create_neighbor failed, return 0 */
		if (!neigh_node)
			goto unlock;

		if (!atomic_inc_not_zero(&neigh_node->refcount)) {
			neigh_node = NULL;
			goto unlock;
		}

		rcu_read_unlock();
			goto out;

		neigh_node->last_valid = jiffies;
	} else {
@@ -190,27 +190,27 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
		hlist_for_each_entry_rcu(tmp_neigh_node, node,
					 &orig_neigh_node->neigh_list, list) {

			if (compare_eth(tmp_neigh_node->addr,
					orig_neigh_node->orig) &&
			    (tmp_neigh_node->if_incoming == if_incoming))
			if (!compare_eth(tmp_neigh_node->addr,
					 orig_neigh_node->orig))
				continue;

			if (tmp_neigh_node->if_incoming != if_incoming)
				continue;

			if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
				continue;

			neigh_node = tmp_neigh_node;
		}
		rcu_read_unlock();

		if (!neigh_node)
			neigh_node = create_neighbor(orig_neigh_node,
						     orig_neigh_node,
						     orig_neigh_node->orig,
						     if_incoming);
		/* create_neighbor failed, return 0 */
		if (!neigh_node)
			goto unlock;

		if (!atomic_inc_not_zero(&neigh_node->refcount)) {
			neigh_node = NULL;
			goto unlock;
		}

		rcu_read_unlock();
			goto out;
	}

	orig_node->last_valid = jiffies;
@@ -265,10 +265,6 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
	if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
		ret = 1;

	goto out;

unlock:
	rcu_read_unlock();
out:
	if (neigh_node)
		neigh_node_free_ref(neigh_node);
@@ -423,11 +419,6 @@ static void update_orig(struct bat_priv *bat_priv,
		orig_node_free_ref(orig_tmp);
		if (!neigh_node)
			goto unlock;

		if (!atomic_inc_not_zero(&neigh_node->refcount)) {
			neigh_node = NULL;
			goto unlock;
		}
	} else
		bat_dbg(DBG_BATMAN, bat_priv,
			"Updating existing last-hop neighbor of originator\n");