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