File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_lsdb.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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: void
   76: ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
   77: {
   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:     }
   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;
  121:   ls_prefix_set (&lp, lsa);
  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:                    (void *)lsa, (void *)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;
  173:   ls_prefix_set (&lp, lsa);
  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;
  224:   ls_prefix_set (&lp, lsa);
  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>