File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_lsdb.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

    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>