Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4a975e8 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller
Browse files

fib_trie: Fib find node should return parent



This change makes it so that the parent pointer is returned by reference in
fib_find_node.  By doing this I can use it to find the parent node when I
am performing an insertion and I don't have to look for it again in
fib_insert_node.

Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8be33e95
Loading
Loading
Loading
Loading
+24 −18
Original line number Original line Diff line number Diff line
@@ -912,9 +912,9 @@ static void fib_insert_alias(struct tnode *l, struct fib_alias *fa,
}
}


/* rcu_read_lock needs to be hold by caller from readside */
/* rcu_read_lock needs to be hold by caller from readside */
static struct tnode *fib_find_node(struct trie *t, u32 key)
static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key)
{
{
	struct tnode *n = rcu_dereference_rtnl(t->trie);
	struct tnode *pn = NULL, *n = rcu_dereference_rtnl(t->trie);


	while (n) {
	while (n) {
		unsigned long index = get_index(key, n);
		unsigned long index = get_index(key, n);
@@ -924,21 +924,30 @@ static struct tnode *fib_find_node(struct trie *t, u32 key)
		 * prefix plus zeros for the bits in the cindex. The index
		 * prefix plus zeros for the bits in the cindex. The index
		 * is the difference between the key and this value.  From
		 * is the difference between the key and this value.  From
		 * this we can actually derive several pieces of data.
		 * this we can actually derive several pieces of data.
		 *   if (index & (~0ul << bits))
		 *   if (index >= (1ul << bits))
		 *     we have a mismatch in skip bits and failed
		 *     we have a mismatch in skip bits and failed
		 *   else
		 *   else
		 *     we know the value is cindex
		 *     we know the value is cindex
		 *
		 * This check is safe even if bits == KEYLENGTH due to the
		 * fact that we can only allocate a node with 32 bits if a
		 * long is greater than 32 bits.
		 */
		 */
		if (index & (~0ul << n->bits))
		if (index >= (1ul << n->bits)) {
			return NULL;
			n = NULL;
			break;
		}


		/* we have found a leaf. Prefixes have already been compared */
		/* we have found a leaf. Prefixes have already been compared */
		if (IS_LEAF(n))
		if (IS_LEAF(n))
			break;
			break;


		pn = n;
		n = tnode_get_child_rcu(n, index);
		n = tnode_get_child_rcu(n, index);
	}
	}


	*tn = pn;

	return n;
	return n;
}
}


@@ -1073,13 +1082,13 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
{
{
	struct trie *t = (struct trie *)tb->tb_data;
	struct trie *t = (struct trie *)tb->tb_data;
	struct fib_alias *fa, *new_fa;
	struct fib_alias *fa, *new_fa;
	struct tnode *l, *tp;
	struct fib_info *fi;
	struct fib_info *fi;
	u8 plen = cfg->fc_dst_len;
	u8 plen = cfg->fc_dst_len;
	u8 slen = KEYLENGTH - plen;
	u8 slen = KEYLENGTH - plen;
	u8 tos = cfg->fc_tos;
	u8 tos = cfg->fc_tos;
	u32 key, mask;
	u32 key;
	int err;
	int err;
	struct tnode *l;


	if (plen > KEYLENGTH)
	if (plen > KEYLENGTH)
		return -EINVAL;
		return -EINVAL;
@@ -1088,9 +1097,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)


	pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen);
	pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen);


	mask = ntohl(inet_make_mask(plen));
	if ((plen < KEYLENGTH) && (key << plen))

	if (key & ~mask)
		return -EINVAL;
		return -EINVAL;


	fi = fib_create_info(cfg);
	fi = fib_create_info(cfg);
@@ -1099,7 +1106,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
		goto err;
		goto err;
	}
	}


	l = fib_find_node(t, key);
	l = fib_find_node(t, &tp, key);
	fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority) : NULL;
	fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority) : NULL;


	/* Now fa, if non-NULL, points to the first fib alias
	/* Now fa, if non-NULL, points to the first fib alias
@@ -1406,22 +1413,21 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
{
{
	struct trie *t = (struct trie *) tb->tb_data;
	struct trie *t = (struct trie *) tb->tb_data;
	struct fib_alias *fa, *fa_to_delete;
	struct fib_alias *fa, *fa_to_delete;
	struct tnode *l, *tp;
	u8 plen = cfg->fc_dst_len;
	u8 plen = cfg->fc_dst_len;
	u8 tos = cfg->fc_tos;
	u8 slen = KEYLENGTH - plen;
	u8 slen = KEYLENGTH - plen;
	struct tnode *l;
	u8 tos = cfg->fc_tos;
	u32 key, mask;
	u32 key;


	if (plen > KEYLENGTH)
	if (plen > KEYLENGTH)
		return -EINVAL;
		return -EINVAL;


	key = ntohl(cfg->fc_dst);
	key = ntohl(cfg->fc_dst);
	mask = ntohl(inet_make_mask(plen));


	if (key & ~mask)
	if ((plen < KEYLENGTH) && (key << plen))
		return -EINVAL;
		return -EINVAL;


	l = fib_find_node(t, key);
	l = fib_find_node(t, &tp, key);
	if (!l)
	if (!l)
		return -ESRCH;
		return -ESRCH;