## modules/rp/rp_tree.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. RP_tree_get
2. RP_tree_add
3. rp_init_attr_tree
4. RP_init_trees

       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 +*/
         /* [<][>][^][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 = 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 (
         /* [<][>][^][v][top][bottom][index][help] */
      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)
         /* [<][>][^][v][top][bottom][index][help] */
     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 )
         /* [<][>][^][v][top][bottom][index][help] */
     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

/* [<][>][^][v][top][bottom][index][help] */