xref: /csrg-svn/sys/net/radix.c (revision 67781)
136210Ssklower /*
263211Sbostic  * Copyright (c) 1988, 1989, 1993
363211Sbostic  *	The Regents of the University of California.  All rights reserved.
436210Ssklower  *
544465Sbostic  * %sccs.include.redist.c%
636210Ssklower  *
7*67781Ssklower  *	@(#)radix.c	8.2.1.1 (Berkeley) 09/23/94
836210Ssklower  */
936210Ssklower 
1036210Ssklower /*
1136210Ssklower  * Routines to build and maintain radix trees for routing lookups.
1236210Ssklower  */
1336210Ssklower #ifndef RNF_NORMAL
1456529Sbostic #include <sys/param.h>
1556529Sbostic #include <sys/systm.h>
1656529Sbostic #include <sys/malloc.h>
1740784Ssklower #define	M_DONTWAIT M_NOWAIT
1854824Ssklower #ifdef	KERNEL
1956529Sbostic #include <sys/domain.h>
2036210Ssklower #endif
2154824Ssklower #endif
2256529Sbostic 
23*67781Ssklower #include "radix.h"
2456529Sbostic 
2554824Ssklower int	max_keylen;
2638846Ssklower struct radix_node_head *mask_rnhead;
2754824Ssklower static char *rn_zeros, *rn_ones;
2854824Ssklower 
2959007Ssklower #define rn_masktop (mask_rnhead->rnh_treetop)
3038846Ssklower #undef Bcmp
3138846Ssklower #define Bcmp(a, b, l) (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l))
3236210Ssklower /*
3336210Ssklower  * The data structure for the keys is a radix tree with one way
3436210Ssklower  * branching removed.  The index rn_b at an internal node n represents a bit
3536210Ssklower  * position to be tested.  The tree is arranged so that all descendants
3636210Ssklower  * of a node n have keys whose bits all agree up to position rn_b - 1.
3736210Ssklower  * (We say the index of n is rn_b.)
3836210Ssklower  *
3936210Ssklower  * There is at least one descendant which has a one bit at position rn_b,
4036210Ssklower  * and at least one with a zero there.
4136210Ssklower  *
4236210Ssklower  * A route is determined by a pair of key and mask.  We require that the
4336210Ssklower  * bit-wise logical and of the key and mask to be the key.
4436210Ssklower  * We define the index of a route to associated with the mask to be
4536210Ssklower  * the first bit number in the mask where 0 occurs (with bit number 0
4636210Ssklower  * representing the highest order bit).
4736210Ssklower  *
4836210Ssklower  * We say a mask is normal if every bit is 0, past the index of the mask.
4936210Ssklower  * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b,
5036210Ssklower  * and m is a normal mask, then the route applies to every descendant of n.
5136210Ssklower  * If the index(m) < rn_b, this implies the trailing last few bits of k
5236210Ssklower  * before bit b are all 0, (and hence consequently true of every descendant
5336210Ssklower  * of n), so the route applies to all descendants of the node as well.
5436210Ssklower  *
55*67781Ssklower  * This version of the code assumes that all masks are normal,
56*67781Ssklower  * and consequently the only thing that needs to be stored about a mask
57*67781Ssklower  * is its length.  This version also permits mapped, and fixed length
58*67781Ssklower  * elements to be entered into the tree.
5936210Ssklower  */
6036210Ssklower 
6136210Ssklower struct radix_node *
62*67781Ssklower rn_search(v_arg, top)
6361341Sbostic 	void *v_arg;
64*67781Ssklower 	struct radix_node *top;
6536210Ssklower {
6636210Ssklower 	register struct radix_node *x;
6761341Sbostic 	register caddr_t v;
6836210Ssklower 
69*67781Ssklower 	for (x = top, v = v_arg; x->rn_b >= 0;) {
7036210Ssklower 		if (x->rn_bmask & v[x->rn_off])
7136210Ssklower 			x = x->rn_r;
7236210Ssklower 		else
7336210Ssklower 			x = x->rn_l;
7436210Ssklower 	}
7561341Sbostic 	return (x);
7636210Ssklower };
7736210Ssklower 
78*67781Ssklower static char search_bits[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
79*67781Ssklower 
8037472Ssklower struct radix_node *
81*67781Ssklower rn_search_unmapped(v_arg, head)
82*67781Ssklower 	void *v_arg;
83*67781Ssklower 	struct radix_node_head *head;
8437472Ssklower {
85*67781Ssklower 	register struct radix_node *x = head->rnh_treetop;
86*67781Ssklower 	register char *v;
87*67781Ssklower 	register int index;
8836210Ssklower 
89*67781Ssklower 	for (v = v_arg; x->rn_b >= 0;) {
90*67781Ssklower 		index = x->rn_b + head->rnh_offset;
91*67781Ssklower 		if (search_bits[index & 7] & v[index >> 3])
9237472Ssklower 			x = x->rn_r;
9337472Ssklower 		else
9437472Ssklower 			x = x->rn_l;
9537472Ssklower 	}
96*67781Ssklower 	return (x);
9737472Ssklower };
9837472Ssklower 
99*67781Ssklower 
100*67781Ssklower /*
101*67781Ssklower  * This routine is used elsewhere in the kernel concerning
102*67781Ssklower  * best matches for interfaces and is no longer used in the
103*67781Ssklower  * radix code.
104*67781Ssklower  *
105*67781Ssklower  */
106*67781Ssklower int
10761341Sbostic rn_refines(m_arg, n_arg)
10861341Sbostic 	void *m_arg, *n_arg;
10950724Ssklower {
11061341Sbostic 	register caddr_t m = m_arg, n = n_arg;
11150724Ssklower 	register caddr_t lim, lim2 = lim = n + *(u_char *)n;
11250724Ssklower 	int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
11353649Ssklower 	int masks_are_equal = 1;
11437472Ssklower 
11550724Ssklower 	if (longer > 0)
11650724Ssklower 		lim -= longer;
11753649Ssklower 	while (n < lim) {
11853649Ssklower 		if (*n & ~(*m))
11950724Ssklower 			return 0;
12053649Ssklower 		if (*n++ != *m++)
12153649Ssklower 			masks_are_equal = 0;
12253649Ssklower 
12353649Ssklower 	}
12450724Ssklower 	while (n < lim2)
12550724Ssklower 		if (*n++)
12650724Ssklower 			return 0;
12753649Ssklower 	if (masks_are_equal && (longer < 0))
12853649Ssklower 		for (lim2 = m - longer; m < lim2; )
12953649Ssklower 			if (*m++)
13053649Ssklower 				return 1;
13153649Ssklower 	return (!masks_are_equal);
13250724Ssklower }
133*67781Ssklower /* Begin bits.c */
134*67781Ssklower static int low_bits[] = {1, 3, 7, 15, 31, 63, 127, 255};
135*67781Ssklower static int mask_bits[] = {1, 2, 4, 8, 16, 32, 64, 128};
13650724Ssklower 
137*67781Ssklower #define x1(a,n) ( a > ((1 << (n + 1)) - 1) ? n+1 : n)
138*67781Ssklower #define x2(a,n) (( a > ((1 << (2 + n)) - 1)) ? x1(a,n+2) : x1(a,n))
139*67781Ssklower #define x4(a,n) (( a > ((1 << (4 + n)) - 1)) ? x2(a,n+4) : x2(a,n))
140*67781Ssklower #define x8(a,n) (( a > ((1 << (8 + n)) - 1)) ? x4(a,n+8) : x4(a,n))
141*67781Ssklower #define x16(a,n) ((a > (((1 << n) - 1)+(65535 << n))) ? x8(a,n+16) : x8(a,n))
14250724Ssklower 
143*67781Ssklower int
144*67781Ssklower rn_mapped_bits_matched(t_a, r_a, rnh, masklen)
145*67781Ssklower 	void	*t_a;			/* Under scrutiny, assumed mapped */
146*67781Ssklower 	void	*r_a;			/* being compared to, not mapped */
147*67781Ssklower 	struct	radix_node_head *rnh;	/* has offset for ref, map for trial */
148*67781Ssklower 	int	masklen;		/* only need this many bits to match*/
149*67781Ssklower {
150*67781Ssklower 	register struct radix_index_table *table = rnh->rnh_table;
151*67781Ssklower 	int matched = 0, k, l;
152*67781Ssklower 	u_char	*trial = t_a;		/* Under scrutiny, assumed mapped */
153*67781Ssklower 	u_char	*ref = r_a;		/* being compared to, not mapped */
154*67781Ssklower 
155*67781Ssklower #ifdef utterly_straightforward_way_of_doing_this
156*67781Ssklower 	for (; table->limit; table++) {
157*67781Ssklower 		for (; matched < table->limit; matched++) {
158*67781Ssklower 			if (matched >= masklen - 1)
159*67781Ssklower 				return (matched);
160*67781Ssklower 			k = matched + table->offset;
161*67781Ssklower 			l = matched + rnh->rnh_offset;
162*67781Ssklower 			/* is bit l of ref == bit k of trial */
163*67781Ssklower 			if (((ref[l >> 3] >> (7 - (l & 7))) ^
164*67781Ssklower 			     (trial[k >> 3] >> (7 - (k & 7)))) & 1)
165*67781Ssklower 				return (matched);
166*67781Ssklower 		}
167*67781Ssklower 	}
168*67781Ssklower #else
169*67781Ssklower 	int test_info, trial_bits, ref_bits, limit, sum_bits, delta;
170*67781Ssklower 
171*67781Ssklower 	for (; table->limit; table++) {
172*67781Ssklower 		limit = MIN(masklen, table->limit);
173*67781Ssklower 		while (matched < limit) {
174*67781Ssklower 			k = matched + table->offset;
175*67781Ssklower 			l = matched + rnh->rnh_offset;
176*67781Ssklower 			trial_bits = 7 - (k & 7);
177*67781Ssklower 			ref_bits = 7 - (l & 7);
178*67781Ssklower 			delta = MIN(MIN(trial_bits, ref_bits), limit - matched);
179*67781Ssklower 			sum_bits = trial_bits + ref_bits;
180*67781Ssklower 
181*67781Ssklower 			test_info = ((int)ref[k >> 3]) << ref_bits;
182*67781Ssklower 			test_info ^= ((int)trial[l >> 3]) << trial_bits;
183*67781Ssklower 			test_info &= low_bits[sum_bits];
184*67781Ssklower 			test_info &= ~low_bits[sum_bits - delta];
185*67781Ssklower 			if (test_info != 0) {
186*67781Ssklower 				int count, mask = mask_bits[sum_bits];
187*67781Ssklower 				for (count = delta; count >= 0; count--) {
188*67781Ssklower 					if (mask & test_info)
189*67781Ssklower 						return (matched);
190*67781Ssklower 					matched++; mask >>= 1;
191*67781Ssklower 				}
192*67781Ssklower 				printf("Bits_matched: should never get here!");
193*67781Ssklower 			}
194*67781Ssklower 			matched += delta;
195*67781Ssklower 			if (matched >= masklen)
196*67781Ssklower 				return (matched);
197*67781Ssklower 		}
198*67781Ssklower 	}
199*67781Ssklower #endif
200*67781Ssklower 	return (matched);
201*67781Ssklower }
202*67781Ssklower 
203*67781Ssklower #if defined(IPPROTO_IP) && defined(IPVERSION) /* #include <netinet/i{n,p}.h>" */
204*67781Ssklower int ip_mapped_bits_matched
205*67781Ssklower 	(void *t_a, void *r_a, struct radix_node_head *rnh, int masklen)
206*67781Ssklower {
207*67781Ssklower 	struct ip *trial = t_a;
208*67781Ssklower 	struct sockaddr_in *ref = r_a;
209*67781Ssklower 
210*67781Ssklower 	u_long bits = trial->sin_addr.s_addr ^ ip->ip_dst.s_adddr;
211*67781Ssklower 	if (bits == 0) return (32); 	/* expected case !*/
212*67781Ssklower 	bits = ntohl(bits);
213*67781Ssklower 	bits =  x16(bits, 0);
214*67781Ssklower 	return bits;
215*67781Ssklower }
216*67781Ssklower #endif
217*67781Ssklower 
218*67781Ssklower rn_mapped_set_mask(index, rn, rnh)
219*67781Ssklower 	int index;
220*67781Ssklower 	register struct radix_node *rn;
221*67781Ssklower 	register struct radix_node_head *rnh;
222*67781Ssklower {
223*67781Ssklower 	register struct radix_index_table *table;
224*67781Ssklower 
225*67781Ssklower 	for (table = rnh->rnh_table; table->limit && index < table->limit;)
226*67781Ssklower 		table++;
227*67781Ssklower 	if (table->limit) {
228*67781Ssklower 		index += table->offset;
229*67781Ssklower 		rn->rn_bmask = mask_bits[7 - (index & 7)];
230*67781Ssklower 		rn->rn_off = (index >> 3);
231*67781Ssklower 	}
232*67781Ssklower }
233*67781Ssklower 
234*67781Ssklower rn_unmapped_bits_matched(t_a, r_a, rnh, masklen)
235*67781Ssklower 	void	*t_a;			/* Under scrutiny, assumed mapped */
236*67781Ssklower 	void	*r_a;			/* being compared to, not mapped */
237*67781Ssklower 	struct	radix_node_head *rnh;	/* has offset for ref, map for trial */
238*67781Ssklower 	int	masklen;		/* only need this many bits to match*/
239*67781Ssklower {
240*67781Ssklower 	register u_char *cp1, *cp2, *limit;
241*67781Ssklower 	int offset = rnh->rnh_offset >> 3;/* XXX: off must be n * 8 */
242*67781Ssklower 	int matched, test_info;
243*67781Ssklower 	u_char	*trial = t_a;		/* Under scrutiny, assumed mapped */
244*67781Ssklower 	u_char	*ref = r_a;		/* being compared to, not mapped */
245*67781Ssklower 
246*67781Ssklower 	cp1 = trial + offset;
247*67781Ssklower 	limit = cp1 + ((masklen + 7) >> 3);
248*67781Ssklower 	for (cp2 = ref + offset; cp1 < limit;)
249*67781Ssklower 		if (*cp1++ != *cp2++) {
250*67781Ssklower 			test_info = cp1[-1] ^ cp2[-1];
251*67781Ssklower 			matched = (cp1 - trial - offset) << 3;
252*67781Ssklower 			for (; test_info; matched--)
253*67781Ssklower 				test_info >>= 1;
254*67781Ssklower 			if (matched > masklen)
255*67781Ssklower 				matched = masklen;
256*67781Ssklower 			return (matched);
257*67781Ssklower 		}
258*67781Ssklower 	return (masklen);
259*67781Ssklower }
260*67781Ssklower 
261*67781Ssklower rn_unmapped_set_mask(index, rn, rnh)
262*67781Ssklower 	int index;
263*67781Ssklower 	register struct radix_node *rn;
264*67781Ssklower 	register struct radix_node_head *rnh;
265*67781Ssklower {
266*67781Ssklower 	index += rnh->rnh_offset;
267*67781Ssklower 	rn->rn_bmask = mask_bits[7 - (index & 7)];
268*67781Ssklower 	rn->rn_off = (index >> 3);
269*67781Ssklower }
270*67781Ssklower /* End bits.c */
271*67781Ssklower 
27261341Sbostic struct radix_node *
27361341Sbostic rn_match(v_arg, head)
27461341Sbostic 	void *v_arg;
27559007Ssklower 	struct radix_node_head *head;
27636210Ssklower {
277*67781Ssklower 	register char *cp = (char *)(v_arg);
278*67781Ssklower 	register struct radix_node *m, *t = head->rnh_treetop;
27959007Ssklower 	struct radix_node *saved_t, *top = t;
280*67781Ssklower 	int bits_matched, rn_b;
28136210Ssklower 
28236210Ssklower 	/*
28359007Ssklower 	 * Open code rn_search(v, top) to avoid overhead of extra
28436210Ssklower 	 * subroutine call.
28536210Ssklower 	 */
286*67781Ssklower 	while (t->rn_b >= 0)
28736210Ssklower 		if (t->rn_bmask & cp[t->rn_off])
28836210Ssklower 			t = t->rn_r;
28936210Ssklower 		else
29036210Ssklower 			t = t->rn_l;
291*67781Ssklower 	bits_matched = (*head->rnh_bits_matched)
292*67781Ssklower 				(v_arg, t->rn_key, head, -1 - t->rn_b);
293*67781Ssklower 	rn_b = -1 - bits_matched;	/* XXX: compatability */
29436210Ssklower 	/*
295*67781Ssklower 	 * Check this node, and any other duped keys.
296*67781Ssklower 	 * We want to match the most specific possible mask, so
297*67781Ssklower 	 * duplicates are sorted longest mask to shortest.
29836210Ssklower 	 */
299*67781Ssklower 	for (saved_t = t; t; t = t->rn_dupedkey)
300*67781Ssklower 		/* if (bits_matched >= mask_index) */
301*67781Ssklower 		if (rn_b <= t->rn_b) {
302*67781Ssklower 			/*
303*67781Ssklower 			 * This extra grot is in case we are explicitly asked
304*67781Ssklower 			 * to look up the default.  Ugh!
305*67781Ssklower 			 */
306*67781Ssklower 			if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey)
307*67781Ssklower 				t = t->rn_dupedkey;
308*67781Ssklower 			return (t);
309*67781Ssklower 		}
310*67781Ssklower 	/* start searching up the tree */
31136210Ssklower 	t = saved_t;
31236210Ssklower 	do {
31336210Ssklower 		t = t->rn_p;
314*67781Ssklower 		for (m = t->rn_mklist; m; m = m->rn_mklist)
315*67781Ssklower 			/* if (bits_matched >= mask_index) */
316*67781Ssklower 			if (rn_b <= m->rn_b)
317*67781Ssklower 				return (m);
31859007Ssklower 	} while (t != top);
31936210Ssklower 	return 0;
32036210Ssklower };
32136210Ssklower 
32236210Ssklower #ifdef RN_DEBUG
32336210Ssklower int	rn_nodenum;
32436210Ssklower struct	radix_node *rn_clist;
32536210Ssklower int	rn_saveinfo;
32659007Ssklower int	rn_debug =  1;
32736210Ssklower #endif
32836210Ssklower 
32936210Ssklower struct radix_node *
330*67781Ssklower rn_newpair1(v, b, nodes, rnh)
33161341Sbostic 	void *v;
33252264Storek 	int b;
33336210Ssklower 	struct radix_node nodes[2];
334*67781Ssklower 	struct radix_node_head *rnh;
33536210Ssklower {
33636210Ssklower 	register struct radix_node *tt = nodes, *t = tt + 1;
337*67781Ssklower 	if (rnh == 0)
338*67781Ssklower 		panic("rn_newpair1");
339*67781Ssklower 	t->rn_b = b; t->rn_l = tt;
340*67781Ssklower 	(*rnh->rnh_set_mask)(b, t, rnh);
34161341Sbostic 	tt->rn_b = -1; tt->rn_key = (caddr_t)v; tt->rn_p = t;
34236210Ssklower 	tt->rn_flags = t->rn_flags = RNF_ACTIVE;
34336210Ssklower #ifdef RN_DEBUG
34436210Ssklower 	tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
34536210Ssklower 	tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
34636210Ssklower #endif
34736210Ssklower 	return t;
34836210Ssklower }
34936210Ssklower 
350*67781Ssklower #define DEFAULT(a, b) (a > 0 ? a : b)
351*67781Ssklower #define VLEN(v, h) ((DEFAULT(h->rnh_addrsize, *(u_char *)v) << 3) - h->rnh_offset)
352*67781Ssklower 
35361341Sbostic struct radix_node *
35461341Sbostic rn_insert(v_arg, head, dupentry, nodes)
35561341Sbostic 	void *v_arg;
356*67781Ssklower 	register struct radix_node_head *head;
35736210Ssklower 	int *dupentry;
35836210Ssklower 	struct radix_node nodes[2];
35936210Ssklower {
360*67781Ssklower 	caddr_t v = (caddr_t)v_arg, cp = (head->rnh_offset >> 3) + v;
361*67781Ssklower 	register struct radix_node *t = rn_search_unmapped(v, head);
362*67781Ssklower 	register struct radix_node *p, *x;
363*67781Ssklower 	int b, vlen = VLEN(v, head);
36436210Ssklower     	/*
365*67781Ssklower 	 * Find first bit at which v and t->rn_key differ
36636210Ssklower 	 */
367*67781Ssklower 	b = rn_unmapped_bits_matched(v, t->rn_key, head, vlen);
368*67781Ssklower 	if (b == vlen) {
369*67781Ssklower 		*dupentry = 1;
370*67781Ssklower 		return t;
371*67781Ssklower 	}
372*67781Ssklower 	/*
373*67781Ssklower 	 * Find appropriate node after which to insert new key
374*67781Ssklower 	 */
375*67781Ssklower 	p = t;
376*67781Ssklower 	do {
377*67781Ssklower 		x = p;
378*67781Ssklower 		p = x->rn_p;
379*67781Ssklower         } while (b <= p->rn_b);
38036210Ssklower 
38136210Ssklower #ifdef RN_DEBUG
38236210Ssklower 	if (rn_debug)
38336210Ssklower 		printf("Going In:\n"), traverse(p);
38436210Ssklower #endif
385*67781Ssklower 	t = rn_newpair1(v, b, nodes, head);
386*67781Ssklower 	/*
387*67781Ssklower 	 * If we went to the left during the matching process,
388*67781Ssklower 	 * the spliced-in node will still be on the left.
389*67781Ssklower 	 */
390*67781Ssklower 	if (p->rn_l == x)
39136210Ssklower 		p->rn_l = t;
39236210Ssklower 	else
39336210Ssklower 		p->rn_r = t;
394*67781Ssklower 	t->rn_p = p;
395*67781Ssklower 	/*
396*67781Ssklower 	 * If the first bit of the input string that didn't match
397*67781Ssklower 	 * was set, put the new leaf to the right of the new node.
398*67781Ssklower 	 */
399*67781Ssklower 	if (cp[b >> 3] & search_bits[b & 7]) {
400*67781Ssklower 		t->rn_r = nodes; t->rn_l = x;
401*67781Ssklower 	} else
40236210Ssklower 		t->rn_r = x;
403*67781Ssklower 	x->rn_p = t;
40436210Ssklower #ifdef RN_DEBUG
40536210Ssklower 	if (rn_debug)
40636210Ssklower 		printf("Coming out:\n"), traverse(p);
40736210Ssklower #endif
408*67781Ssklower 	return (nodes);
40936210Ssklower }
41036210Ssklower 
411*67781Ssklower /*
412*67781Ssklower  * Here mostly for compatability's sake with
413*67781Ssklower  * the previous networking code, which expects to find masks.
414*67781Ssklower  */
41536210Ssklower struct radix_node *
416*67781Ssklower rn_masksubr(n_arg, v_arg, skip, head, len_p)
417*67781Ssklower 	void *n_arg, *v_arg;
418*67781Ssklower 	int skip, *len_p;
419*67781Ssklower 	struct radix_node_head *head;
42043336Ssklower {
421*67781Ssklower 	caddr_t netmask = (caddr_t)n_arg, v = v_arg;
422*67781Ssklower 	register struct radix_node *x = rn_masktop;
42343336Ssklower 	register caddr_t cp, cplim;
424*67781Ssklower 	register int b, j, mlen, vlen;
42543336Ssklower 	int maskduplicated;
426*67781Ssklower 	struct radix_node *saved_x;
42743336Ssklower 
428*67781Ssklower 	if (head == 0)
429*67781Ssklower 		head = mask_rnhead;
430*67781Ssklower 	if (netmask == 0) {
431*67781Ssklower 		if (*len_p)
432*67781Ssklower 			*len_p = VLEN(v, head);
433*67781Ssklower 		return 0;
434*67781Ssklower 	}
435*67781Ssklower 	if (skip > 0)
436*67781Ssklower 		for (j = skip << 3; j > ((unsigned)x->rn_b);)
437*67781Ssklower 			x = x->rn_r;
438*67781Ssklower 	x = rn_search(netmask, x);
43943336Ssklower 	mlen = *(u_char *)netmask;
440*67781Ssklower 	if ((skip > mlen) ||
441*67781Ssklower 	    Bcmp(netmask + skip, x->rn_key + skip, mlen - skip) == 0)
442*67781Ssklower 		goto found;
44354824Ssklower 	R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x));
44443336Ssklower 	if (x == 0)
44543336Ssklower 		return (0);
446*67781Ssklower 	saved_x = x;
44754824Ssklower 	Bzero(x, max_keylen + 2 * sizeof (*x));
44843336Ssklower 	cp = (caddr_t)(x + 2);
44943336Ssklower 	Bcopy(netmask, cp, mlen);
450*67781Ssklower 	if (skip > 1)
451*67781Ssklower 		Bcopy(rn_ones, cp + 1, skip - 1);
452*67781Ssklower 	maskduplicated = 0;
453*67781Ssklower 	x = rn_insert(cp, mask_rnhead, &maskduplicated, x);
454*67781Ssklower 	mlen = rn_unmapped_bits_matched(cp, rn_ones, head, mlen << 3);
455*67781Ssklower 	if (maskduplicated) {
456*67781Ssklower 		printf("rn_addmask1: impossible dup");
457*67781Ssklower 		Free(saved_x);
458*67781Ssklower 	} else {
459*67781Ssklower 		x->rn_b = -1 - mlen;
46043336Ssklower 	}
461*67781Ssklower found:
462*67781Ssklower 	if (len_p)
463*67781Ssklower 		*len_p = (-1 - x->rn_b) - head->rnh_offset;
46443336Ssklower 	return (x);
46543336Ssklower }
46643336Ssklower 
46761341Sbostic struct radix_node *
46861341Sbostic rn_addroute(v_arg, n_arg, head, treenodes)
46961341Sbostic 	void *v_arg, *n_arg;
47059007Ssklower 	struct radix_node_head *head;
47136210Ssklower 	struct radix_node treenodes[2];
47236210Ssklower {
47361341Sbostic 	caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
474*67781Ssklower 	register struct radix_node *m, *us = treenodes;
475*67781Ssklower 	struct radix_node *t, *tt, *x, *base, *top = head->rnh_treetop;
476*67781Ssklower 	struct radix_node *s /*sibling*/, *p /*parent*/, **mp;
47736210Ssklower 	short b = 0, b_leaf;
478*67781Ssklower 	int masklen, masklen_leaf, mlen, keyduplicated = 0;
47936210Ssklower 
48036210Ssklower 	/*
481*67781Ssklower 	 * This version assumes contiguous masks and only cares about
482*67781Ssklower 	 * the index of the mask, if present.
48336210Ssklower 	 */
484*67781Ssklower 	(void) rn_masksubr(v_arg, n_arg, (head->rnh_offset >> 3), head, &masklen);
485*67781Ssklower 	masklen_leaf = -1 - masklen;
486*67781Ssklower 	base = tt = rn_insert(v, head, &keyduplicated, treenodes);
487*67781Ssklower 	t = p = tt->rn_p;
48836210Ssklower 	/*
48936210Ssklower 	 * Deal with duplicated keys: attach node to previous instance
490*67781Ssklower 	 * We sort the nodes so that the longest mask comes first.
49136210Ssklower 	 */
49236210Ssklower 	if (keyduplicated) {
49336210Ssklower 		/*
494*67781Ssklower 		 * Examine each node and continue past any where the
495*67781Ssklower 		 * mask length is greater than the new one;
496*67781Ssklower 		 * since we are storing -1 - masklength, the sense
497*67781Ssklower 		 * of the test is reversed.
49836210Ssklower 		 */
499*67781Ssklower 		for (; tt && (tt->rn_b <= masklen_leaf);
500*67781Ssklower 					x = tt, tt = tt->rn_dupedkey)
501*67781Ssklower 			if (tt->rn_mask == netmask)
502*67781Ssklower 				return (0);  /* mask is also duplicated */
503*67781Ssklower 		if (tt == base) {
50450724Ssklower 			/* link in at head of list */
505*67781Ssklower 			us->rn_dupedkey = tt;
506*67781Ssklower 			us->rn_p = p;
507*67781Ssklower 			if (p->rn_l == tt)
508*67781Ssklower 				p->rn_l = us; else p->rn_r = us;
509*67781Ssklower 			base = us;
51050724Ssklower 		} else {
511*67781Ssklower 			us->rn_dupedkey = x->rn_dupedkey;
512*67781Ssklower 			x->rn_dupedkey = us;
51350724Ssklower 		}
51436210Ssklower #ifdef RN_DEBUG
51536210Ssklower 		t=tt+1; tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;
51636210Ssklower 		tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;
51736210Ssklower #endif
518*67781Ssklower 		us->rn_key = (caddr_t) v;
519*67781Ssklower 		us->rn_flags = RNF_ACTIVE;
52036210Ssklower 	}
521*67781Ssklower 	us->rn_b = masklen_leaf;
522*67781Ssklower 	us->rn_mask = netmask;
52336210Ssklower 	/*
524*67781Ssklower 	 * Annotate tree about masks.
52536210Ssklower 	 */
526*67781Ssklower 	b = p->rn_b;
527*67781Ssklower 	b_leaf = -1 - b;
528*67781Ssklower 	if (p->rn_r == base) s = p->rn_l; else s = p->rn_r;
529*67781Ssklower 	if (s->rn_b < 0) {
530*67781Ssklower 	    if (s->rn_mask || s->rn_dupedkey) {
531*67781Ssklower 		/*
532*67781Ssklower 		 * There may be network routes among our sibling's
533*67781Ssklower 		 * dupedkey chain that previously couldn't be lifted
534*67781Ssklower 		 * which should now be added to the new parent.
535*67781Ssklower 		 */
536*67781Ssklower 		int previous_index = p->rn_p->rn_b;
537*67781Ssklower 		mp = &(p->rn_mklist);
538*67781Ssklower 		for (m = s; m; m = m->rn_dupedkey) {
539*67781Ssklower 			if (m->rn_mask) {
540*67781Ssklower 				int m_index = -1 - m->rn_b;
541*67781Ssklower 				if (previous_index < m_index && b >= m_index) {
542*67781Ssklower 					*mp = m;
543*67781Ssklower 					mp = &(m->rn_mklist);
544*67781Ssklower 				}
54536210Ssklower 			}
546*67781Ssklower 
54736210Ssklower 		}
548*67781Ssklower 	    }
549*67781Ssklower 	} else if (s->rn_mklist) {
55036210Ssklower 		/*
55136210Ssklower 		 * Skip over masks whose index is > that of new node
55236210Ssklower 		 */
553*67781Ssklower 		for (mp = &(s->rn_mklist); m = *mp; mp = &m->rn_mklist)
554*67781Ssklower 			if (m->rn_b >= b_leaf)
55536210Ssklower 				break;
556*67781Ssklower 		p->rn_mklist = m; *mp = 0;
55736210Ssklower 	}
55836210Ssklower 	/* Add new route to highest possible ancestor's list */
559*67781Ssklower 	if ((netmask == 0) || (masklen > p->rn_b ))
560*67781Ssklower 		return us; /* can't lift at all */
56136210Ssklower 	do {
56236210Ssklower 		x = t;
56336210Ssklower 		t = t->rn_p;
564*67781Ssklower 	} while (masklen <= t->rn_b && x != top);
56536210Ssklower 	/*
56636210Ssklower 	 * Search through routes associated with node to
56736210Ssklower 	 * insert new route according to index.
56836210Ssklower 	 * For nodes of equal index, place more specific
56936210Ssklower 	 * masks first.
57036210Ssklower 	 */
571*67781Ssklower 	for (mp = &x->rn_mklist; m = *mp; mp = &m->rn_mklist) {
572*67781Ssklower 		if (m->rn_b > masklen_leaf)
57336210Ssklower 			continue;
574*67781Ssklower 		if (m->rn_b < masklen_leaf)
57536210Ssklower 			break;
576*67781Ssklower 		if (m->rn_b == masklen_leaf) {
577*67781Ssklower 			printf("rn_addroute: impossible duplicate mask\n");
578*67781Ssklower 			return us;
57936210Ssklower 		}
58036210Ssklower 	}
581*67781Ssklower 	*mp = us;
582*67781Ssklower 	us->rn_mklist = m;
583*67781Ssklower 	return us;
58436210Ssklower }
58536210Ssklower 
58661341Sbostic struct radix_node *
587*67781Ssklower rn_delete(v_arg, n_arg, head)
588*67781Ssklower 	void *v_arg, *n_arg;
58959007Ssklower 	struct radix_node_head *head;
59036210Ssklower {
59161341Sbostic 	register struct radix_node *t, *p, *x, *tt;
592*67781Ssklower 	struct radix_node *m, *saved_m, **mp;
593*67781Ssklower 	struct radix_node *dupedkey, *base, *top = head->rnh_treetop;
594*67781Ssklower 	int b, head_off = head->rnh_offset >> 3, masklen, masklen_leaf;
595*67781Ssklower 	int vlen = VLEN(v_arg, head) >> 3;
596*67781Ssklower 	caddr_t v = v_arg;
59736210Ssklower 
598*67781Ssklower 	base = tt = rn_search_unmapped(v_arg, head);
599*67781Ssklower 	if (tt == 0 || Bcmp(v + head_off, tt->rn_key + head_off, vlen))
60036210Ssklower 		return (0);
601*67781Ssklower 	p = t = tt->rn_p;
602*67781Ssklower 	(void) rn_masksubr(v_arg, n_arg, head_off, head, &masklen);
603*67781Ssklower 	masklen_leaf = -1 - masklen;
60436210Ssklower 	if (dupedkey = tt->rn_dupedkey) {
605*67781Ssklower 		while (tt->rn_b != masklen_leaf)
60646255Ssklower 			if ((tt = tt->rn_dupedkey) == 0)
60736210Ssklower 				return (0);
60836210Ssklower 	}
609*67781Ssklower 	/*
610*67781Ssklower 	 * Delete our route from mask lists.
611*67781Ssklower 	 */
612*67781Ssklower 	if (tt->rn_mask == 0 || masklen > t->rn_b)
61336210Ssklower 		goto on1; /* Wasn't lifted at all */
61436210Ssklower 	do {
615*67781Ssklower 		x = p;
616*67781Ssklower 		p = p->rn_p;
617*67781Ssklower 	} while (masklen <= p->rn_b && x != top);
618*67781Ssklower 	for (mp = &x->rn_mklist; m = *mp; mp = &m->rn_mklist)
619*67781Ssklower 		if (m == tt) {
620*67781Ssklower 			*mp = tt->rn_mklist;
62138846Ssklower 			break;
62236210Ssklower 		}
62338846Ssklower 	if (m == 0)
62438846Ssklower 		printf("rn_delete: couldn't find our annotation\n");
62536210Ssklower on1:
62636210Ssklower 	/*
62736210Ssklower 	 * Eliminate us from tree
62836210Ssklower 	 */
62936210Ssklower 	if (tt->rn_flags & RNF_ROOT)
63036210Ssklower 		return (0);
63136210Ssklower #ifdef RN_DEBUG
63236210Ssklower 	/* Get us out of the creation list */
63336210Ssklower 	for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) {}
63436210Ssklower 	if (t) t->rn_ybro = tt->rn_ybro;
63560346Storek #endif
63636210Ssklower 	if (dupedkey) {
637*67781Ssklower 		if (tt == base) {
63836210Ssklower 			x = dupedkey; x->rn_p = t;
63936210Ssklower 			if (t->rn_l == tt) t->rn_l = x; else t->rn_r = x;
64050724Ssklower 		} else {
641*67781Ssklower 			for (x = base; x && x->rn_dupedkey != tt;)
642*67781Ssklower 				x = x->rn_dupedkey;
643*67781Ssklower 			if (x) x->rn_dupedkey = tt->rn_dupedkey;
64450724Ssklower 			else printf("rn_delete: couldn't find us\n");
64550724Ssklower 		}
646*67781Ssklower 		x = tt + 1;
647*67781Ssklower 		if  (x->rn_flags & RNF_ACTIVE) {
648*67781Ssklower 		/* Find inactive node to clober among this chain.  */
649*67781Ssklower 			for (t = base; t; t = x->rn_dupedkey)
650*67781Ssklower 				if ((t[1].rn_flags & RNF_ACTIVE) == 0)
651*67781Ssklower 					break;
652*67781Ssklower 			if (t == 0) {
653*67781Ssklower 				printf("rn_delete: lost inactive node");
654*67781Ssklower 				return (0);
655*67781Ssklower 			}
656*67781Ssklower 			t++;
657*67781Ssklower 			goto clobber;
65836210Ssklower 		}
65936210Ssklower 		goto out;
66036210Ssklower 	}
66136210Ssklower 	if (t->rn_l == tt) x = t->rn_r; else x = t->rn_l;
66236210Ssklower 	p = t->rn_p;
66336210Ssklower 	if (p->rn_r == t) p->rn_r = x; else p->rn_l = x;
66436210Ssklower 	x->rn_p = p;
66536210Ssklower 	/*
66636210Ssklower 	 * Demote routes attached to us.
66736210Ssklower 	 */
66836210Ssklower 	if (t->rn_mklist) {
66936210Ssklower 		if (x->rn_b >= 0) {
67045620Ssklower 			for (mp = &x->rn_mklist; m = *mp;)
671*67781Ssklower 				mp = &m->rn_mklist;
67245620Ssklower 			*mp = t->rn_mklist;
67336210Ssklower 		}
67436210Ssklower 	}
67536210Ssklower 	/*
67636210Ssklower 	 * We may be holding an active internal node in the tree.
67736210Ssklower 	 */
67836210Ssklower 	x = tt + 1;
67936210Ssklower 	if (t != x) {
680*67781Ssklower clobber:
68136210Ssklower #ifndef RN_DEBUG
68236210Ssklower 		*t = *x;
68336210Ssklower #else
68436210Ssklower 		b = t->rn_info; *t = *x; t->rn_info = b;
68536210Ssklower #endif
68636210Ssklower 		t->rn_l->rn_p = t; t->rn_r->rn_p = t;
68736210Ssklower 		p = x->rn_p;
68836210Ssklower 		if (p->rn_l == x) p->rn_l = t; else p->rn_r = t;
68936210Ssklower 	}
69036210Ssklower out:
69136210Ssklower 	tt->rn_flags &= ~RNF_ACTIVE;
69236210Ssklower 	tt[1].rn_flags &= ~RNF_ACTIVE;
69336210Ssklower 	return (tt);
69436210Ssklower }
69550689Ssklower 
69661341Sbostic int
69759007Ssklower rn_walktree(h, f, w)
69859007Ssklower 	struct radix_node_head *h;
69950689Ssklower 	register int (*f)();
70061341Sbostic 	void *w;
70150689Ssklower {
70250689Ssklower 	int error;
70354824Ssklower 	struct radix_node *base, *next;
70459007Ssklower 	register struct radix_node *rn = h->rnh_treetop;
70554824Ssklower 	/*
70654824Ssklower 	 * This gets complicated because we may delete the node
70754824Ssklower 	 * while applying the function f to it, so we need to calculate
70854824Ssklower 	 * the successor node in advance.
70954824Ssklower 	 */
71054824Ssklower 	/* First time through node, go left */
71154824Ssklower 	while (rn->rn_b >= 0)
71254824Ssklower 		rn = rn->rn_l;
71350689Ssklower 	for (;;) {
71454824Ssklower 		base = rn;
71554824Ssklower 		/* If at right child go back up, otherwise, go right */
71654824Ssklower 		while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0)
71754824Ssklower 			rn = rn->rn_p;
71854824Ssklower 		/* Find the next *leaf* since next node might vanish, too */
71954824Ssklower 		for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;)
72054824Ssklower 			rn = rn->rn_l;
72154824Ssklower 		next = rn;
72254824Ssklower 		/* Process leaves */
72354824Ssklower 		while (rn = base) {
72454824Ssklower 			base = rn->rn_dupedkey;
72550812Ssklower 			if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w)))
72650812Ssklower 				return (error);
72750689Ssklower 		}
72854824Ssklower 		rn = next;
72954824Ssklower 		if (rn->rn_flags & RNF_ROOT)
73054824Ssklower 			return (0);
73150689Ssklower 	}
73261341Sbostic 	/* NOTREACHED */
73350689Ssklower }
73436210Ssklower 
73561341Sbostic int
73650689Ssklower rn_inithead(head, off)
73754824Ssklower 	void **head;
73852264Storek 	int off;
73936210Ssklower {
74036354Ssklower 	register struct radix_node_head *rnh;
74136210Ssklower 	register struct radix_node *t, *tt, *ttt;
74236210Ssklower 	if (*head)
74336210Ssklower 		return (1);
74436354Ssklower 	R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh));
74536354Ssklower 	if (rnh == 0)
74636210Ssklower 		return (0);
74736354Ssklower 	Bzero(rnh, sizeof (*rnh));
74836354Ssklower 	*head = rnh;
749*67781Ssklower 	rnh->rnh_offset = off;
750*67781Ssklower 	t = rn_newpair1(rn_zeros, 0, rnh->rnh_nodes, rnh);
75136354Ssklower 	ttt = rnh->rnh_nodes + 2;
75236210Ssklower 	t->rn_r = ttt;
75336210Ssklower 	t->rn_p = t;
75436210Ssklower 	tt = t->rn_l;
75536210Ssklower 	tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;
756*67781Ssklower 	tt->rn_b = -1;
75736210Ssklower 	*ttt = *tt;
75836210Ssklower 	ttt->rn_key = rn_ones;
759*67781Ssklower 	rnh->rnh_treetop = t;
76059007Ssklower 	rnh->rnh_addaddr = rn_addroute;
76159007Ssklower 	rnh->rnh_deladdr = rn_delete;
76259007Ssklower 	rnh->rnh_matchaddr = rn_match;
76359007Ssklower 	rnh->rnh_walktree = rn_walktree;
764*67781Ssklower 	rnh->rnh_bits_matched = rn_unmapped_bits_matched;
765*67781Ssklower 	rnh->rnh_set_mask = rn_unmapped_set_mask;
76636210Ssklower 	return (1);
76736210Ssklower }
76854824Ssklower 
76961341Sbostic void
77054824Ssklower rn_init()
77154824Ssklower {
77254824Ssklower 	char *cp, *cplim;
77354824Ssklower #ifdef KERNEL
77454824Ssklower 	struct domain *dom;
77554824Ssklower 
77654824Ssklower 	for (dom = domains; dom; dom = dom->dom_next)
77754824Ssklower 		if (dom->dom_maxrtkey > max_keylen)
77854824Ssklower 			max_keylen = dom->dom_maxrtkey;
77954824Ssklower #endif
78054824Ssklower 	if (max_keylen == 0) {
78154824Ssklower 		printf("rn_init: radix functions require max_keylen be set\n");
78254824Ssklower 		return;
78354824Ssklower 	}
78454824Ssklower 	R_Malloc(rn_zeros, char *, 3 * max_keylen);
78554824Ssklower 	if (rn_zeros == NULL)
78654824Ssklower 		panic("rn_init");
787*67781Ssklower 	Bzero(rn_zeros, 2 * max_keylen);
78854824Ssklower 	rn_ones = cp = rn_zeros + max_keylen;
78954824Ssklower 	while (cp < cplim)
79054824Ssklower 		*cp++ = -1;
79154824Ssklower 	if (rn_inithead((void **)&mask_rnhead, 0) == 0)
79254824Ssklower 		panic("rn_init 2");
79354824Ssklower }
794