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 |