1    | /***************************************
2    |   $Revision: 1.9 $
3    | 
4    |   Radix tree (rx). rxroutines.h - header file for radix tree handling module.
5    | 
6    |   Status: NOT REVUED, TESTED
7    | 
8    |   Design and implementation by: marek
9    | 
10   |   ******************/ /******************
11   |   Copyright (c) 1999                              RIPE NCC
12   |  
13   |   All Rights Reserved
14   |   
15   |   Permission to use, copy, modify, and distribute this software and its
16   |   documentation for any purpose and without fee is hereby granted,
17   |   provided that the above copyright notice appear in all copies and that
18   |   both that copyright notice and this permission notice appear in
19   |   supporting documentation, and that the name of the author not be
20   |   used in advertising or publicity pertaining to distribution of the
21   |   software without specific, written prior permission.
22   |   
23   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
25   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
26   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29   |   ***************************************/
30   | 
31   | #ifndef _RX_H
32   | #define _RX_H
33   | 
34   | #include <glib.h>
35   | #ifndef G_THREADS_ENABLED
36   | #error "GLib must be compiled with thread support enabled to be MT-Safe"
37   | #endif
38   | 
39   | #include <pthread.h>
40   | #include <stubs.h>
41   | 
42   | #include <memwrap.h>
43   | #include <stdio.h>
44   | #include <iproutines.h>
45   | 
46   | #include <rx_globals.h>
47   | 
48   | typedef int rx_regid_t;
49   | 
50   | typedef enum {
51   |   RX_FAM_RT = 1,
52   |   RX_FAM_IN,
53   |   RX_FAM_BOTH           /*+ used only in asc_search, meaningless otherwise
54   | 			   Relies on the fact that 1+2=3 :-) (bitmask) +*/
55   | } rx_fam_t;
56   | 
57   | /*+ the node operation modes +*/
58   | typedef enum {
59   |   RX_OPER_CRE = 1,
60   |   RX_OPER_MOD,
61   |   RX_OPER_DEL
62   | } rx_oper_mt;
63   | 
64   | 
65   | /*+ stack building modes +*/
66   | typedef enum {
67   |   RX_STK_CREAT = 1, /*+ - creation = all glue nodes, stop at first non-glue +*/
68   |   RX_STK_QUERY_ALLNOD,   /*+ - query = all glue nodes, stop when deep enough */
69   |   RX_STK_QUERY_NOGLUE    /*+ - query = no glue nodes, stop when deep enough */
70   | } rx_stk_mt;
71   | 
72   | /*+ the search modes +*/
73   | typedef enum {
74   |   RX_SRCH_CREAT = 1,      /*+ special search - does not skip glue nodes +*/
75   |   RX_SRCH_EXLESS,         /*+ the default search +*/
76   |   RX_SRCH_EXACT,
77   |   RX_SRCH_LESS,
78   |   RX_SRCH_MORE,           /*+ more specific search +*/
79   |   RX_SRCH_DBLS,           /*+ special more spec: return only nodes with
80   | 			     more than one data leaves +*/
81   |   RX_SRCH_RANG            /*+ more specific range search, RPSL style : ^n-m +*/
82   | } rx_srch_mt;
83   | 
84   | 
85   | // constant to mean 'unlimited number of answers from a search'
86   | #define RX_ANS_ALL (-1)
87   | 
88   | #define RX_ALL_DEPTHS 255
89   | 
90   | 
91   | /*+ radix tree's memory modes -- not yet implemented +*/
92   | typedef enum {
93   |   RX_MEM_RAMONLY,
94   |   RX_MEM_RAMSQL,
95   |   RX_MEM_SQLONLY
96   | } rx_mem_mt;
97   | 
98   | 
99   | 
100  | /*+ subtree modes -- not yet implemented +*/
101  | typedef enum {
102  |   RX_SUB_NONE,
103  |   RX_SUB_AUTO,
104  |   RX_SUB_HAND
105  | } rx_subtree_mt;
106  | 
107  | /* modes for tree traversal (walk_tree) */
108  | typedef enum {
109  |   RX_WALK_CNTGLU=1,  /*+ default: count also glue nodes and make the level
110  | 			   checking aware of them +*/
111  | 
112  |   RX_WALK_SKPGLU=2,  /*+ only real nodes counted & watched in level checks +*/
113  | 
114  |   RX_WALK_PRFLEN=4,  /*+ make level check a check for prefix length;
115  | 		       still only non-glue nodes are counted +*/
116  |   RX_WALK_REVERS=8   /*+ reverse the order of traversing the tree 
117  | 		       (first link 1 then 0) +*/
118  | } rx_walk_mt;
119  | 
120  | 
121  | /*+  A struct for data hooked via a double linked list at a radix node. 
122  | Must uniquely define the object for lookups in the SQL tables and/or memory. 
123  | Must also contain enough info to let the delete_node choose (and remove) 
124  | the proper object from the (linked) list +*/
125  | 
126  | typedef struct { 
127  |   ip_range_t    iprange;        /*+ for inetnums. empty for routes +*/
128  |   
129  |   char            composed;	/*+ flag; non-zero for composed inetnums +*/
130  | 
131  |   void           *data_ptr;	/*+ to in-memory immediate data +*/
132  |   int             data_len;     /*+ and its length +*/
133  | 
134  |   sql_key_t       data_key;	/*+ key to the SQL full-text data record +*/
135  |   sql_key_t       leaf_key;     /*+ pointer to the SQL data leaf record  +*/
136  | } rx_dataleaf_t;
137  | 
138  | /*+ 
139  | The struct for radix nodes.
140  | 
141  | Must contain prefix, parent, left/right child links in memory and sql, 
142  | link to the sql version of the node. 
143  | And of course data: pointer to a double linked list of rx_data_t's. 
144  | +*/
145  | 
146  | typedef struct _rx_node_str {
147  |   ip_prefix_t     prefix;	/*+ who am i. +*/
148  | 
149  |   char            glue;         
150  |                                 /*+ now this is an indicator for a node that it
151  | 				   is not holding a real prefix, 
152  | 				   but is only a glue node +*/
153  |   
154  |   GList          *leaves_ptr;	/*+ a double-linked list of rx_data_t structs 
155  |                                    the data leaves can be multiple at each node
156  | 				   (due to a user error the inetnum ranges can
157  | 				   overlap, due to multihoming or error routes 
158  | 				   can be duplicated ). 
159  | 				   So we link a dynamic thing here +*/
160  | 
161  |   //  sql_key_t       leaves_key;   
162  |                                 /* "linked list" not needed in sql - 
163  | 				   the data leaves can be found in node_leaf 
164  | 				   table as those that have 
165  | 				   node_key in node_id  */
166  | 
167  |   struct _rx_node_str
168  |                  *parent_ptr,	/*+ radix links in memory +*/
169  |                  *child_ptr[2];	/*+ NULL means empty +*/
170  | 
171  |   sql_key_t       parent_key,	/*+ radix links in SQL +*/
172  |                   child_key[2];	/*+ zero means empty +*/
173  | 
174  |   sql_key_t       node_key;	/*+ key of the corresponding SQL radix node +*/
175  | 
176  | } rx_node_t;
177  | 
178  | 
179  | /*+
180  |  rx_tree_t - defines a radix tree.
181  | 
182  |  includes a pointer(key) to the top node, 
183  |  
184  |  names of the corresponding SQL tables 
185  |     (they can be generated automatically, 
186  |     but this is the place to store the result)
187  |     Data_table  is for data_key.
188  |     Radix_table is for parent_id, right_id, left_id, node_id.
189  |     Leaves_table is for leaves_key (double linked list in SQL).
190  |  +*/
191  | 
192  | typedef struct _rx_tree_str {
193  |   rx_regid_t      reg_id;	/*+ registry id +*/
194  |   ip_space_t      space;	/*+ one of IPv4, IPv6 +*/
195  |   rx_fam_t        family;       /*+ one of RT, IN +*/
196  | 
197  |   rx_subtree_mt   subtrees;	/*+ one of NONE, AUTO, HAND +*/
198  |   rx_mem_mt       mem_mode;     /*+ where the tree will sit - SQL or RAM +*/
199  |   struct rx_tree_str 
200  |                  *parent_tree;  /*+ pointer to the parent tree +*/
201  | 
202  |   ip_prefix_t     prefix;	/*+ of the IP space this tree covers +*/
203  | 
204  |   int             maxbits;	/*+ max depth of this tree 
205  | 				   (depends on the space, so it is redundant)+*/
206  |   sql_tblnam_t    data_table;
207  |   sql_tblnam_t    radix_table; 
208  |   sql_tblnam_t    leaves_table;
209  | 
210  |   int             num_nodes;	/*+ number of nodes in tree - for assertions +*/
211  | 
212  |   rx_node_t      *top_ptr;	/*+ pointer to the top node +*/
213  |   long            top_key;	/*+ the same in SQL +*/
214  | 
215  |   pthread_mutex_t mutex;	/*+ per-tree mutex +*/
216  | 
217  | } rx_tree_t;
218  | 
219  | 
220  | /*+ this is a definition of a node copy used for:
221  | 
222  |  * stack elements returned from rx_stack_build,
223  | 
224  |  * answer elements from an rx_nod_search.
225  |    
226  |    It *must* hold pointers to the original locations of it (in terms of 
227  |    memory and SQL) so that one could actually modify the node...
228  |    In SQL tree mode it holds also a copy of a node.
229  |    This seems to be unnecessary for in-memory radix trees but is a must
230  |    for sql ones.
231  | 
232  |    WARNING!!!!! The fact that pointers to tree and memory / SQL nodes are
233  |    here is a subject to race condition. The location of the tree in the 
234  |    forest list and the node in memory must not change.
235  | 
236  | +*/
237  | 
238  | typedef struct {
239  |   rx_tree_t   *tree;  /*+ contains registry_id, space_id, sql table names +*/
240  |   rx_node_t *srcptr;
241  |   sql_key_t srckey;
242  |   rx_node_t cpy;      /*+ filled in if the tree is kept in SQL only mode +*/
243  | } rx_nodcpy_t;
244  | 
245  | 
246  | /*+ 
247  |   This represents one data leaf (by reference). It's used for returning data 
248  | from rx_bin_search() to rx_asc_search().
249  | +*/
250  | typedef struct {
251  |   sql_key_t      srckey;
252  |   rx_dataleaf_t *leafptr;
253  | } rx_datref_t;
254  | 
255  | 
256  | /*+ this is a structure used for returning the data from the search.
257  |    It contains a copy of the dataleaf and a pointer to the source +*/
258  | typedef struct {
259  |   sql_key_t      srckey;
260  |   rx_dataleaf_t  leafcpy;
261  | } rx_datcpy_t;
262  | 
263  | /* 
264  |  * -----------------------------------------------------------------------
265  |  *  
266  |  *       now, THIS is a scrap heap for things that MAY BE useful 
267  |  */
268  | 
269  | /* a definite pointer to an sql object: table name + key
270  | However, it might be nice to include the table TYPE so that one knows 
271  | what data it holds :-) 
272  |  */
273  | typedef struct {
274  |   sql_tblnam_t  name;
275  |   sql_key_t     key;
276  | } rx_sqlobj_t;
277  | 
278  | 
279  | typedef struct {
280  |   GList        **nodlist;
281  |   rx_tree_t     *tree; 
282  |   ip_prefix_t   *prefix;
283  | } hook_addnode_userdat_t;
284  | 
285  | /********************* P R O T O T Y P E S **********************/
286  | 
287  | 
288  | void rx_free_list_element(void *cpy, void *trash);
289  | 
290  | er_ret_t 
291  | RX_space_cre (
292  | 	      rx_regid_t reg_id,
293  | 	      ip_space_t spc_id,
294  | 	      rx_fam_t   fam_id,
295  | 	      char      *prefixstr,
296  | 	      rx_mem_mt      mem_mode,	// memory only, memory+sql, sql only
297  | 	      rx_subtree_mt  subtrees	// NONE, AUTO, HAND
298  | 	     );
299  | er_ret_t 
300  | RX_get_tree ( rx_tree_t **treeptr, 
301  | 	      rx_regid_t reg_id,
302  | 	      ip_space_t spc_id,
303  | 	      rx_fam_t   fam_id
304  | 	      );
305  | 
306  | er_ret_t
307  | rx_build_stack(rx_nodcpy_t    stack[], 
308  | 	       int            *maxdepth, 
309  | 	       rx_tree_t      *tree, 
310  | 	       ip_prefix_t    *newpref,
311  | 	       rx_stk_mt      dmode
312  | 	       );
313  | 
314  | er_ret_t
315  | rx_nod_search (
316  | 	       rx_srch_mt  search_mode,
317  | 	       int     	   par_a,
318  | 	       int         par_b,
319  | 	       /* see rx_asc_search() for explanation */
320  | 	       rx_tree_t  *tree,           // tree ptr
321  | 	       ip_prefix_t  *prefix,          // binary prefix
322  | 
323  | 	       rx_nodcpy_t stack[],         // stack==array of node_copies
324  | 	       int         stackcount,      // number of element on the stack,
325  | 	                                    // can come from a creat stack!
326  | 
327  | 	       GList	   **nodlist,	    // answers go here
328  | 	       int         max_count        // max # of answers
329  | 	       );
330  | int
331  | rx_walk_tree(rx_node_t *node, 
332  | 	     er_ret_t (*func)(rx_node_t *node, int level, int nodecounter,
333  | 			      void *userptr), 
334  | 	     rx_walk_mt walk_mode, 
335  | 	     int maxlevel, 
336  | 	     int level, 
337  | 	     int nodecounter,
338  | 	     void *userptr,
339  | 	     er_ret_t *err);
340  | 
341  | er_ret_t rx_tree_print( rx_tree_t     *tree );
342  | void rx_space_list(void);
343  | void rx_nod_print( rx_node_t *node, char *buf, int maxchar );
344  | void rx_stk_print( rx_nodcpy_t   stack[], int stackdepth );
345  | 
346  | #undef EXTDEF
347  | #endif /* _RX_H */