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