Annotation of embedaddon/quagga/ospfd/ospf_lsdb.c, revision 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>