xref: /onnv-gate/usr/src/uts/common/net/radix.h (revision 2535)
1*2535Ssangeeta /*
2*2535Ssangeeta  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
3*2535Ssangeeta  * Use is subject to license terms.
4*2535Ssangeeta  *
5*2535Ssangeeta  * Copyright (c) 1988, 1989, 1993
6*2535Ssangeeta  *	The Regents of the University of California.  All rights reserved.
7*2535Ssangeeta  *
8*2535Ssangeeta  * Redistribution and use in source and binary forms, with or without
9*2535Ssangeeta  * modification, are permitted provided that the following conditions
10*2535Ssangeeta  * are met:
11*2535Ssangeeta  * 1. Redistributions of source code must retain the above copyright
12*2535Ssangeeta  *    notice, this list of conditions and the following disclaimer.
13*2535Ssangeeta  * 2. Redistributions in binary form must reproduce the above copyright
14*2535Ssangeeta  *    notice, this list of conditions and the following disclaimer in the
15*2535Ssangeeta  *    documentation and/or other materials provided with the distribution.
16*2535Ssangeeta  * 4. Neither the name of the University nor the names of its contributors
17*2535Ssangeeta  *    may be used to endorse or promote products derived from this software
18*2535Ssangeeta  *    without specific prior written permission.
19*2535Ssangeeta  *
20*2535Ssangeeta  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21*2535Ssangeeta  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*2535Ssangeeta  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*2535Ssangeeta  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24*2535Ssangeeta  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*2535Ssangeeta  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*2535Ssangeeta  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*2535Ssangeeta  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*2535Ssangeeta  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*2535Ssangeeta  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*2535Ssangeeta  * SUCH DAMAGE.
31*2535Ssangeeta  *
32*2535Ssangeeta  *	@(#)radix.h	8.2 (Berkeley) 10/31/94
33*2535Ssangeeta  * $FreeBSD: /repoman/r/ncvs/src/sys/net/radix.h,v 1.25.2.1 2005/01/31 23:26:23
34*2535Ssangeeta  * imp Exp $
35*2535Ssangeeta  */
36*2535Ssangeeta 
37*2535Ssangeeta #ifndef _RADIX_H_
38*2535Ssangeeta #define	_RADIX_H_
39*2535Ssangeeta 
40*2535Ssangeeta #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*2535Ssangeeta 
42*2535Ssangeeta #ifdef	__cplusplus
43*2535Ssangeeta extern "C" {
44*2535Ssangeeta #endif
45*2535Ssangeeta 
46*2535Ssangeeta #ifdef _KERNEL
47*2535Ssangeeta #include <sys/mutex.h>
48*2535Ssangeeta #include <netinet/in.h>
49*2535Ssangeeta #endif
50*2535Ssangeeta #include <sys/sysmacros.h>
51*2535Ssangeeta 
52*2535Ssangeeta #ifdef MALLOC_DECLARE
53*2535Ssangeeta MALLOC_DECLARE(M_RTABLE);
54*2535Ssangeeta #endif
55*2535Ssangeeta 
56*2535Ssangeeta /*
57*2535Ssangeeta  * Radix search tree node layout.
58*2535Ssangeeta  */
59*2535Ssangeeta 
60*2535Ssangeeta struct radix_node {
61*2535Ssangeeta 	struct	radix_mask *rn_mklist;	/* list of masks contained in subtree */
62*2535Ssangeeta 	struct	radix_node *rn_parent;	/* parent */
63*2535Ssangeeta 	short	rn_bit;			/* bit offset; -1-index(netmask) */
64*2535Ssangeeta 	char	rn_bmask;		/* node: mask for bit test */
65*2535Ssangeeta 	uchar_t	rn_flags;		/* enumerated next */
66*2535Ssangeeta #define	RNF_NORMAL	1		/* leaf contains normal route */
67*2535Ssangeeta #define	RNF_ROOT	2		/* leaf is root leaf for tree */
68*2535Ssangeeta #define	RNF_ACTIVE	4		/* This node is alive (for rtfree) */
69*2535Ssangeeta #define	RNF_SUNW_FT	8		/* kernel ip ftable */
70*2535Ssangeeta 	union {
71*2535Ssangeeta 		struct {			/* leaf only data: */
72*2535Ssangeeta 			caddr_t	rn_Key;		/* object of search */
73*2535Ssangeeta 			caddr_t	rn_Mask;	/* netmask, if present */
74*2535Ssangeeta 			struct	radix_node *rn_Dupedkey;
75*2535Ssangeeta 		} rn_leaf;
76*2535Ssangeeta 		struct {			/* node only data: */
77*2535Ssangeeta 			int	rn_Off;		/* where to start compare */
78*2535Ssangeeta 			struct	radix_node *rn_L; /* progeny */
79*2535Ssangeeta 			struct	radix_node *rn_R; /* progeny */
80*2535Ssangeeta 		} rn_node;
81*2535Ssangeeta 	}		rn_u;
82*2535Ssangeeta };
83*2535Ssangeeta 
84*2535Ssangeeta 
85*2535Ssangeeta #define	rn_dupedkey	rn_u.rn_leaf.rn_Dupedkey
86*2535Ssangeeta #define	rn_key		rn_u.rn_leaf.rn_Key
87*2535Ssangeeta #define	rn_mask		rn_u.rn_leaf.rn_Mask
88*2535Ssangeeta #define	rn_offset	rn_u.rn_node.rn_Off
89*2535Ssangeeta #define	rn_left		rn_u.rn_node.rn_L
90*2535Ssangeeta #define	rn_right	rn_u.rn_node.rn_R
91*2535Ssangeeta 
92*2535Ssangeeta /*
93*2535Ssangeeta  * Annotations to tree concerning potential routes applying to subtrees.
94*2535Ssangeeta  */
95*2535Ssangeeta 
96*2535Ssangeeta struct radix_mask {
97*2535Ssangeeta 	short	rm_bit;			/* bit offset; -1-index(netmask) */
98*2535Ssangeeta 	char	rm_unused;		/* cf. rn_bmask */
99*2535Ssangeeta 	uchar_t	rm_flags;		/* cf. rn_flags */
100*2535Ssangeeta 	struct	radix_mask *rm_mklist;	/* more masks to try */
101*2535Ssangeeta 	union	{
102*2535Ssangeeta 		caddr_t	rmu_mask;		/* the mask */
103*2535Ssangeeta 		struct	radix_node *rmu_leaf;	/* for normal routes */
104*2535Ssangeeta 	}	rm_rmu;
105*2535Ssangeeta 	int	rm_refs;		/* # of references to this struct */
106*2535Ssangeeta };
107*2535Ssangeeta 
108*2535Ssangeeta #define	rm_mask rm_rmu.rmu_mask
109*2535Ssangeeta #define	rm_leaf rm_rmu.rmu_leaf		/* extra field would make 32 bytes */
110*2535Ssangeeta 
111*2535Ssangeeta typedef int walktree_f_t(struct radix_node *, void *);
112*2535Ssangeeta typedef boolean_t match_leaf_t(struct radix_node *, void *);
113*2535Ssangeeta 
114*2535Ssangeeta struct radix_node_head {
115*2535Ssangeeta 	struct	radix_node *rnh_treetop;
116*2535Ssangeeta 	int	rnh_addrsize;		/* permit, but not require fixed keys */
117*2535Ssangeeta 	int	rnh_pktsize;		/* permit, but not require fixed keys */
118*2535Ssangeeta 	struct	radix_node *(*rnh_addaddr)	/* add based on sockaddr */
119*2535Ssangeeta 		(void *v, void *mask,
120*2535Ssangeeta 		struct radix_node_head *head, struct radix_node nodes[]);
121*2535Ssangeeta 	struct	radix_node *(*rnh_addpkt)	/* add based on packet hdr */
122*2535Ssangeeta 		(void *v, void *mask,
123*2535Ssangeeta 		    struct radix_node_head *head, struct radix_node nodes[]);
124*2535Ssangeeta 	struct	radix_node *(*rnh_deladdr)	/* remove based on sockaddr */
125*2535Ssangeeta 		(void *v, void *mask, struct radix_node_head *head);
126*2535Ssangeeta 	struct	radix_node *(*rnh_delpkt)	/* remove based on packet hdr */
127*2535Ssangeeta 		(void *v, void *mask, struct radix_node_head *head);
128*2535Ssangeeta 	struct	radix_node *(*rnh_matchaddr)	/* locate based on sockaddr */
129*2535Ssangeeta 		(void *v, struct radix_node_head *head);
130*2535Ssangeeta 	/* rnh_matchaddr_args: locate based on sockaddr and match_leaf_t() */
131*2535Ssangeeta 	struct	radix_node *(*rnh_matchaddr_args)
132*2535Ssangeeta 		(void *v, struct radix_node_head *head,
133*2535Ssangeeta 		match_leaf_t *f, void *w);
134*2535Ssangeeta 	struct	radix_node *(*rnh_lookup)	/* locate based on sockaddr */
135*2535Ssangeeta 		(void *v, void *mask, struct radix_node_head *head);
136*2535Ssangeeta 	struct	radix_node *(*rnh_matchpkt)	/* locate based on packet hdr */
137*2535Ssangeeta 		(void *v, struct radix_node_head *head);
138*2535Ssangeeta 	int	(*rnh_walktree)			/* traverse tree */
139*2535Ssangeeta 		(struct radix_node_head *head, walktree_f_t *f, void *w);
140*2535Ssangeeta 	int	(*rnh_walktree_from)		/* traverse tree below a */
141*2535Ssangeeta 		(struct radix_node_head *head, void *a, void *m,
142*2535Ssangeeta 		    walktree_f_t *f, void *w);
143*2535Ssangeeta 	void	(*rnh_close)	/* do something when the last ref drops */
144*2535Ssangeeta 		(struct radix_node *rn, struct radix_node_head *head);
145*2535Ssangeeta 	struct	radix_node rnh_nodes[3];	/* empty tree for common case */
146*2535Ssangeeta #ifdef _KERNEL
147*2535Ssangeeta 	krwlock_t rnh_lock;			/* locks entire radix tree */
148*2535Ssangeeta #endif
149*2535Ssangeeta };
150*2535Ssangeeta 
151*2535Ssangeeta #ifdef _KERNEL
152*2535Ssangeeta /*
153*2535Ssangeeta  * BSD's sockaddr_in and sockadr have a sin_len and an sa_len
154*2535Ssangeeta  * field respectively, as the first field in the structure, and
155*2535Ssangeeta  * everything in radix.c assumes that the first byte of the "varg"
156*2535Ssangeeta  * passed in tells the length of the key (the sockaddr).
157*2535Ssangeeta  *
158*2535Ssangeeta  * Since Solaris' sockaddr_in and sockadr, do not have these fields, we
159*2535Ssangeeta  * define a BSD4-like sockaddr_in structure with rt_sin_len field to
160*2535Ssangeeta  * make LEN macro wn radix.c to work correctly for Solaris
161*2535Ssangeeta  * See comments around LEN() macro in ip/radix.c
162*2535Ssangeeta  * The callers of functions of radix.c have to use this data structure
163*2535Ssangeeta  */
164*2535Ssangeeta struct rt_sockaddr  {
165*2535Ssangeeta 	uint8_t		rt_sin_len;
166*2535Ssangeeta 	uint8_t		rt_sin_family;
167*2535Ssangeeta 	uint16_t	rt_sin_port;
168*2535Ssangeeta 	struct in_addr	rt_sin_addr;
169*2535Ssangeeta 	char		rt_sin_zero[8];
170*2535Ssangeeta };
171*2535Ssangeeta 
172*2535Ssangeeta 
173*2535Ssangeeta #define	R_Malloc(p, c, n)  p = kmem_cache_alloc((c),  KM_NOSLEEP)
174*2535Ssangeeta #define	R_Zalloc(p, c, n) \
175*2535Ssangeeta 		if (p = kmem_cache_alloc((c), KM_NOSLEEP)) {\
176*2535Ssangeeta 			bzero(p, n); \
177*2535Ssangeeta 		}
178*2535Ssangeeta #define	R_ZallocSleep(p, t, n)	p = (t) kmem_zalloc(n, KM_SLEEP)
179*2535Ssangeeta #define	Free(p, c)  kmem_cache_free(c, p)
180*2535Ssangeeta #define	FreeHead(p, n)  kmem_free(p, n)
181*2535Ssangeeta 
182*2535Ssangeeta typedef struct radix_node rn_t;
183*2535Ssangeeta typedef struct radix_mask rmsk_t;
184*2535Ssangeeta typedef struct radix_node_head rnh_t;
185*2535Ssangeeta typedef struct rt_sockaddr rt_sa_t;
186*2535Ssangeeta 
187*2535Ssangeeta #define	RADIX_NODE_HEAD_LOCK_INIT(rnh)	\
188*2535Ssangeeta 	rw_init(&(rnh)->rnh_lock, NULL, RW_DEFAULT, NULL)
189*2535Ssangeeta #define	RADIX_NODE_HEAD_RLOCK(rnh)	rw_enter(&(rnh)->rnh_lock, RW_READER)
190*2535Ssangeeta #define	RADIX_NODE_HEAD_WLOCK(rnh)	rw_enter(&(rnh)->rnh_lock, RW_WRITER)
191*2535Ssangeeta #define	RADIX_NODE_HEAD_UNLOCK(rnh)	rw_exit(&(rnh)->rnh_lock)
192*2535Ssangeeta #define	RADIX_NODE_HEAD_DESTROY(rnh)	rw_destroy(&(rnh)->rnh_lock)
193*2535Ssangeeta #define	RADIX_NODE_HEAD_LOCK_ASSERT(rnh) RW_WRITE_HELD(&(rnh)->rnh_lock)
194*2535Ssangeeta 
195*2535Ssangeeta #else /* _KERNEL */
196*2535Ssangeeta 
197*2535Ssangeeta #define	R_Malloc(p, t, n) (p =  malloc((unsigned int)(n)))
198*2535Ssangeeta #define	R_Zalloc(p, t, n) (p =  calloc(1, (unsigned int)(n)))
199*2535Ssangeeta #define	R_ZallocSleep(p, t, n) R_Zalloc(p, t, n)
200*2535Ssangeeta #define	Free(p, c) free((char *)p); /* c is ignored */
201*2535Ssangeeta #ifndef	RADIX_NODE_HEAD_RLOCK
202*2535Ssangeeta #define	RADIX_NODE_HEAD_RLOCK(x)	/* */
203*2535Ssangeeta #endif
204*2535Ssangeeta #ifndef	RADIX_NODE_HEAD_WLOCK
205*2535Ssangeeta #define	RADIX_NODE_HEAD_WLOCK(x)	/* */
206*2535Ssangeeta #endif
207*2535Ssangeeta #ifndef	RADIX_NODE_HEAD_UNLOCK
208*2535Ssangeeta #define	RADIX_NODE_HEAD_UNLOCK(x)	/* */
209*2535Ssangeeta #endif
210*2535Ssangeeta 
211*2535Ssangeeta #endif /* _KERNEL */
212*2535Ssangeeta 
213*2535Ssangeeta #ifndef min
214*2535Ssangeeta #define	min MIN
215*2535Ssangeeta #endif
216*2535Ssangeeta #ifndef max
217*2535Ssangeeta #define	max MAX
218*2535Ssangeeta #endif
219*2535Ssangeeta 
220*2535Ssangeeta void	rn_init(void);
221*2535Ssangeeta void	rn_fini(void);
222*2535Ssangeeta int	rn_inithead(void **, int);
223*2535Ssangeeta int	rn_freenode(struct radix_node *, void *);
224*2535Ssangeeta void	rn_freehead(struct radix_node_head *);
225*2535Ssangeeta 
226*2535Ssangeeta #ifdef	__cplusplus
227*2535Ssangeeta }
228*2535Ssangeeta #endif
229*2535Ssangeeta 
230*2535Ssangeeta #endif /* _RADIX_H_ */
231