/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- RP_tree_get
- RP_tree_add
- RP_tree_del
- rp_init_attr_tree
- RP_init_trees
1 /***************************************
2 $Revision: 1.9 $
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,2000,2001,2002 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 "rip.h"
35
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 +*/
/* [<][>][^][v][top][bottom][index][help] */
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;
54 rp_tentry_t *trdef;
55 /* lock the forest */
56 TH_acquire_read_lockw(&rx_forest_rwlock);
57 elem = g_list_first(rx_forest);
58
59 while( elem != NULL ) {
60 trdef = elem->data;
61
62
63 if( trdef->reg_id == reg_id
64 && trdef->attr == attr
65 && trdef->tree->space == spc_id ) {
66 /* copy the value to user's data */
67 *treeptr = trdef->tree;
68 ER_dbg_va(FAC_RP, ASP_RP_TREE_DET,
69 "tree found at %08x -> %08x",trdef, trdef->tree);
70 return RP_OK;
71 }
72 elem = g_list_next(elem);
73 }
74
75 *treeptr = NULL; /* set when NOT FOUND*/
76 TH_release_read_lockw(&rx_forest_rwlock);
77 /* pthread_mutex_unlock(&rx_forest_mx);*/
78 return RP_NOTREE;
79 }
80
81
82
83 /*++++++++++++++++++++++++++++++++
84 put into LL of trees; handle alloc err ???
85
86 since other threads are supposed to be reading already,
87 must create the tree locked and observe the forest mutex.
88 ++++++++++++++++++++*/
89 er_ret_t
90 RP_tree_add (
/* [<][>][^][v][top][bottom][index][help] */
91 rp_regid_t reg_id, /*+ id of the registry +*/
92 rp_attr_t attr, /*+ extra tree id (within the same registry/space/family +*/
93 char *prefixstr, /*+ prefix the tree will cover (string) +*/
94 rx_mem_mt mem_mode, /* memory only, memory+sql, sql only +*/
95 rx_subtree_mt subtrees /*+ one of NONE, AUTO, HAND +*/
96 )
97 {
98 er_ret_t err;
99 rp_tentry_t *treedef;
100 rx_tree_t *mytree;
101 rx_tree_t *existree;
102 rx_fam_t fam_id = RP_attr2fam( attr );
103
104 if( (err = RX_tree_cre(prefixstr, fam_id, mem_mode, subtrees, &mytree)) == RX_OK) {
105
106 /* OK, see if there is a tree for this space already */
107 if( RP_tree_get(&existree, reg_id, mytree->space, attr) == RP_OK ) {
108 /* In this case we need to delete and re-initialize it */
109 /* lock the tree for writing and leave it in the locked state for loading */
110 TH_acquire_write_lockw(&existree->rwlock);
111
112 if( (err = RP_tree_del(existree)) == RP_OK){
113 /* Initialize the tree */
114 existree->num_nodes=0;
115 }
116 /* free the newly created tree */
117 UT_free(mytree);
118 return err;
119 }
120
121 treedef = (rp_tentry_t *)UT_malloc(sizeof(rp_tentry_t));
122
123 treedef -> reg_id = reg_id;
124 treedef -> attr = attr;
125 treedef -> tree = mytree;
126
127 /* add the tree to the forest in locked state */
128 TH_acquire_write_lockw( &(mytree->rwlock) );
129
130 /* Lock the forest */
131 TH_acquire_write_lockw(&rx_forest_rwlock);
132 rx_forest = g_list_append (rx_forest, treedef);
133 TH_release_write_lockw(&rx_forest_rwlock);
134 }
135
136 return err;
137 }
138
139 /*++++++++++++++
140 finds a tree and deletes its contents
141 the tree itself is not deleted !
142
143 Returns: RX_OK or RX_NOTREE if no such tree can be found.
144 +++++++++++*/
145
146 er_ret_t
147 RP_tree_del ( rx_tree_t *tree )
/* [<][>][^][v][top][bottom][index][help] */
148 {
149 int cnt;
150
151 if( tree->top_ptr != NULL ) {
152 cnt = rx_delete_tree(tree, tree->top_ptr, 255, 0, 0, NULL);
153 ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN,
154 "tree at %08x: %d nodes deleted", tree, cnt);
155 if (cnt != tree->num_nodes){
156 ER_perror(FAC_RP, RP_NOYETI,
157 "tree at %p: %d nodes deleted, should be %d", tree, cnt, tree->num_nodes);
158 return RP_NOYETI;
159 }
160 }
161 return RP_OK;
162 }
163
164
165 er_ret_t
166 rp_init_attr_tree( rp_regid_t reg_id, rp_attr_t attr)
/* [<][>][^][v][top][bottom][index][help] */
167 {
168 er_ret_t err;
169
170 err = RP_OK;
171
172 /* Some (DN) attributes are related to two trees */
173 if( RP_attr2spc(attr, IP_V4) ) {
174 err=RP_tree_add(reg_id, attr, "0.0.0.0/0",
175 RX_MEM_RAMONLY, RX_SUB_NONE);
176 }
177
178 if( RP_attr2spc(attr, IP_V6) ) {
179 err=RP_tree_add(reg_id, attr, "0::/0",
180 RX_MEM_RAMONLY, RX_SUB_NONE);
181 }
182
183 return err;
184 }
185 /***************************************************************************/
186
187 er_ret_t
188 RP_init_trees( rp_regid_t reg_id )
/* [<][>][^][v][top][bottom][index][help] */
189 {
190 er_ret_t err;
191
192 if( NOERR(err=rp_init_attr_tree(reg_id, A_IN))
193 && NOERR(err=rp_init_attr_tree(reg_id, A_RT))
194 && NOERR(err=rp_init_attr_tree(reg_id, A_I6))
195 && NOERR(err=rp_init_attr_tree(reg_id, A_DN)) ) {
196 return RP_OK;
197 }
198
199 return err;
200 }
201
202
203
204