Annotation of embedaddon/quagga/ospf6d/ospf6_flood.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 "log.h"
                     25: #include "thread.h"
                     26: #include "linklist.h"
                     27: #include "vty.h"
                     28: #include "command.h"
                     29: 
                     30: #include "ospf6d.h"
                     31: #include "ospf6_proto.h"
                     32: #include "ospf6_lsa.h"
                     33: #include "ospf6_lsdb.h"
                     34: #include "ospf6_message.h"
                     35: #include "ospf6_route.h"
                     36: #include "ospf6_spf.h"
                     37: 
                     38: #include "ospf6_top.h"
                     39: #include "ospf6_area.h"
                     40: #include "ospf6_interface.h"
                     41: #include "ospf6_neighbor.h"
                     42: 
                     43: #include "ospf6_flood.h"
                     44: 
                     45: unsigned char conf_debug_ospf6_flooding;
                     46: 
                     47: struct ospf6_lsdb *
                     48: ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa)
                     49: {
                     50:   struct ospf6_lsdb *lsdb = NULL;
                     51:   switch (OSPF6_LSA_SCOPE (lsa->header->type))
                     52:     {
                     53:     case OSPF6_SCOPE_LINKLOCAL:
                     54:       lsdb = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb;
                     55:       break;
                     56:     case OSPF6_SCOPE_AREA:
                     57:       lsdb = OSPF6_AREA (lsa->lsdb->data)->lsdb;
                     58:       break;
                     59:     case OSPF6_SCOPE_AS:
                     60:       lsdb = OSPF6_PROCESS (lsa->lsdb->data)->lsdb;
                     61:       break;
                     62:     default:
                     63:       assert (0);
                     64:       break;
                     65:     }
                     66:   return lsdb;
                     67: }
                     68: 
                     69: struct ospf6_lsdb *
                     70: ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa)
                     71: {
                     72:   struct ospf6_lsdb *lsdb_self = NULL;
                     73:   switch (OSPF6_LSA_SCOPE (lsa->header->type))
                     74:     {
                     75:     case OSPF6_SCOPE_LINKLOCAL:
                     76:       lsdb_self = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb_self;
                     77:       break;
                     78:     case OSPF6_SCOPE_AREA:
                     79:       lsdb_self = OSPF6_AREA (lsa->lsdb->data)->lsdb_self;
                     80:       break;
                     81:     case OSPF6_SCOPE_AS:
                     82:       lsdb_self = OSPF6_PROCESS (lsa->lsdb->data)->lsdb_self;
                     83:       break;
                     84:     default:
                     85:       assert (0);
                     86:       break;
                     87:     }
                     88:   return lsdb_self;
                     89: }
                     90: 
                     91: void
                     92: ospf6_lsa_originate (struct ospf6_lsa *lsa)
                     93: {
                     94:   struct ospf6_lsa *old;
                     95:   struct ospf6_lsdb *lsdb_self;
                     96: 
                     97:   /* find previous LSA */
                     98:   old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                     99:                            lsa->header->adv_router, lsa->lsdb);
                    100: 
                    101:   /* if the new LSA does not differ from previous,
                    102:      suppress this update of the LSA */
                    103:   if (old && ! OSPF6_LSA_IS_DIFFER (lsa, old))
                    104:     {
                    105:       if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
                    106:         zlog_debug ("Suppress updating LSA: %s", lsa->name);
                    107:       ospf6_lsa_delete (lsa);
                    108:       return;
                    109:     }
                    110: 
                    111:   /* store it in the LSDB for self-originated LSAs */
                    112:   lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
                    113:   ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self);
                    114: 
                    115:   lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
                    116:                                    LS_REFRESH_TIME);
                    117: 
                    118:   if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
                    119:       IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
                    120:     {
                    121:       zlog_debug ("LSA Originate:");
                    122:       ospf6_lsa_header_print (lsa);
                    123:     }
                    124: 
                    125:   if (old)
                    126:     ospf6_flood_clear (old);
                    127:   ospf6_flood (NULL, lsa);
                    128:   ospf6_install_lsa (lsa);
                    129: }
                    130: 
                    131: void
                    132: ospf6_lsa_originate_process (struct ospf6_lsa *lsa,
                    133:                              struct ospf6 *process)
                    134: {
                    135:   lsa->lsdb = process->lsdb;
                    136:   ospf6_lsa_originate (lsa);
                    137: }
                    138: 
                    139: void
                    140: ospf6_lsa_originate_area (struct ospf6_lsa *lsa,
                    141:                           struct ospf6_area *oa)
                    142: {
                    143:   lsa->lsdb = oa->lsdb;
                    144:   ospf6_lsa_originate (lsa);
                    145: }
                    146: 
                    147: void
                    148: ospf6_lsa_originate_interface (struct ospf6_lsa *lsa,
                    149:                                struct ospf6_interface *oi)
                    150: {
                    151:   lsa->lsdb = oi->lsdb;
                    152:   ospf6_lsa_originate (lsa);
                    153: }
                    154: 
                    155: void
                    156: ospf6_lsa_purge (struct ospf6_lsa *lsa)
                    157: {
                    158:   struct ospf6_lsa *self;
                    159:   struct ospf6_lsdb *lsdb_self;
                    160: 
                    161:   /* remove it from the LSDB for self-originated LSAs */
                    162:   lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
                    163:   self = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                    164:                             lsa->header->adv_router, lsdb_self);
                    165:   if (self)
                    166:     {
                    167:       THREAD_OFF (self->expire);
                    168:       THREAD_OFF (self->refresh);
                    169:       ospf6_lsdb_remove (self, lsdb_self);
                    170:     }
                    171: 
                    172:   ospf6_lsa_premature_aging (lsa);
                    173: }
                    174: 
                    175: 
                    176: void
                    177: ospf6_increment_retrans_count (struct ospf6_lsa *lsa)
                    178: {
                    179:   /* The LSA must be the original one (see the description
                    180:      in ospf6_decrement_retrans_count () below) */
                    181:   lsa->retrans_count++;
                    182: }
                    183: 
                    184: void
                    185: ospf6_decrement_retrans_count (struct ospf6_lsa *lsa)
                    186: {
                    187:   struct ospf6_lsdb *lsdb;
                    188:   struct ospf6_lsa *orig;
                    189: 
                    190:   /* The LSA must be on the retrans-list of a neighbor. It means
                    191:      the "lsa" is a copied one, and we have to decrement the
                    192:      retransmission count of the original one (instead of this "lsa"'s).
                    193:      In order to find the original LSA, first we have to find
                    194:      appropriate LSDB that have the original LSA. */
                    195:   lsdb = ospf6_get_scoped_lsdb (lsa);
                    196: 
                    197:   /* Find the original LSA of which the retrans_count should be decremented */
                    198:   orig = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                    199:                             lsa->header->adv_router, lsdb);
                    200:   if (orig)
                    201:     {
                    202:       orig->retrans_count--;
                    203:       assert (orig->retrans_count >= 0);
                    204:     }
                    205: }
                    206: 
                    207: /* RFC2328 section 13.2 Installing LSAs in the database */
                    208: void
                    209: ospf6_install_lsa (struct ospf6_lsa *lsa)
                    210: {
                    211:   struct ospf6_lsa *old;
                    212:   struct timeval now;
                    213: 
                    214:   if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
                    215:       IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
                    216:     zlog_debug ("Install LSA: %s", lsa->name);
                    217: 
                    218:   /* Remove the old instance from all neighbors' Link state
                    219:      retransmission list (RFC2328 13.2 last paragraph) */
                    220:   old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                    221:                            lsa->header->adv_router, lsa->lsdb);
                    222:   if (old)
                    223:     {
                    224:       THREAD_OFF (old->expire);
                    225:       ospf6_flood_clear (old);
                    226:     }
                    227: 
                    228:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                    229:   if (! OSPF6_LSA_IS_MAXAGE (lsa))
                    230:     lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
                    231:                                     MAXAGE + lsa->birth.tv_sec - now.tv_sec);
                    232:   else
                    233:     lsa->expire = NULL;
                    234: 
                    235:   /* actually install */
                    236:   lsa->installed = now;
                    237:   ospf6_lsdb_add (lsa, lsa->lsdb);
                    238: 
                    239:   return;
                    240: }
                    241: 
                    242: /* RFC2740 section 3.5.2. Sending Link State Update packets */
                    243: /* RFC2328 section 13.3 Next step in the flooding procedure */
                    244: static void
                    245: ospf6_flood_interface (struct ospf6_neighbor *from,
                    246:                        struct ospf6_lsa *lsa, struct ospf6_interface *oi)
                    247: {
                    248:   struct listnode *node, *nnode;
                    249:   struct ospf6_neighbor *on;
                    250:   struct ospf6_lsa *req;
                    251:   int retrans_added = 0;
                    252:   int is_debug = 0;
                    253: 
                    254:   if (IS_OSPF6_DEBUG_FLOODING ||
                    255:       IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
                    256:     {
                    257:       is_debug++;
                    258:       zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
                    259:     }
                    260: 
                    261:   /* (1) For each neighbor */
                    262:   for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
                    263:     {
                    264:       if (is_debug)
                    265:         zlog_debug ("To neighbor %s", on->name);
                    266: 
                    267:       /* (a) if neighbor state < Exchange, examin next */
                    268:       if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
                    269:         {
                    270:           if (is_debug)
                    271:             zlog_debug ("Neighbor state less than ExChange, next neighbor");
                    272:           continue;
                    273:         }
                    274: 
                    275:       /* (b) if neighbor not yet Full, check request-list */
                    276:       if (on->state != OSPF6_NEIGHBOR_FULL)
                    277:         {
                    278:           if (is_debug)
                    279:             zlog_debug ("Neighbor not yet Full");
                    280: 
                    281:           req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                    282:                                    lsa->header->adv_router, on->request_list);
                    283:           if (req == NULL)
                    284:             {
                    285:               if (is_debug)
                    286:                 zlog_debug ("Not on request-list for this neighbor");
                    287:               /* fall through */
                    288:             }
                    289:           else
                    290:             {
                    291:               /* If new LSA less recent, examin next neighbor */
                    292:               if (ospf6_lsa_compare (lsa, req) > 0)
                    293:                 {
                    294:                   if (is_debug)
                    295:                     zlog_debug ("Requesting is newer, next neighbor");
                    296:                   continue;
                    297:                 }
                    298: 
                    299:               /* If the same instance, delete from request-list and
                    300:                  examin next neighbor */
                    301:               if (ospf6_lsa_compare (lsa, req) == 0)
                    302:                 {
                    303:                   if (is_debug)
                    304:                     zlog_debug ("Requesting the same, remove it, next neighbor");
                    305:                   ospf6_lsdb_remove (req, on->request_list);
                    306:                   continue;
                    307:                 }
                    308: 
                    309:               /* If the new LSA is more recent, delete from request-list */
                    310:               if (ospf6_lsa_compare (lsa, req) < 0)
                    311:                 {
                    312:                   if (is_debug)
                    313:                     zlog_debug ("Received is newer, remove requesting");
                    314:                   ospf6_lsdb_remove (req, on->request_list);
                    315:                   /* fall through */
                    316:                 }
                    317:             }
                    318:         }
                    319: 
                    320:       /* (c) If the new LSA was received from this neighbor,
                    321:          examin next neighbor */
                    322:       if (from == on)
                    323:         {
                    324:           if (is_debug)
                    325:             zlog_debug ("Received is from the neighbor, next neighbor");
                    326:           continue;
                    327:         }
                    328: 
                    329:       /* (d) add retrans-list, schedule retransmission */
                    330:       if (is_debug)
                    331:         zlog_debug ("Add retrans-list of this neighbor");
                    332:       ospf6_increment_retrans_count (lsa);
                    333:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
                    334:       if (on->thread_send_lsupdate == NULL)
                    335:         on->thread_send_lsupdate =
                    336:           thread_add_timer (master, ospf6_lsupdate_send_neighbor,
                    337:                             on, on->ospf6_if->rxmt_interval);
                    338:       retrans_added++;
                    339:     }
                    340: 
                    341:   /* (2) examin next interface if not added to retrans-list */
                    342:   if (retrans_added == 0)
                    343:     {
                    344:       if (is_debug)
                    345:         zlog_debug ("No retransmission scheduled, next interface");
                    346:       return;
                    347:     }
                    348: 
                    349:   /* (3) If the new LSA was received on this interface,
                    350:      and it was from DR or BDR, examin next interface */
                    351:   if (from && from->ospf6_if == oi &&
                    352:       (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
                    353:     {
                    354:       if (is_debug)
                    355:         zlog_debug ("Received is from the I/F's DR or BDR, next interface");
                    356:       return;
                    357:     }
                    358: 
                    359:   /* (4) If the new LSA was received on this interface,
                    360:      and the interface state is BDR, examin next interface */
                    361:   if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
                    362:     {
                    363:       if (is_debug)
                    364:         zlog_debug ("Received is from the I/F, itself BDR, next interface");
                    365:       return;
                    366:     }
                    367: 
                    368:   /* (5) flood the LSA out the interface. */
                    369:   if (is_debug)
                    370:     zlog_debug ("Schedule flooding for the interface");
                    371:   if (if_is_broadcast (oi->interface))
                    372:     {
                    373:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
                    374:       if (oi->thread_send_lsupdate == NULL)
                    375:         oi->thread_send_lsupdate =
                    376:           thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
                    377:     }
                    378:   else
                    379:     {
                    380:       /* reschedule retransmissions to all neighbors */
                    381:       for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
                    382:         {
                    383:           THREAD_OFF (on->thread_send_lsupdate);
                    384:           on->thread_send_lsupdate =
                    385:             thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
                    386:         }
                    387:     }
                    388: }
                    389: 
                    390: static void
                    391: ospf6_flood_area (struct ospf6_neighbor *from,
                    392:                   struct ospf6_lsa *lsa, struct ospf6_area *oa)
                    393: {
                    394:   struct listnode *node, *nnode;
                    395:   struct ospf6_interface *oi;
                    396: 
                    397:   for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
                    398:     {
                    399:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
                    400:           oi != OSPF6_INTERFACE (lsa->lsdb->data))
                    401:         continue;
                    402: 
                    403: #if 0
                    404:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
                    405:           ospf6_is_interface_virtual_link (oi))
                    406:         continue;
                    407: #endif/*0*/
                    408: 
                    409:       ospf6_flood_interface (from, lsa, oi);
                    410:     }
                    411: }
                    412: 
                    413: static void
                    414: ospf6_flood_process (struct ospf6_neighbor *from,
                    415:                      struct ospf6_lsa *lsa, struct ospf6 *process)
                    416: {
                    417:   struct listnode *node, *nnode;
                    418:   struct ospf6_area *oa;
                    419: 
                    420:   for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
                    421:     {
                    422:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
                    423:           oa != OSPF6_AREA (lsa->lsdb->data))
                    424:         continue;
                    425:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
                    426:           oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
                    427:         continue;
                    428: 
                    429:       if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
                    430:           IS_AREA_STUB (oa))
                    431:         continue;
                    432: 
                    433:       ospf6_flood_area (from, lsa, oa);
                    434:     }
                    435: }
                    436: 
                    437: void
                    438: ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
                    439: {
                    440:   ospf6_flood_process (from, lsa, ospf6);
                    441: }
                    442: 
                    443: static void
                    444: ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
                    445: {
                    446:   struct listnode *node, *nnode;
                    447:   struct ospf6_neighbor *on;
                    448:   struct ospf6_lsa *rem;
                    449: 
                    450:   for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
                    451:     {
                    452:       rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                    453:                                lsa->header->adv_router, on->retrans_list);
                    454:       if (rem && ! ospf6_lsa_compare (rem, lsa))
                    455:         {
                    456:           if (IS_OSPF6_DEBUG_FLOODING ||
                    457:               IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
                    458:             zlog_debug ("Remove %s from retrans_list of %s",
                    459:                        rem->name, on->name);
                    460:           ospf6_decrement_retrans_count (rem);
                    461:           ospf6_lsdb_remove (rem, on->retrans_list);
                    462:         }
                    463:     }
                    464: }
                    465: 
                    466: static void
                    467: ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
                    468: {
                    469:   struct listnode *node, *nnode;
                    470:   struct ospf6_interface *oi;
                    471: 
                    472:   for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
                    473:     {
                    474:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
                    475:           oi != OSPF6_INTERFACE (lsa->lsdb->data))
                    476:         continue;
                    477: 
                    478: #if 0
                    479:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
                    480:           ospf6_is_interface_virtual_link (oi))
                    481:         continue;
                    482: #endif/*0*/
                    483: 
                    484:       ospf6_flood_clear_interface (lsa, oi);
                    485:     }
                    486: }
                    487: 
                    488: static void
                    489: ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
                    490: {
                    491:   struct listnode *node, *nnode;
                    492:   struct ospf6_area *oa;
                    493: 
                    494:   for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
                    495:     {
                    496:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
                    497:           oa != OSPF6_AREA (lsa->lsdb->data))
                    498:         continue;
                    499:       if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
                    500:           oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
                    501:         continue;
                    502: 
                    503:       if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
                    504:           IS_AREA_STUB (oa))
                    505:         continue;
                    506: 
                    507:       ospf6_flood_clear_area (lsa, oa);
                    508:     }
                    509: }
                    510: 
                    511: void
                    512: ospf6_flood_clear (struct ospf6_lsa *lsa)
                    513: {
                    514:   ospf6_flood_clear_process (lsa, ospf6);
                    515: }
                    516: 
                    517: 
                    518: /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
                    519: static void
                    520: ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
                    521:                                 struct ospf6_neighbor *from)
                    522: {
                    523:   struct ospf6_interface *oi;
                    524:   int is_debug = 0;
                    525: 
                    526:   if (IS_OSPF6_DEBUG_FLOODING ||
                    527:       IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
                    528:     is_debug++;
                    529: 
                    530:   assert (from && from->ospf6_if);
                    531:   oi = from->ospf6_if;
                    532: 
                    533:   /* LSA has been flood back out receiving interface.
                    534:      No acknowledgement sent. */
                    535:   if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
                    536:     {
                    537:       if (is_debug)
                    538:         zlog_debug ("No acknowledgement (BDR & FloodBack)");
                    539:       return;
                    540:     }
                    541: 
                    542:   /* LSA is more recent than database copy, but was not flooded
                    543:      back out receiving interface. Delayed acknowledgement sent
                    544:      if advertisement received from Designated Router,
                    545:      otherwide do nothing. */
                    546:   if (ismore_recent < 0)
                    547:     {
                    548:       if (oi->drouter == from->router_id)
                    549:         {
                    550:           if (is_debug)
                    551:             zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
                    552:           /* Delayed acknowledgement */
                    553:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
                    554:           if (oi->thread_send_lsack == NULL)
                    555:             oi->thread_send_lsack =
                    556:               thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
                    557:         }
                    558:       else
                    559:         {
                    560:           if (is_debug)
                    561:             zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
                    562:         }
                    563:       return;
                    564:     }
                    565: 
                    566:   /* LSA is a duplicate, and was treated as an implied acknowledgement.
                    567:      Delayed acknowledgement sent if advertisement received from
                    568:      Designated Router, otherwise do nothing */
                    569:   if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
                    570:       CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
                    571:     {
                    572:       if (oi->drouter == from->router_id)
                    573:         {
                    574:           if (is_debug)
                    575:             zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
                    576:           /* Delayed acknowledgement */
                    577:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
                    578:           if (oi->thread_send_lsack == NULL)
                    579:             oi->thread_send_lsack =
                    580:               thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
                    581:         }
                    582:       else
                    583:         {
                    584:           if (is_debug)
                    585:             zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
                    586:         }
                    587:       return;
                    588:     }
                    589: 
                    590:   /* LSA is a duplicate, and was not treated as an implied acknowledgement.
                    591:      Direct acknowledgement sent */
                    592:   if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
                    593:       ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
                    594:     {
                    595:       if (is_debug)
                    596:         zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
                    597:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
                    598:       if (from->thread_send_lsack == NULL)
                    599:         from->thread_send_lsack =
                    600:           thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
                    601:       return;
                    602:     }
                    603: 
                    604:   /* LSA's LS age is equal to Maxage, and there is no current instance
                    605:      of the LSA in the link state database, and none of router's
                    606:      neighbors are in states Exchange or Loading */
                    607:   /* Direct acknowledgement sent, but this case is handled in
                    608:      early of ospf6_receive_lsa () */
                    609: }
                    610: 
                    611: static void
                    612: ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
                    613:                                 struct ospf6_neighbor *from)
                    614: {
                    615:   struct ospf6_interface *oi;
                    616:   int is_debug = 0;
                    617: 
                    618:   if (IS_OSPF6_DEBUG_FLOODING ||
                    619:       IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
                    620:     is_debug++;
                    621: 
                    622:   assert (from && from->ospf6_if);
                    623:   oi = from->ospf6_if;
                    624: 
                    625:   /* LSA has been flood back out receiving interface.
                    626:      No acknowledgement sent. */
                    627:   if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
                    628:     {
                    629:       if (is_debug)
                    630:         zlog_debug ("No acknowledgement (AllOther & FloodBack)");
                    631:       return;
                    632:     }
                    633: 
                    634:   /* LSA is more recent than database copy, but was not flooded
                    635:      back out receiving interface. Delayed acknowledgement sent. */
                    636:   if (ismore_recent < 0)
                    637:     {
                    638:       if (is_debug)
                    639:         zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
                    640:       /* Delayed acknowledgement */
                    641:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
                    642:       if (oi->thread_send_lsack == NULL)
                    643:         oi->thread_send_lsack =
                    644:           thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
                    645:       return;
                    646:     }
                    647: 
                    648:   /* LSA is a duplicate, and was treated as an implied acknowledgement.
                    649:      No acknowledgement sent. */
                    650:   if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
                    651:       CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
                    652:     {
                    653:       if (is_debug)
                    654:         zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
                    655:       return;
                    656:     }
                    657: 
                    658:   /* LSA is a duplicate, and was not treated as an implied acknowledgement.
                    659:      Direct acknowledgement sent */
                    660:   if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
                    661:       ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
                    662:     {
                    663:       if (is_debug)
                    664:         zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
                    665:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
                    666:       if (from->thread_send_lsack == NULL)
                    667:         from->thread_send_lsack =
                    668:           thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
                    669:       return;
                    670:     }
                    671: 
                    672:   /* LSA's LS age is equal to Maxage, and there is no current instance
                    673:      of the LSA in the link state database, and none of router's
                    674:      neighbors are in states Exchange or Loading */
                    675:   /* Direct acknowledgement sent, but this case is handled in
                    676:      early of ospf6_receive_lsa () */
                    677: }
                    678: 
                    679: static void
                    680: ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
                    681:                        struct ospf6_neighbor *from)
                    682: {
                    683:   struct ospf6_interface *oi;
                    684: 
                    685:   assert (from && from->ospf6_if);
                    686:   oi = from->ospf6_if;
                    687: 
                    688:   if (oi->state == OSPF6_INTERFACE_BDR)
                    689:     ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
                    690:   else
                    691:     ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
                    692: }
                    693: 
                    694: /* RFC2328 section 13 (4):
                    695:    if MaxAge LSA and if we have no instance, and no neighbor
                    696:    is in states Exchange or Loading
                    697:    returns 1 if match this case, else returns 0 */
                    698: static int
                    699: ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
                    700: {
                    701:   struct ospf6_neighbor *on;
                    702:   struct ospf6_interface *oi;
                    703:   struct ospf6_area *oa;
                    704:   struct ospf6 *process = NULL;
                    705:   struct listnode *i, *j, *k;
                    706:   int count = 0;
                    707: 
                    708:   if (! OSPF6_LSA_IS_MAXAGE (lsa))
                    709:     return 0;
                    710: 
                    711:   if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                    712:                          lsa->header->adv_router, lsa->lsdb))
                    713:     return 0;
                    714: 
                    715:   process = from->ospf6_if->area->ospf6;
                    716: 
                    717:   for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
                    718:     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
                    719:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
                    720:         if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
                    721:             on->state == OSPF6_NEIGHBOR_LOADING)
                    722:           count++;
                    723: 
                    724:   if (count == 0)
                    725:     return 1;
                    726:   return 0;
                    727: }
                    728: 
                    729: /* RFC2328 section 13 The Flooding Procedure */
                    730: void
                    731: ospf6_receive_lsa (struct ospf6_neighbor *from,
                    732:                    struct ospf6_lsa_header *lsa_header)
                    733: {
                    734:   struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
                    735:   int ismore_recent;
                    736:   unsigned short cksum;
                    737:   int is_debug = 0;
                    738: 
                    739:   ismore_recent = 1;
                    740:   assert (from);
                    741: 
                    742:   /* make lsa structure for received lsa */
                    743:   new = ospf6_lsa_create (lsa_header);
                    744: 
                    745:   if (IS_OSPF6_DEBUG_FLOODING ||
                    746:       IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
                    747:     {
                    748:       is_debug++;
                    749:       zlog_debug ("LSA Receive from %s", from->name);
                    750:       ospf6_lsa_header_print (new);
                    751:     }
                    752: 
                    753:   /* (1) LSA Checksum */
                    754:   cksum = ntohs (new->header->checksum);
                    755:   if (ntohs (ospf6_lsa_checksum (new->header)) != cksum)
                    756:     {
                    757:       if (is_debug)
                    758:         zlog_debug ("Wrong LSA Checksum, discard");
                    759:       ospf6_lsa_delete (new);
                    760:       return;
                    761:     }
                    762: 
                    763:   /* (2) Examine the LSA's LS type. 
                    764:      RFC2470 3.5.1. Receiving Link State Update packets  */
                    765:   if (IS_AREA_STUB (from->ospf6_if->area) &&
                    766:       OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
                    767:     {
                    768:       if (is_debug)
                    769:         zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
                    770:       ospf6_lsa_delete (new);
                    771:       return;
                    772:     }
                    773: 
                    774:   /* (3) LSA which have reserved scope is discarded
                    775:      RFC2470 3.5.1. Receiving Link State Update packets  */
                    776:   /* Flooding scope check. LSAs with unknown scope are discarded here.
                    777:      Set appropriate LSDB for the LSA */
                    778:   switch (OSPF6_LSA_SCOPE (new->header->type))
                    779:     {
                    780:     case OSPF6_SCOPE_LINKLOCAL:
                    781:       new->lsdb = from->ospf6_if->lsdb;
                    782:       break;
                    783:     case OSPF6_SCOPE_AREA:
                    784:       new->lsdb = from->ospf6_if->area->lsdb;
                    785:       break;
                    786:     case OSPF6_SCOPE_AS:
                    787:       new->lsdb = from->ospf6_if->area->ospf6->lsdb;
                    788:       break;
                    789:     default:
                    790:       if (is_debug)
                    791:         zlog_debug ("LSA has reserved scope, discard");
                    792:       ospf6_lsa_delete (new);
                    793:       return;
                    794:     }
                    795: 
                    796:   /* (4) if MaxAge LSA and if we have no instance, and no neighbor
                    797:          is in states Exchange or Loading */
                    798:   if (ospf6_is_maxage_lsa_drop (new, from))
                    799:     {
                    800:       /* log */
                    801:       if (is_debug)
                    802:         zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
                    803: 
                    804:       /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
                    805:       ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
                    806:       if (from->thread_send_lsack == NULL)
                    807:         from->thread_send_lsack =
                    808:           thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
                    809: 
                    810:       /* b) Discard */
                    811:       ospf6_lsa_delete (new);
                    812:       return;
                    813:     }
                    814: 
                    815:   /* (5) */
                    816:   /* lookup the same database copy in lsdb */
                    817:   old = ospf6_lsdb_lookup (new->header->type, new->header->id,
                    818:                            new->header->adv_router, new->lsdb);
                    819:   if (old)
                    820:     {
                    821:       ismore_recent = ospf6_lsa_compare (new, old);
                    822:       if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
                    823:         {
                    824:           if (is_debug)
                    825:             zlog_debug ("Received is duplicated LSA");
                    826:           SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
                    827:         }
                    828:     }
                    829: 
                    830:   /* if no database copy or received is more recent */
                    831:   if (old == NULL || ismore_recent < 0)
                    832:     {
                    833:       /* in case we have no database copy */
                    834:       ismore_recent = -1;
                    835: 
                    836:       /* (a) MinLSArrival check */
                    837:       if (old)
                    838:         {
                    839:           struct timeval now, res;
                    840:           quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                    841:           timersub (&now, &old->installed, &res);
                    842:           if (res.tv_sec < MIN_LS_ARRIVAL)
                    843:             {
                    844:               if (is_debug)
                    845:                 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
                    846:               ospf6_lsa_delete (new);
                    847:               return;   /* examin next lsa */
                    848:             }
                    849:         }
                    850: 
                    851:       quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
                    852: 
                    853:       if (is_debug)
                    854:         zlog_debug ("Flood, Install, Possibly acknowledge the received LSA");
                    855: 
                    856:       /* (b) immediately flood and (c) remove from all retrans-list */
                    857:       /* Prevent self-originated LSA to be flooded. this is to make
                    858:       reoriginated instance of the LSA not to be rejected by other routers
                    859:       due to MinLSArrival. */
                    860:       if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
                    861:         ospf6_flood (from, new);
                    862: 
                    863:       /* (c) Remove the current database copy from all neighbors' Link
                    864:              state retransmission lists. */
                    865:       /* XXX, flood_clear ? */
                    866: 
                    867:       /* (d), installing lsdb, which may cause routing
                    868:               table calculation (replacing database copy) */
                    869:       ospf6_install_lsa (new);
                    870: 
                    871:       /* (e) possibly acknowledge */
                    872:       ospf6_acknowledge_lsa (new, ismore_recent, from);
                    873: 
                    874:       /* (f) Self Originated LSA, section 13.4 */
                    875:       if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
                    876:         {
                    877:           /* Self-originated LSA (newer than ours) is received from
                    878:              another router. We have to make a new instance of the LSA
                    879:              or have to flush this LSA. */
                    880:           if (is_debug)
                    881:             {
                    882:               zlog_debug ("Newer instance of the self-originated LSA");
                    883:               zlog_debug ("Schedule reorigination");
                    884:             }
                    885:           new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
                    886:         }
                    887: 
                    888:       return;
                    889:     }
                    890: 
                    891:   /* (6) if there is instance on sending neighbor's request list */
                    892:   if (ospf6_lsdb_lookup (new->header->type, new->header->id,
                    893:                          new->header->adv_router, from->request_list))
                    894:     {
                    895:       /* if no database copy, should go above state (5) */
                    896:       assert (old);
                    897: 
                    898:       if (is_debug)
                    899:         {
                    900:           zlog_debug ("Received is not newer, on the neighbor's request-list");
                    901:           zlog_debug ("BadLSReq, discard the received LSA");
                    902:         }
                    903: 
                    904:       /* BadLSReq */
                    905:       thread_add_event (master, bad_lsreq, from, 0);
                    906: 
                    907:       ospf6_lsa_delete (new);
                    908:       return;
                    909:     }
                    910: 
                    911:   /* (7) if neither one is more recent */
                    912:   if (ismore_recent == 0)
                    913:     {
                    914:       if (is_debug)
                    915:         zlog_debug ("The same instance as database copy (neither recent)");
                    916: 
                    917:       /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
                    918:       rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
                    919:                                new->header->adv_router, from->retrans_list);
                    920:       if (rem)
                    921:         {
                    922:           if (is_debug)
                    923:             {
                    924:               zlog_debug ("It is on the neighbor's retrans-list.");
                    925:               zlog_debug ("Treat as an Implied acknowledgement");
                    926:             }
                    927:           SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
                    928:           ospf6_decrement_retrans_count (rem);
                    929:           ospf6_lsdb_remove (rem, from->retrans_list);
                    930:         }
                    931: 
                    932:       if (is_debug)
                    933:         zlog_debug ("Possibly acknowledge and then discard");
                    934: 
                    935:       /* (b) possibly acknowledge */
                    936:       ospf6_acknowledge_lsa (new, ismore_recent, from);
                    937: 
                    938:       ospf6_lsa_delete (new);
                    939:       return;
                    940:     }
                    941: 
                    942:   /* (8) previous database copy is more recent */
                    943:     {
                    944:       assert (old);
                    945: 
                    946:       /* If database copy is in 'Seqnumber Wrapping',
                    947:          simply discard the received LSA */
                    948:       if (OSPF6_LSA_IS_MAXAGE (old) &&
                    949:           old->header->seqnum == htonl (MAX_SEQUENCE_NUMBER))
                    950:         {
                    951:           if (is_debug)
                    952:             {
                    953:               zlog_debug ("The LSA is in Seqnumber Wrapping");
                    954:               zlog_debug ("MaxAge & MaxSeqNum, discard");
                    955:             }
                    956:           ospf6_lsa_delete (new);
                    957:           return;
                    958:         }
                    959: 
                    960:       /* Otherwise, Send database copy of this LSA to this neighbor */
                    961:         {
                    962:           if (is_debug)
                    963:             {
                    964:               zlog_debug ("Database copy is more recent.");
                    965:               zlog_debug ("Send back directly and then discard");
                    966:             }
                    967: 
                    968:           /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
                    969: 
                    970:           ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
                    971:           if (from->thread_send_lsupdate == NULL)
                    972:             from->thread_send_lsupdate =
                    973:               thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
                    974:           ospf6_lsa_delete (new);
                    975:           return;
                    976:         }
                    977:       return;
                    978:     }
                    979: }
                    980: 
                    981: 
                    982: DEFUN (debug_ospf6_flooding,
                    983:        debug_ospf6_flooding_cmd,
                    984:        "debug ospf6 flooding",
                    985:        DEBUG_STR
                    986:        OSPF6_STR
                    987:        "Debug OSPFv3 flooding function\n"
                    988:       )
                    989: {
                    990:   OSPF6_DEBUG_FLOODING_ON ();
                    991:   return CMD_SUCCESS;
                    992: }
                    993: 
                    994: DEFUN (no_debug_ospf6_flooding,
                    995:        no_debug_ospf6_flooding_cmd,
                    996:        "no debug ospf6 flooding",
                    997:        NO_STR
                    998:        DEBUG_STR
                    999:        OSPF6_STR
                   1000:        "Debug OSPFv3 flooding function\n"
                   1001:       )
                   1002: {
                   1003:   OSPF6_DEBUG_FLOODING_OFF ();
                   1004:   return CMD_SUCCESS;
                   1005: }
                   1006: 
                   1007: int
                   1008: config_write_ospf6_debug_flood (struct vty *vty)
                   1009: {
                   1010:   if (IS_OSPF6_DEBUG_FLOODING)
                   1011:     vty_out (vty, "debug ospf6 flooding%s", VNL);
                   1012:   return 0;
                   1013: }
                   1014: 
                   1015: void
                   1016: install_element_ospf6_debug_flood (void)
                   1017: {
                   1018:   install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
                   1019:   install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
                   1020:   install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
                   1021:   install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
                   1022: }
                   1023: 
                   1024: 
                   1025: 
                   1026: 
                   1027: 

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