xref: /minix3/sys/net/radix.h (revision 7f2d47d84ca758d43a9bd9c1a1fefc2c1bcb3375)
1*7f2d47d8SEvgeniy Ivanov /*	$NetBSD: radix.h,v 1.22 2009/05/27 17:46:50 pooka Exp $	*/
2*7f2d47d8SEvgeniy Ivanov 
3*7f2d47d8SEvgeniy Ivanov /*
4*7f2d47d8SEvgeniy Ivanov  * Copyright (c) 1988, 1989, 1993
5*7f2d47d8SEvgeniy Ivanov  *	The Regents of the University of California.  All rights reserved.
6*7f2d47d8SEvgeniy Ivanov  *
7*7f2d47d8SEvgeniy Ivanov  * Redistribution and use in source and binary forms, with or without
8*7f2d47d8SEvgeniy Ivanov  * modification, are permitted provided that the following conditions
9*7f2d47d8SEvgeniy Ivanov  * are met:
10*7f2d47d8SEvgeniy Ivanov  * 1. Redistributions of source code must retain the above copyright
11*7f2d47d8SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer.
12*7f2d47d8SEvgeniy Ivanov  * 2. Redistributions in binary form must reproduce the above copyright
13*7f2d47d8SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer in the
14*7f2d47d8SEvgeniy Ivanov  *    documentation and/or other materials provided with the distribution.
15*7f2d47d8SEvgeniy Ivanov  * 3. Neither the name of the University nor the names of its contributors
16*7f2d47d8SEvgeniy Ivanov  *    may be used to endorse or promote products derived from this software
17*7f2d47d8SEvgeniy Ivanov  *    without specific prior written permission.
18*7f2d47d8SEvgeniy Ivanov  *
19*7f2d47d8SEvgeniy Ivanov  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*7f2d47d8SEvgeniy Ivanov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*7f2d47d8SEvgeniy Ivanov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*7f2d47d8SEvgeniy Ivanov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*7f2d47d8SEvgeniy Ivanov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*7f2d47d8SEvgeniy Ivanov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*7f2d47d8SEvgeniy Ivanov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*7f2d47d8SEvgeniy Ivanov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*7f2d47d8SEvgeniy Ivanov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*7f2d47d8SEvgeniy Ivanov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*7f2d47d8SEvgeniy Ivanov  * SUCH DAMAGE.
30*7f2d47d8SEvgeniy Ivanov  *
31*7f2d47d8SEvgeniy Ivanov  *	@(#)radix.h	8.2 (Berkeley) 10/31/94
32*7f2d47d8SEvgeniy Ivanov  */
33*7f2d47d8SEvgeniy Ivanov 
34*7f2d47d8SEvgeniy Ivanov #ifndef _NET_RADIX_H_
35*7f2d47d8SEvgeniy Ivanov #define	_NET_RADIX_H_
36*7f2d47d8SEvgeniy Ivanov 
37*7f2d47d8SEvgeniy Ivanov /*
38*7f2d47d8SEvgeniy Ivanov  * Radix search tree node layout.
39*7f2d47d8SEvgeniy Ivanov  */
40*7f2d47d8SEvgeniy Ivanov 
41*7f2d47d8SEvgeniy Ivanov struct radix_node {
42*7f2d47d8SEvgeniy Ivanov 	struct	radix_mask *rn_mklist;	/* list of masks contained in subtree */
43*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *rn_p;	/* parent */
44*7f2d47d8SEvgeniy Ivanov 	short	rn_b;			/* bit offset; -1-index(netmask) */
45*7f2d47d8SEvgeniy Ivanov 	char	rn_bmask;		/* node: mask for bit test*/
46*7f2d47d8SEvgeniy Ivanov 	u_char	rn_flags;		/* enumerated next */
47*7f2d47d8SEvgeniy Ivanov #define RNF_NORMAL	1		/* leaf contains normal route */
48*7f2d47d8SEvgeniy Ivanov #define RNF_ROOT	2		/* leaf is root leaf for tree */
49*7f2d47d8SEvgeniy Ivanov #define RNF_ACTIVE	4		/* This node is alive (for rtfree) */
50*7f2d47d8SEvgeniy Ivanov 	union {
51*7f2d47d8SEvgeniy Ivanov 		struct {			/* leaf only data: */
52*7f2d47d8SEvgeniy Ivanov 			const char *rn_Key;	/* object of search */
53*7f2d47d8SEvgeniy Ivanov 			const char *rn_Mask;	/* netmask, if present */
54*7f2d47d8SEvgeniy Ivanov 			struct	radix_node *rn_Dupedkey;
55*7f2d47d8SEvgeniy Ivanov 		} rn_leaf;
56*7f2d47d8SEvgeniy Ivanov 		struct {			/* node only data: */
57*7f2d47d8SEvgeniy Ivanov 			int	rn_Off;		/* where to start compare */
58*7f2d47d8SEvgeniy Ivanov 			struct	radix_node *rn_L;/* progeny */
59*7f2d47d8SEvgeniy Ivanov 			struct	radix_node *rn_R;/* progeny */
60*7f2d47d8SEvgeniy Ivanov 		} rn_node;
61*7f2d47d8SEvgeniy Ivanov 	} rn_u;
62*7f2d47d8SEvgeniy Ivanov #ifdef RN_DEBUG
63*7f2d47d8SEvgeniy Ivanov 	int rn_info;
64*7f2d47d8SEvgeniy Ivanov 	struct radix_node *rn_twin;
65*7f2d47d8SEvgeniy Ivanov 	struct radix_node *rn_ybro;
66*7f2d47d8SEvgeniy Ivanov #endif
67*7f2d47d8SEvgeniy Ivanov };
68*7f2d47d8SEvgeniy Ivanov 
69*7f2d47d8SEvgeniy Ivanov #define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey
70*7f2d47d8SEvgeniy Ivanov #define rn_key rn_u.rn_leaf.rn_Key
71*7f2d47d8SEvgeniy Ivanov #define rn_mask rn_u.rn_leaf.rn_Mask
72*7f2d47d8SEvgeniy Ivanov #define rn_off rn_u.rn_node.rn_Off
73*7f2d47d8SEvgeniy Ivanov #define rn_l rn_u.rn_node.rn_L
74*7f2d47d8SEvgeniy Ivanov #define rn_r rn_u.rn_node.rn_R
75*7f2d47d8SEvgeniy Ivanov 
76*7f2d47d8SEvgeniy Ivanov /*
77*7f2d47d8SEvgeniy Ivanov  * Annotations to tree concerning potential routes applying to subtrees.
78*7f2d47d8SEvgeniy Ivanov  */
79*7f2d47d8SEvgeniy Ivanov 
80*7f2d47d8SEvgeniy Ivanov struct radix_mask {
81*7f2d47d8SEvgeniy Ivanov 	short	rm_b;			/* bit offset; -1-index(netmask) */
82*7f2d47d8SEvgeniy Ivanov 	char	rm_unused;		/* cf. rn_bmask */
83*7f2d47d8SEvgeniy Ivanov 	u_char	rm_flags;		/* cf. rn_flags */
84*7f2d47d8SEvgeniy Ivanov 	struct	radix_mask *rm_mklist;	/* more masks to try */
85*7f2d47d8SEvgeniy Ivanov 	union	{
86*7f2d47d8SEvgeniy Ivanov 		const char *rmu_mask;		/* the mask */
87*7f2d47d8SEvgeniy Ivanov 		struct	radix_node *rmu_leaf;	/* for normal routes */
88*7f2d47d8SEvgeniy Ivanov 	}	rm_rmu;
89*7f2d47d8SEvgeniy Ivanov 	int	rm_refs;		/* # of references to this struct */
90*7f2d47d8SEvgeniy Ivanov };
91*7f2d47d8SEvgeniy Ivanov 
92*7f2d47d8SEvgeniy Ivanov #define rm_mask rm_rmu.rmu_mask
93*7f2d47d8SEvgeniy Ivanov #define rm_leaf rm_rmu.rmu_leaf		/* extra field would make 32 bytes */
94*7f2d47d8SEvgeniy Ivanov 
95*7f2d47d8SEvgeniy Ivanov #define MKGet(m) {\
96*7f2d47d8SEvgeniy Ivanov 	if (rn_mkfreelist) {\
97*7f2d47d8SEvgeniy Ivanov 		m = rn_mkfreelist; \
98*7f2d47d8SEvgeniy Ivanov 		rn_mkfreelist = (m)->rm_mklist; \
99*7f2d47d8SEvgeniy Ivanov 	} else \
100*7f2d47d8SEvgeniy Ivanov 		R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\
101*7f2d47d8SEvgeniy Ivanov 
102*7f2d47d8SEvgeniy Ivanov #define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}
103*7f2d47d8SEvgeniy Ivanov 
104*7f2d47d8SEvgeniy Ivanov struct radix_node_head {
105*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *rnh_treetop;
106*7f2d47d8SEvgeniy Ivanov 	int	rnh_addrsize;		/* permit, but not require fixed keys */
107*7f2d47d8SEvgeniy Ivanov 	int	rnh_pktsize;		/* permit, but not require fixed keys */
108*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_addaddr)	/* add based on sockaddr */
109*7f2d47d8SEvgeniy Ivanov 		(const void *v, const void *mask,
110*7f2d47d8SEvgeniy Ivanov 		     struct radix_node_head *head, struct radix_node nodes[]);
111*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_addpkt)	/* add based on packet hdr */
112*7f2d47d8SEvgeniy Ivanov 		(const void *v, const void *mask,
113*7f2d47d8SEvgeniy Ivanov 		     struct radix_node_head *head, struct radix_node nodes[]);
114*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_deladdr)	/* remove based on sockaddr */
115*7f2d47d8SEvgeniy Ivanov 		(const void *v, const void *mask, struct radix_node_head *head);
116*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_delpkt)	/* remove based on packet hdr */
117*7f2d47d8SEvgeniy Ivanov 		(const void *v, const void *mask, struct radix_node_head *head);
118*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_matchaddr)	/* locate based on sockaddr */
119*7f2d47d8SEvgeniy Ivanov 		(const void *v, struct radix_node_head *head);
120*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_lookup)	/* locate based on sockaddr */
121*7f2d47d8SEvgeniy Ivanov 		(const void *v, const void *mask, struct radix_node_head *head);
122*7f2d47d8SEvgeniy Ivanov 	struct	radix_node *(*rnh_matchpkt)	/* locate based on packet hdr */
123*7f2d47d8SEvgeniy Ivanov 		(const void *v, struct radix_node_head *head);
124*7f2d47d8SEvgeniy Ivanov 	struct	radix_node rnh_nodes[3];	/* empty tree for common case */
125*7f2d47d8SEvgeniy Ivanov };
126*7f2d47d8SEvgeniy Ivanov 
127*7f2d47d8SEvgeniy Ivanov #ifdef _KERNEL
128*7f2d47d8SEvgeniy Ivanov extern struct radix_mask *rn_mkfreelist;
129*7f2d47d8SEvgeniy Ivanov 
130*7f2d47d8SEvgeniy Ivanov #define R_Malloc(p, t, n) (p = (t) malloc((size_t)(n), M_RTABLE, M_NOWAIT))
131*7f2d47d8SEvgeniy Ivanov #define Free(p) free(p, M_RTABLE);
132*7f2d47d8SEvgeniy Ivanov #endif /*_KERNEL*/
133*7f2d47d8SEvgeniy Ivanov 
134*7f2d47d8SEvgeniy Ivanov void	rn_init(void);
135*7f2d47d8SEvgeniy Ivanov int	rn_inithead(void **, int);
136*7f2d47d8SEvgeniy Ivanov void	rn_delayedinit(void **, int);
137*7f2d47d8SEvgeniy Ivanov int	rn_inithead0(struct radix_node_head *, int);
138*7f2d47d8SEvgeniy Ivanov int	rn_refines(const void *, const void *);
139*7f2d47d8SEvgeniy Ivanov int	rn_walktree(struct radix_node_head *,
140*7f2d47d8SEvgeniy Ivanov 	            int (*)(struct radix_node *, void *),
141*7f2d47d8SEvgeniy Ivanov 		    void *);
142*7f2d47d8SEvgeniy Ivanov struct radix_node
143*7f2d47d8SEvgeniy Ivanov 	 *rn_addmask(const void *, int, int),
144*7f2d47d8SEvgeniy Ivanov 	 *rn_addroute(const void *, const void *, struct radix_node_head *,
145*7f2d47d8SEvgeniy Ivanov 			struct radix_node [2]),
146*7f2d47d8SEvgeniy Ivanov 	 *rn_delete1(const void *, const void *, struct radix_node_head *,
147*7f2d47d8SEvgeniy Ivanov 			struct radix_node *),
148*7f2d47d8SEvgeniy Ivanov 	 *rn_delete(const void *, const void *, struct radix_node_head *),
149*7f2d47d8SEvgeniy Ivanov 	 *rn_insert(const void *, struct radix_node_head *, int *,
150*7f2d47d8SEvgeniy Ivanov 			struct radix_node [2]),
151*7f2d47d8SEvgeniy Ivanov 	 *rn_lookup(const void *, const void *, struct radix_node_head *),
152*7f2d47d8SEvgeniy Ivanov 	 *rn_match(const void *, struct radix_node_head *),
153*7f2d47d8SEvgeniy Ivanov 	 *rn_newpair(const void *, int, struct radix_node[2]),
154*7f2d47d8SEvgeniy Ivanov 	 *rn_search(const void *, struct radix_node *),
155*7f2d47d8SEvgeniy Ivanov 	 *rn_search_m(const void *, struct radix_node *, const void *);
156*7f2d47d8SEvgeniy Ivanov 
157*7f2d47d8SEvgeniy Ivanov #endif /* !_NET_RADIX_H_ */
158