Annotation of embedaddon/quagga/ospfd/ospf_lsdb.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * OSPF LSDB support.
                      3:  * Copyright (C) 1999, 2000 Alex Zinin, Kunihiro Ishiguro, Toshiaki Takada
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2, or (at your option) any
                     10:  * later version.
                     11:  *
                     12:  * GNU Zebra is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     20:  * 02111-1307, USA.
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "prefix.h"
                     26: #include "table.h"
                     27: #include "memory.h"
                     28: #include "log.h"
                     29: 
                     30: #include "ospfd/ospfd.h"
                     31: #include "ospfd/ospf_asbr.h"
                     32: #include "ospfd/ospf_lsa.h"
                     33: #include "ospfd/ospf_lsdb.h"
                     34: 
                     35: struct ospf_lsdb *
                     36: ospf_lsdb_new ()
                     37: {
                     38:   struct ospf_lsdb *new;
                     39: 
                     40:   new = XCALLOC (MTYPE_OSPF_LSDB, sizeof (struct ospf_lsdb));
                     41:   ospf_lsdb_init (new);
                     42: 
                     43:   return new;
                     44: }
                     45: 
                     46: void
                     47: ospf_lsdb_init (struct ospf_lsdb *lsdb)
                     48: {
                     49:   int i;
                     50:   
                     51:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                     52:     lsdb->type[i].db = route_table_init ();
                     53: }
                     54: 
                     55: void
                     56: ospf_lsdb_free (struct ospf_lsdb *lsdb)
                     57: {
                     58:   ospf_lsdb_cleanup (lsdb);
                     59:   XFREE (MTYPE_OSPF_LSDB, lsdb);
                     60: }
                     61: 
                     62: void
                     63: ospf_lsdb_cleanup (struct ospf_lsdb *lsdb)
                     64: {
                     65:   int i;
                     66:   assert (lsdb);
                     67:   assert (lsdb->total == 0);
                     68: 
                     69:   ospf_lsdb_delete_all (lsdb);
                     70:   
                     71:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                     72:     route_table_finish (lsdb->type[i].db);
                     73: }
                     74: 
1.1.1.2 ! misho      75: void
        !            76: ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
1.1       misho      77: {
1.1.1.2 ! misho      78:   if (lp && lsa && lsa->data)
        !            79:     {
        !            80:       lp->family = 0;
        !            81:       lp->prefixlen = 64;
        !            82:       lp->id = lsa->data->id;
        !            83:       lp->adv_router = lsa->data->adv_router;
        !            84:     }
1.1       misho      85: }
                     86: 
                     87: static void
                     88: ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
                     89: {
                     90:   struct ospf_lsa *lsa = rn->info;
                     91:   
                     92:   if (!lsa)
                     93:     return;
                     94:   
                     95:   assert (rn->table == lsdb->type[lsa->data->type].db);
                     96:   
                     97:   if (IS_LSA_SELF (lsa))
                     98:     lsdb->type[lsa->data->type].count_self--;
                     99:   lsdb->type[lsa->data->type].count--;
                    100:   lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
                    101:   lsdb->total--;
                    102:   rn->info = NULL;
                    103:   route_unlock_node (rn);
                    104: #ifdef MONITOR_LSDB_CHANGE
                    105:   if (lsdb->del_lsa_hook != NULL)
                    106:     (* lsdb->del_lsa_hook)(lsa);
                    107: #endif /* MONITOR_LSDB_CHANGE */
                    108:   ospf_lsa_unlock (&lsa); /* lsdb */
                    109:   return;
                    110: }
                    111: 
                    112: /* Add new LSA to lsdb. */
                    113: void
                    114: ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
                    115: {
                    116:   struct route_table *table;
                    117:   struct prefix_ls lp;
                    118:   struct route_node *rn;
                    119: 
                    120:   table = lsdb->type[lsa->data->type].db;
1.1.1.2 ! misho     121:   ls_prefix_set (&lp, lsa);
1.1       misho     122:   rn = route_node_get (table, (struct prefix *)&lp);
                    123:   
                    124:   /* nothing to do? */
                    125:   if (rn->info && rn->info == lsa)
                    126:     {
                    127:       route_unlock_node (rn);
                    128:       return;
                    129:     }
                    130:   
                    131:   /* purge old entry? */
                    132:   if (rn->info)
                    133:     ospf_lsdb_delete_entry (lsdb, rn);
                    134: 
                    135:   if (IS_LSA_SELF (lsa))
                    136:     lsdb->type[lsa->data->type].count_self++;
                    137:   lsdb->type[lsa->data->type].count++;
                    138:   lsdb->total++;
                    139: 
                    140: #ifdef MONITOR_LSDB_CHANGE
                    141:   if (lsdb->new_lsa_hook != NULL)
                    142:     (* lsdb->new_lsa_hook)(lsa);
                    143: #endif /* MONITOR_LSDB_CHANGE */
                    144:   lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
                    145:   rn->info = ospf_lsa_lock (lsa); /* lsdb */
                    146: }
                    147: 
                    148: void
                    149: ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
                    150: {
                    151:   struct route_table *table;
                    152:   struct prefix_ls lp;
                    153:   struct route_node *rn;
                    154: 
                    155:   if (!lsdb)
                    156:     {
                    157:       zlog_warn ("%s: Called with NULL LSDB", __func__);
                    158:       if (lsa)
                    159:         zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
                    160:                    lsa->data->type, inet_ntoa (lsa->data->id),
                    161:                    lsa, lsa->lsdb);
                    162:       return;
                    163:     }
                    164:   
                    165:   if (!lsa)
                    166:     {
                    167:       zlog_warn ("%s: Called with NULL LSA", __func__);
                    168:       return;
                    169:     }
                    170:   
                    171:   assert (lsa->data->type < OSPF_MAX_LSA);
                    172:   table = lsdb->type[lsa->data->type].db;
1.1.1.2 ! misho     173:   ls_prefix_set (&lp, lsa);
1.1       misho     174:   if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
                    175:     {
                    176:       if (rn->info == lsa)
                    177:         ospf_lsdb_delete_entry (lsdb, rn);
                    178:       route_unlock_node (rn); /* route_node_lookup */
                    179:     }
                    180: }
                    181: 
                    182: void
                    183: ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
                    184: {
                    185:   struct route_table *table;
                    186:   struct route_node *rn;
                    187:   int i;
                    188: 
                    189:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                    190:     {
                    191:       table = lsdb->type[i].db;
                    192:       for (rn = route_top (table); rn; rn = route_next (rn))
                    193:        if (rn->info != NULL)
                    194:          ospf_lsdb_delete_entry (lsdb, rn);
                    195:     }
                    196: }
                    197: 
                    198: void
                    199: ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
                    200: {
                    201:   struct route_table *table;
                    202:   struct route_node *rn;
                    203:   struct ospf_lsa *lsa;
                    204:   int i;
                    205: 
                    206:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                    207:     {
                    208:       table = lsdb->type[i].db;
                    209:       for (rn = route_top (table); rn; rn = route_next (rn))
                    210:        if ((lsa = (rn->info)) != NULL)
                    211:          lsa->stat = LSA_SPF_NOT_EXPLORED;
                    212:     }
                    213: }
                    214: 
                    215: struct ospf_lsa *
                    216: ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
                    217: {
                    218:   struct route_table *table;
                    219:   struct prefix_ls lp;
                    220:   struct route_node *rn;
                    221:   struct ospf_lsa *find;
                    222: 
                    223:   table = lsdb->type[lsa->data->type].db;
1.1.1.2 ! misho     224:   ls_prefix_set (&lp, lsa);
1.1       misho     225:   rn = route_node_lookup (table, (struct prefix *) &lp);
                    226:   if (rn)
                    227:     {
                    228:       find = rn->info;
                    229:       route_unlock_node (rn);
                    230:       return find;
                    231:     }
                    232:   return NULL;
                    233: }
                    234: 
                    235: struct ospf_lsa *
                    236: ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
                    237:                       struct in_addr id, struct in_addr adv_router)
                    238: {
                    239:   struct route_table *table;
                    240:   struct prefix_ls lp;
                    241:   struct route_node *rn;
                    242:   struct ospf_lsa *find;
                    243: 
                    244:   table = lsdb->type[type].db;
                    245: 
                    246:   memset (&lp, 0, sizeof (struct prefix_ls));
                    247:   lp.family = 0;
                    248:   lp.prefixlen = 64;
                    249:   lp.id = id;
                    250:   lp.adv_router = adv_router;
                    251: 
                    252:   rn = route_node_lookup (table, (struct prefix *) &lp);
                    253:   if (rn)
                    254:     {
                    255:       find = rn->info;
                    256:       route_unlock_node (rn);
                    257:       return find;
                    258:     }
                    259:   return NULL;
                    260: }
                    261: 
                    262: struct ospf_lsa *
                    263: ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
                    264:                            struct in_addr id, struct in_addr adv_router,
                    265:                            int first)
                    266: {
                    267:   struct route_table *table;
                    268:   struct prefix_ls lp;
                    269:   struct route_node *rn;
                    270:   struct ospf_lsa *find;
                    271: 
                    272:   table = lsdb->type[type].db;
                    273: 
                    274:   memset (&lp, 0, sizeof (struct prefix_ls));
                    275:   lp.family = 0;
                    276:   lp.prefixlen = 64;
                    277:   lp.id = id;
                    278:   lp.adv_router = adv_router;
                    279: 
                    280:   if (first)
                    281:       rn = route_top (table);
                    282:   else
                    283:     {
                    284:       if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
                    285:         return NULL;
                    286:       rn = route_next (rn);
                    287:     }
                    288: 
                    289:   for (; rn; rn = route_next (rn))
                    290:     if (rn->info)
                    291:       break;
                    292: 
                    293:   if (rn && rn->info)
                    294:     {
                    295:       find = rn->info;
                    296:       route_unlock_node (rn);
                    297:       return find;
                    298:     }
                    299:   return NULL;
                    300: }
                    301: 
                    302: unsigned long
                    303: ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
                    304: {
                    305:   return lsdb->total;
                    306: }
                    307: 
                    308: unsigned long
                    309: ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
                    310: {
                    311:   return lsdb->type[type].count;
                    312: }
                    313: 
                    314: unsigned long
                    315: ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
                    316: {
                    317:   return lsdb->type[type].count_self;
                    318: }
                    319: 
                    320: unsigned int
                    321: ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
                    322: {
                    323:   return lsdb->type[type].checksum;
                    324: }
                    325: 
                    326: unsigned long
                    327: ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
                    328: {
                    329:   return (lsdb->total == 0);
                    330: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>