12535Ssangeeta /* 22535Ssangeeta * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 32535Ssangeeta * Use is subject to license terms. 42535Ssangeeta * 52535Ssangeeta * Copyright (c) 1988, 1989, 1993 62535Ssangeeta * The Regents of the University of California. All rights reserved. 72535Ssangeeta * 82535Ssangeeta * Redistribution and use in source and binary forms, with or without 92535Ssangeeta * modification, are permitted provided that the following conditions 102535Ssangeeta * are met: 112535Ssangeeta * 1. Redistributions of source code must retain the above copyright 122535Ssangeeta * notice, this list of conditions and the following disclaimer. 132535Ssangeeta * 2. Redistributions in binary form must reproduce the above copyright 142535Ssangeeta * notice, this list of conditions and the following disclaimer in the 152535Ssangeeta * documentation and/or other materials provided with the distribution. 162535Ssangeeta * 4. Neither the name of the University nor the names of its contributors 172535Ssangeeta * may be used to endorse or promote products derived from this software 182535Ssangeeta * without specific prior written permission. 192535Ssangeeta * 202535Ssangeeta * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 212535Ssangeeta * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 222535Ssangeeta * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 232535Ssangeeta * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 242535Ssangeeta * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 252535Ssangeeta * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 262535Ssangeeta * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 272535Ssangeeta * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 282535Ssangeeta * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 292535Ssangeeta * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 302535Ssangeeta * SUCH DAMAGE. 312535Ssangeeta * 322535Ssangeeta * @(#)radix.h 8.2 (Berkeley) 10/31/94 332535Ssangeeta * $FreeBSD: /repoman/r/ncvs/src/sys/net/radix.h,v 1.25.2.1 2005/01/31 23:26:23 342535Ssangeeta * imp Exp $ 352535Ssangeeta */ 362535Ssangeeta 372535Ssangeeta #ifndef _RADIX_H_ 382535Ssangeeta #define _RADIX_H_ 392535Ssangeeta 402535Ssangeeta #pragma ident "%Z%%M% %I% %E% SMI" 412535Ssangeeta 422535Ssangeeta #ifdef __cplusplus 432535Ssangeeta extern "C" { 442535Ssangeeta #endif 452535Ssangeeta 462535Ssangeeta #ifdef _KERNEL 472535Ssangeeta #include <sys/mutex.h> 482535Ssangeeta #include <netinet/in.h> 492535Ssangeeta #endif 502535Ssangeeta #include <sys/sysmacros.h> 512535Ssangeeta 522535Ssangeeta #ifdef MALLOC_DECLARE 532535Ssangeeta MALLOC_DECLARE(M_RTABLE); 542535Ssangeeta #endif 552535Ssangeeta 562535Ssangeeta /* 572535Ssangeeta * Radix search tree node layout. 582535Ssangeeta */ 592535Ssangeeta 602535Ssangeeta struct radix_node { 612535Ssangeeta struct radix_mask *rn_mklist; /* list of masks contained in subtree */ 622535Ssangeeta struct radix_node *rn_parent; /* parent */ 632535Ssangeeta short rn_bit; /* bit offset; -1-index(netmask) */ 642535Ssangeeta char rn_bmask; /* node: mask for bit test */ 652535Ssangeeta uchar_t rn_flags; /* enumerated next */ 662535Ssangeeta #define RNF_NORMAL 1 /* leaf contains normal route */ 672535Ssangeeta #define RNF_ROOT 2 /* leaf is root leaf for tree */ 682535Ssangeeta #define RNF_ACTIVE 4 /* This node is alive (for rtfree) */ 692535Ssangeeta union { 702535Ssangeeta struct { /* leaf only data: */ 712535Ssangeeta caddr_t rn_Key; /* object of search */ 722535Ssangeeta caddr_t rn_Mask; /* netmask, if present */ 732535Ssangeeta struct radix_node *rn_Dupedkey; 742535Ssangeeta } rn_leaf; 752535Ssangeeta struct { /* node only data: */ 762535Ssangeeta int rn_Off; /* where to start compare */ 772535Ssangeeta struct radix_node *rn_L; /* progeny */ 782535Ssangeeta struct radix_node *rn_R; /* progeny */ 792535Ssangeeta } rn_node; 802535Ssangeeta } rn_u; 812535Ssangeeta }; 822535Ssangeeta 832535Ssangeeta 842535Ssangeeta #define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey 852535Ssangeeta #define rn_key rn_u.rn_leaf.rn_Key 862535Ssangeeta #define rn_mask rn_u.rn_leaf.rn_Mask 872535Ssangeeta #define rn_offset rn_u.rn_node.rn_Off 882535Ssangeeta #define rn_left rn_u.rn_node.rn_L 892535Ssangeeta #define rn_right rn_u.rn_node.rn_R 902535Ssangeeta 912535Ssangeeta /* 922535Ssangeeta * Annotations to tree concerning potential routes applying to subtrees. 932535Ssangeeta */ 942535Ssangeeta 952535Ssangeeta struct radix_mask { 962535Ssangeeta short rm_bit; /* bit offset; -1-index(netmask) */ 972535Ssangeeta char rm_unused; /* cf. rn_bmask */ 982535Ssangeeta uchar_t rm_flags; /* cf. rn_flags */ 992535Ssangeeta struct radix_mask *rm_mklist; /* more masks to try */ 1002535Ssangeeta union { 1012535Ssangeeta caddr_t rmu_mask; /* the mask */ 1022535Ssangeeta struct radix_node *rmu_leaf; /* for normal routes */ 1032535Ssangeeta } rm_rmu; 1042535Ssangeeta int rm_refs; /* # of references to this struct */ 1052535Ssangeeta }; 1062535Ssangeeta 1072535Ssangeeta #define rm_mask rm_rmu.rmu_mask 1082535Ssangeeta #define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ 1092535Ssangeeta 1102535Ssangeeta typedef int walktree_f_t(struct radix_node *, void *); 1112535Ssangeeta typedef boolean_t match_leaf_t(struct radix_node *, void *); 112*2783Ssowmini typedef void (*lockf_t)(struct radix_node *); 1132535Ssangeeta 1142535Ssangeeta struct radix_node_head { 1152535Ssangeeta struct radix_node *rnh_treetop; 1162535Ssangeeta int rnh_addrsize; /* permit, but not require fixed keys */ 1172535Ssangeeta int rnh_pktsize; /* permit, but not require fixed keys */ 1182535Ssangeeta struct radix_node *(*rnh_addaddr) /* add based on sockaddr */ 1192535Ssangeeta (void *v, void *mask, 1202535Ssangeeta struct radix_node_head *head, struct radix_node nodes[]); 1212535Ssangeeta struct radix_node *(*rnh_addpkt) /* add based on packet hdr */ 1222535Ssangeeta (void *v, void *mask, 1232535Ssangeeta struct radix_node_head *head, struct radix_node nodes[]); 1242535Ssangeeta struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */ 1252535Ssangeeta (void *v, void *mask, struct radix_node_head *head); 1262535Ssangeeta struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */ 1272535Ssangeeta (void *v, void *mask, struct radix_node_head *head); 1282535Ssangeeta struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ 1292535Ssangeeta (void *v, struct radix_node_head *head); 1302535Ssangeeta /* rnh_matchaddr_args: locate based on sockaddr and match_leaf_t() */ 1312535Ssangeeta struct radix_node *(*rnh_matchaddr_args) 1322535Ssangeeta (void *v, struct radix_node_head *head, 1332535Ssangeeta match_leaf_t *f, void *w); 1342535Ssangeeta struct radix_node *(*rnh_lookup) /* locate based on sockaddr */ 1352535Ssangeeta (void *v, void *mask, struct radix_node_head *head); 1362535Ssangeeta struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ 1372535Ssangeeta (void *v, struct radix_node_head *head); 1382535Ssangeeta int (*rnh_walktree) /* traverse tree */ 1392535Ssangeeta (struct radix_node_head *head, walktree_f_t *f, void *w); 140*2783Ssowmini int (*rnh_walktree_mt) /* traverse tree */ 141*2783Ssowmini (struct radix_node_head *head, walktree_f_t *f, void *w, 142*2783Ssowmini lockf_t lockf, lockf_t unlockf); 143*2783Ssowmini /* rn_walktree_mt: MT safe version of rn_walktree */ 1442535Ssangeeta int (*rnh_walktree_from) /* traverse tree below a */ 1452535Ssangeeta (struct radix_node_head *head, void *a, void *m, 1462535Ssangeeta walktree_f_t *f, void *w); 1472535Ssangeeta void (*rnh_close) /* do something when the last ref drops */ 1482535Ssangeeta (struct radix_node *rn, struct radix_node_head *head); 1492535Ssangeeta struct radix_node rnh_nodes[3]; /* empty tree for common case */ 1502535Ssangeeta #ifdef _KERNEL 1512535Ssangeeta krwlock_t rnh_lock; /* locks entire radix tree */ 1522535Ssangeeta #endif 1532535Ssangeeta }; 1542535Ssangeeta 1552535Ssangeeta #ifdef _KERNEL 1562535Ssangeeta /* 1572535Ssangeeta * BSD's sockaddr_in and sockadr have a sin_len and an sa_len 1582535Ssangeeta * field respectively, as the first field in the structure, and 1592535Ssangeeta * everything in radix.c assumes that the first byte of the "varg" 1602535Ssangeeta * passed in tells the length of the key (the sockaddr). 1612535Ssangeeta * 1622535Ssangeeta * Since Solaris' sockaddr_in and sockadr, do not have these fields, we 1632535Ssangeeta * define a BSD4-like sockaddr_in structure with rt_sin_len field to 1642535Ssangeeta * make LEN macro wn radix.c to work correctly for Solaris 1652535Ssangeeta * See comments around LEN() macro in ip/radix.c 1662535Ssangeeta * The callers of functions of radix.c have to use this data structure 1672535Ssangeeta */ 1682535Ssangeeta struct rt_sockaddr { 1692535Ssangeeta uint8_t rt_sin_len; 1702535Ssangeeta uint8_t rt_sin_family; 1712535Ssangeeta uint16_t rt_sin_port; 1722535Ssangeeta struct in_addr rt_sin_addr; 1732535Ssangeeta char rt_sin_zero[8]; 1742535Ssangeeta }; 1752535Ssangeeta 1762535Ssangeeta 1772535Ssangeeta #define R_Malloc(p, c, n) p = kmem_cache_alloc((c), KM_NOSLEEP) 1782535Ssangeeta #define R_Zalloc(p, c, n) \ 1792535Ssangeeta if (p = kmem_cache_alloc((c), KM_NOSLEEP)) {\ 1802535Ssangeeta bzero(p, n); \ 1812535Ssangeeta } 1822535Ssangeeta #define R_ZallocSleep(p, t, n) p = (t) kmem_zalloc(n, KM_SLEEP) 1832535Ssangeeta #define Free(p, c) kmem_cache_free(c, p) 1842535Ssangeeta #define FreeHead(p, n) kmem_free(p, n) 1852535Ssangeeta 1862535Ssangeeta typedef struct radix_node rn_t; 1872535Ssangeeta typedef struct radix_mask rmsk_t; 1882535Ssangeeta typedef struct radix_node_head rnh_t; 1892535Ssangeeta typedef struct rt_sockaddr rt_sa_t; 1902535Ssangeeta 1912535Ssangeeta #define RADIX_NODE_HEAD_LOCK_INIT(rnh) \ 1922535Ssangeeta rw_init(&(rnh)->rnh_lock, NULL, RW_DEFAULT, NULL) 1932535Ssangeeta #define RADIX_NODE_HEAD_RLOCK(rnh) rw_enter(&(rnh)->rnh_lock, RW_READER) 1942535Ssangeeta #define RADIX_NODE_HEAD_WLOCK(rnh) rw_enter(&(rnh)->rnh_lock, RW_WRITER) 1952535Ssangeeta #define RADIX_NODE_HEAD_UNLOCK(rnh) rw_exit(&(rnh)->rnh_lock) 1962535Ssangeeta #define RADIX_NODE_HEAD_DESTROY(rnh) rw_destroy(&(rnh)->rnh_lock) 1972535Ssangeeta #define RADIX_NODE_HEAD_LOCK_ASSERT(rnh) RW_WRITE_HELD(&(rnh)->rnh_lock) 1982535Ssangeeta 1992535Ssangeeta #else /* _KERNEL */ 2002535Ssangeeta 2012535Ssangeeta #define R_Malloc(p, t, n) (p = malloc((unsigned int)(n))) 2022535Ssangeeta #define R_Zalloc(p, t, n) (p = calloc(1, (unsigned int)(n))) 2032535Ssangeeta #define R_ZallocSleep(p, t, n) R_Zalloc(p, t, n) 2042535Ssangeeta #define Free(p, c) free((char *)p); /* c is ignored */ 2052535Ssangeeta #ifndef RADIX_NODE_HEAD_RLOCK 2062535Ssangeeta #define RADIX_NODE_HEAD_RLOCK(x) /* */ 2072535Ssangeeta #endif 2082535Ssangeeta #ifndef RADIX_NODE_HEAD_WLOCK 2092535Ssangeeta #define RADIX_NODE_HEAD_WLOCK(x) /* */ 2102535Ssangeeta #endif 2112535Ssangeeta #ifndef RADIX_NODE_HEAD_UNLOCK 2122535Ssangeeta #define RADIX_NODE_HEAD_UNLOCK(x) /* */ 2132535Ssangeeta #endif 2142535Ssangeeta 2152535Ssangeeta #endif /* _KERNEL */ 2162535Ssangeeta 2172535Ssangeeta #ifndef min 2182535Ssangeeta #define min MIN 2192535Ssangeeta #endif 2202535Ssangeeta #ifndef max 2212535Ssangeeta #define max MAX 2222535Ssangeeta #endif 2232535Ssangeeta 2242535Ssangeeta void rn_init(void); 2252535Ssangeeta void rn_fini(void); 2262535Ssangeeta int rn_inithead(void **, int); 2272535Ssangeeta int rn_freenode(struct radix_node *, void *); 2282535Ssangeeta void rn_freehead(struct radix_node_head *); 2292535Ssangeeta 2302535Ssangeeta #ifdef __cplusplus 2312535Ssangeeta } 2322535Ssangeeta #endif 2332535Ssangeeta 2342535Ssangeeta #endif /* _RADIX_H_ */ 235