Annotation of embedaddon/quagga/ospf6d/ospf6_lsdb.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2003 Yasuhiro Ohara
                      3:  *
                      4:  * This file is part of GNU Zebra.
                      5:  *
                      6:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2, or (at your option) any
                      9:  * later version.
                     10:  *
                     11:  * GNU Zebra is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
                     18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
                     19:  * Boston, MA 02111-1307, USA.  
                     20:  */
                     21: 
                     22: #include <zebra.h>
                     23: 
                     24: #include "memory.h"
                     25: #include "log.h"
                     26: #include "command.h"
                     27: #include "prefix.h"
                     28: #include "table.h"
                     29: #include "vty.h"
                     30: 
                     31: #include "ospf6_proto.h"
                     32: #include "ospf6_lsa.h"
                     33: #include "ospf6_lsdb.h"
                     34: #include "ospf6d.h"
                     35: 
                     36: struct ospf6_lsdb *
                     37: ospf6_lsdb_create (void *data)
                     38: {
                     39:   struct ospf6_lsdb *lsdb;
                     40: 
                     41:   lsdb = XCALLOC (MTYPE_OSPF6_LSDB, sizeof (struct ospf6_lsdb));
                     42:   if (lsdb == NULL)
                     43:     {
                     44:       zlog_warn ("Can't malloc lsdb");
                     45:       return NULL;
                     46:     }
                     47:   memset (lsdb, 0, sizeof (struct ospf6_lsdb));
                     48: 
                     49:   lsdb->data = data;
                     50:   lsdb->table = route_table_init ();
                     51:   return lsdb;
                     52: }
                     53: 
                     54: void
                     55: ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
                     56: {
                     57:   ospf6_lsdb_remove_all (lsdb);
                     58:   route_table_finish (lsdb->table);
                     59:   XFREE (MTYPE_OSPF6_LSDB, lsdb);
                     60: }
                     61: 
                     62: static void
                     63: ospf6_lsdb_set_key (struct prefix_ipv6 *key, void *value, int len)
                     64: {
                     65:   assert (key->prefixlen % 8 == 0);
                     66: 
                     67:   memcpy ((caddr_t) &key->prefix + key->prefixlen / 8,
                     68:           (caddr_t) value, len);
                     69:   key->family = AF_INET6;
                     70:   key->prefixlen += len * 8;
                     71: }
                     72: 
                     73: #ifndef NDEBUG
                     74: static void
                     75: _lsdb_count_assert (struct ospf6_lsdb *lsdb)
                     76: {
                     77:   struct ospf6_lsa *debug;
                     78:   unsigned int num = 0;
                     79:   for (debug = ospf6_lsdb_head (lsdb); debug;
                     80:        debug = ospf6_lsdb_next (debug))
                     81:     num++;
                     82: 
                     83:   if (num == lsdb->count)
                     84:     return;
                     85: 
                     86:   zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d",
                     87:              lsdb, lsdb->count, num);
                     88:   for (debug = ospf6_lsdb_head (lsdb); debug;
                     89:        debug = ospf6_lsdb_next (debug))
                     90:     zlog_debug ("%p %p %s lsdb[%p]", debug->prev, debug->next, debug->name,
                     91:                debug->lsdb);
                     92:   zlog_debug ("DUMP END");
                     93: 
                     94:   assert (num == lsdb->count);
                     95: }
                     96: #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
                     97: #else /*NDEBUG*/
                     98: #define ospf6_lsdb_count_assert(t) ((void) 0)
                     99: #endif /*NDEBUG*/
                    100: 
                    101: void
                    102: ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
                    103: {
                    104:   struct prefix_ipv6 key;
                    105:   struct route_node *current, *nextnode, *prevnode;
                    106:   struct ospf6_lsa *next, *prev, *old = NULL;
                    107: 
                    108:   memset (&key, 0, sizeof (key));
                    109:   ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
                    110:   ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
                    111:                       sizeof (lsa->header->adv_router));
                    112:   ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
                    113: 
                    114:   current = route_node_get (lsdb->table, (struct prefix *) &key);
                    115:   old = current->info;
                    116:   current->info = lsa;
                    117:   ospf6_lsa_lock (lsa);
                    118: 
                    119:   if (old)
                    120:     {
                    121:       if (old->prev)
                    122:         old->prev->next = lsa;
                    123:       if (old->next)
                    124:         old->next->prev = lsa;
                    125:       lsa->next = old->next;
                    126:       lsa->prev = old->prev;
                    127:     }
                    128:   else
                    129:     {
                    130:       /* next link */
                    131:       nextnode = current;
                    132:       route_lock_node (nextnode);
                    133:       do {
                    134:         nextnode = route_next (nextnode);
                    135:       } while (nextnode && nextnode->info == NULL);
                    136:       if (nextnode == NULL)
                    137:         lsa->next = NULL;
                    138:       else
                    139:         {
                    140:           next = nextnode->info;
                    141:           lsa->next = next;
                    142:           next->prev = lsa;
                    143:           route_unlock_node (nextnode);
                    144:         }
                    145: 
                    146:       /* prev link */
                    147:       prevnode = current;
                    148:       route_lock_node (prevnode);
                    149:       do {
                    150:         prevnode = route_prev (prevnode);
                    151:       } while (prevnode && prevnode->info == NULL);
                    152:       if (prevnode == NULL)
                    153:         lsa->prev = NULL;
                    154:       else
                    155:         {
                    156:           prev = prevnode->info;
                    157:           lsa->prev = prev;
                    158:           prev->next = lsa;
                    159:           route_unlock_node (prevnode);
                    160:         }
                    161: 
                    162:       lsdb->count++;
                    163:     }
                    164: 
                    165:   if (old)
                    166:     {
                    167:       if (OSPF6_LSA_IS_CHANGED (old, lsa))
                    168:         {
                    169:           if (OSPF6_LSA_IS_MAXAGE (lsa))
                    170:             {
                    171:               if (lsdb->hook_remove)
                    172:                 {
                    173:                   (*lsdb->hook_remove) (old);
                    174:                   (*lsdb->hook_remove) (lsa);
                    175:                 }
                    176:             }
                    177:           else if (OSPF6_LSA_IS_MAXAGE (old))
                    178:             {
                    179:               if (lsdb->hook_add)
                    180:                 (*lsdb->hook_add) (lsa);
                    181:             }
                    182:           else
                    183:             {
                    184:               if (lsdb->hook_remove)
                    185:                 (*lsdb->hook_remove) (old);
                    186:               if (lsdb->hook_add)
                    187:                 (*lsdb->hook_add) (lsa);
                    188:             }
                    189:         }
                    190:     }
                    191:   else if (OSPF6_LSA_IS_MAXAGE (lsa))
                    192:     {
                    193:       if (lsdb->hook_remove)
                    194:         (*lsdb->hook_remove) (lsa);
                    195:     }
                    196:   else
                    197:     {
                    198:       if (lsdb->hook_add)
                    199:         (*lsdb->hook_add) (lsa);
                    200:     }
                    201: 
                    202:   if (old)
                    203:     ospf6_lsa_unlock (old);
                    204: 
                    205:   ospf6_lsdb_count_assert (lsdb);
                    206: }
                    207: 
                    208: void
                    209: ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
                    210: {
                    211:   struct route_node *node;
                    212:   struct prefix_ipv6 key;
                    213: 
                    214:   memset (&key, 0, sizeof (key));
                    215:   ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
                    216:   ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
                    217:                       sizeof (lsa->header->adv_router));
                    218:   ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
                    219: 
                    220:   node = route_node_lookup (lsdb->table, (struct prefix *) &key);
                    221:   assert (node && node->info == lsa);
                    222: 
                    223:   if (lsa->prev)
                    224:     lsa->prev->next = lsa->next;
                    225:   if (lsa->next)
                    226:     lsa->next->prev = lsa->prev;
                    227: 
                    228:   node->info = NULL;
                    229:   lsdb->count--;
                    230: 
                    231:   if (lsdb->hook_remove)
                    232:     (*lsdb->hook_remove) (lsa);
                    233: 
                    234:   ospf6_lsa_unlock (lsa);
                    235:   route_unlock_node (node);
                    236: 
                    237:   ospf6_lsdb_count_assert (lsdb);
                    238: }
                    239: 
                    240: struct ospf6_lsa *
                    241: ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
                    242:                    struct ospf6_lsdb *lsdb)
                    243: {
                    244:   struct route_node *node;
                    245:   struct prefix_ipv6 key;
                    246: 
                    247:   if (lsdb == NULL)
                    248:     return NULL;
                    249: 
                    250:   memset (&key, 0, sizeof (key));
                    251:   ospf6_lsdb_set_key (&key, &type, sizeof (type));
                    252:   ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
                    253:   ospf6_lsdb_set_key (&key, &id, sizeof (id));
                    254: 
                    255:   node = route_node_lookup (lsdb->table, (struct prefix *) &key);
                    256:   if (node == NULL || node->info == NULL)
                    257:     return NULL;
                    258:   return (struct ospf6_lsa *) node->info;
                    259: }
                    260: 
                    261: struct ospf6_lsa *
                    262: ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
                    263:                         struct ospf6_lsdb *lsdb)
                    264: {
                    265:   struct route_node *node;
                    266:   struct route_node *matched = NULL;
                    267:   struct prefix_ipv6 key;
                    268:   struct prefix *p;
                    269: 
                    270:   if (lsdb == NULL)
                    271:     return NULL;
                    272: 
                    273:   memset (&key, 0, sizeof (key));
                    274:   ospf6_lsdb_set_key (&key, &type, sizeof (type));
                    275:   ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
                    276:   ospf6_lsdb_set_key (&key, &id, sizeof (id));
                    277:   p = (struct prefix *) &key;
                    278: 
                    279:   {
                    280:     char buf[64];
                    281:     prefix2str (p, buf, sizeof (buf));
                    282:     zlog_debug ("lsdb_lookup_next: key: %s", buf);
                    283:   }
                    284: 
                    285:   node = lsdb->table->top;
                    286:   /* walk down tree. */
                    287:   while (node && node->p.prefixlen <= p->prefixlen &&
                    288:          prefix_match (&node->p, p))
                    289:     {
                    290:       matched = node;
                    291:       node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
                    292:     }
                    293: 
                    294:   if (matched)
                    295:     node = matched;
                    296:   else
                    297:     node = lsdb->table->top;
                    298:   route_lock_node (node);
                    299: 
                    300:   /* skip to real existing entry */
                    301:   while (node && node->info == NULL)
                    302:     node = route_next (node);
                    303: 
                    304:   if (! node)
                    305:     return NULL;
                    306: 
                    307:   if (prefix_same (&node->p, p))
                    308:     {
                    309:       struct route_node *prev = node;
                    310:       struct ospf6_lsa *lsa_prev;
                    311:       struct ospf6_lsa *lsa_next;
                    312: 
                    313:       node = route_next (node);
                    314:       while (node && node->info == NULL)
                    315:         node = route_next (node);
                    316: 
                    317:       lsa_prev = prev->info;
                    318:       lsa_next = (node ? node->info : NULL);
                    319:       assert (lsa_prev);
                    320:       assert (lsa_prev->next == lsa_next);
                    321:       if (lsa_next)
                    322:         assert (lsa_next->prev == lsa_prev);
                    323:       zlog_debug ("lsdb_lookup_next: assert OK with previous LSA");
                    324:     }
                    325: 
                    326:   if (! node)
                    327:     return NULL;
                    328: 
                    329:   route_unlock_node (node);
                    330:   return (struct ospf6_lsa *) node->info;
                    331: }
                    332: 
                    333: /* Iteration function */
                    334: struct ospf6_lsa *
                    335: ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
                    336: {
                    337:   struct route_node *node;
                    338: 
                    339:   node = route_top (lsdb->table);
                    340:   if (node == NULL)
                    341:     return NULL;
                    342: 
                    343:   /* skip to the existing lsdb entry */
                    344:   while (node && node->info == NULL)
                    345:     node = route_next (node);
                    346:   if (node == NULL)
                    347:     return NULL;
                    348: 
                    349:   route_unlock_node (node);
                    350:   if (node->info)
                    351:     ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
                    352:   return (struct ospf6_lsa *) node->info;
                    353: }
                    354: 
                    355: struct ospf6_lsa *
                    356: ospf6_lsdb_next (struct ospf6_lsa *lsa)
                    357: {
                    358:   struct ospf6_lsa *next = lsa->next;
                    359: 
                    360:   ospf6_lsa_unlock (lsa);
                    361:   if (next)
                    362:     ospf6_lsa_lock (next);
                    363: 
                    364:   return next;
                    365: }
                    366: 
                    367: struct ospf6_lsa *
                    368: ospf6_lsdb_type_router_head (u_int16_t type, u_int32_t adv_router,
                    369:                              struct ospf6_lsdb *lsdb)
                    370: {
                    371:   struct route_node *node;
                    372:   struct prefix_ipv6 key;
                    373:   struct ospf6_lsa *lsa;
                    374: 
                    375:   memset (&key, 0, sizeof (key));
                    376:   ospf6_lsdb_set_key (&key, &type, sizeof (type));
                    377:   ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
                    378: 
                    379:   node = lsdb->table->top;
                    380: 
                    381:   /* Walk down tree. */
                    382:   while (node && node->p.prefixlen <= key.prefixlen &&
                    383:         prefix_match (&node->p, (struct prefix *) &key))
                    384:     node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)];
                    385: 
                    386:   if (node)
                    387:     route_lock_node (node);
                    388:   while (node && node->info == NULL)
                    389:     node = route_next (node);
                    390: 
                    391:   if (node == NULL)
                    392:     return NULL;
                    393:   else
                    394:     route_unlock_node (node);
                    395: 
                    396:   if (! prefix_match ((struct prefix *) &key, &node->p))
                    397:     return NULL;
                    398: 
                    399:   lsa = node->info;
                    400:   ospf6_lsa_lock (lsa);
                    401: 
                    402:   return lsa;
                    403: }
                    404: 
                    405: struct ospf6_lsa *
                    406: ospf6_lsdb_type_router_next (u_int16_t type, u_int32_t adv_router,
                    407:                              struct ospf6_lsa *lsa)
                    408: {
                    409:   struct ospf6_lsa *next = lsa->next;
                    410: 
                    411:   if (next)
                    412:     {
                    413:       if (next->header->type != type ||
                    414:           next->header->adv_router != adv_router)
                    415:         next = NULL;
                    416:     }
                    417: 
                    418:   if (next)
                    419:     ospf6_lsa_lock (next);
                    420:   ospf6_lsa_unlock (lsa);
                    421:   return next;
                    422: }
                    423: 
                    424: struct ospf6_lsa *
                    425: ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
                    426: {
                    427:   struct route_node *node;
                    428:   struct prefix_ipv6 key;
                    429:   struct ospf6_lsa *lsa;
                    430: 
                    431:   memset (&key, 0, sizeof (key));
                    432:   ospf6_lsdb_set_key (&key, &type, sizeof (type));
                    433: 
                    434:   /* Walk down tree. */
                    435:   node = lsdb->table->top;
                    436:   while (node && node->p.prefixlen <= key.prefixlen &&
                    437:         prefix_match (&node->p, (struct prefix *) &key))
                    438:     node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)];
                    439: 
                    440:   if (node)
                    441:     route_lock_node (node);
                    442:   while (node && node->info == NULL)
                    443:     node = route_next (node);
                    444: 
                    445:   if (node == NULL)
                    446:     return NULL;
                    447:   else
                    448:     route_unlock_node (node);
                    449: 
                    450:   if (! prefix_match ((struct prefix *) &key, &node->p))
                    451:     return NULL;
                    452: 
                    453:   lsa = node->info;
                    454:   ospf6_lsa_lock (lsa);
                    455: 
                    456:   return lsa;
                    457: }
                    458: 
                    459: struct ospf6_lsa *
                    460: ospf6_lsdb_type_next (u_int16_t type, struct ospf6_lsa *lsa)
                    461: {
                    462:   struct ospf6_lsa *next = lsa->next;
                    463: 
                    464:   if (next)
                    465:     {
                    466:       if (next->header->type != type)
                    467:         next = NULL;
                    468:     }
                    469: 
                    470:   if (next)
                    471:     ospf6_lsa_lock (next);
                    472:   ospf6_lsa_unlock (lsa);
                    473:   return next;
                    474: }
                    475: 
                    476: void
                    477: ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
                    478: {
                    479:   struct ospf6_lsa *lsa;
                    480:   for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
                    481:     ospf6_lsdb_remove (lsa, lsdb);
                    482: }
                    483: 
                    484: void
                    485: ospf6_lsdb_show (struct vty *vty, int level,
                    486:                  u_int16_t *type, u_int32_t *id, u_int32_t *adv_router,
                    487:                  struct ospf6_lsdb *lsdb)
                    488: {
                    489:   struct ospf6_lsa *lsa;
                    490:   void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
                    491: 
                    492:   if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
                    493:     showfunc = ospf6_lsa_show_summary;
                    494:   else if (level == OSPF6_LSDB_SHOW_LEVEL_DETAIL)
                    495:     showfunc = ospf6_lsa_show;
                    496:   else if (level == OSPF6_LSDB_SHOW_LEVEL_INTERNAL)
                    497:     showfunc = ospf6_lsa_show_internal;
                    498:   else if (level == OSPF6_LSDB_SHOW_LEVEL_DUMP)
                    499:     showfunc = ospf6_lsa_show_dump;
                    500: 
                    501:   if (type && id && adv_router)
                    502:     {
                    503:       lsa = ospf6_lsdb_lookup (*type, *id, *adv_router, lsdb);
                    504:       if (lsa)
                    505:         {
                    506:           if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
                    507:             ospf6_lsa_show (vty, lsa);
                    508:           else
                    509:             (*showfunc) (vty, lsa);
                    510:         }
                    511:       return;
                    512:     }
                    513: 
                    514:   if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
                    515:     ospf6_lsa_show_summary_header (vty);
                    516: 
                    517:   if (type && adv_router)
                    518:     lsa = ospf6_lsdb_type_router_head (*type, *adv_router, lsdb);
                    519:   else if (type)
                    520:     lsa = ospf6_lsdb_type_head (*type, lsdb);
                    521:   else
                    522:     lsa = ospf6_lsdb_head (lsdb);
                    523:   while (lsa)
                    524:     {
                    525:       if ((! adv_router || lsa->header->adv_router == *adv_router) &&
                    526:           (! id || lsa->header->id == *id))
                    527:         (*showfunc) (vty, lsa);
                    528: 
                    529:       if (type && adv_router)
                    530:         lsa = ospf6_lsdb_type_router_next (*type, *adv_router, lsa);
                    531:       else if (type)
                    532:         lsa = ospf6_lsdb_type_next (*type, lsa);
                    533:       else
                    534:         lsa = ospf6_lsdb_next (lsa);
                    535:     }
                    536: }
                    537: 
                    538: /* Decide new Link State ID to originate.
                    539:    note return value is network byte order */
                    540: u_int32_t
                    541: ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
                    542:                  struct ospf6_lsdb *lsdb)
                    543: {
                    544:   struct ospf6_lsa *lsa;
                    545:   u_int32_t id = 1;
                    546: 
                    547:   for (lsa = ospf6_lsdb_type_router_head (type, adv_router, lsdb); lsa;
                    548:        lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa))
                    549:     {
                    550:       if (ntohl (lsa->header->id) < id)
                    551:         continue;
                    552:       if (ntohl (lsa->header->id) > id)
                    553:       {
                    554:         ospf6_lsa_unlock (lsa);
                    555:         break;
                    556:       }
                    557:       id++;
                    558:     }
                    559: 
                    560:   return ((u_int32_t) htonl (id));
                    561: }
                    562: 
                    563: /* Decide new LS sequence number to originate.
                    564:    note return value is network byte order */
                    565: u_int32_t
                    566: ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
                    567:                      struct ospf6_lsdb *lsdb)
                    568: {
                    569:   struct ospf6_lsa *lsa;
                    570:   signed long seqnum = 0;
                    571: 
                    572:   /* if current database copy not found, return InitialSequenceNumber */
                    573:   lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
                    574:   if (lsa == NULL)
                    575:     seqnum = INITIAL_SEQUENCE_NUMBER;
                    576:   else
                    577:     seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
                    578: 
                    579:   return ((u_int32_t) htonl (seqnum));
                    580: }
                    581: 
                    582: 

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