1/*	$NetBSD: radix.c,v 1.7 2012/02/15 17:55:04 riz Exp $	*/
2
3/*
4 * Copyright (c) 1988, 1989, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 *	@(#)radix.c	8.6 (Berkeley) 10/17/95
29 */
30
31/*
32 * Routines to build and maintain radix trees for routing lookups.
33 */
34#if defined(KERNEL) || defined(_KERNEL)
35# undef KERNEL
36# undef _KERNEL
37# define        KERNEL  1
38# define        _KERNEL 1
39#endif
40#define __SYS_ATOMIC_OPS_H__
41#if !defined(__svr4__) && !defined(__SVR4) && !defined(__osf__) && \
42    !defined(__hpux) && !defined(__sgi)
43#include <sys/cdefs.h>
44#endif
45#ifdef __osf__
46# define CONST
47# define _IPV6_SWTAB_H
48# define _PROTO_NET_H_
49# define _PROTO_IPV6_H
50# include <sys/malloc.h>
51#endif
52
53#include <sys/param.h>
54#ifdef	_KERNEL
55#include <sys/systm.h>
56#else
57void panic(char *str);
58#include <stdlib.h>
59#include <stdio.h>
60#include <stdarg.h>
61#include <string.h>
62#endif
63#ifdef __hpux
64#include <syslog.h>
65#else
66#include <sys/syslog.h>
67#endif
68#include <sys/time.h>
69#include <netinet/in.h>
70#include <sys/socket.h>
71#include <net/if.h>
72#ifdef SOLARIS2
73# define _RADIX_H_
74#endif
75#include "netinet/ip_compat.h"
76#include "netinet/ip_fil.h"
77#ifdef SOLARIS2
78# undef _RADIX_H_
79#endif
80/* END OF INCLUDES */
81#include "radix_ipf.h"
82#ifndef min
83# define	min	MIN
84#endif
85#ifndef max
86# define	max	MAX
87#endif
88
89int	max_keylen = 16;
90static struct radix_mask *rn_mkfreelist;
91static struct radix_node_head *mask_rnhead;
92static char *addmask_key;
93static u_char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
94static char *rn_zeros = NULL, *rn_ones = NULL;
95
96#define rn_masktop (mask_rnhead->rnh_treetop)
97#undef Bcmp
98#define Bcmp(a, b, l) (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l))
99
100static int rn_satisfies_leaf(char *, struct radix_node *, int);
101static int rn_lexobetter(void *, void *);
102static struct radix_mask *rn_new_radix_mask(struct radix_node *,
103    struct radix_mask *);
104static int rn_freenode(struct radix_node *, void *);
105#if defined(AIX) && !defined(_KERNEL)
106struct radix_node *rn_match(void *, struct radix_node_head *);
107struct radix_node *rn_addmask(int, int, void *);
108#define	FreeS(x, y)	KFREES(x, y)
109#define	Bcopy(x, y, z)	bcopy(x, y, z)
110#endif
111
112/*
113 * The data structure for the keys is a radix tree with one way
114 * branching removed.  The index rn_b at an internal node n represents a bit
115 * position to be tested.  The tree is arranged so that all descendants
116 * of a node n have keys whose bits all agree up to position rn_b - 1.
117 * (We say the index of n is rn_b.)
118 *
119 * There is at least one descendant which has a one bit at position rn_b,
120 * and at least one with a zero there.
121 *
122 * A route is determined by a pair of key and mask.  We require that the
123 * bit-wise logical and of the key and mask to be the key.
124 * We define the index of a route to associated with the mask to be
125 * the first bit number in the mask where 0 occurs (with bit number 0
126 * representing the highest order bit).
127 *
128 * We say a mask is normal if every bit is 0, past the index of the mask.
129 * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b,
130 * and m is a normal mask, then the route applies to every descendant of n.
131 * If the index(m) < rn_b, this implies the trailing last few bits of k
132 * before bit b are all 0, (and hence consequently true of every descendant
133 * of n), so the route applies to all descendants of the node as well.
134 *
135 * Similar logic shows that a non-normal mask m such that
136 * index(m) <= index(n) could potentially apply to many children of n.
137 * Thus, for each non-host route, we attach its mask to a list at an internal
138 * node as high in the tree as we can go.
139 *
140 * The present version of the code makes use of normal routes in short-
141 * circuiting an explicit mask and compare operation when testing whether
142 * a key satisfies a normal route, and also in remembering the unique leaf
143 * that governs a subtree.
144 */
145
146struct radix_node *
147rn_search(void *v_arg, struct radix_node *head)
148{
149	struct radix_node *x;
150	caddr_t v;
151
152	for (x = head, v = v_arg; x->rn_b >= 0;) {
153		if (x->rn_bmask & v[x->rn_off])
154			x = x->rn_r;
155		else
156			x = x->rn_l;
157	}
158	return (x);
159}
160
161struct radix_node *
162rn_search_m(void *v_arg, struct radix_node *head, void *m_arg)
163{
164	struct radix_node *x;
165	caddr_t v = v_arg, m = m_arg;
166
167	for (x = head; x->rn_b >= 0;) {
168		if ((x->rn_bmask & m[x->rn_off]) &&
169		    (x->rn_bmask & v[x->rn_off]))
170			x = x->rn_r;
171		else
172			x = x->rn_l;
173	}
174	return x;
175}
176
177int
178rn_refines(void *m_arg, void *n_arg)
179{
180	caddr_t m = m_arg, n = n_arg;
181	caddr_t lim, lim2 = lim = n + *(u_char *)n;
182	int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
183	int masks_are_equal = 1;
184
185	if (longer > 0)
186		lim -= longer;
187	while (n < lim) {
188		if (*n & ~(*m))
189			return 0;
190		if (*n++ != *m++)
191			masks_are_equal = 0;
192	}
193	while (n < lim2)
194		if (*n++)
195			return 0;
196	if (masks_are_equal && (longer < 0))
197		for (lim2 = m - longer; m < lim2; )
198			if (*m++)
199				return 1;
200	return (!masks_are_equal);
201}
202
203struct radix_node *
204rn_lookup(void *v_arg, void *m_arg, struct radix_node_head *head)
205{
206	struct radix_node *x;
207	caddr_t netmask = 0;
208
209	if (m_arg) {
210		if ((x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_off)) == 0)
211			return (0);
212		netmask = x->rn_key;
213	}
214	x = rn_match(v_arg, head);
215	if (x && netmask) {
216		while (x && x->rn_mask != netmask)
217			x = x->rn_dupedkey;
218	}
219	return x;
220}
221
222static int
223rn_satisfies_leaf(char *trial, struct radix_node *leaf, int skip)
224{
225	char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask;
226	char *cplim;
227	int length = min(*(u_char *)cp, *(u_char *)cp2);
228
229	if (cp3 == 0)
230		cp3 = rn_ones;
231	else
232		length = min(length, *(u_char *)cp3);
233	cplim = cp + length;
234	cp3 += skip;
235	cp2 += skip;
236	for (cp += skip; cp < cplim; cp++, cp2++, cp3++)
237		if ((*cp ^ *cp2) & *cp3)
238			return 0;
239	return 1;
240}
241
242struct radix_node *
243rn_match(void *v_arg, struct radix_node_head *head)
244{
245	caddr_t v = v_arg;
246	struct radix_node *t = head->rnh_treetop, *x;
247	caddr_t cp = v, cp2;
248	caddr_t cplim;
249	struct radix_node *saved_t, *top = t;
250	int off = t->rn_off, vlen = *(u_char *)cp, matched_off;
251	int test, b, rn_b;
252
253	/*
254	 * Open code rn_search(v, top) to avoid overhead of extra
255	 * subroutine call.
256	 */
257	for (; t->rn_b >= 0; ) {
258		if (t->rn_bmask & cp[t->rn_off])
259			t = t->rn_r;
260		else
261			t = t->rn_l;
262	}
263	/*
264	 * See if we match exactly as a host destination
265	 * or at least learn how many bits match, for normal mask finesse.
266	 *
267	 * It doesn't hurt us to limit how many bytes to check
268	 * to the length of the mask, since if it matches we had a genuine
269	 * match and the leaf we have is the most specific one anyway;
270	 * if it didn't match with a shorter length it would fail
271	 * with a long one.  This wins big for class B&C netmasks which
272	 * are probably the most common case...
273	 */
274	if (t->rn_mask)
275		vlen = *(u_char *)t->rn_mask;
276	cp += off;
277	cp2 = t->rn_key + off;
278	cplim = v + vlen;
279	for (; cp < cplim; cp++, cp2++)
280		if (*cp != *cp2)
281			goto on1;
282	/*
283	 * This extra grot is in case we are explicitly asked
284	 * to look up the default.  Ugh!
285	 */
286	if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey)
287		t = t->rn_dupedkey;
288	return t;
289on1:
290	test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */
291	for (b = 7; (test >>= 1) > 0;)
292		b--;
293	matched_off = cp - v;
294	b += matched_off << 3;
295	rn_b = -1 - b;
296	/*
297	 * If there is a host route in a duped-key chain, it will be first.
298	 */
299	if ((saved_t = t)->rn_mask == 0)
300		t = t->rn_dupedkey;
301	for (; t; t = t->rn_dupedkey)
302		/*
303		 * Even if we don't match exactly as a host,
304		 * we may match if the leaf we wound up at is
305		 * a route to a net.
306		 */
307		if (t->rn_flags & RNF_NORMAL) {
308			if (rn_b <= t->rn_b)
309				return t;
310		} else if (rn_satisfies_leaf(v, t, matched_off))
311				return t;
312	t = saved_t;
313	/* start searching up the tree */
314	do {
315		struct radix_mask *m;
316		t = t->rn_p;
317		m = t->rn_mklist;
318		if (m) {
319			/*
320			 * If non-contiguous masks ever become important
321			 * we can restore the masking and open coding of
322			 * the search and satisfaction test and put the
323			 * calculation of "off" back before the "do".
324			 */
325			do {
326				if (m->rm_flags & RNF_NORMAL) {
327					if (rn_b <= m->rm_b)
328						return (m->rm_leaf);
329				} else {
330					off = min(t->rn_off, matched_off);
331					x = rn_search_m(v, t, m->rm_mask);
332					while (x && x->rn_mask != m->rm_mask)
333						x = x->rn_dupedkey;
334					if (x && rn_satisfies_leaf(v, x, off))
335						return x;
336				}
337				m = m->rm_mklist;
338			} while (m);
339		}
340	} while (t != top);
341	return 0;
342}
343
344#ifdef RN_DEBUG
345int	rn_nodenum;
346struct	radix_node *rn_clist;
347int	rn_saveinfo;
348int	rn_debug =  1;
349#endif
350
351struct radix_node *
352rn_newpair(v, b, nodes)
353	void *v;
354	int b;
355	struct radix_node nodes[2];
356{
357	struct radix_node *tt = nodes, *t = tt + 1;
358	t->rn_b = b;
359	t->rn_bmask = 0x80 >> (b & 7);
360	t->rn_l = tt;
361	t->rn_off = b >> 3;
362	tt->rn_b = -1;
363	tt->rn_key = (caddr_t)v;
364	tt->rn_p = t;
365	tt->rn_flags = t->rn_flags = RNF_ACTIVE;
366#ifdef RN_DEBUG
367	tt->rn_info = rn_nodenum++;
368	t->rn_info = rn_nodenum++;
369	tt->rn_twin = t;
370	tt->rn_ybro = rn_clist;
371	rn_clist = tt;
372#endif
373	return t;
374}
375
376struct radix_node *
377rn_insert(v_arg, head, dupentry, nodes)
378	void *v_arg;
379	struct radix_node_head *head;
380	int *dupentry;
381	struct radix_node nodes[2];
382{
383	caddr_t v = v_arg;
384	struct radix_node *top = head->rnh_treetop;
385	int head_off = top->rn_off, vlen = (int)*((u_char *)v);
386	struct radix_node *t = rn_search(v_arg, top);
387	caddr_t cp = v + head_off;
388	int b;
389	struct radix_node *tt;
390
391#ifdef	RN_DEBUG
392	if (rn_debug)
393		log(LOG_DEBUG, "rn_insert(%p,%p,%p,%p)\n", v_arg, head, dupentry, nodes);
394#endif
395    	/*
396	 * Find first bit at which v and t->rn_key differ
397	 */
398    {
399	caddr_t cp2 = t->rn_key + head_off;
400	int cmp_res;
401	caddr_t cplim = v + vlen;
402
403	while (cp < cplim)
404		if (*cp2++ != *cp++)
405			goto on1;
406	*dupentry = 1;
407	return t;
408on1:
409	*dupentry = 0;
410	cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
411	for (b = (cp - v) << 3; cmp_res; b--)
412		cmp_res >>= 1;
413    }
414    {
415	struct radix_node *p, *x = top;
416	cp = v;
417	do {
418		p = x;
419		if (cp[x->rn_off] & x->rn_bmask)
420			x = x->rn_r;
421		else
422			x = x->rn_l;
423	} while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */
424#ifdef RN_DEBUG
425	if (rn_debug)
426		log(LOG_DEBUG, "rn_insert: Going In:\n"); // traverse(p);
427#endif
428	t = rn_newpair(v_arg, b, nodes);
429	tt = t->rn_l;
430	if ((cp[p->rn_off] & p->rn_bmask) == 0)
431		p->rn_l = t;
432	else
433		p->rn_r = t;
434	x->rn_p = t;
435	t->rn_p = p; /* frees x, p as temp vars below */
436	if ((cp[t->rn_off] & t->rn_bmask) == 0) {
437		t->rn_r = x;
438	} else {
439		t->rn_r = tt;
440		t->rn_l = x;
441	}
442#ifdef RN_DEBUG
443	if (rn_debug)
444		log(LOG_DEBUG, "rn_insert: Coming Out:\n"); // traverse(p);
445#endif
446    }
447	return (tt);
448}
449
450struct radix_node *
451rn_addmask(void *n_arg, int search, int skip)
452{
453	caddr_t netmask = (caddr_t)n_arg;
454	struct radix_node *x;
455	caddr_t cp, cplim;
456	int b = 0, mlen, j;
457	int maskduplicated, m0, isnormal;
458	struct radix_node *saved_x;
459	static int last_zeroed = 0;
460
461#ifdef	RN_DEBUG
462	if (rn_debug)
463		log(LOG_DEBUG, "rn_addmask(%p,%d,%d)\n", n_arg, search, skip);
464#endif
465	mlen = *(u_char *)netmask;
466	if ((mlen = *(u_char *)netmask) > max_keylen)
467		mlen = max_keylen;
468	if (skip == 0)
469		skip = 1;
470	if (mlen <= skip)
471		return (mask_rnhead->rnh_nodes);
472	if (skip > 1)
473		Bcopy(rn_ones + 1, addmask_key + 1, skip - 1);
474	if ((m0 = mlen) > skip)
475		Bcopy(netmask + skip, addmask_key + skip, mlen - skip);
476	/*
477	 * Trim trailing zeroes.
478	 */
479	for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;)
480		cp--;
481	mlen = cp - addmask_key;
482	if (mlen <= skip) {
483		if (m0 >= last_zeroed)
484			last_zeroed = mlen;
485		return (mask_rnhead->rnh_nodes);
486	}
487	if (m0 < last_zeroed)
488		Bzero(addmask_key + m0, last_zeroed - m0);
489	*addmask_key = last_zeroed = mlen;
490	x = rn_search(addmask_key, rn_masktop);
491	if (Bcmp(addmask_key, x->rn_key, mlen) != 0)
492		x = 0;
493	if (x || search)
494		return (x);
495	R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x));
496	if ((saved_x = x) == 0)
497		return (0);
498	Bzero(x, max_keylen + 2 * sizeof (*x));
499	netmask = cp = (caddr_t)(x + 2);
500	Bcopy(addmask_key, cp, mlen);
501	x = rn_insert(cp, mask_rnhead, &maskduplicated, x);
502	if (maskduplicated) {
503#if 0
504		log(LOG_ERR, "rn_addmask: mask impossibly already in tree\n");
505#endif
506		Free(saved_x);
507		return (x);
508	}
509	/*
510	 * Calculate index of mask, and check for normalcy.
511	 */
512	cplim = netmask + mlen;
513	isnormal = 1;
514	for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
515		cp++;
516	if (cp != cplim) {
517		for (j = 0x80; (j & *cp) != 0; j >>= 1)
518			b++;
519		if (*cp != normal_chars[b] || cp != (cplim - 1))
520			isnormal = 0;
521	}
522	b += (cp - netmask) << 3;
523	x->rn_b = -1 - b;
524	if (isnormal)
525		x->rn_flags |= RNF_NORMAL;
526	return (x);
527}
528
529static int	/* XXX: arbitrary ordering for non-contiguous masks */
530rn_lexobetter(void *m_arg, void *n_arg)
531{
532	u_char *mp = m_arg, *np = n_arg, *lim;
533
534	if (*mp > *np)
535		return 1;  /* not really, but need to check longer one first */
536	if (*mp == *np)
537		for (lim = mp + *mp; mp < lim;)
538			if (*mp++ > *np++)
539				return 1;
540	return 0;
541}
542
543static struct radix_mask *
544rn_new_radix_mask(struct radix_node *tt, struct radix_mask *next)
545{
546	struct radix_mask *m;
547
548	MKGet(m);
549	if (m == 0) {
550#if 0
551		log(LOG_ERR, "Mask for route not entered\n");
552#endif
553		return (0);
554	}
555	Bzero(m, sizeof *m);
556	m->rm_b = tt->rn_b;
557	m->rm_flags = tt->rn_flags;
558	if (tt->rn_flags & RNF_NORMAL)
559		m->rm_leaf = tt;
560	else
561		m->rm_mask = tt->rn_mask;
562	m->rm_mklist = next;
563	tt->rn_mklist = m;
564	return m;
565}
566
567struct radix_node *
568rn_addroute(v_arg, n_arg, head, treenodes)
569	void *v_arg, *n_arg;
570	struct radix_node_head *head;
571	struct radix_node treenodes[2];
572{
573	caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
574	struct radix_node *t, *x = NULL, *tt;
575	struct radix_node *saved_tt, *top = head->rnh_treetop;
576	short b = 0, b_leaf = 0;
577	int keyduplicated;
578	caddr_t mmask;
579	struct radix_mask *m, **mp;
580
581#ifdef	RN_DEBUG
582	if (rn_debug)
583		log(LOG_DEBUG, "rn_addroute(%p,%p,%p,%p)\n", v_arg, n_arg, head, treenodes);
584#endif
585	/*
586	 * In dealing with non-contiguous masks, there may be
587	 * many different routes which have the same mask.
588	 * We will find it useful to have a unique pointer to
589	 * the mask to speed avoiding duplicate references at
590	 * nodes and possibly save time in calculating indices.
591	 */
592	if (netmask) {
593		if ((x = rn_addmask(netmask, 0, top->rn_off)) == 0)
594			return (0);
595		b_leaf = x->rn_b;
596		b = -1 - x->rn_b;
597		netmask = x->rn_key;
598	}
599	/*
600	 * Deal with duplicated keys: attach node to previous instance
601	 */
602	saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes);
603	if (keyduplicated) {
604		for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) {
605			if (tt->rn_mask == netmask)
606				return (0);
607			if (netmask == 0 ||
608			    (tt->rn_mask &&
609			     ((b_leaf < tt->rn_b) || /* index(netmask) > node */
610			       rn_refines(netmask, tt->rn_mask) ||
611			       rn_lexobetter(netmask, tt->rn_mask))))
612				break;
613		}
614		/*
615		 * If the mask is not duplicated, we wouldn't
616		 * find it among possible duplicate key entries
617		 * anyway, so the above test doesn't hurt.
618		 *
619		 * We sort the masks for a duplicated key the same way as
620		 * in a masklist -- most specific to least specific.
621		 * This may require the unfortunate nuisance of relocating
622		 * the head of the list.
623		 *
624		 * We also reverse, or doubly link the list through the
625		 * parent pointer.
626		 */
627		if (tt == saved_tt) {
628			struct	radix_node *xx = x;
629			/* link in at head of list */
630			(tt = treenodes)->rn_dupedkey = t;
631			tt->rn_flags = t->rn_flags;
632			tt->rn_p = x = t->rn_p;
633			t->rn_p = tt;
634			if (x->rn_l == t)
635				x->rn_l = tt;
636			else
637				x->rn_r = tt;
638			saved_tt = tt;
639			x = xx;
640		} else {
641			(tt = treenodes)->rn_dupedkey = t->rn_dupedkey;
642			t->rn_dupedkey = tt;
643			tt->rn_p = t;
644			if (tt->rn_dupedkey)
645				tt->rn_dupedkey->rn_p = tt;
646		}
647#ifdef RN_DEBUG
648		t=tt+1;
649		tt->rn_info = rn_nodenum++;
650		t->rn_info = rn_nodenum++;
651		tt->rn_twin = t;
652		tt->rn_ybro = rn_clist;
653		rn_clist = tt;
654#endif
655		tt->rn_key = (caddr_t) v;
656		tt->rn_b = -1;
657		tt->rn_flags = RNF_ACTIVE;
658	}
659	/*
660	 * Put mask in tree.
661	 */
662	if (netmask) {
663		tt->rn_mask = netmask;
664		tt->rn_b = x->rn_b;
665		tt->rn_flags |= x->rn_flags & RNF_NORMAL;
666	}
667	t = saved_tt->rn_p;
668	if (keyduplicated)
669		goto on2;
670	b_leaf = -1 - t->rn_b;
671	if (t->rn_r == saved_tt)
672		x = t->rn_l;
673	else
674		x = t->rn_r;
675	/* Promote general routes from below */
676	if (x->rn_b < 0) {
677	    for (mp = &t->rn_mklist; x; x = x->rn_dupedkey)
678		if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) {
679			*mp = m = rn_new_radix_mask(x, 0);
680			if (m)
681				mp = &m->rm_mklist;
682		}
683	} else if (x->rn_mklist) {
684		/*
685		 * Skip over masks whose index is > that of new node
686		 */
687		for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist)
688			if (m->rm_b >= b_leaf)
689				break;
690		t->rn_mklist = m;
691		*mp = 0;
692	}
693on2:
694	/* Add new route to highest possible ancestor's list */
695	if ((netmask == 0) || (b > t->rn_b ))
696		return tt; /* can't lift at all */
697	b_leaf = tt->rn_b;
698	do {
699		x = t;
700		t = t->rn_p;
701	} while (b <= t->rn_b && x != top);
702	/*
703	 * Search through routes associated with node to
704	 * insert new route according to index.
705	 * Need same criteria as when sorting dupedkeys to avoid
706	 * double loop on deletion.
707	 */
708	for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) {
709		if (m->rm_b < b_leaf)
710			continue;
711		if (m->rm_b > b_leaf)
712			break;
713		if (m->rm_flags & RNF_NORMAL) {
714			mmask = m->rm_leaf->rn_mask;
715			if (tt->rn_flags & RNF_NORMAL) {
716#if 0
717				log(LOG_ERR, "Non-unique normal route,"
718				    " mask not entered\n");
719#endif
720				return tt;
721			}
722		} else
723			mmask = m->rm_mask;
724		if (mmask == netmask) {
725			m->rm_refs++;
726			tt->rn_mklist = m;
727			return tt;
728		}
729		if (rn_refines(netmask, mmask)
730		    || rn_lexobetter(netmask, mmask))
731			break;
732	}
733	*mp = rn_new_radix_mask(tt, *mp);
734	return tt;
735}
736
737struct radix_node *
738rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head)
739{
740	struct radix_node *t, *p, *x, *tt;
741	struct radix_mask *m, *saved_m, **mp;
742	struct radix_node *dupedkey, *saved_tt, *top;
743	caddr_t v, netmask;
744	int b, head_off, vlen;
745
746	v = v_arg;
747	netmask = netmask_arg;
748	x = head->rnh_treetop;
749	tt = rn_search(v, x);
750	head_off = x->rn_off;
751	vlen =  *(u_char *)v;
752	saved_tt = tt;
753	top = x;
754	if (tt == 0 ||
755	    Bcmp(v + head_off, tt->rn_key + head_off, vlen - head_off))
756		return (0);
757	/*
758	 * Delete our route from mask lists.
759	 */
760	if (netmask) {
761		if ((x = rn_addmask(netmask, 1, head_off)) == 0)
762			return (0);
763		netmask = x->rn_key;
764		while (tt->rn_mask != netmask)
765			if ((tt = tt->rn_dupedkey) == 0)
766				return (0);
767	}
768	if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0)
769		goto on1;
770	if (tt->rn_flags & RNF_NORMAL) {
771		if (m->rm_leaf != tt || m->rm_refs > 0) {
772#if 0
773			log(LOG_ERR, "rn_delete: inconsistent annotation\n");
774#endif
775			return 0;  /* dangling ref could cause disaster */
776		}
777	} else {
778		if (m->rm_mask != tt->rn_mask) {
779#if 0
780			log(LOG_ERR, "rn_delete: inconsistent annotation\n");
781#endif
782			goto on1;
783		}
784		if (--m->rm_refs >= 0)
785			goto on1;
786	}
787	b = -1 - tt->rn_b;
788	t = saved_tt->rn_p;
789	if (b > t->rn_b)
790		goto on1; /* Wasn't lifted at all */
791	do {
792		x = t;
793		t = t->rn_p;
794	} while (b <= t->rn_b && x != top);
795	for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist)
796		if (m == saved_m) {
797			*mp = m->rm_mklist;
798			MKFree(m);
799			break;
800		}
801	if (m == 0) {
802#if 0
803		log(LOG_ERR, "rn_delete: couldn't find our annotation\n");
804#endif
805		if (tt->rn_flags & RNF_NORMAL)
806			return (0); /* Dangling ref to us */
807	}
808on1:
809	/*
810	 * Eliminate us from tree
811	 */
812	if (tt->rn_flags & RNF_ROOT)
813		return (0);
814#ifdef RN_DEBUG
815	/* Get us out of the creation list */
816	for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro)
817		;
818	if (t) t->rn_ybro = tt->rn_ybro;
819#endif
820	t = tt->rn_p;
821	dupedkey = saved_tt->rn_dupedkey;
822	if (dupedkey) {
823		/*
824		 * Here, tt is the deletion target and
825		 * saved_tt is the head of the dupedkey chain.
826		 */
827		if (tt == saved_tt) {
828			x = dupedkey;
829			x->rn_p = t;
830			if (t->rn_l == tt)
831				t->rn_l = x;
832			else
833				t->rn_r = x;
834		} else {
835			/* find node in front of tt on the chain */
836			for (x = p = saved_tt; p && p->rn_dupedkey != tt;)
837				p = p->rn_dupedkey;
838			if (p) {
839				p->rn_dupedkey = tt->rn_dupedkey;
840				if (tt->rn_dupedkey)
841					tt->rn_dupedkey->rn_p = p;
842			}
843#if 0
844			else
845				log(LOG_ERR, "rn_delete: couldn't find us\n");
846#endif
847		}
848		t = tt + 1;
849		if  (t->rn_flags & RNF_ACTIVE) {
850#ifndef RN_DEBUG
851			*++x = *t;
852			p = t->rn_p;
853#else
854			b = t->rn_info;
855			*++x = *t;
856			t->rn_info = b;
857			p = t->rn_p;
858#endif
859			if (p->rn_l == t)
860				p->rn_l = x;
861			else
862				p->rn_r = x;
863			x->rn_l->rn_p = x;
864			x->rn_r->rn_p = x;
865		}
866		goto out;
867	}
868	if (t->rn_l == tt)
869		x = t->rn_r;
870	else
871		x = t->rn_l;
872	p = t->rn_p;
873	if (p->rn_r == t)
874		p->rn_r = x;
875	else
876		p->rn_l = x;
877	x->rn_p = p;
878	/*
879	 * Demote routes attached to us.
880	 */
881	if (t->rn_mklist) {
882		if (x->rn_b >= 0) {
883			for (mp = &x->rn_mklist; (m = *mp) != NULL;)
884				mp = &m->rm_mklist;
885			*mp = t->rn_mklist;
886		} else {
887			/* If there are any key,mask pairs in a sibling
888			   duped-key chain, some subset will appear sorted
889			   in the same order attached to our mklist */
890			for (m = t->rn_mklist; m && x; x = x->rn_dupedkey)
891				if (m == x->rn_mklist) {
892					struct radix_mask *mm = m->rm_mklist;
893					x->rn_mklist = 0;
894					if (--(m->rm_refs) < 0)
895						MKFree(m);
896					m = mm;
897				}
898#if 0
899			if (m)
900				log(LOG_ERR, "%s %p at %p\n",
901				    "rn_delete: Orphaned Mask", m, x);
902#endif
903		}
904	}
905	/*
906	 * We may be holding an active internal node in the tree.
907	 */
908	x = tt + 1;
909	if (t != x) {
910#ifndef RN_DEBUG
911		*t = *x;
912#else
913		b = t->rn_info;
914		*t = *x;
915		t->rn_info = b;
916#endif
917		t->rn_l->rn_p = t;
918		t->rn_r->rn_p = t;
919		p = x->rn_p;
920		if (p->rn_l == x)
921			p->rn_l = t;
922		else
923			p->rn_r = t;
924	}
925out:
926	tt->rn_flags &= ~RNF_ACTIVE;
927	tt[1].rn_flags &= ~RNF_ACTIVE;
928	return (tt);
929}
930
931int
932rn_walktree(struct radix_node_head *h, int (*f)(struct radix_node *, void *),
933	void *w)
934{
935	int error;
936	struct radix_node *base, *next;
937	struct radix_node *rn = h->rnh_treetop;
938	/*
939	 * This gets complicated because we may delete the node
940	 * while applying the function f to it, so we need to calculate
941	 * the successor node in advance.
942	 */
943	/* First time through node, go left */
944	while (rn->rn_b >= 0)
945		rn = rn->rn_l;
946	for (;;) {
947		base = rn;
948		/* If at right child go back up, otherwise, go right */
949		while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0)
950			rn = rn->rn_p;
951		/* Find the next *leaf* since next node might vanish, too */
952		for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;)
953			rn = rn->rn_l;
954		next = rn;
955		/* Process leaves */
956		while ((rn = base) != NULL) {
957			base = rn->rn_dupedkey;
958			if (!(rn->rn_flags & RNF_ROOT)
959			    && (error = (*f)(rn, w)))
960				return (error);
961		}
962		rn = next;
963		if (rn->rn_flags & RNF_ROOT)
964			return (0);
965	}
966	/* NOTREACHED */
967}
968
969int
970rn_inithead(void **head, int off)
971{
972	struct radix_node_head *rnh;
973
974	if (*head)
975		return (1);
976	R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh));
977	if (rnh == 0)
978		return (0);
979	*head = rnh;
980	return rn_inithead0(rnh, off);
981}
982
983int
984rn_inithead0(struct radix_node_head *rnh, int off)
985{
986	struct radix_node *t, *tt, *ttt;
987
988	Bzero(rnh, sizeof (*rnh));
989	t = rn_newpair(rn_zeros, off, rnh->rnh_nodes);
990	ttt = rnh->rnh_nodes + 2;
991	t->rn_r = ttt;
992	t->rn_p = t;
993	tt = t->rn_l;
994	tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;
995	tt->rn_b = -1 - off;
996	*ttt = *tt;
997	ttt->rn_key = rn_ones;
998	rnh->rnh_addaddr = rn_addroute;
999	rnh->rnh_deladdr = rn_delete;
1000	rnh->rnh_matchaddr = rn_match;
1001	rnh->rnh_lookup = rn_lookup;
1002	rnh->rnh_walktree = rn_walktree;
1003	rnh->rnh_treetop = t;
1004	return (1);
1005}
1006
1007void
1008rn_init(void)
1009{
1010	char *cp, *cplim;
1011
1012	if (max_keylen == 0) {
1013#if 0
1014		log(LOG_ERR,
1015		    "rn_init: radix functions require max_keylen be set\n");
1016#endif
1017		return;
1018	}
1019	if (rn_zeros == NULL) {
1020		R_Malloc(rn_zeros, char *, 3 * max_keylen);
1021	}
1022	if (rn_zeros == NULL)
1023		panic("rn_init");
1024	Bzero(rn_zeros, 3 * max_keylen);
1025	rn_ones = cp = rn_zeros + max_keylen;
1026	addmask_key = cplim = rn_ones + max_keylen;
1027	while (cp < cplim)
1028		*cp++ = -1;
1029	if (rn_inithead((void *)&mask_rnhead, 0) == 0)
1030		panic("rn_init 2");
1031}
1032
1033
1034static int
1035rn_freenode(struct radix_node *n, void *p)
1036{
1037	struct radix_node_head *rnh = p;
1038	struct radix_node *d;
1039
1040	d = rnh->rnh_deladdr(n->rn_key, NULL, rnh);
1041	if (d != NULL) {
1042		FreeS(d, max_keylen + 2 * sizeof (*d));
1043	}
1044	return 0;
1045}
1046
1047
1048void
1049rn_freehead(struct radix_node_head *rnh)
1050{
1051
1052	(void)rn_walktree(rnh, rn_freenode, rnh);
1053
1054	rnh->rnh_addaddr = NULL;
1055	rnh->rnh_deladdr = NULL;
1056	rnh->rnh_matchaddr = NULL;
1057	rnh->rnh_lookup = NULL;
1058	rnh->rnh_walktree = NULL;
1059
1060	Free(rnh);
1061}
1062
1063
1064void
1065rn_fini(void)
1066{
1067	struct radix_mask *m;
1068
1069	if (rn_zeros != NULL) {
1070		FreeS(rn_zeros, 3 * max_keylen);
1071		rn_zeros = NULL;
1072	}
1073
1074	if (mask_rnhead != NULL) {
1075		rn_freehead(mask_rnhead);
1076		mask_rnhead = NULL;
1077	}
1078
1079	while ((m = rn_mkfreelist) != NULL) {
1080		rn_mkfreelist = m->rm_mklist;
1081		KFREE(m);
1082	}
1083}
1084
1085
1086#ifdef	USE_MAIN
1087
1088typedef struct myst {
1089	addrfamily_t	dst;
1090	addrfamily_t	mask;
1091	struct radix_node nodes[2];
1092} myst_t;
1093
1094int
1095main(int argc, char *argv[])
1096{
1097	struct radix_node_head *rnh;
1098	struct radix_node *rn;
1099	addrfamily_t af, mf;
1100	myst_t st1, st2, *stp;
1101
1102	memset(&st1, 0, sizeof(st1));
1103	memset(&st2, 0, sizeof(st2));
1104	memset(&af, 0, sizeof(af));
1105
1106	rn_init();
1107
1108	rnh = NULL;
1109	rn_inithead(&rnh, offsetof(addrfamily_t, adf_addr) << 3);
1110
1111	st1.dst.adf_len = sizeof(st1);
1112	st1.mask.adf_len = sizeof(st1);
1113	st1.dst.adf_addr.in4.s_addr = inet_addr("127.0.0.0");
1114	st1.mask.adf_addr.in4.s_addr = inet_addr("255.0.0.0");
1115	rn = rnh->rnh_addaddr(&st1.dst, &st1.mask, rnh, st1.nodes);
1116	printf("add.1 %p\n", rn);
1117
1118	st2.dst.adf_len = sizeof(st2);
1119	st2.mask.adf_len = sizeof(st2);
1120	st2.dst.adf_addr.in4.s_addr = inet_addr("127.0.1.0");
1121	st2.mask.adf_addr.in4.s_addr = inet_addr("255.255.255.0");
1122	rn = rnh->rnh_addaddr(&st2.dst, &st2.mask, rnh, st2.nodes);
1123	printf("add.2 %p\n", rn);
1124
1125	af.adf_len = sizeof(af);
1126	af.adf_addr.in4.s_addr = inet_addr("127.0.1.0");
1127	rn = rnh->rnh_matchaddr(&af, rnh);
1128	if (rn != NULL) {
1129		printf("1.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
1130		stp = rn->rn_key;
1131		printf("%s/", inet_ntoa(stp->dst.adf_addr.in4));
1132		stp = rn->rn_mask;
1133		printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4));
1134	}
1135
1136	mf.adf_len = sizeof(mf);
1137	mf.adf_addr.in4.s_addr = inet_addr("255.255.255.0");
1138	rn = rnh->rnh_lookup(&af, &mf, rnh);
1139	if (rn != NULL) {
1140		printf("2.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
1141		stp = rn->rn_key;
1142		printf("%s/", inet_ntoa(stp->dst.adf_addr.in4));
1143		stp = rn->rn_mask;
1144		printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4));
1145	}
1146
1147	af.adf_len = sizeof(af);
1148	af.adf_addr.in4.s_addr = inet_addr("126.0.0.1");
1149	rn = rnh->rnh_matchaddr(&af, rnh);
1150	if (rn != NULL) {
1151		printf("3.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask);
1152		stp = rn->rn_key;
1153		printf("%s/", inet_ntoa(stp->dst.adf_addr.in4));
1154		stp = rn->rn_mask;
1155		printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4));
1156	}
1157
1158	return 0;
1159}
1160
1161
1162void
1163log(int level, char *format, ...)
1164{
1165	va_list ap;
1166
1167	va_start(ap, format);
1168	vfprintf(stderr, format, ap);
1169	va_end(ap);
1170}
1171#endif
1172
1173
1174#ifndef	_KERNEL
1175void
1176panic(char *str)
1177{
1178	fputs(str, stderr);
1179	abort();
1180}
1181#endif
1182