Annotation of embedaddon/quagga/ospf6d/ospf6_flood.c, revision 1.1.1.3

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

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