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

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: 
                     75: static void
                     76: lsdb_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
                     77: {
                     78:   lp->family = 0;
                     79:   lp->prefixlen = 64;
                     80:   lp->id = lsa->data->id;
                     81:   lp->adv_router = lsa->data->adv_router;
                     82: }
                     83: 
                     84: static void
                     85: ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
                     86: {
                     87:   struct ospf_lsa *lsa = rn->info;
                     88:   
                     89:   if (!lsa)
                     90:     return;
                     91:   
                     92:   assert (rn->table == lsdb->type[lsa->data->type].db);
                     93:   
                     94:   if (IS_LSA_SELF (lsa))
                     95:     lsdb->type[lsa->data->type].count_self--;
                     96:   lsdb->type[lsa->data->type].count--;
                     97:   lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
                     98:   lsdb->total--;
                     99:   rn->info = NULL;
                    100:   route_unlock_node (rn);
                    101: #ifdef MONITOR_LSDB_CHANGE
                    102:   if (lsdb->del_lsa_hook != NULL)
                    103:     (* lsdb->del_lsa_hook)(lsa);
                    104: #endif /* MONITOR_LSDB_CHANGE */
                    105:   ospf_lsa_unlock (&lsa); /* lsdb */
                    106:   return;
                    107: }
                    108: 
                    109: /* Add new LSA to lsdb. */
                    110: void
                    111: ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
                    112: {
                    113:   struct route_table *table;
                    114:   struct prefix_ls lp;
                    115:   struct route_node *rn;
                    116: 
                    117:   table = lsdb->type[lsa->data->type].db;
                    118:   lsdb_prefix_set (&lp, lsa);
                    119:   rn = route_node_get (table, (struct prefix *)&lp);
                    120:   
                    121:   /* nothing to do? */
                    122:   if (rn->info && rn->info == lsa)
                    123:     {
                    124:       route_unlock_node (rn);
                    125:       return;
                    126:     }
                    127:   
                    128:   /* purge old entry? */
                    129:   if (rn->info)
                    130:     ospf_lsdb_delete_entry (lsdb, rn);
                    131: 
                    132:   if (IS_LSA_SELF (lsa))
                    133:     lsdb->type[lsa->data->type].count_self++;
                    134:   lsdb->type[lsa->data->type].count++;
                    135:   lsdb->total++;
                    136: 
                    137: #ifdef MONITOR_LSDB_CHANGE
                    138:   if (lsdb->new_lsa_hook != NULL)
                    139:     (* lsdb->new_lsa_hook)(lsa);
                    140: #endif /* MONITOR_LSDB_CHANGE */
                    141:   lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
                    142:   rn->info = ospf_lsa_lock (lsa); /* lsdb */
                    143: }
                    144: 
                    145: void
                    146: ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
                    147: {
                    148:   struct route_table *table;
                    149:   struct prefix_ls lp;
                    150:   struct route_node *rn;
                    151: 
                    152:   if (!lsdb)
                    153:     {
                    154:       zlog_warn ("%s: Called with NULL LSDB", __func__);
                    155:       if (lsa)
                    156:         zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
                    157:                    lsa->data->type, inet_ntoa (lsa->data->id),
                    158:                    lsa, lsa->lsdb);
                    159:       return;
                    160:     }
                    161:   
                    162:   if (!lsa)
                    163:     {
                    164:       zlog_warn ("%s: Called with NULL LSA", __func__);
                    165:       return;
                    166:     }
                    167:   
                    168:   assert (lsa->data->type < OSPF_MAX_LSA);
                    169:   table = lsdb->type[lsa->data->type].db;
                    170:   lsdb_prefix_set (&lp, lsa);
                    171:   if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
                    172:     {
                    173:       if (rn->info == lsa)
                    174:         ospf_lsdb_delete_entry (lsdb, rn);
                    175:       route_unlock_node (rn); /* route_node_lookup */
                    176:     }
                    177: }
                    178: 
                    179: void
                    180: ospf_lsdb_delete_all (struct ospf_lsdb *lsdb)
                    181: {
                    182:   struct route_table *table;
                    183:   struct route_node *rn;
                    184:   int i;
                    185: 
                    186:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                    187:     {
                    188:       table = lsdb->type[i].db;
                    189:       for (rn = route_top (table); rn; rn = route_next (rn))
                    190:        if (rn->info != NULL)
                    191:          ospf_lsdb_delete_entry (lsdb, rn);
                    192:     }
                    193: }
                    194: 
                    195: void
                    196: ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb)
                    197: {
                    198:   struct route_table *table;
                    199:   struct route_node *rn;
                    200:   struct ospf_lsa *lsa;
                    201:   int i;
                    202: 
                    203:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                    204:     {
                    205:       table = lsdb->type[i].db;
                    206:       for (rn = route_top (table); rn; rn = route_next (rn))
                    207:        if ((lsa = (rn->info)) != NULL)
                    208:          lsa->stat = LSA_SPF_NOT_EXPLORED;
                    209:     }
                    210: }
                    211: 
                    212: struct ospf_lsa *
                    213: ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
                    214: {
                    215:   struct route_table *table;
                    216:   struct prefix_ls lp;
                    217:   struct route_node *rn;
                    218:   struct ospf_lsa *find;
                    219: 
                    220:   table = lsdb->type[lsa->data->type].db;
                    221:   lsdb_prefix_set (&lp, lsa);
                    222:   rn = route_node_lookup (table, (struct prefix *) &lp);
                    223:   if (rn)
                    224:     {
                    225:       find = rn->info;
                    226:       route_unlock_node (rn);
                    227:       return find;
                    228:     }
                    229:   return NULL;
                    230: }
                    231: 
                    232: struct ospf_lsa *
                    233: ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type,
                    234:                       struct in_addr id, struct in_addr adv_router)
                    235: {
                    236:   struct route_table *table;
                    237:   struct prefix_ls lp;
                    238:   struct route_node *rn;
                    239:   struct ospf_lsa *find;
                    240: 
                    241:   table = lsdb->type[type].db;
                    242: 
                    243:   memset (&lp, 0, sizeof (struct prefix_ls));
                    244:   lp.family = 0;
                    245:   lp.prefixlen = 64;
                    246:   lp.id = id;
                    247:   lp.adv_router = adv_router;
                    248: 
                    249:   rn = route_node_lookup (table, (struct prefix *) &lp);
                    250:   if (rn)
                    251:     {
                    252:       find = rn->info;
                    253:       route_unlock_node (rn);
                    254:       return find;
                    255:     }
                    256:   return NULL;
                    257: }
                    258: 
                    259: struct ospf_lsa *
                    260: ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
                    261:                            struct in_addr id, struct in_addr adv_router,
                    262:                            int first)
                    263: {
                    264:   struct route_table *table;
                    265:   struct prefix_ls lp;
                    266:   struct route_node *rn;
                    267:   struct ospf_lsa *find;
                    268: 
                    269:   table = lsdb->type[type].db;
                    270: 
                    271:   memset (&lp, 0, sizeof (struct prefix_ls));
                    272:   lp.family = 0;
                    273:   lp.prefixlen = 64;
                    274:   lp.id = id;
                    275:   lp.adv_router = adv_router;
                    276: 
                    277:   if (first)
                    278:       rn = route_top (table);
                    279:   else
                    280:     {
                    281:       if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
                    282:         return NULL;
                    283:       rn = route_next (rn);
                    284:     }
                    285: 
                    286:   for (; rn; rn = route_next (rn))
                    287:     if (rn->info)
                    288:       break;
                    289: 
                    290:   if (rn && rn->info)
                    291:     {
                    292:       find = rn->info;
                    293:       route_unlock_node (rn);
                    294:       return find;
                    295:     }
                    296:   return NULL;
                    297: }
                    298: 
                    299: unsigned long
                    300: ospf_lsdb_count_all (struct ospf_lsdb *lsdb)
                    301: {
                    302:   return lsdb->total;
                    303: }
                    304: 
                    305: unsigned long
                    306: ospf_lsdb_count (struct ospf_lsdb *lsdb, int type)
                    307: {
                    308:   return lsdb->type[type].count;
                    309: }
                    310: 
                    311: unsigned long
                    312: ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type)
                    313: {
                    314:   return lsdb->type[type].count_self;
                    315: }
                    316: 
                    317: unsigned int
                    318: ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type)
                    319: {
                    320:   return lsdb->type[type].checksum;
                    321: }
                    322: 
                    323: unsigned long
                    324: ospf_lsdb_isempty (struct ospf_lsdb *lsdb)
                    325: {
                    326:   return (lsdb->total == 0);
                    327: }

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