1    | /***************************************
2    |   $Revision: 1.6 $
3    | 
4    |   Radix payload (rp) - user level functions for storing data in radix trees
5    | 
6    |   rp_load = user level tree maintenance (knows about registries and attributes)
7    | 
8    |   Status: NOT REVIEWED, TESTED
9    |   
10   |   Design and implementation by: Marek Bukowy
11   |   
12   |   ******************/ /******************
13   |   Copyright (c) 1999                              RIPE NCC
14   |  
15   |   All Rights Reserved
16   |   
17   |   Permission to use, copy, modify, and distribute this software and its
18   |   documentation for any purpose and without fee is hereby granted,
19   |   provided that the above copyright notice appear in all copies and that
20   |   both that copyright notice and this permission notice appear in
21   |   supporting documentation, and that the name of the author not be
22   |   used in advertising or publicity pertaining to distribution of the
23   |   software without specific, written prior permission.
24   |   
25   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
26   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
27   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
28   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
29   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31   |   ***************************************/
32   | 
33   | #define RP_IMPL
34   | #include <rp.h>
35   | #include <rxroutines.h>
36   | /***************************************************************************/
37   | /*++++++++++++++
38   |   finds a tree matching the specified criteria(registry+space+family+tid).
39   | 
40   |   MT-note: locks/unlocks forest (still to be done)
41   | 
42   |   Returns: RX_OK or RX_NOTREE if no such tree can be found.
43   | +++++++++++*/
44   | 
45   | er_ret_t 
46   | RP_tree_get ( rx_tree_t **treeptr, /*+ answer goes here, please +*/
47   | 	      rp_regid_t reg_id,   /*+ id of the registry +*/
48   | 	      ip_space_t spc_id,   /*+ type of space (ipv4/ipv6) +*/
49   | 	      rp_attr_t  attr    /*+ extra tree id (within the same reg/spc/fam +*/
50   | 	      )
51   |      
52   | {
53   |   GList *elem = g_list_first(rx_forest);
54   |   rp_tentry_t  *trdef;
55   |   
56   |   while( elem != NULL ) {
57   |     trdef = elem->data;
58   |     
59   |     
60   |     if(    trdef->reg_id == reg_id   
61   | 	&& trdef->attr == attr 
62   | 	&& trdef->tree->space == spc_id ) {
63   |       /* copy the value to user's data */
64   |       *treeptr = trdef->tree;
65   |       ER_dbg_va(FAC_RP, ASP_RP_TREE_DET, 
66   | 		"tree found at %08x -> %08x",trdef, trdef->tree);
67   | 
68   |       return RP_OK;
69   |     }
70   |     elem = g_list_next(elem);
71   |   }
72   |   
73   |   *treeptr = NULL; /* set when NOT FOUND*/
74   |   return RP_NOTREE; 
75   | }
76   | 
77   | 
78   | 
79   | /*++++++++++++++++++++++++++++++++
80   |        put into LL of trees; handle alloc err ??? 
81   | 
82   |        since other threads are supposed to be reading already, 
83   |        must create the tree locked and observe the forest mutex.
84   |        ++++++++++++++++++++*/
85   | er_ret_t 
86   | RP_tree_add (
87   | 	     rp_regid_t reg_id,    /*+ id of the registry +*/
88   | 	     rp_attr_t  attr,      /*+ extra tree id (within the same registry/space/family +*/
89   | 	     char      *prefixstr, /*+ prefix the tree will cover (string) +*/
90   | 	     rx_mem_mt   mem_mode, /* memory only, memory+sql, sql only +*/
91   | 	     rx_subtree_mt subtrees	/*+ one of NONE, AUTO, HAND +*/
92   | 	     )
93   | {
94   |   er_ret_t     err;
95   |   rp_tentry_t *treedef;
96   |   rx_tree_t   *mytree;
97   |   rx_tree_t   *existree;
98   |   rx_fam_t   fam_id = RP_attr2fam( attr );
99   | 
100  |   if( (err = RX_tree_cre(prefixstr, fam_id, mem_mode, subtrees, &mytree)) == RX_OK) {
101  | 
102  |     /* OK, see if there is a tree for this space already */
103  |     if( RP_tree_get(&existree, reg_id, mytree->space, attr) == RP_OK ) {
104  |       /* oops, it exists  */
105  |       
106  |       wr_free(&mytree);
107  | 
108  |       return RP_TRALEX;      
109  |     }
110  | 
111  |     dieif(wr_malloc((void **) &treedef, sizeof(rp_tentry_t)) != UT_OK);
112  |     
113  |     treedef -> reg_id = reg_id;
114  |     treedef -> attr   = attr;
115  |     treedef -> tree   = mytree;
116  | 
117  |     /* add the tree to the forest in locked state */
118  |     TH_acquire_write_lock( &(mytree->rwlock) );
119  | 
120  |     /* XXX TBD forest mutex!! */
121  |     rx_forest = g_list_append (rx_forest, treedef);
122  |   }
123  |   
124  |   return err;
125  | }
126  | 
127  | er_ret_t 
128  | rp_init_attr_tree( rp_regid_t reg_id, rp_attr_t attr)
129  | {
130  |   er_ret_t err;
131  |   
132  |   /* Some (DN) attributes are related to two trees */
133  |   if( RP_attr2spc(attr, IP_V4) ) {
134  |     err=RP_tree_add(reg_id, attr, "0.0.0.0/0",
135  | 		    RX_MEM_RAMONLY, RX_SUB_NONE);
136  |   }
137  |   
138  |   if( RP_attr2spc(attr, IP_V6) ) {
139  |    err=RP_tree_add(reg_id, attr, "0::/0",
140  | 		   RX_MEM_RAMONLY, RX_SUB_NONE);
141  |   }
142  |   
143  |   return err;
144  | }
145  | /***************************************************************************/
146  | 
147  | 
148  | er_ret_t 
149  | RP_init_trees( rp_regid_t reg_id )
150  | {
151  |   er_ret_t err;
152  |   
153  |   if(    NOERR(err=rp_init_attr_tree(reg_id, A_IN))
154  |       && NOERR(err=rp_init_attr_tree(reg_id, A_RT))
155  |       && NOERR(err=rp_init_attr_tree(reg_id, A_I6))
156  |       && NOERR(err=rp_init_attr_tree(reg_id, A_DN)) ) {
157  |     return RP_OK;
158  |   }
159  |   
160  |   return err;
161  | }
162  |