Source File modules/rx/rxroutines.h

    1    | /***************************************
    2    |   $Revision: 1.10 $
    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   | #include "socket.h" /*condat*/
    48   |
    49   | #include "thread.h" /*rwlock*/
    50   |
    51   | typedef int rx_regid_t;
    52   |
    53   | typedef enum {
    54   |   RX_FAM_RT = 1,
    55   |   RX_FAM_IN,
    56   |   RX_FAM_BOTH,          /*+ used only in asc_search, meaningless otherwise
    57   | 			   Relies on the fact that 1+2=3 :-) (bitmask) +*/
    58   |   RX_FAM_IP             /*+ ~RT but no data leaves between node&payload +*/
    59   | } rx_fam_t;
    60   |
    61   | /*+ the node operation modes +*/
    62   | typedef enum {
    63   |   RX_OPER_CRE = 1,
    64   |   RX_OPER_MOD,
    65   |   RX_OPER_DEL
    66   | } rx_oper_mt;
    67   |
    68   |
    69   | /*+ stack building modes +*/
    70   | typedef enum {
    71   |   RX_STK_CREAT = 1, /*+ - creation = all glue nodes, stop at first non-glue +*/
    72   |   RX_STK_QUERY_ALLNOD,   /*+ - query = all glue nodes, stop when deep enough */
    73   |   RX_STK_QUERY_NOGLUE    /*+ - query = no glue nodes, stop when deep enough */
    74   | } rx_stk_mt;
    75   |
    76   | /*+ the search modes +*/
    77   | typedef enum {
    78   |   RX_SRCH_CREAT = 1,      /*+ special search - does not skip glue nodes +*/
    79   |   RX_SRCH_EXLESS,         /*+ the default search +*/
    80   |   RX_SRCH_EXACT,
    81   |   RX_SRCH_LESS,
    82   |   RX_SRCH_MORE,           /*+ more specific search +*/
    83   |   RX_SRCH_DBLS,           /*+ special more spec: return only nodes with
    84   | 			     more than one data leaves +*/
    85   |   RX_SRCH_RANG            /*+ more specific range search, RPSL style : ^n-m +*/
    86   | } rx_srch_mt;
    87   |
    88   |
    89   | // constant to mean 'unlimited number of answers from a search'
    90   | #define RX_ANS_ALL (-1)
    91   |
    92   | #define RX_ALL_DEPTHS 255
    93   |
    94   |
    95   | /*+ radix tree's memory modes -- not yet implemented +*/
    96   | typedef enum {
    97   |   RX_MEM_RAMONLY,
    98   |   RX_MEM_RAMSQL,
    99   |   RX_MEM_SQLONLY
    100  | } rx_mem_mt;
    101  |
    102  |
    103  |
    104  | /*+ subtree modes -- not yet implemented +*/
    105  | typedef enum {
    106  |   RX_SUB_NONE,
    107  |   RX_SUB_AUTO,
    108  |   RX_SUB_HAND
    109  | } rx_subtree_mt;
    110  |
    111  | /* modes for tree traversal (walk_tree) */
    112  | typedef enum {
    113  |   RX_WALK_CNTGLU=1,  /*+ default: count also glue nodes and make the level
    114  | 			   checking aware of them +*/
    115  |
    116  |   RX_WALK_SKPGLU=2,  /*+ only real nodes counted & watched in level checks +*/
    117  |
    118  |   RX_WALK_PRFLEN=4,  /*+ make level check a check for prefix length;
    119  | 		       still only non-glue nodes are counted +*/
    120  |   RX_WALK_REVERS=8   /*+ reverse the order of traversing the tree
    121  | 		       (first link 1 then 0) +*/
    122  | } rx_walk_mt;
    123  |
    124  |
    125  | /*+  A struct for data hooked via a double linked list at a radix node.
    126  | Must uniquely define the object for lookups in the SQL tables and/or memory.
    127  | Must also contain enough info to let the delete_node choose (and remove)
    128  | the proper object from the (linked) list +*/
    129  |
    130  | typedef struct {
    131  |   ip_range_t    iprange;        /*+ for inetnums. empty for routes +*/
    132  |
    133  |   char            composed;	/*+ flag; non-zero for composed inetnums +*/
    134  |
    135  |   void           *data_ptr;	/*+ to in-memory immediate data +*/
    136  |   int             data_len;     /*+ and its length +*/
    137  |
    138  |   sql_key_t       data_key;	/*+ key to the SQL full-text data record +*/
    139  |   sql_key_t       leaf_key;     /*+ pointer to the SQL data leaf record  +*/
    140  | } rx_dataleaf_t;
    141  |
    142  | /*+
    143  | The struct for radix nodes.
    144  |
    145  | Must contain prefix, parent, left/right child links in memory and sql,
    146  | link to the sql version of the node.
    147  | And of course data: pointer to a double linked list of rx_data_t's.
    148  | +*/
    149  |
    150  | typedef struct _rx_node_str {
    151  |   ip_prefix_t     prefix;	/*+ who am i. +*/
    152  |
    153  |   char            glue;
    154  |                                 /*+ now this is an indicator for a node that it
    155  | 				   is not holding a real prefix,
    156  | 				   but is only a glue node +*/
    157  |
    158  |   GList          *leaves_ptr;	/*+ a double-linked list of rx_data_t structs
    159  |                                    the data leaves can be multiple at each node
    160  | 				   (due to a user error the inetnum ranges can
    161  | 				   overlap, due to multihoming or error routes
    162  | 				   can be duplicated ).
    163  | 				   So we link a dynamic thing here +*/
    164  |
    165  |   //  sql_key_t       leaves_key;
    166  |                                 /* "linked list" not needed in sql -
    167  | 				   the data leaves can be found in node_leaf
    168  | 				   table as those that have
    169  | 				   node_key in node_id  */
    170  |
    171  |   struct _rx_node_str
    172  |                  *parent_ptr,	/*+ radix links in memory +*/
    173  |                  *child_ptr[2];	/*+ NULL means empty +*/
    174  |
    175  |   sql_key_t       parent_key,	/*+ radix links in SQL +*/
    176  |                   child_key[2];	/*+ zero means empty +*/
    177  |
    178  |   sql_key_t       node_key;	/*+ key of the corresponding SQL radix node +*/
    179  |
    180  | } rx_node_t;
    181  |
    182  |
    183  | /*+
    184  |  rx_tree_t - defines a radix tree.
    185  |
    186  |  includes a pointer(key) to the top node,
    187  |
    188  |  names of the corresponding SQL tables
    189  |     (they can be generated automatically,
    190  |     but this is the place to store the result)
    191  |     Data_table  is for data_key.
    192  |     Radix_table is for parent_id, right_id, left_id, node_id.
    193  |     Leaves_table is for leaves_key (double linked list in SQL).
    194  |  +*/
    195  |
    196  | typedef struct _rx_tree_str {
    197  |   rx_regid_t      reg_id;	/*+ registry id +*/
    198  |   ip_space_t      space;	/*+ one of IPv4, IPv6 +*/
    199  |   rx_fam_t        family;       /*+ one of RT, IN +*/
    200  |
    201  |   rx_subtree_mt   subtrees;	/*+ one of NONE, AUTO, HAND +*/
    202  |   rx_mem_mt       mem_mode;     /*+ where the tree will sit - SQL or RAM +*/
    203  |   struct rx_tree_str
    204  |                  *parent_tree;  /*+ pointer to the parent tree +*/
    205  |
    206  |   ip_prefix_t     prefix;	/*+ of the IP space this tree covers +*/
    207  |
    208  |   int             maxbits;	/*+ max depth of this tree
    209  | 				   (depends on the space, so it is redundant)+*/
    210  |   sql_tblnam_t    data_table;
    211  |   sql_tblnam_t    radix_table;
    212  |   sql_tblnam_t    leaves_table;
    213  |
    214  |   int             num_nodes;	/*+ number of nodes in tree - for assertions +*/
    215  |
    216  |   rx_node_t      *top_ptr;	/*+ pointer to the top node +*/
    217  |   long            top_key;	/*+ the same in SQL +*/
    218  |
    219  |   rw_lock_t      rwlock;	/*+ per-tree reader/writer lock +*/
    220  |
    221  | } rx_tree_t;
    222  |
    223  |
    224  | /*+ this is a definition of a node copy used for:
    225  |
    226  |  * stack elements returned from rx_stack_build,
    227  |
    228  |  * answer elements from an rx_nod_search.
    229  |
    230  |    It *must* hold pointers to the original locations of it (in terms of
    231  |    memory and SQL) so that one could actually modify the node...
    232  |    In SQL tree mode it holds also a copy of a node.
    233  |    This seems to be unnecessary for in-memory radix trees but is a must
    234  |    for sql ones.
    235  |
    236  |    WARNING!!!!! The fact that pointers to tree and memory / SQL nodes are
    237  |    here is a subject to race condition. The location of the tree in the
    238  |    forest list and the node in memory must not change.
    239  |
    240  | +*/
    241  |
    242  | typedef struct {
    243  |   rx_tree_t   *tree;  /*+ contains registry_id, space_id, sql table names +*/
    244  |   rx_node_t *srcptr;
    245  |   sql_key_t srckey;
    246  |   rx_node_t cpy;      /*+ filled in if the tree is kept in SQL only mode +*/
    247  | } rx_nodcpy_t;
    248  |
    249  |
    250  | /*+
    251  |   This represents one data leaf (by reference). It's used for returning data
    252  | from rx_bin_search() to rx_asc_search().
    253  | +*/
    254  | typedef struct {
    255  |   sql_key_t      srckey;
    256  |   rx_dataleaf_t *leafptr;
    257  | } rx_datref_t;
    258  |
    259  |
    260  | /*+ this is a structure used for returning the data from the search.
    261  |    It contains a copy of the dataleaf and a pointer to the source +*/
    262  | typedef struct {
    263  |   sql_key_t      srckey;
    264  |   rx_dataleaf_t  leafcpy;
    265  | } rx_datcpy_t;
    266  |
    267  | /*
    268  |  * -----------------------------------------------------------------------
    269  |  *
    270  |  *       now, THIS is a scrap heap for things that MAY BE useful
    271  |  */
    272  |
    273  | /* a definite pointer to an sql object: table name + key
    274  | However, it might be nice to include the table TYPE so that one knows
    275  | what data it holds :-)
    276  |  */
    277  | typedef struct {
    278  |   sql_tblnam_t  name;
    279  |   sql_key_t     key;
    280  | } rx_sqlobj_t;
    281  |
    282  |
    283  | typedef struct {
    284  |   GList        **nodlist;
    285  |   rx_tree_t     *tree;
    286  |   ip_prefix_t   *prefix;
    287  | } hook_addnode_userdat_t;
    288  |
    289  | /********************* P R O T O T Y P E S **********************/
    290  |
    291  |
    292  | void rx_free_list_element(void *cpy, void *trash);
    293  | void RX_attach2forest(rx_tree_t *newtree);
    294  | er_ret_t
    295  | RX_tree_cre (
    296  | 	      rx_regid_t reg_id,
    297  | 	      ip_space_t spc_id,
    298  | 	      rx_fam_t   fam_id,
    299  | 	      char      *prefixstr,
    300  | 	      rx_mem_mt      mem_mode,	// memory only, memory+sql, sql only
    301  | 	      rx_subtree_mt  subtrees,	// NONE, AUTO, HAND
    302  | 	      rx_tree_t **treeptr
    303  | 	     );
    304  | er_ret_t
    305  | RX_get_tree ( rx_tree_t **treeptr,
    306  | 	      rx_regid_t reg_id,
    307  | 	      ip_space_t spc_id,
    308  | 	      rx_fam_t   fam_id
    309  | 	      );
    310  |
    311  | er_ret_t
    312  | RX_bin_search (
    313  | 	       rx_srch_mt  search_mode,
    314  | 	       int     	   par_a,
    315  | 	       int         par_b,
    316  | 	       rx_tree_t  *tree,           // tree ptr
    317  | 	       ip_prefix_t *prefix,         // binary prefix
    318  | 	       GList       **datleaves,    // data leaves go here
    319  | 	       int         max_count
    320  | 	       );
    321  | er_ret_t
    322  | RX_asc_search (
    323  | 	       rx_srch_mt search_mode,
    324  | 	       int par_a,
    325  | 	       int par_b,
    326  | 	       char *key,          /*+ search term:  prefix/range/IP +*/
    327  | 	       int   reg_id,
    328  | 	       ip_space_t spc_id,  /*+ space id, one of IPv4 IPv6. +*/
    329  | 	       rx_fam_t   fam_id,  /*+ RX_FAM_RT or RX_FAM_IN +*/
    330  | 	       GList **anslist,    /*+ answers go here, please +*/
    331  | 	       int    max_count    /*+ # of answers.  +*/
    332  | 	       );
    333  |
    334  | er_ret_t
    335  | RX_asc_node ( rx_oper_mt mode,       /*+ MODE={cre|mod|del} +*/
    336  | 	      char *rangstr,         /*+ string prefix/range/IP +*/
    337  | 	      rx_regid_t reg_id,     /*+ id of the registry +*/
    338  | 	      ip_space_t spc_id,     /*+ type of space (ipv4/ipv6) +*/
    339  | 	      rx_fam_t   fam_id,     /*+ family of objects (route/inetnum) +*/
    340  | 	      void *data             /*+ pointer to the payload +*/
    341  | 	      );
    342  | er_ret_t
    343  | RX_bin_node (
    344  | 	     rx_oper_mt   mode,       /*+ MODE={cre|mod|del} +*/
    345  | 	     ip_prefix_t *newpref,    /*+ prefix of the node +*/
    346  | 	     rx_tree_t	*tree,        /*+ pointer to the tree structure +*/
    347  | 	     rx_dataleaf_t *dataleaf  /*+ dataleaf to attach at the node +*/
    348  | 	     );
    349  |
    350  | er_ret_t
    351  | RX_inum_node( rx_oper_mt mode,       /*+ MODE={cre|mod|del} +*/
    352  | 	      ip_range_t *rang,      /*+ range of IP addresses +*/
    353  | 	      rx_tree_t *tree,       /*+ pointer to the tree structure +*/
    354  | 	      rx_dataleaf_t *leafptr /*+ dataleaf to attach at the node +*/
    355  | 	      );
    356  |
    357  | er_ret_t
    358  | rx_build_stack(rx_nodcpy_t    stack[],
    359  | 	       int            *maxdepth,
    360  | 	       rx_tree_t      *tree,
    361  | 	       ip_prefix_t    *newpref,
    362  | 	       rx_stk_mt      dmode
    363  | 	       );
    364  |
    365  | er_ret_t
    366  | rx_nod_search (
    367  | 	       rx_srch_mt  search_mode,
    368  | 	       int     	   par_a,
    369  | 	       int         par_b,
    370  | 	       /* see rx_asc_search() for explanation */
    371  | 	       rx_tree_t  *tree,           // tree ptr
    372  | 	       ip_prefix_t  *prefix,          // binary prefix
    373  |
    374  | 	       rx_nodcpy_t stack[],         // stack==array of node_copies
    375  | 	       int         stackcount,      // number of element on the stack,
    376  | 	                                    // can come from a creat stack!
    377  |
    378  | 	       GList	   **nodlist,	    // answers go here
    379  | 	       int         max_count        // max # of answers
    380  | 	       );
    381  | int
    382  | rx_walk_tree(rx_node_t *node,
    383  | 	     er_ret_t (*func)(rx_node_t *node, int level, int nodecounter,
    384  | 			      void *userptr),
    385  | 	     rx_walk_mt walk_mode,
    386  | 	     int maxlevel,
    387  | 	     int level,
    388  | 	     int nodecounter,
    389  | 	     void *userptr,
    390  | 	     er_ret_t *err);
    391  |
    392  |
    393  |
    394  | er_ret_t rx_tree_print( sk_conn_st *condat,rx_tree_t     *tree );
    395  | void rx_space_list(sk_conn_st *condat);
    396  | void rx_nod_print( rx_node_t *node, char *buf, int maxchar );
    397  | void rx_stk_print( rx_nodcpy_t   stack[], int stackdepth );
    398  |
    399  | #undef EXTDEF
    400  | #endif /* _RX_H */