Пример #1
0
int
rn_inithead(struct radix_node_head **head, int off)
{
	struct radix_node_head *rnh;
	struct radix_node *t, *tt, *ttt;
	if (*head)
		return (1);
	rnh = (struct radix_node_head *)rtmalloc(sizeof(*rnh), "rn_inithead");
	Bzero(rnh, sizeof (*rnh));
	*head = rnh;
	t = rn_newpair(rn_zeros, off, rnh->rnh_nodes);
	ttt = rnh->rnh_nodes + 2;
	t->rn_r = ttt;
	t->rn_p = t;
	tt = t->rn_l;
	tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;
	tt->rn_b = -1 - off;
	*ttt = *tt;
	ttt->rn_key = rn_ones;
	rnh->rnh_addaddr = rn_addroute;
	rnh->rnh_deladdr = rn_delete;
	rnh->rnh_matchaddr = rn_match;
	rnh->rnh_lookup = rn_lookup;
	rnh->rnh_walktree = rn_walktree;
	rnh->rnh_treetop = t;
	return (1);
}
Пример #2
0
static struct radix_node *
rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry,
	struct radix_node nodes[2])
{
	uint8 *v = v_arg;
	struct radix_node *top = head->rnh_treetop;
	int head_off = top->rn_offset, vlen = (int)LEN(v);
	register struct radix_node *t = rn_search(v_arg, top);
	register uint8 *cp = v + head_off;
	register int b;
	struct radix_node *tt;
	/*
	 * Find first bit at which v and t->rn_key differ
	 */
    {
		register uint8 *cp2 = t->rn_key + head_off;
		register int cmp_res;
		uint8 *cplim = v + vlen;

		while (cp < cplim) {
			if (*cp2++ != *cp++)
				goto on1;
		}
		*dupentry = 1;
		return t;
	on1:
		*dupentry = 0;
		cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
		for (b = (cp - v) << 3; cmp_res; b--) {
			cmp_res >>= 1;
		}
    }
    {
		register struct radix_node *p, *x = top;
		cp = v;
		do {
			p = x;
			if (cp[x->rn_offset] & x->rn_bmask)
				x = x->rn_right;
			else
				x = x->rn_left;
		} while (b > (unsigned) x->rn_bit);
					/* x->rn_bit < b && x->rn_bit >= 0 */
		t = rn_newpair(v_arg, b, nodes); 
		tt = t->rn_left;
		if ((cp[p->rn_offset] & p->rn_bmask) == 0)
			p->rn_left = t;
		else
			p->rn_right = t;
		x->rn_parent = t;
		t->rn_parent = p; /* frees x, p as temp vars below */
		if ((cp[t->rn_offset] & t->rn_bmask) == 0) {
			t->rn_right = x;
		} else {
			t->rn_right = tt;
			t->rn_left = x;
		}
    }
	return tt;
}
Пример #3
0
static struct radix_node *
rn_insert(void* v_arg,
	  struct radix_node_head *head,
	  int *dupentry,
	  struct radix_node nodes[2])
{
	caddr_t v = v_arg;
	struct radix_node *top = head->rnh_treetop;
	int head_off = top->rn_off, vlen = (int)*((u_char *)v);
	struct radix_node *t = rn_search(v_arg, top);
	caddr_t cp = v + head_off;
	int b;
	struct radix_node *tt;

	/*
	 * Find first bit at which v and t->rn_key differ
	 */
    {
		caddr_t cp2 = t->rn_key + head_off;
		int cmp_res;
	caddr_t cplim = v + vlen;

	while (cp < cplim)
		if (*cp2++ != *cp++)
			goto on1;
	/* handle adding 255.255.255.255 */
	if (!(t->rn_flags & RNF_ROOT) || *(cp2-1) == 0) {
		*dupentry = 1;
		return t;
	}
on1:
	*dupentry = 0;
	cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
	for (b = (cp - v) << 3; cmp_res; b--)
		cmp_res >>= 1;
    }
    {
	    struct radix_node *p, *x = top;
	cp = v;
	do {
		p = x;
		if (cp[x->rn_off] & x->rn_bmask)
			x = x->rn_r;
		else x = x->rn_l;
	} while ((unsigned)b > (unsigned)x->rn_b);
#ifdef RN_DEBUG
	if (rn_debug)
		log(LOG_DEBUG, "rn_insert: Going In:\n"), traverse(p);
#endif
	t = rn_newpair(v_arg, b, nodes); tt = t->rn_l;
	if ((cp[p->rn_off] & p->rn_bmask) == 0)
		p->rn_l = t;
	else
		p->rn_r = t;
	x->rn_p = t; t->rn_p = p; /* frees x, p as temp vars below */
	if ((cp[t->rn_off] & t->rn_bmask) == 0) {
		t->rn_r = x;
	} else {
		t->rn_r = tt; t->rn_l = x;
	}
#ifdef RN_DEBUG
	if (rn_debug)
		log(LOG_DEBUG, "rn_insert: Coming Out:\n"), traverse(p);
#endif
    }
	return (tt);
}