sl@0: /*- sl@0: * Copyright (c) 1988, 1989, 1993 sl@0: * The Regents of the University of California. All rights reserved. sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the above copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * 4. Neither the name of the University nor the names of its contributors sl@0: * may be used to endorse or promote products derived from this software sl@0: * without specific prior written permission. sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND sl@0: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE sl@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE sl@0: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL sl@0: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS sl@0: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT sl@0: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY sl@0: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF sl@0: * SUCH DAMAGE. sl@0: * sl@0: * Portions Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: * @(#)radix.h 8.2 (Berkeley) 10/31/94 sl@0: * $FreeBSD: src/sys/net/radix.h,v 1.26 2005/01/07 01:45:35 imp Exp $ sl@0: */ sl@0: sl@0: #ifndef _RADIX_H_ sl@0: #define _RADIX_H_ sl@0: sl@0: #ifdef _KERNEL sl@0: #include sl@0: #include sl@0: #endif sl@0: sl@0: /* sl@0: * Radix search tree node layout. sl@0: */ sl@0: sl@0: struct radix_node { sl@0: struct radix_mask *rn_mklist; /* list of masks contained in subtree */ sl@0: struct radix_node *rn_parent; /* parent */ sl@0: short rn_bit; /* bit offset; -1-index(netmask) */ sl@0: char rn_bmask; /* node: mask for bit test*/ sl@0: u_char rn_flags; /* enumerated next */ sl@0: #define RNF_NORMAL 1 /* leaf contains normal route */ sl@0: #define RNF_ROOT 2 /* leaf is root leaf for tree */ sl@0: #define RNF_ACTIVE 4 /* This node is alive (for rtfree) */ sl@0: union { sl@0: struct { /* leaf only data: */ sl@0: caddr_t rn_Key; /* object of search */ sl@0: caddr_t rn_Mask; /* netmask, if present */ sl@0: struct radix_node *rn_Dupedkey; sl@0: } rn_leaf; sl@0: struct { /* node only data: */ sl@0: int rn_Off; /* where to start compare */ sl@0: struct radix_node *rn_L;/* progeny */ sl@0: struct radix_node *rn_R;/* progeny */ sl@0: } rn_node; sl@0: } rn_u; sl@0: #ifdef RN_DEBUG sl@0: int rn_info; sl@0: struct radix_node *rn_twin; sl@0: struct radix_node *rn_ybro; sl@0: #endif sl@0: }; sl@0: sl@0: #define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey sl@0: #define rn_key rn_u.rn_leaf.rn_Key sl@0: #define rn_mask rn_u.rn_leaf.rn_Mask sl@0: #define rn_offset rn_u.rn_node.rn_Off sl@0: #define rn_left rn_u.rn_node.rn_L sl@0: #define rn_right rn_u.rn_node.rn_R sl@0: sl@0: /* sl@0: * Annotations to tree concerning potential routes applying to subtrees. sl@0: */ sl@0: sl@0: struct radix_mask { sl@0: short rm_bit; /* bit offset; -1-index(netmask) */ sl@0: char rm_unused; /* cf. rn_bmask */ sl@0: u_char rm_flags; /* cf. rn_flags */ sl@0: struct radix_mask *rm_mklist; /* more masks to try */ sl@0: union { sl@0: caddr_t rmu_mask; /* the mask */ sl@0: struct radix_node *rmu_leaf; /* for normal routes */ sl@0: } rm_rmu; sl@0: int rm_refs; /* # of references to this struct */ sl@0: }; sl@0: sl@0: #define rm_mask rm_rmu.rmu_mask sl@0: #define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ sl@0: sl@0: #ifndef __SYMBIAN32__ sl@0: typedef int walktree_f_t(struct radix_node *, void *); sl@0: sl@0: struct radix_node_head { sl@0: struct radix_node *rnh_treetop; sl@0: int rnh_addrsize; /* permit, but not require fixed keys */ sl@0: int rnh_pktsize; /* permit, but not require fixed keys */ sl@0: struct radix_node *(*rnh_addaddr) /* add based on sockaddr */ sl@0: (void *v, void *mask, sl@0: struct radix_node_head *head, struct radix_node nodes[]); sl@0: struct radix_node *(*rnh_addpkt) /* add based on packet hdr */ sl@0: (void *v, void *mask, sl@0: struct radix_node_head *head, struct radix_node nodes[]); sl@0: struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */ sl@0: (void *v, void *mask, struct radix_node_head *head); sl@0: struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */ sl@0: (void *v, void *mask, struct radix_node_head *head); sl@0: struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ sl@0: (void *v, struct radix_node_head *head); sl@0: struct radix_node *(*rnh_lookup) /* locate based on sockaddr */ sl@0: (void *v, void *mask, struct radix_node_head *head); sl@0: struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ sl@0: (void *v, struct radix_node_head *head); sl@0: int (*rnh_walktree) /* traverse tree */ sl@0: (struct radix_node_head *head, walktree_f_t *f, void *w); sl@0: int (*rnh_walktree_from) /* traverse tree below a */ sl@0: (struct radix_node_head *head, void *a, void *m, sl@0: walktree_f_t *f, void *w); sl@0: void (*rnh_close) /* do something when the last ref drops */ sl@0: (struct radix_node *rn, struct radix_node_head *head); sl@0: struct radix_node rnh_nodes[3]; /* empty tree for common case */ sl@0: #ifdef _KERNEL sl@0: struct mtx rnh_mtx; /* locks entire radix tree */ sl@0: #endif sl@0: }; sl@0: sl@0: #ifndef _KERNEL sl@0: #define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n))) sl@0: #define R_Zalloc(p, t, n) (p = (t) calloc(1,(unsigned int)(n))) sl@0: #ifndef __SYMBIAN32__ sl@0: #define Free(p) free((char *)p); sl@0: #endif sl@0: #else sl@0: #define R_Malloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_NOWAIT)) sl@0: #define R_Zalloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_NOWAIT | M_ZERO)) sl@0: #ifndef __SYMBIAN32__ sl@0: #define Free(p) free((caddr_t)p, M_RTABLE); sl@0: #endif sl@0: #define RADIX_NODE_HEAD_LOCK_INIT(rnh) \ sl@0: mtx_init(&(rnh)->rnh_mtx, "radix node head", NULL, MTX_DEF | MTX_RECURSE) sl@0: #define RADIX_NODE_HEAD_LOCK(rnh) mtx_lock(&(rnh)->rnh_mtx) sl@0: #define RADIX_NODE_HEAD_UNLOCK(rnh) mtx_unlock(&(rnh)->rnh_mtx) sl@0: #define RADIX_NODE_HEAD_DESTROY(rnh) mtx_destroy(&(rnh)->rnh_mtx) sl@0: #define RADIX_NODE_HEAD_LOCK_ASSERT(rnh) mtx_assert(&(rnh)->rnh_mtx, MA_OWNED) sl@0: #endif /* _KERNEL */ sl@0: sl@0: struct radix_node sl@0: *rn_addmask(void *, int, int), sl@0: *rn_addroute (void *, void *, struct radix_node_head *, sl@0: struct radix_node [2]), sl@0: *rn_delete(void *, void *, struct radix_node_head *), sl@0: *rn_lookup (void *v_arg, void *m_arg, sl@0: struct radix_node_head *head), sl@0: *rn_match(void *, struct radix_node_head *); sl@0: #endif //__SYMBIAN32__ sl@0: #endif /* _RADIX_H_ */