Annotation of embedaddon/quagga/ospfd/ospf_lsa.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * OSPF Link State Advertisement
        !             3:  * Copyright (C) 1999, 2000 Toshiaki Takada
        !             4:  *
        !             5:  * This file is part of GNU Zebra.
        !             6:  *
        !             7:  * GNU Zebra is free software; you can redistribute it and/or modify it
        !             8:  * under the terms of the GNU General Public License as published by the
        !             9:  * Free Software Foundation; either version 2, or (at your option) any
        !            10:  * later version.
        !            11:  *
        !            12:  * GNU Zebra is distributed in the hope that it will be useful, but
        !            13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            15:  * General Public License for more details.
        !            16:  *
        !            17:  * You should have received a copy of the GNU General Public License
        !            18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
        !            19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
        !            20:  * 02111-1307, USA.
        !            21:  */
        !            22: 
        !            23: #include <zebra.h>
        !            24: 
        !            25: #include "linklist.h"
        !            26: #include "prefix.h"
        !            27: #include "if.h"
        !            28: #include "table.h"
        !            29: #include "memory.h"
        !            30: #include "stream.h"
        !            31: #include "log.h"
        !            32: #include "thread.h"
        !            33: #include "hash.h"
        !            34: #include "sockunion.h"         /* for inet_aton() */
        !            35: #include "checksum.h"
        !            36: 
        !            37: #include "ospfd/ospfd.h"
        !            38: #include "ospfd/ospf_interface.h"
        !            39: #include "ospfd/ospf_ism.h"
        !            40: #include "ospfd/ospf_asbr.h"
        !            41: #include "ospfd/ospf_lsa.h"
        !            42: #include "ospfd/ospf_lsdb.h"
        !            43: #include "ospfd/ospf_neighbor.h"
        !            44: #include "ospfd/ospf_nsm.h"
        !            45: #include "ospfd/ospf_flood.h"
        !            46: #include "ospfd/ospf_packet.h"
        !            47: #include "ospfd/ospf_spf.h"
        !            48: #include "ospfd/ospf_dump.h"
        !            49: #include "ospfd/ospf_route.h"
        !            50: #include "ospfd/ospf_ase.h"
        !            51: #include "ospfd/ospf_zebra.h"
        !            52: 
        !            53: 
        !            54: u_int32_t
        !            55: get_metric (u_char *metric)
        !            56: {
        !            57:   u_int32_t m;
        !            58:   m = metric[0];
        !            59:   m = (m << 8) + metric[1];
        !            60:   m = (m << 8) + metric[2];
        !            61:   return m;
        !            62: }
        !            63: 
        !            64: 
        !            65: struct timeval
        !            66: tv_adjust (struct timeval a)
        !            67: {
        !            68:   while (a.tv_usec >= 1000000)
        !            69:     {
        !            70:       a.tv_usec -= 1000000;
        !            71:       a.tv_sec++;
        !            72:     }
        !            73: 
        !            74:   while (a.tv_usec < 0)
        !            75:     {
        !            76:       a.tv_usec += 1000000;
        !            77:       a.tv_sec--;
        !            78:     }
        !            79: 
        !            80:   return a;
        !            81: }
        !            82: 
        !            83: int
        !            84: tv_ceil (struct timeval a)
        !            85: {
        !            86:   a = tv_adjust (a);
        !            87: 
        !            88:   return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
        !            89: }
        !            90: 
        !            91: int
        !            92: tv_floor (struct timeval a)
        !            93: {
        !            94:   a = tv_adjust (a);
        !            95: 
        !            96:   return a.tv_sec;
        !            97: }
        !            98: 
        !            99: struct timeval
        !           100: int2tv (int a)
        !           101: {
        !           102:   struct timeval ret;
        !           103: 
        !           104:   ret.tv_sec = a;
        !           105:   ret.tv_usec = 0;
        !           106: 
        !           107:   return ret;
        !           108: }
        !           109: 
        !           110: struct timeval
        !           111: tv_add (struct timeval a, struct timeval b)
        !           112: {
        !           113:   struct timeval ret;
        !           114: 
        !           115:   ret.tv_sec = a.tv_sec + b.tv_sec;
        !           116:   ret.tv_usec = a.tv_usec + b.tv_usec;
        !           117: 
        !           118:   return tv_adjust (ret);
        !           119: }
        !           120: 
        !           121: struct timeval
        !           122: tv_sub (struct timeval a, struct timeval b)
        !           123: {
        !           124:   struct timeval ret;
        !           125: 
        !           126:   ret.tv_sec = a.tv_sec - b.tv_sec;
        !           127:   ret.tv_usec = a.tv_usec - b.tv_usec;
        !           128: 
        !           129:   return tv_adjust (ret);
        !           130: }
        !           131: 
        !           132: int
        !           133: tv_cmp (struct timeval a, struct timeval b)
        !           134: {
        !           135:   return (a.tv_sec == b.tv_sec ?
        !           136:          a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
        !           137: }
        !           138: 
        !           139: int
        !           140: ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
        !           141: {
        !           142:   struct timeval delta, now;
        !           143:   int delay = 0;
        !           144: 
        !           145:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
        !           146:   delta = tv_sub (now, lsa->tv_orig);
        !           147: 
        !           148:   if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
        !           149:     {
        !           150:       delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
        !           151: 
        !           152:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           153:         zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
        !           154:                   lsa->data->type, inet_ntoa (lsa->data->id), delay);
        !           155: 
        !           156:       assert (delay > 0);
        !           157:     }
        !           158: 
        !           159:   return delay;
        !           160: }
        !           161: 
        !           162: 
        !           163: int
        !           164: get_age (struct ospf_lsa *lsa)
        !           165: {
        !           166:   int age;
        !           167: 
        !           168:   age = ntohs (lsa->data->ls_age) 
        !           169:         + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
        !           170: 
        !           171:   return age;
        !           172: }
        !           173: 
        !           174: 
        !           175: /* Fletcher Checksum -- Refer to RFC1008. */
        !           176: 
        !           177: /* All the offsets are zero-based. The offsets in the RFC1008 are 
        !           178:    one-based. */
        !           179: u_int16_t
        !           180: ospf_lsa_checksum (struct lsa_header *lsa)
        !           181: {
        !           182:   u_char *buffer = (u_char *) &lsa->options;
        !           183:   int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
        !           184: 
        !           185:   /* Skip the AGE field */
        !           186:   u_int16_t len = ntohs(lsa->length) - options_offset; 
        !           187: 
        !           188:   /* Checksum offset starts from "options" field, not the beginning of the
        !           189:      lsa_header struct. The offset is 14, rather than 16. */
        !           190:   int checksum_offset = (u_char *) &lsa->checksum - buffer;
        !           191: 
        !           192:   return fletcher_checksum(buffer, len, checksum_offset);
        !           193: }
        !           194: 
        !           195: 
        !           196: 
        !           197: /* Create OSPF LSA. */
        !           198: struct ospf_lsa *
        !           199: ospf_lsa_new ()
        !           200: {
        !           201:   struct ospf_lsa *new;
        !           202: 
        !           203:   new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
        !           204: 
        !           205:   new->flags = 0;
        !           206:   new->lock = 1;
        !           207:   new->retransmit_counter = 0;
        !           208:   new->tv_recv = recent_relative_time ();
        !           209:   new->tv_orig = new->tv_recv;
        !           210:   new->refresh_list = -1;
        !           211:   
        !           212:   return new;
        !           213: }
        !           214: 
        !           215: /* Duplicate OSPF LSA. */
        !           216: struct ospf_lsa *
        !           217: ospf_lsa_dup (struct ospf_lsa *lsa)
        !           218: {
        !           219:   struct ospf_lsa *new;
        !           220: 
        !           221:   if (lsa == NULL)
        !           222:     return NULL;
        !           223: 
        !           224:   new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
        !           225: 
        !           226:   memcpy (new, lsa, sizeof (struct ospf_lsa));
        !           227:   UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
        !           228:   new->lock = 1;
        !           229:   new->retransmit_counter = 0;
        !           230:   new->data = ospf_lsa_data_dup (lsa->data);
        !           231: 
        !           232:   /* kevinm: Clear the refresh_list, otherwise there are going
        !           233:      to be problems when we try to remove the LSA from the
        !           234:      queue (which it's not a member of.)
        !           235:      XXX: Should we add the LSA to the refresh_list queue? */
        !           236:   new->refresh_list = -1;
        !           237: 
        !           238:   if (IS_DEBUG_OSPF (lsa, LSA))
        !           239:     zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
        !           240: 
        !           241:   return new;
        !           242: }
        !           243: 
        !           244: /* Free OSPF LSA. */
        !           245: void
        !           246: ospf_lsa_free (struct ospf_lsa *lsa)
        !           247: {
        !           248:   assert (lsa->lock == 0);
        !           249:   
        !           250:   if (IS_DEBUG_OSPF (lsa, LSA))
        !           251:     zlog_debug ("LSA: freed %p", lsa);
        !           252: 
        !           253:   /* Delete LSA data. */
        !           254:   if (lsa->data != NULL)
        !           255:     ospf_lsa_data_free (lsa->data);
        !           256: 
        !           257:   assert (lsa->refresh_list < 0);
        !           258: 
        !           259:   memset (lsa, 0, sizeof (struct ospf_lsa)); 
        !           260:   XFREE (MTYPE_OSPF_LSA, lsa);
        !           261: }
        !           262: 
        !           263: /* Lock LSA. */
        !           264: struct ospf_lsa *
        !           265: ospf_lsa_lock (struct ospf_lsa *lsa)
        !           266: {
        !           267:   lsa->lock++;
        !           268:   return lsa;
        !           269: }
        !           270: 
        !           271: /* Unlock LSA. */
        !           272: void
        !           273: ospf_lsa_unlock (struct ospf_lsa **lsa)
        !           274: {
        !           275:   /* This is sanity check. */
        !           276:   if (!lsa || !*lsa)
        !           277:     return;
        !           278:   
        !           279:   (*lsa)->lock--;
        !           280: 
        !           281:   assert ((*lsa)->lock >= 0);
        !           282: 
        !           283:   if ((*lsa)->lock == 0)
        !           284:     {
        !           285:       assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
        !           286:       ospf_lsa_free (*lsa);
        !           287:       *lsa = NULL;
        !           288:     }
        !           289: }
        !           290: 
        !           291: /* Check discard flag. */
        !           292: void
        !           293: ospf_lsa_discard (struct ospf_lsa *lsa)
        !           294: {
        !           295:   if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
        !           296:     {
        !           297:       SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
        !           298:       ospf_lsa_unlock (&lsa);
        !           299:     }
        !           300: }
        !           301: 
        !           302: /* Create LSA data. */
        !           303: struct lsa_header *
        !           304: ospf_lsa_data_new (size_t size)
        !           305: {
        !           306:   return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
        !           307: }
        !           308: 
        !           309: /* Duplicate LSA data. */
        !           310: struct lsa_header *
        !           311: ospf_lsa_data_dup (struct lsa_header *lsah)
        !           312: {
        !           313:   struct lsa_header *new;
        !           314: 
        !           315:   new = ospf_lsa_data_new (ntohs (lsah->length));
        !           316:   memcpy (new, lsah, ntohs (lsah->length));
        !           317: 
        !           318:   return new;
        !           319: }
        !           320: 
        !           321: /* Free LSA data. */
        !           322: void
        !           323: ospf_lsa_data_free (struct lsa_header *lsah)
        !           324: {
        !           325:   if (IS_DEBUG_OSPF (lsa, LSA))
        !           326:     zlog_debug ("LSA[Type%d:%s]: data freed %p",
        !           327:               lsah->type, inet_ntoa (lsah->id), lsah);
        !           328: 
        !           329:   XFREE (MTYPE_OSPF_LSA_DATA, lsah);
        !           330: }
        !           331: 
        !           332: 
        !           333: /* LSA general functions. */
        !           334: 
        !           335: const char *
        !           336: dump_lsa_key (struct ospf_lsa *lsa)
        !           337: {
        !           338:   static char buf[] = {
        !           339:     "Type255,id(255.255.255.255),ar(255.255.255.255)"
        !           340:   };
        !           341:   struct lsa_header *lsah;
        !           342: 
        !           343:   if (lsa != NULL && (lsah = lsa->data) != NULL)
        !           344:     {
        !           345:       char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
        !           346:       strcpy (id, inet_ntoa (lsah->id));
        !           347:       strcpy (ar, inet_ntoa (lsah->adv_router));
        !           348: 
        !           349:       sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
        !           350:     }
        !           351:   else
        !           352:     strcpy (buf, "NULL");
        !           353: 
        !           354:   return buf;
        !           355: }
        !           356: 
        !           357: u_int32_t
        !           358: lsa_seqnum_increment (struct ospf_lsa *lsa)
        !           359: {
        !           360:   u_int32_t seqnum;
        !           361: 
        !           362:   seqnum = ntohl (lsa->data->ls_seqnum) + 1;
        !           363: 
        !           364:   return htonl (seqnum);
        !           365: }
        !           366: 
        !           367: void
        !           368: lsa_header_set (struct stream *s, u_char options,
        !           369:                u_char type, struct in_addr id, struct in_addr router_id)
        !           370: {
        !           371:   struct lsa_header *lsah;
        !           372: 
        !           373:   lsah = (struct lsa_header *) STREAM_DATA (s);
        !           374: 
        !           375:   lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
        !           376:   lsah->options = options;
        !           377:   lsah->type = type;
        !           378:   lsah->id = id;
        !           379:   lsah->adv_router = router_id;
        !           380:   lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
        !           381: 
        !           382:   stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
        !           383: }
        !           384: 
        !           385: 
        !           386: /* router-LSA related functions. */
        !           387: /* Get router-LSA flags. */
        !           388: static u_char
        !           389: router_lsa_flags (struct ospf_area *area)
        !           390: {
        !           391:   u_char flags;
        !           392: 
        !           393:   flags = area->ospf->flags;
        !           394: 
        !           395:   /* Set virtual link flag. */
        !           396:   if (ospf_full_virtual_nbrs (area))
        !           397:     SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
        !           398:   else
        !           399:     /* Just sanity check */
        !           400:     UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
        !           401: 
        !           402:   /* Set Shortcut ABR behabiour flag. */
        !           403:   UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
        !           404:   if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
        !           405:     if (!OSPF_IS_AREA_BACKBONE (area))
        !           406:       if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
        !           407:           area->ospf->backbone == NULL) ||
        !           408:          area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
        !           409:        SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
        !           410: 
        !           411:   /* ASBR can't exit in stub area. */
        !           412:   if (area->external_routing == OSPF_AREA_STUB)
        !           413:     UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
        !           414:   /* If ASBR set External flag */
        !           415:   else if (IS_OSPF_ASBR (area->ospf))
        !           416:     SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
        !           417: 
        !           418:   /* Set ABR dependent flags */
        !           419:   if (IS_OSPF_ABR (area->ospf))
        !           420:     {
        !           421:       SET_FLAG (flags,  ROUTER_LSA_BORDER);
        !           422:       /* If Area is NSSA and we are both ABR and unconditional translator, 
        !           423:        * set Nt bit to inform other routers.
        !           424:        */
        !           425:       if ( (area->external_routing == OSPF_AREA_NSSA)
        !           426:            && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
        !           427:         SET_FLAG (flags, ROUTER_LSA_NT);
        !           428:     }
        !           429:   return flags;
        !           430: }
        !           431: 
        !           432: /* Lookup neighbor other than myself.
        !           433:    And check neighbor count,
        !           434:    Point-to-Point link must have only 1 neighbor. */
        !           435: struct ospf_neighbor *
        !           436: ospf_nbr_lookup_ptop (struct ospf_interface *oi)
        !           437: {
        !           438:   struct ospf_neighbor *nbr = NULL;
        !           439:   struct route_node *rn;
        !           440: 
        !           441:   /* Search neighbor, there must be one of two nbrs. */
        !           442:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
        !           443:     if ((nbr = rn->info))
        !           444:       if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
        !           445:        if (nbr->state == NSM_Full)
        !           446:          {
        !           447:            route_unlock_node (rn);
        !           448:            break;
        !           449:          }
        !           450: 
        !           451:   /* PtoP link must have only 1 neighbor. */
        !           452:   if (ospf_nbr_count (oi, 0) > 1)
        !           453:     zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
        !           454: 
        !           455:   return nbr;
        !           456: }
        !           457: 
        !           458: /* Determine cost of link, taking RFC3137 stub-router support into
        !           459:  * consideration
        !           460:  */
        !           461: static u_int16_t
        !           462: ospf_link_cost (struct ospf_interface *oi)
        !           463: {
        !           464:   /* RFC3137 stub router support */
        !           465:   if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
        !           466:     return oi->output_cost;
        !           467:   else
        !           468:     return OSPF_OUTPUT_COST_INFINITE;
        !           469: }
        !           470: 
        !           471: /* Set a link information. */
        !           472: static char
        !           473: link_info_set (struct stream *s, struct in_addr id,
        !           474:               struct in_addr data, u_char type, u_char tos, u_int16_t cost)
        !           475: {
        !           476:   /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
        !           477:    * vast majority of cases. Some rare routers with lots of links need more.
        !           478:    * we try accomodate those here.
        !           479:    */
        !           480:   if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
        !           481:     {
        !           482:       size_t ret = OSPF_MAX_LSA_SIZE;
        !           483:       
        !           484:       /* Can we enlarge the stream still? */
        !           485:       if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
        !           486:         {
        !           487:           /* we futz the size here for simplicity, really we need to account
        !           488:            * for just:
        !           489:            * IP Header - (sizeof (struct ip))
        !           490:            * OSPF Header - OSPF_HEADER_SIZE
        !           491:            * LSA Header - OSPF_LSA_HEADER_SIZE
        !           492:            * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
        !           493:            *
        !           494:            * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
        !           495:            */
        !           496:           ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
        !           497:         }
        !           498:       
        !           499:       if (ret == OSPF_MAX_LSA_SIZE)
        !           500:         {
        !           501:           zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
        !           502:                      __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
        !           503:           return 0;
        !           504:         }
        !           505:     }
        !           506:   
        !           507:   /* TOS based routing is not supported. */
        !           508:   stream_put_ipv4 (s, id.s_addr);              /* Link ID. */
        !           509:   stream_put_ipv4 (s, data.s_addr);            /* Link Data. */
        !           510:   stream_putc (s, type);                       /* Link Type. */
        !           511:   stream_putc (s, tos);                                /* TOS = 0. */
        !           512:   stream_putw (s, cost);                       /* Link Cost. */
        !           513:   
        !           514:   return 1;
        !           515: }
        !           516: 
        !           517: /* Describe Point-to-Point link (Section 12.4.1.1). */
        !           518: static int
        !           519: lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
        !           520: {
        !           521:   int links = 0;
        !           522:   struct ospf_neighbor *nbr;
        !           523:   struct in_addr id, mask;
        !           524:   u_int16_t cost = ospf_link_cost (oi);
        !           525: 
        !           526:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           527:     zlog_debug ("LSA[Type1]: Set link Point-to-Point");
        !           528: 
        !           529:   if ((nbr = ospf_nbr_lookup_ptop (oi)))
        !           530:     if (nbr->state == NSM_Full)
        !           531:       {
        !           532:        /* For unnumbered point-to-point networks, the Link Data field
        !           533:           should specify the interface's MIB-II ifIndex value. */
        !           534:        links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
        !           535:                                LSA_LINK_TYPE_POINTOPOINT, 0, cost);
        !           536:       }
        !           537: 
        !           538:   /* Regardless of the state of the neighboring router, we must
        !           539:      add a Type 3 link (stub network).
        !           540:      N.B. Options 1 & 2 share basically the same logic. */
        !           541:   masklen2ip (oi->address->prefixlen, &mask);
        !           542:   id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
        !           543:   links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
        !           544:                          oi->output_cost);
        !           545:   return links;
        !           546: }
        !           547: 
        !           548: /* Describe Broadcast Link. */
        !           549: static int
        !           550: lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
        !           551: {
        !           552:   struct ospf_neighbor *dr;
        !           553:   struct in_addr id, mask;
        !           554:   u_int16_t cost = ospf_link_cost (oi);
        !           555:   
        !           556:   /* Describe Type 3 Link. */
        !           557:   if (oi->state == ISM_Waiting)
        !           558:     {
        !           559:       masklen2ip (oi->address->prefixlen, &mask);
        !           560:       id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
        !           561:       return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
        !           562:                             oi->output_cost);
        !           563:     }
        !           564: 
        !           565:   dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
        !           566:   /* Describe Type 2 link. */
        !           567:   if (dr && (dr->state == NSM_Full ||
        !           568:             IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
        !           569:       ospf_nbr_count (oi, NSM_Full) > 0)
        !           570:     {
        !           571:       return link_info_set (s, DR (oi), oi->address->u.prefix4,
        !           572:                             LSA_LINK_TYPE_TRANSIT, 0, cost);
        !           573:     }
        !           574:   /* Describe type 3 link. */
        !           575:   else
        !           576:     {
        !           577:       masklen2ip (oi->address->prefixlen, &mask);
        !           578:       id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
        !           579:       return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
        !           580:                             oi->output_cost);
        !           581:     }
        !           582: }
        !           583: 
        !           584: static int
        !           585: lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
        !           586: {
        !           587:   struct in_addr id, mask;
        !           588:   
        !           589:   /* Describe Type 3 Link. */
        !           590:   if (oi->state != ISM_Loopback)
        !           591:     return 0;
        !           592: 
        !           593:   mask.s_addr = 0xffffffff;
        !           594:   id.s_addr = oi->address->u.prefix4.s_addr;
        !           595:   return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
        !           596: }
        !           597: 
        !           598: /* Describe Virtual Link. */
        !           599: static int
        !           600: lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
        !           601: {
        !           602:   struct ospf_neighbor *nbr;
        !           603:   u_int16_t cost = ospf_link_cost (oi);
        !           604: 
        !           605:   if (oi->state == ISM_PointToPoint)
        !           606:     if ((nbr = ospf_nbr_lookup_ptop (oi)))
        !           607:       if (nbr->state == NSM_Full)
        !           608:        {
        !           609:          return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
        !           610:                                LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
        !           611:        }
        !           612: 
        !           613:   return 0;
        !           614: }
        !           615: 
        !           616: #define lsa_link_nbma_set(S,O)  lsa_link_broadcast_set (S, O)
        !           617: 
        !           618: /* this function add for support point-to-multipoint ,see rfc2328 
        !           619: 12.4.1.4.*/
        !           620: /* from "edward rrr" <edward_rrr@hotmail.com>
        !           621:    http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
        !           622: static int
        !           623: lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
        !           624: {
        !           625:   int links = 0;
        !           626:   struct route_node *rn;
        !           627:   struct ospf_neighbor *nbr = NULL;
        !           628:   struct in_addr id, mask;
        !           629:   u_int16_t cost = ospf_link_cost (oi);
        !           630: 
        !           631:   mask.s_addr = 0xffffffff;
        !           632:   id.s_addr = oi->address->u.prefix4.s_addr;
        !           633:   links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
        !           634: 
        !           635:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           636:     zlog_debug ("PointToMultipoint: running ptomultip_set");
        !           637: 
        !           638:   /* Search neighbor, */
        !           639:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
        !           640:     if ((nbr = rn->info) != NULL)
        !           641:       /* Ignore myself. */
        !           642:       if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
        !           643:        if (nbr->state == NSM_Full)
        !           644: 
        !           645:          {
        !           646:            links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
        !           647:                                    LSA_LINK_TYPE_POINTOPOINT, 0, cost);
        !           648:             if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           649:              zlog_debug ("PointToMultipoint: set link to %s",
        !           650:                         inet_ntoa(oi->address->u.prefix4));
        !           651:          }
        !           652:   
        !           653:   return links;
        !           654: }
        !           655: 
        !           656: /* Set router-LSA link information. */
        !           657: static int
        !           658: router_lsa_link_set (struct stream *s, struct ospf_area *area)
        !           659: {
        !           660:   struct listnode *node;
        !           661:   struct ospf_interface *oi;
        !           662:   int links = 0;
        !           663: 
        !           664:   for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
        !           665:     {
        !           666:       struct interface *ifp = oi->ifp;
        !           667: 
        !           668:       /* Check interface is up, OSPF is enable. */
        !           669:       if (if_is_operative (ifp))
        !           670:        {
        !           671:          if (oi->state != ISM_Down)
        !           672:            {
        !           673:              /* Describe each link. */
        !           674:              switch (oi->type)
        !           675:                {
        !           676:                case OSPF_IFTYPE_POINTOPOINT:
        !           677:                  links += lsa_link_ptop_set (s, oi);
        !           678:                  break;
        !           679:                case OSPF_IFTYPE_BROADCAST:
        !           680:                  links += lsa_link_broadcast_set (s, oi);
        !           681:                  break;
        !           682:                case OSPF_IFTYPE_NBMA:
        !           683:                  links += lsa_link_nbma_set (s, oi);
        !           684:                  break;
        !           685:                case OSPF_IFTYPE_POINTOMULTIPOINT:
        !           686:                  links += lsa_link_ptomp_set (s, oi);
        !           687:                  break;
        !           688:                case OSPF_IFTYPE_VIRTUALLINK:
        !           689:                  links += lsa_link_virtuallink_set (s, oi);
        !           690:                  break;
        !           691:                case OSPF_IFTYPE_LOOPBACK:
        !           692:                  links += lsa_link_loopback_set (s, oi); 
        !           693:                }
        !           694:            }
        !           695:        }
        !           696:     }
        !           697: 
        !           698:   return links;
        !           699: }
        !           700: 
        !           701: /* Set router-LSA body. */
        !           702: static void
        !           703: ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
        !           704: {
        !           705:   unsigned long putp;
        !           706:   u_int16_t cnt;
        !           707: 
        !           708:   /* Set flags. */
        !           709:   stream_putc (s, router_lsa_flags (area));
        !           710: 
        !           711:   /* Set Zero fields. */
        !           712:   stream_putc (s, 0);
        !           713: 
        !           714:   /* Keep pointer to # links. */
        !           715:   putp = stream_get_endp(s);
        !           716: 
        !           717:   /* Forward word */
        !           718:   stream_putw(s, 0);
        !           719: 
        !           720:   /* Set all link information. */
        !           721:   cnt = router_lsa_link_set (s, area);
        !           722: 
        !           723:   /* Set # of links here. */
        !           724:   stream_putw_at (s, putp, cnt);
        !           725: }
        !           726: 
        !           727: static int
        !           728: ospf_stub_router_timer (struct thread *t)
        !           729: {
        !           730:   struct ospf_area *area = THREAD_ARG (t);
        !           731:   
        !           732:   area->t_stub_router = NULL;
        !           733:   
        !           734:   SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
        !           735:   
        !           736:   /* clear stub route state and generate router-lsa refresh, don't
        !           737:    * clobber an administratively set stub-router state though.
        !           738:    */
        !           739:   if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
        !           740:     return 0;
        !           741:   
        !           742:   UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
        !           743:   
        !           744:   ospf_router_lsa_update_area (area);
        !           745:   
        !           746:   return 0;
        !           747: }
        !           748: 
        !           749: inline static void
        !           750: ospf_stub_router_check (struct ospf_area *area)
        !           751: {
        !           752:   /* area must either be administratively configured to be stub
        !           753:    * or startup-time stub-router must be configured and we must in a pre-stub
        !           754:    * state.
        !           755:    */
        !           756:   if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
        !           757:     {
        !           758:       SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
        !           759:       return;
        !           760:     }
        !           761:   
        !           762:   /* not admin-stubbed, check whether startup stubbing is configured and
        !           763:    * whether it's not been done yet
        !           764:    */
        !           765:   if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
        !           766:     return;
        !           767:   
        !           768:   if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
        !           769:     {
        !           770:       /* stub-router is hence done forever for this area, even if someone
        !           771:        * tries configure it (take effect next restart).
        !           772:        */
        !           773:       SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
        !           774:       return;
        !           775:     }
        !           776:   
        !           777:   /* startup stub-router configured and not yet done */
        !           778:   SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
        !           779:   
        !           780:   OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
        !           781:                       area->ospf->stub_router_startup_time);
        !           782: }
        !           783:  
        !           784: /* Create new router-LSA. */
        !           785: static struct ospf_lsa *
        !           786: ospf_router_lsa_new (struct ospf_area *area)
        !           787: {
        !           788:   struct ospf *ospf = area->ospf;
        !           789:   struct stream *s;
        !           790:   struct lsa_header *lsah;
        !           791:   struct ospf_lsa *new;
        !           792:   int length;
        !           793: 
        !           794:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           795:     zlog_debug ("LSA[Type1]: Create router-LSA instance");
        !           796: 
        !           797:   /* check whether stub-router is desired, and if this is the first 
        !           798:    * router LSA.
        !           799:    */
        !           800:   ospf_stub_router_check (area);
        !           801:   
        !           802:   /* Create a stream for LSA. */
        !           803:   s = stream_new (OSPF_MAX_LSA_SIZE);
        !           804:   /* Set LSA common header fields. */
        !           805:   lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
        !           806:                  OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
        !           807: 
        !           808:   /* Set router-LSA body fields. */
        !           809:   ospf_router_lsa_body_set (s, area);
        !           810: 
        !           811:   /* Set length. */
        !           812:   length = stream_get_endp (s);
        !           813:   lsah = (struct lsa_header *) STREAM_DATA (s);
        !           814:   lsah->length = htons (length);
        !           815: 
        !           816:   /* Now, create OSPF LSA instance. */
        !           817:   if ( (new = ospf_lsa_new ()) == NULL)
        !           818:     {
        !           819:       zlog_err ("%s: Unable to create new lsa", __func__);
        !           820:       return NULL;
        !           821:     }
        !           822:   
        !           823:   new->area = area;
        !           824:   SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        !           825: 
        !           826:   /* Copy LSA data to store, discard stream. */
        !           827:   new->data = ospf_lsa_data_new (length);
        !           828:   memcpy (new->data, lsah, length);
        !           829:   stream_free (s);
        !           830: 
        !           831:   return new;
        !           832: }
        !           833: 
        !           834: /* Originate Router-LSA. */
        !           835: static struct ospf_lsa *
        !           836: ospf_router_lsa_originate (struct ospf_area *area)
        !           837: {
        !           838:   struct ospf_lsa *new;
        !           839:   
        !           840:   /* Create new router-LSA instance. */
        !           841:   if ( (new = ospf_router_lsa_new (area)) == NULL)
        !           842:     {
        !           843:       zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
        !           844:       return NULL;
        !           845:     }
        !           846: 
        !           847:   /* Sanity check. */
        !           848:   if (new->data->adv_router.s_addr == 0)
        !           849:     {
        !           850:       if (IS_DEBUG_OSPF_EVENT)
        !           851:        zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
        !           852:       ospf_lsa_discard (new);
        !           853:       return NULL;
        !           854:     }
        !           855: 
        !           856:   /* Install LSA to LSDB. */
        !           857:   new = ospf_lsa_install (area->ospf, NULL, new);
        !           858: 
        !           859:   /* Update LSA origination count. */
        !           860:   area->ospf->lsa_originate_count++;
        !           861: 
        !           862:   /* Flooding new LSA through area. */
        !           863:   ospf_flood_through_area (area, NULL, new);
        !           864: 
        !           865:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           866:     {
        !           867:       zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
        !           868:                 new->data->type, inet_ntoa (new->data->id), new);
        !           869:       ospf_lsa_header_dump (new->data);
        !           870:     }
        !           871: 
        !           872:   return new;
        !           873: }
        !           874: 
        !           875: /* Refresh router-LSA. */
        !           876: static struct ospf_lsa *
        !           877: ospf_router_lsa_refresh (struct ospf_lsa *lsa)
        !           878: {
        !           879:   struct ospf_area *area = lsa->area;
        !           880:   struct ospf_lsa *new;
        !           881: 
        !           882:   /* Sanity check. */
        !           883:   assert (lsa->data);
        !           884: 
        !           885:   /* Delete LSA from neighbor retransmit-list. */
        !           886:   ospf_ls_retransmit_delete_nbr_area (area, lsa);
        !           887: 
        !           888:   /* Unregister LSA from refresh-list */
        !           889:   ospf_refresher_unregister_lsa (area->ospf, lsa);
        !           890:   
        !           891:   /* Create new router-LSA instance. */
        !           892:   if ( (new = ospf_router_lsa_new (area)) == NULL)
        !           893:     {
        !           894:       zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
        !           895:       return NULL;
        !           896:     }
        !           897:   
        !           898:   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
        !           899: 
        !           900:   ospf_lsa_install (area->ospf, NULL, new);
        !           901: 
        !           902:   /* Flood LSA through area. */
        !           903:   ospf_flood_through_area (area, NULL, new);
        !           904: 
        !           905:   /* Debug logging. */
        !           906:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           907:     {
        !           908:       zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
        !           909:                 new->data->type, inet_ntoa (new->data->id));
        !           910:       ospf_lsa_header_dump (new->data);
        !           911:     }
        !           912: 
        !           913:   return NULL;
        !           914: }
        !           915: 
        !           916: int
        !           917: ospf_router_lsa_update_area (struct ospf_area *area)
        !           918: {
        !           919:   if (IS_DEBUG_OSPF_EVENT)
        !           920:     zlog_debug ("[router-LSA]: (router-LSA area update)");
        !           921: 
        !           922:   /* Now refresh router-LSA. */
        !           923:   if (area->router_lsa_self)
        !           924:     ospf_lsa_refresh (area->ospf, area->router_lsa_self);
        !           925:   /* Newly originate router-LSA. */
        !           926:   else
        !           927:     ospf_router_lsa_originate (area);
        !           928: 
        !           929:   return 0;
        !           930: }
        !           931: 
        !           932: int
        !           933: ospf_router_lsa_update (struct ospf *ospf)
        !           934: {
        !           935:   struct listnode *node, *nnode;
        !           936:   struct ospf_area *area;
        !           937: 
        !           938:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           939:     zlog_debug ("Timer[router-LSA Update]: (timer expire)");
        !           940: 
        !           941:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
        !           942:     {
        !           943:       struct ospf_lsa *lsa = area->router_lsa_self;
        !           944:       struct router_lsa *rl;
        !           945:       const char *area_str;
        !           946: 
        !           947:       /* Keep Area ID string. */
        !           948:       area_str = AREA_NAME (area);
        !           949: 
        !           950:       /* If LSA not exist in this Area, originate new. */
        !           951:       if (lsa == NULL)
        !           952:         {
        !           953:          if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           954:            zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
        !           955: 
        !           956:          ospf_router_lsa_originate (area);
        !           957:         }
        !           958:       /* If router-ID is changed, Link ID must change.
        !           959:         First flush old LSA, then originate new. */
        !           960:       else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
        !           961:        {
        !           962:          if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !           963:            zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
        !           964:                      lsa->data->type, inet_ntoa (lsa->data->id), area_str);
        !           965:           ospf_refresher_unregister_lsa (ospf, lsa);
        !           966:          ospf_lsa_flush_area (lsa, area);
        !           967:          ospf_lsa_unlock (&area->router_lsa_self);
        !           968:          area->router_lsa_self = NULL;
        !           969: 
        !           970:          /* Refresh router-LSA, (not install) and flood through area. */
        !           971:          ospf_router_lsa_update_area (area);
        !           972:        }
        !           973:       else
        !           974:        {
        !           975:          rl = (struct router_lsa *) lsa->data;
        !           976:          /* Refresh router-LSA, (not install) and flood through area. */
        !           977:          if (rl->flags != ospf->flags)
        !           978:            ospf_router_lsa_update_area (area);
        !           979:        }
        !           980:     }
        !           981: 
        !           982:   return 0;
        !           983: }
        !           984: 
        !           985: 
        !           986: /* network-LSA related functions. */
        !           987: /* Originate Network-LSA. */
        !           988: static void
        !           989: ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
        !           990: {
        !           991:   struct in_addr mask;
        !           992:   struct route_node *rn;
        !           993:   struct ospf_neighbor *nbr;
        !           994: 
        !           995:   masklen2ip (oi->address->prefixlen, &mask);
        !           996:   stream_put_ipv4 (s, mask.s_addr);
        !           997: 
        !           998:   /* The network-LSA lists those routers that are fully adjacent to
        !           999:     the Designated Router; each fully adjacent router is identified by
        !          1000:     its OSPF Router ID.  The Designated Router includes itself in this
        !          1001:     list. RFC2328, Section 12.4.2 */
        !          1002: 
        !          1003:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
        !          1004:     if ((nbr = rn->info) != NULL)
        !          1005:       if (nbr->state == NSM_Full || nbr == oi->nbr_self)
        !          1006:        stream_put_ipv4 (s, nbr->router_id.s_addr);
        !          1007: }
        !          1008: 
        !          1009: static struct ospf_lsa *
        !          1010: ospf_network_lsa_new (struct ospf_interface *oi)
        !          1011: {
        !          1012:   struct stream *s;
        !          1013:   struct ospf_lsa *new;
        !          1014:   struct lsa_header *lsah;
        !          1015:   struct ospf_if_params *oip;
        !          1016:   int length;
        !          1017: 
        !          1018:   /* If there are no neighbours on this network (the net is stub),
        !          1019:      the router does not originate network-LSA (see RFC 12.4.2) */
        !          1020:   if (oi->full_nbrs == 0)
        !          1021:     return NULL;
        !          1022:   
        !          1023:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1024:     zlog_debug ("LSA[Type2]: Create network-LSA instance");
        !          1025: 
        !          1026:   /* Create new stream for LSA. */
        !          1027:   s = stream_new (OSPF_MAX_LSA_SIZE);
        !          1028:   lsah = (struct lsa_header *) STREAM_DATA (s);
        !          1029: 
        !          1030:   lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
        !          1031:                  OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
        !          1032: 
        !          1033:   /* Set network-LSA body fields. */
        !          1034:   ospf_network_lsa_body_set (s, oi);
        !          1035: 
        !          1036:   /* Set length. */
        !          1037:   length = stream_get_endp (s);
        !          1038:   lsah->length = htons (length);
        !          1039: 
        !          1040:   /* Create OSPF LSA instance. */
        !          1041:   if ( (new = ospf_lsa_new ()) == NULL)
        !          1042:     {
        !          1043:       zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
        !          1044:       return NULL;
        !          1045:     }
        !          1046:   
        !          1047:   new->area = oi->area;
        !          1048:   SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        !          1049: 
        !          1050:   /* Copy LSA to store. */
        !          1051:   new->data = ospf_lsa_data_new (length);
        !          1052:   memcpy (new->data, lsah, length);
        !          1053:   stream_free (s);
        !          1054:   
        !          1055:   /* Remember prior network LSA sequence numbers, even if we stop
        !          1056:    * originating one for this oi, to try avoid re-originating LSAs with a
        !          1057:    * prior sequence number, and thus speed up adjency forming & convergence.
        !          1058:    */
        !          1059:   if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
        !          1060:     {
        !          1061:       new->data->ls_seqnum = oip->network_lsa_seqnum;
        !          1062:       new->data->ls_seqnum = lsa_seqnum_increment (new);
        !          1063:     }
        !          1064:   else
        !          1065:     {
        !          1066:       oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
        !          1067:       ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
        !          1068:     }
        !          1069:   oip->network_lsa_seqnum = new->data->ls_seqnum;
        !          1070:   
        !          1071:   return new;
        !          1072: }
        !          1073: 
        !          1074: /* Originate network-LSA. */
        !          1075: void
        !          1076: ospf_network_lsa_update (struct ospf_interface *oi)
        !          1077: {
        !          1078:   struct ospf_lsa *new;
        !          1079:   
        !          1080:   if (oi->network_lsa_self != NULL)
        !          1081:     {
        !          1082:       ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
        !          1083:       return;
        !          1084:     }
        !          1085:   
        !          1086:   /* Create new network-LSA instance. */
        !          1087:   new = ospf_network_lsa_new (oi);
        !          1088:   if (new == NULL)
        !          1089:     return;
        !          1090: 
        !          1091:   /* Install LSA to LSDB. */
        !          1092:   new = ospf_lsa_install (oi->ospf, oi, new);
        !          1093: 
        !          1094:   /* Update LSA origination count. */
        !          1095:   oi->ospf->lsa_originate_count++;
        !          1096: 
        !          1097:   /* Flooding new LSA through area. */
        !          1098:   ospf_flood_through_area (oi->area, NULL, new);
        !          1099: 
        !          1100:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1101:     {
        !          1102:       zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
        !          1103:                 new->data->type, inet_ntoa (new->data->id), new);
        !          1104:       ospf_lsa_header_dump (new->data);
        !          1105:     }
        !          1106: 
        !          1107:   return;
        !          1108: }
        !          1109: 
        !          1110: static struct ospf_lsa *
        !          1111: ospf_network_lsa_refresh (struct ospf_lsa *lsa)
        !          1112: {
        !          1113:   struct ospf_area *area = lsa->area;
        !          1114:   struct ospf_lsa *new, *new2;
        !          1115:   struct ospf_if_params *oip;
        !          1116:   struct ospf_interface *oi;
        !          1117:   
        !          1118:   assert (lsa->data);
        !          1119:   
        !          1120:   /* Retrieve the oi for the network LSA */
        !          1121:   oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
        !          1122:   if (oi == NULL)
        !          1123:     {
        !          1124:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1125:         {
        !          1126:           zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
        !          1127:                       "no oi found, ick, ignoring.",
        !          1128:                      lsa->data->type, inet_ntoa (lsa->data->id));
        !          1129:           ospf_lsa_header_dump (lsa->data);
        !          1130:         }
        !          1131:       return NULL;
        !          1132:     }
        !          1133:   /* Delete LSA from neighbor retransmit-list. */
        !          1134:   ospf_ls_retransmit_delete_nbr_area (area, lsa);
        !          1135: 
        !          1136:   /* Unregister LSA from refresh-list */
        !          1137:   ospf_refresher_unregister_lsa (area->ospf, lsa);
        !          1138:   
        !          1139:   /* Create new network-LSA instance. */
        !          1140:   new = ospf_network_lsa_new (oi);
        !          1141:   if (new == NULL)
        !          1142:     return NULL;
        !          1143:   
        !          1144:   oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
        !          1145:   assert (oip != NULL);
        !          1146:   oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
        !          1147: 
        !          1148:   new2 = ospf_lsa_install (area->ospf, oi, new);
        !          1149:   
        !          1150:   assert (new2 == new);
        !          1151:   
        !          1152:   /* Flood LSA through aera. */
        !          1153:   ospf_flood_through_area (area, NULL, new);
        !          1154: 
        !          1155:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1156:     {
        !          1157:       zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
        !          1158:                 new->data->type, inet_ntoa (new->data->id));
        !          1159:       ospf_lsa_header_dump (new->data);
        !          1160:     }
        !          1161: 
        !          1162:   return new;
        !          1163: }
        !          1164: 
        !          1165: static void
        !          1166: stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
        !          1167: {
        !          1168:   u_int32_t metric;
        !          1169:   char *mp;
        !          1170: 
        !          1171:   /* Put 0 metric. TOS metric is not supported. */
        !          1172:   metric = htonl (metric_value);
        !          1173:   mp = (char *) &metric;
        !          1174:   mp++;
        !          1175:   stream_put (s, mp, 3);
        !          1176: }
        !          1177: 
        !          1178: /* summary-LSA related functions. */
        !          1179: static void
        !          1180: ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
        !          1181:                           u_int32_t metric)
        !          1182: {
        !          1183:   struct in_addr mask;
        !          1184: 
        !          1185:   masklen2ip (p->prefixlen, &mask);
        !          1186: 
        !          1187:   /* Put Network Mask. */
        !          1188:   stream_put_ipv4 (s, mask.s_addr);
        !          1189: 
        !          1190:   /* Set # TOS. */
        !          1191:   stream_putc (s, (u_char) 0);
        !          1192: 
        !          1193:   /* Set metric. */
        !          1194:   stream_put_ospf_metric (s, metric);
        !          1195: }
        !          1196: 
        !          1197: static struct ospf_lsa *
        !          1198: ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
        !          1199:                      u_int32_t metric, struct in_addr id)
        !          1200: {
        !          1201:   struct stream *s;
        !          1202:   struct ospf_lsa *new;
        !          1203:   struct lsa_header *lsah;
        !          1204:   int length;
        !          1205: 
        !          1206:   if (id.s_addr == 0xffffffff)
        !          1207:     {
        !          1208:       /* Maybe Link State ID not available. */
        !          1209:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1210:         zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
        !          1211:                     OSPF_SUMMARY_LSA);
        !          1212:       return NULL;
        !          1213:     }
        !          1214: 
        !          1215:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1216:     zlog_debug ("LSA[Type3]: Create summary-LSA instance");
        !          1217: 
        !          1218:   /* Create new stream for LSA. */
        !          1219:   s = stream_new (OSPF_MAX_LSA_SIZE);
        !          1220:   lsah = (struct lsa_header *) STREAM_DATA (s);
        !          1221: 
        !          1222:   lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
        !          1223:                  id, area->ospf->router_id);
        !          1224: 
        !          1225:   /* Set summary-LSA body fields. */
        !          1226:   ospf_summary_lsa_body_set (s, p, metric);
        !          1227: 
        !          1228:   /* Set length. */
        !          1229:   length = stream_get_endp (s);
        !          1230:   lsah->length = htons (length);
        !          1231: 
        !          1232:   /* Create OSPF LSA instance. */
        !          1233:   new = ospf_lsa_new ();
        !          1234:   new->area = area;
        !          1235:   SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        !          1236: 
        !          1237:   /* Copy LSA to store. */
        !          1238:   new->data = ospf_lsa_data_new (length);
        !          1239:   memcpy (new->data, lsah, length);
        !          1240:   stream_free (s);
        !          1241: 
        !          1242:   return new;
        !          1243: }
        !          1244: 
        !          1245: /* Originate Summary-LSA. */
        !          1246: struct ospf_lsa *
        !          1247: ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric, 
        !          1248:                            struct ospf_area *area)
        !          1249: {
        !          1250:   struct ospf_lsa *new;
        !          1251:   struct in_addr id;
        !          1252:   
        !          1253:   id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
        !          1254: 
        !          1255:   if (id.s_addr == 0xffffffff)
        !          1256:     {
        !          1257:       /* Maybe Link State ID not available. */
        !          1258:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1259:         zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
        !          1260:                     OSPF_SUMMARY_LSA);
        !          1261:       return NULL;
        !          1262:     }
        !          1263:   
        !          1264:   /* Create new summary-LSA instance. */
        !          1265:   if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
        !          1266:     return NULL;
        !          1267: 
        !          1268:   /* Instlal LSA to LSDB. */
        !          1269:   new = ospf_lsa_install (area->ospf, NULL, new);
        !          1270: 
        !          1271:   /* Update LSA origination count. */
        !          1272:   area->ospf->lsa_originate_count++;
        !          1273: 
        !          1274:   /* Flooding new LSA through area. */
        !          1275:   ospf_flood_through_area (area, NULL, new);
        !          1276: 
        !          1277:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1278:     {
        !          1279:       zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
        !          1280:                 new->data->type, inet_ntoa (new->data->id), new);
        !          1281:       ospf_lsa_header_dump (new->data);
        !          1282:     }
        !          1283: 
        !          1284:   return new;
        !          1285: }
        !          1286: 
        !          1287: static struct ospf_lsa*
        !          1288: ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
        !          1289: {
        !          1290:   struct ospf_lsa *new;
        !          1291:   struct summary_lsa *sl;
        !          1292:   struct prefix p;
        !          1293:   
        !          1294:   /* Sanity check. */
        !          1295:   assert (lsa->data);
        !          1296: 
        !          1297:   sl = (struct summary_lsa *)lsa->data;
        !          1298:   p.prefixlen = ip_masklen (sl->mask);
        !          1299:   new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
        !          1300:                              sl->header.id);
        !          1301:   
        !          1302:   if (!new)
        !          1303:     return NULL;
        !          1304:   
        !          1305:   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
        !          1306: 
        !          1307:   ospf_lsa_install (ospf, NULL, new);
        !          1308:   
        !          1309:   /* Flood LSA through AS. */
        !          1310:   ospf_flood_through_area (new->area, NULL, new);
        !          1311: 
        !          1312:   /* Debug logging. */
        !          1313:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1314:     {
        !          1315:       zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
        !          1316:                 new->data->type, inet_ntoa (new->data->id));
        !          1317:       ospf_lsa_header_dump (new->data);
        !          1318:     }
        !          1319:   
        !          1320:   return new;
        !          1321: }
        !          1322: 
        !          1323: 
        !          1324: /* summary-ASBR-LSA related functions. */
        !          1325: static void
        !          1326: ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
        !          1327:                                u_int32_t metric)
        !          1328: {
        !          1329:   struct in_addr mask;
        !          1330: 
        !          1331:   masklen2ip (p->prefixlen, &mask);
        !          1332: 
        !          1333:   /* Put Network Mask. */
        !          1334:   stream_put_ipv4 (s, mask.s_addr);
        !          1335: 
        !          1336:   /* Set # TOS. */
        !          1337:   stream_putc (s, (u_char) 0);
        !          1338: 
        !          1339:   /* Set metric. */
        !          1340:   stream_put_ospf_metric (s, metric);
        !          1341: }
        !          1342: 
        !          1343: static struct ospf_lsa *
        !          1344: ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
        !          1345:                           u_int32_t metric, struct in_addr id)
        !          1346: {
        !          1347:   struct stream *s;
        !          1348:   struct ospf_lsa *new;
        !          1349:   struct lsa_header *lsah;
        !          1350:   int length;
        !          1351: 
        !          1352:   if (id.s_addr == 0xffffffff)
        !          1353:     {
        !          1354:       /* Maybe Link State ID not available. */
        !          1355:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1356:         zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
        !          1357:                     OSPF_ASBR_SUMMARY_LSA);
        !          1358:       return NULL;
        !          1359:     }
        !          1360: 
        !          1361:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1362:     zlog_debug ("LSA[Type3]: Create summary-LSA instance");
        !          1363: 
        !          1364:   /* Create new stream for LSA. */
        !          1365:   s = stream_new (OSPF_MAX_LSA_SIZE);
        !          1366:   lsah = (struct lsa_header *) STREAM_DATA (s);
        !          1367: 
        !          1368:   lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
        !          1369:                  id, area->ospf->router_id);
        !          1370: 
        !          1371:   /* Set summary-LSA body fields. */
        !          1372:   ospf_summary_asbr_lsa_body_set (s, p, metric);
        !          1373: 
        !          1374:   /* Set length. */
        !          1375:   length = stream_get_endp (s);
        !          1376:   lsah->length = htons (length);
        !          1377: 
        !          1378:   /* Create OSPF LSA instance. */
        !          1379:   new = ospf_lsa_new ();
        !          1380:   new->area = area;
        !          1381:   SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        !          1382: 
        !          1383:   /* Copy LSA to store. */
        !          1384:   new->data = ospf_lsa_data_new (length);
        !          1385:   memcpy (new->data, lsah, length);
        !          1386:   stream_free (s);
        !          1387: 
        !          1388:   return new;
        !          1389: }
        !          1390: 
        !          1391: /* Originate summary-ASBR-LSA. */
        !          1392: struct ospf_lsa *
        !          1393: ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric, 
        !          1394:                                 struct ospf_area *area)
        !          1395: {
        !          1396:   struct ospf_lsa *new;
        !          1397:   struct in_addr id;
        !          1398:   
        !          1399:   id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
        !          1400: 
        !          1401:   if (id.s_addr == 0xffffffff)
        !          1402:     {
        !          1403:       /* Maybe Link State ID not available. */
        !          1404:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1405:         zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
        !          1406:                     OSPF_ASBR_SUMMARY_LSA);
        !          1407:       return NULL;
        !          1408:     }
        !          1409:   
        !          1410:   /* Create new summary-LSA instance. */
        !          1411:   new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
        !          1412:   if (!new)
        !          1413:     return NULL;
        !          1414: 
        !          1415:   /* Install LSA to LSDB. */
        !          1416:   new = ospf_lsa_install (area->ospf, NULL, new);
        !          1417:   
        !          1418:   /* Update LSA origination count. */
        !          1419:   area->ospf->lsa_originate_count++;
        !          1420: 
        !          1421:   /* Flooding new LSA through area. */
        !          1422:   ospf_flood_through_area (area, NULL, new);
        !          1423: 
        !          1424:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1425:     {
        !          1426:       zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
        !          1427:                 new->data->type, inet_ntoa (new->data->id), new);
        !          1428:       ospf_lsa_header_dump (new->data);
        !          1429:     }
        !          1430: 
        !          1431:   return new;
        !          1432: }
        !          1433: 
        !          1434: static struct ospf_lsa*
        !          1435: ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
        !          1436: {
        !          1437:   struct ospf_lsa *new;
        !          1438:   struct summary_lsa *sl;
        !          1439:   struct prefix p;
        !          1440: 
        !          1441:   /* Sanity check. */
        !          1442:   assert (lsa->data);
        !          1443: 
        !          1444:   sl = (struct summary_lsa *)lsa->data;
        !          1445:   p.prefixlen = ip_masklen (sl->mask);
        !          1446:   new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
        !          1447:                                   sl->header.id);
        !          1448:   if (!new)
        !          1449:     return NULL;
        !          1450:   
        !          1451:   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
        !          1452: 
        !          1453:   ospf_lsa_install (ospf, NULL, new);
        !          1454:   
        !          1455:   /* Flood LSA through area. */
        !          1456:   ospf_flood_through_area (new->area, NULL, new);
        !          1457: 
        !          1458:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1459:     {
        !          1460:       zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
        !          1461:                 new->data->type, inet_ntoa (new->data->id));
        !          1462:       ospf_lsa_header_dump (new->data);
        !          1463:     }
        !          1464: 
        !          1465:   return new;
        !          1466: }
        !          1467: 
        !          1468: /* AS-external-LSA related functions. */
        !          1469: 
        !          1470: /* Get nexthop for AS-external-LSAs.  Return nexthop if its interface
        !          1471:    is connected, else 0*/
        !          1472: static struct in_addr
        !          1473: ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
        !          1474: {
        !          1475:   struct in_addr fwd;
        !          1476:   struct prefix nh;
        !          1477:   struct listnode *node;
        !          1478:   struct ospf_interface *oi;
        !          1479: 
        !          1480:   fwd.s_addr = 0;
        !          1481: 
        !          1482:   if (!nexthop.s_addr)
        !          1483:     return fwd;
        !          1484: 
        !          1485:   /* Check whether nexthop is covered by OSPF network. */
        !          1486:   nh.family = AF_INET;
        !          1487:   nh.u.prefix4 = nexthop;
        !          1488:   nh.prefixlen = IPV4_MAX_BITLEN;
        !          1489:   
        !          1490:   /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
        !          1491:    * better to make use of the per-ifp table of ois.
        !          1492:    */
        !          1493:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
        !          1494:     if (if_is_operative (oi->ifp))
        !          1495:       if (oi->address->family == AF_INET)
        !          1496:         if (prefix_match (oi->address, &nh))
        !          1497:           return nexthop;
        !          1498: 
        !          1499:   return fwd;
        !          1500: }
        !          1501: 
        !          1502: /* NSSA-external-LSA related functions. */
        !          1503: 
        !          1504: /* Get 1st IP connection for Forward Addr */
        !          1505: 
        !          1506: struct in_addr
        !          1507: ospf_get_ip_from_ifp (struct ospf_interface *oi)
        !          1508: {
        !          1509:   struct in_addr fwd;
        !          1510: 
        !          1511:   fwd.s_addr = 0;
        !          1512: 
        !          1513:   if (if_is_operative (oi->ifp))
        !          1514:     return oi->address->u.prefix4;
        !          1515:   
        !          1516:   return fwd;
        !          1517: }
        !          1518: 
        !          1519: /* Get 1st IP connection for Forward Addr */
        !          1520: struct in_addr
        !          1521: ospf_get_nssa_ip (struct ospf_area *area)
        !          1522: {
        !          1523:   struct in_addr fwd;
        !          1524:   struct in_addr best_default;
        !          1525:   struct listnode *node;
        !          1526:   struct ospf_interface *oi;
        !          1527: 
        !          1528:   fwd.s_addr = 0;
        !          1529:   best_default.s_addr = 0;
        !          1530: 
        !          1531:   for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
        !          1532:     {
        !          1533:       if (if_is_operative (oi->ifp))
        !          1534:        if (oi->area->external_routing == OSPF_AREA_NSSA)
        !          1535:          if (oi->address && oi->address->family == AF_INET)
        !          1536:            {
        !          1537:              if (best_default.s_addr == 0)
        !          1538:                best_default = oi->address->u.prefix4;
        !          1539:              if (oi->area == area)
        !          1540:                return oi->address->u.prefix4;
        !          1541:            }
        !          1542:     }
        !          1543:   if (best_default.s_addr != 0)
        !          1544:     return best_default;
        !          1545: 
        !          1546:   if (best_default.s_addr != 0)
        !          1547:     return best_default;
        !          1548: 
        !          1549:   return fwd;
        !          1550: }
        !          1551: 
        !          1552: #define DEFAULT_DEFAULT_METRIC              20
        !          1553: #define DEFAULT_DEFAULT_ORIGINATE_METRIC     10
        !          1554: #define DEFAULT_DEFAULT_ALWAYS_METRIC        1
        !          1555: 
        !          1556: #define DEFAULT_METRIC_TYPE                 EXTERNAL_METRIC_TYPE_2
        !          1557: 
        !          1558: int
        !          1559: metric_type (struct ospf *ospf, u_char src)
        !          1560: {
        !          1561:   return (ospf->dmetric[src].type < 0 ?
        !          1562:          DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
        !          1563: }
        !          1564: 
        !          1565: int
        !          1566: metric_value (struct ospf *ospf, u_char src)
        !          1567: {
        !          1568:   if (ospf->dmetric[src].value < 0)
        !          1569:     {
        !          1570:       if (src == DEFAULT_ROUTE)
        !          1571:        {
        !          1572:          if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
        !          1573:            return DEFAULT_DEFAULT_ORIGINATE_METRIC;
        !          1574:          else
        !          1575:            return DEFAULT_DEFAULT_ALWAYS_METRIC;
        !          1576:        }
        !          1577:       else if (ospf->default_metric < 0)
        !          1578:        return DEFAULT_DEFAULT_METRIC;
        !          1579:       else
        !          1580:        return ospf->default_metric;
        !          1581:     }
        !          1582: 
        !          1583:   return ospf->dmetric[src].value;
        !          1584: }
        !          1585: 
        !          1586: /* Set AS-external-LSA body. */
        !          1587: static void
        !          1588: ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
        !          1589:                            struct ospf *ospf)
        !          1590: {
        !          1591:   struct prefix_ipv4 *p = &ei->p;
        !          1592:   struct in_addr mask, fwd_addr;
        !          1593:   u_int32_t mvalue;
        !          1594:   int mtype;
        !          1595:   int type;
        !          1596: 
        !          1597:   /* Put Network Mask. */
        !          1598:   masklen2ip (p->prefixlen, &mask);
        !          1599:   stream_put_ipv4 (s, mask.s_addr);
        !          1600: 
        !          1601:   /* If prefix is default, specify DEFAULT_ROUTE. */
        !          1602:   type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
        !          1603:   
        !          1604:   mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
        !          1605:     ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
        !          1606: 
        !          1607:   mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
        !          1608:     ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
        !          1609: 
        !          1610:   /* Put type of external metric. */
        !          1611:   stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
        !          1612: 
        !          1613:   /* Put 0 metric. TOS metric is not supported. */
        !          1614:   stream_put_ospf_metric (s, mvalue);
        !          1615:   
        !          1616:   /* Get forwarding address to nexthop if on the Connection List, else 0. */
        !          1617:   fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
        !          1618: 
        !          1619:   /* Put forwarding address. */
        !          1620:   stream_put_ipv4 (s, fwd_addr.s_addr);
        !          1621:   
        !          1622:   /* Put route tag -- This value should be introduced from configuration. */
        !          1623:   stream_putl (s, 0);
        !          1624: }
        !          1625: 
        !          1626: /* Create new external-LSA. */
        !          1627: static struct ospf_lsa *
        !          1628: ospf_external_lsa_new (struct ospf *ospf,
        !          1629:                       struct external_info *ei, struct in_addr *old_id)
        !          1630: {
        !          1631:   struct stream *s;
        !          1632:   struct lsa_header *lsah;
        !          1633:   struct ospf_lsa *new;
        !          1634:   struct in_addr id;
        !          1635:   int length;
        !          1636: 
        !          1637:   if (ei == NULL)
        !          1638:     {
        !          1639:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1640:        zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
        !          1641:       return NULL;
        !          1642:     }
        !          1643: 
        !          1644:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1645:     zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
        !          1646: 
        !          1647:   /* If old Link State ID is specified, refresh LSA with same ID. */
        !          1648:   if (old_id)
        !          1649:     id = *old_id;
        !          1650:   /* Get Link State with unique ID. */
        !          1651:   else
        !          1652:     {
        !          1653:       id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
        !          1654:       if (id.s_addr == 0xffffffff)
        !          1655:        {
        !          1656:          /* Maybe Link State ID not available. */
        !          1657:          if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          1658:            zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
        !          1659:          return NULL;
        !          1660:        }
        !          1661:     }
        !          1662: 
        !          1663:   /* Create new stream for LSA. */
        !          1664:   s = stream_new (OSPF_MAX_LSA_SIZE);
        !          1665:   lsah = (struct lsa_header *) STREAM_DATA (s);
        !          1666: 
        !          1667:   /* Set LSA common header fields. */
        !          1668:   lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
        !          1669:                  id, ospf->router_id);
        !          1670: 
        !          1671:   /* Set AS-external-LSA body fields. */
        !          1672:   ospf_external_lsa_body_set (s, ei, ospf);
        !          1673: 
        !          1674:   /* Set length. */
        !          1675:   length = stream_get_endp (s);
        !          1676:   lsah->length = htons (length);
        !          1677: 
        !          1678:   /* Now, create OSPF LSA instance. */
        !          1679:   new = ospf_lsa_new ();
        !          1680:   new->area = NULL;
        !          1681:   SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
        !          1682: 
        !          1683:   /* Copy LSA data to store, discard stream. */
        !          1684:   new->data = ospf_lsa_data_new (length);
        !          1685:   memcpy (new->data, lsah, length);
        !          1686:   stream_free (s);
        !          1687: 
        !          1688:   return new;
        !          1689: }
        !          1690: 
        !          1691: /* As Type-7 */
        !          1692: static void
        !          1693: ospf_install_flood_nssa (struct ospf *ospf, 
        !          1694:                         struct ospf_lsa *lsa, struct external_info *ei)
        !          1695: {
        !          1696:   struct ospf_lsa *new;
        !          1697:   struct as_external_lsa *extlsa;
        !          1698:   struct ospf_area *area;
        !          1699:   struct listnode *node, *nnode;
        !          1700: 
        !          1701:   /* LSA may be a Type-5 originated via translation of a Type-7 LSA
        !          1702:    * which originated from an NSSA area. In which case it should not be 
        !          1703:    * flooded back to NSSA areas.
        !          1704:    */
        !          1705:   if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
        !          1706:     return;
        !          1707:     
        !          1708:   /* NSSA Originate or Refresh (If anyNSSA)
        !          1709: 
        !          1710:   LSA is self-originated. And just installed as Type-5.
        !          1711:   Additionally, install as Type-7 LSDB for every attached NSSA.
        !          1712: 
        !          1713:   P-Bit controls which ABR performs translation to outside world; If
        !          1714:   we are an ABR....do not set the P-bit, because we send the Type-5,
        !          1715:   not as the ABR Translator, but as the ASBR owner within the AS!
        !          1716: 
        !          1717:   If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set.  The
        !          1718:   elected ABR Translator will see the P-bit, Translate, and re-flood.
        !          1719: 
        !          1720:   Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
        !          1721:   Type-5's to non-NSSA Areas.  (it will also attempt a re-install) */
        !          1722: 
        !          1723:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
        !          1724:     {
        !          1725:       /* Don't install Type-7 LSA's into nonNSSA area */
        !          1726:       if (area->external_routing != OSPF_AREA_NSSA)
        !          1727:         continue;
        !          1728: 
        !          1729:       /* make lsa duplicate, lock=1 */
        !          1730:       new = ospf_lsa_dup (lsa);
        !          1731:       new->area = area;
        !          1732:       new->data->type = OSPF_AS_NSSA_LSA;
        !          1733: 
        !          1734:       /* set P-bit if not ABR */
        !          1735:       if (! IS_OSPF_ABR (ospf))
        !          1736:         {
        !          1737:          SET_FLAG(new->data->options, OSPF_OPTION_NP);
        !          1738:        
        !          1739:          /* set non-zero FWD ADDR
        !          1740:        
        !          1741:          draft-ietf-ospf-nssa-update-09.txt
        !          1742:        
        !          1743:          if the network between the NSSA AS boundary router and the
        !          1744:          adjacent AS is advertised into OSPF as an internal OSPF route,
        !          1745:          the forwarding address should be the next op address as is cu
        !          1746:          currently done with type-5 LSAs.  If the intervening network is
        !          1747:          not adversited into OSPF as an internal OSPF route and the
        !          1748:          type-7 LSA's P-bit is set a forwarding address should be
        !          1749:          selected from one of the router's active OSPF inteface addresses
        !          1750:          which belong to the NSSA.  If no such addresses exist, then
        !          1751:          no type-7 LSA's with the P-bit set should originate from this
        !          1752:          router.   */
        !          1753:        
        !          1754:          /* kevinm: not updating lsa anymore, just new */
        !          1755:          extlsa = (struct as_external_lsa *)(new->data);
        !          1756:        
        !          1757:          if (extlsa->e[0].fwd_addr.s_addr == 0)
        !          1758:            extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
        !          1759: 
        !          1760:          if (extlsa->e[0].fwd_addr.s_addr == 0) 
        !          1761:          {
        !          1762:            if (IS_DEBUG_OSPF_NSSA)
        !          1763:              zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
        !          1764:            ospf_lsa_discard (new);
        !          1765:            return;
        !          1766:          }
        !          1767:        }
        !          1768: 
        !          1769:       /* install also as Type-7 */
        !          1770:       ospf_lsa_install (ospf, NULL, new);   /* Remove Old, Lock New = 2 */
        !          1771: 
        !          1772:       /* will send each copy, lock=2+n */
        !          1773:       ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
        !          1774:     }
        !          1775: }
        !          1776: 
        !          1777: static struct ospf_lsa *
        !          1778: ospf_lsa_translated_nssa_new (struct ospf *ospf, 
        !          1779:                              struct ospf_lsa *type7)
        !          1780: {
        !          1781: 
        !          1782:   struct ospf_lsa *new;
        !          1783:   struct as_external_lsa *ext, *extnew;
        !          1784:   struct external_info ei;
        !          1785:   
        !          1786:   ext = (struct as_external_lsa *)(type7->data);
        !          1787: 
        !          1788:   /* need external_info struct, fill in bare minimum */  
        !          1789:   ei.p.family = AF_INET;
        !          1790:   ei.p.prefix = type7->data->id;
        !          1791:   ei.p.prefixlen = ip_masklen (ext->mask);
        !          1792:   ei.type = ZEBRA_ROUTE_OSPF;
        !          1793:   ei.nexthop = ext->header.adv_router;
        !          1794:   ei.route_map_set.metric = -1;
        !          1795:   ei.route_map_set.metric_type = -1;
        !          1796:   ei.tag = 0;
        !          1797:   
        !          1798:   if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
        !          1799:   {
        !          1800:     if (IS_DEBUG_OSPF_NSSA)
        !          1801:       zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
        !          1802:                  "Translated Type-5 for %s", 
        !          1803:                  inet_ntoa (ei.p.prefix));
        !          1804:     return NULL;
        !          1805:   }
        !          1806: 
        !          1807:   extnew = (struct as_external_lsa *)(new->data);
        !          1808:    
        !          1809:   /* copy over Type-7 data to new */
        !          1810:   extnew->e[0].tos = ext->e[0].tos;
        !          1811:   extnew->e[0].route_tag = ext->e[0].route_tag;
        !          1812:   extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
        !          1813:   new->data->ls_seqnum = type7->data->ls_seqnum;
        !          1814: 
        !          1815:   /* add translated flag, checksum and lock new lsa */
        !          1816:   SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7  */   
        !          1817:   new = ospf_lsa_lock (new);
        !          1818:   
        !          1819:   return new; 
        !          1820: }
        !          1821: 
        !          1822: /* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
        !          1823: struct ospf_lsa *
        !          1824: ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
        !          1825: {
        !          1826:   struct ospf_lsa *new;
        !          1827:   struct as_external_lsa *extnew;
        !          1828:   
        !          1829:   /* we cant use ospf_external_lsa_originate() as we need to set
        !          1830:    * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
        !          1831:    */
        !          1832:   
        !          1833:   if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
        !          1834:     {
        !          1835:       if (IS_DEBUG_OSPF_NSSA)
        !          1836:         zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
        !          1837:                  "Type-7, Id %s, to Type-5",
        !          1838:                  inet_ntoa (type7->data->id));
        !          1839:       return NULL;
        !          1840:     }
        !          1841:     
        !          1842:   extnew = (struct as_external_lsa *)new;
        !          1843:   
        !          1844:   if (IS_DEBUG_OSPF_NSSA)
        !          1845:     {
        !          1846:       zlog_debug ("ospf_translated_nssa_originate(): "
        !          1847:                  "translated Type 7, installed:");
        !          1848:       ospf_lsa_header_dump (new->data);
        !          1849:       zlog_debug ("   Network mask: %d",ip_masklen (extnew->mask));
        !          1850:       zlog_debug ("   Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
        !          1851:     }
        !          1852:   
        !          1853:   if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
        !          1854:     {
        !          1855:       if (IS_DEBUG_OSPF_NSSA);
        !          1856:         zlog_debug ("ospf_lsa_translated_nssa_originate(): "
        !          1857:                    "Could not install LSA "
        !          1858:                    "id %s", inet_ntoa (type7->data->id));
        !          1859:       return NULL;
        !          1860:     }
        !          1861:     
        !          1862:   ospf->lsa_originate_count++;
        !          1863:   ospf_flood_through_as (ospf, NULL, new);
        !          1864: 
        !          1865:   return new;
        !          1866: }
        !          1867: 
        !          1868: /* Refresh Translated from NSSA AS-external-LSA. */
        !          1869: struct ospf_lsa *
        !          1870: ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7, 
        !          1871:                               struct ospf_lsa *type5)
        !          1872: {
        !          1873:   struct ospf_lsa *new = NULL;
        !          1874:   
        !          1875:   /* Sanity checks. */
        !          1876:   assert (type7 || type5);
        !          1877:   if (!(type7 || type5))
        !          1878:     return NULL;
        !          1879:   if (type7)
        !          1880:     assert (type7->data);
        !          1881:   if (type5)
        !          1882:     assert (type5->data);
        !          1883:   assert (ospf->anyNSSA);
        !          1884: 
        !          1885:   /* get required data according to what has been given */
        !          1886:   if (type7 && type5 == NULL)
        !          1887:     {
        !          1888:       /* find the translated Type-5 for this Type-7 */
        !          1889:       struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
        !          1890:       struct prefix_ipv4 p = 
        !          1891:         { 
        !          1892:           .prefix = type7->data->id,
        !          1893:           .prefixlen = ip_masklen (ext->mask),
        !          1894:           .family = AF_INET,
        !          1895:         };
        !          1896: 
        !          1897:       type5 = ospf_external_info_find_lsa (ospf, &p);
        !          1898:     }
        !          1899:   else if (type5 && type7 == NULL)
        !          1900:     {
        !          1901:       /* find the type-7 from which supplied type-5 was translated,
        !          1902:        * ie find first type-7 with same LSA Id.
        !          1903:        */
        !          1904:       struct listnode *ln, *lnn;
        !          1905:       struct route_node *rn;
        !          1906:       struct ospf_lsa *lsa;
        !          1907:       struct ospf_area *area;
        !          1908:           
        !          1909:       for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
        !          1910:         {
        !          1911:           if (area->external_routing != OSPF_AREA_NSSA 
        !          1912:               && !type7)
        !          1913:             continue;
        !          1914:             
        !          1915:           LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
        !          1916:             {
        !          1917:               if (lsa->data->id.s_addr == type5->data->id.s_addr)
        !          1918:                 {
        !          1919:                   type7 = lsa;
        !          1920:                   break;
        !          1921:                 }
        !          1922:             }
        !          1923:         }
        !          1924:     }
        !          1925: 
        !          1926:   /* do we have type7? */
        !          1927:   if (!type7)
        !          1928:     {
        !          1929:       if (IS_DEBUG_OSPF_NSSA)
        !          1930:         zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
        !          1931:                    "Type-5 LSA Id %s",
        !          1932:                    inet_ntoa (type5->data->id));
        !          1933:       return NULL;
        !          1934:     }
        !          1935: 
        !          1936:   /* do we have valid translated type5? */
        !          1937:   if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
        !          1938:     {
        !          1939:       if (IS_DEBUG_OSPF_NSSA)
        !          1940:         zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
        !          1941:                    "found for Type-7 with Id %s",
        !          1942:                    inet_ntoa (type7->data->id));
        !          1943:       return NULL;
        !          1944:     }
        !          1945: 
        !          1946:   /* Delete LSA from neighbor retransmit-list. */
        !          1947:   ospf_ls_retransmit_delete_nbr_as (ospf, type5);
        !          1948:   
        !          1949:   /* create new translated LSA */
        !          1950:   if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
        !          1951:     {
        !          1952:       if (IS_DEBUG_OSPF_NSSA)
        !          1953:         zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
        !          1954:                    "Type-7 for %s to Type-5",
        !          1955:                    inet_ntoa (type7->data->id));
        !          1956:       return NULL;
        !          1957:     }
        !          1958: 
        !          1959:   if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
        !          1960:     {
        !          1961:       if (IS_DEBUG_OSPF_NSSA)
        !          1962:         zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
        !          1963:                    "translated LSA, Id %s",
        !          1964:                    inet_ntoa (type7->data->id));
        !          1965:       return NULL;
        !          1966:     }
        !          1967:   
        !          1968:   /* Flood LSA through area. */
        !          1969:   ospf_flood_through_as (ospf, NULL, new);
        !          1970: 
        !          1971:   return new;
        !          1972: }
        !          1973: 
        !          1974: int
        !          1975: is_prefix_default (struct prefix_ipv4 *p)
        !          1976: {
        !          1977:   struct prefix_ipv4 q;
        !          1978: 
        !          1979:   q.family = AF_INET;
        !          1980:   q.prefix.s_addr = 0;
        !          1981:   q.prefixlen = 0;
        !          1982: 
        !          1983:   return prefix_same ((struct prefix *) p, (struct prefix *) &q);
        !          1984: }
        !          1985: 
        !          1986: /* Originate an AS-external-LSA, install and flood. */
        !          1987: struct ospf_lsa *
        !          1988: ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
        !          1989: {
        !          1990:   struct ospf_lsa *new;
        !          1991: 
        !          1992:   /* Added for NSSA project....
        !          1993: 
        !          1994:        External LSAs are originated in ASBRs as usual, but for NSSA systems.
        !          1995:      there is the global Type-5 LSDB and a Type-7 LSDB installed for
        !          1996:      every area.  The Type-7's are flooded to every IR and every ABR; We
        !          1997:      install the Type-5 LSDB so that the normal "refresh" code operates
        !          1998:      as usual, and flag them as not used during ASE calculations.  The
        !          1999:      Type-7 LSDB is used for calculations.  Each Type-7 has a Forwarding
        !          2000:      Address of non-zero.
        !          2001: 
        !          2002:      If an ABR is the elected NSSA translator, following SPF and during
        !          2003:      the ABR task it will translate all the scanned Type-7's, with P-bit
        !          2004:      ON and not-self generated, and translate to Type-5's throughout the
        !          2005:      non-NSSA/STUB AS.
        !          2006: 
        !          2007:      A difference in operation depends whether this ASBR is an ABR
        !          2008:      or not.  If not an ABR, the P-bit is ON, to indicate that any
        !          2009:      elected NSSA-ABR can perform its translation.
        !          2010: 
        !          2011:      If an ABR, the P-bit is OFF;  No ABR will perform translation and
        !          2012:      this ASBR will flood the Type-5 LSA as usual.
        !          2013: 
        !          2014:      For the case where this ASBR is not an ABR, the ASE calculations
        !          2015:      are based on the Type-5 LSDB;  The Type-7 LSDB exists just to
        !          2016:      demonstrate to the user that there are LSA's that belong to any
        !          2017:      attached NSSA.
        !          2018: 
        !          2019:      Finally, it just so happens that when the ABR is translating every
        !          2020:      Type-7 into Type-5, it installs it into the Type-5 LSDB as an
        !          2021:      approved Type-5 (translated from Type-7);  at the end of translation
        !          2022:      if any Translated Type-5's remain unapproved, then they must be
        !          2023:      flushed from the AS.
        !          2024: 
        !          2025:      */
        !          2026:   
        !          2027:   /* Check the AS-external-LSA should be originated. */
        !          2028:   if (!ospf_redistribute_check (ospf, ei, NULL))
        !          2029:     return NULL;
        !          2030:   
        !          2031:   /* Create new AS-external-LSA instance. */
        !          2032:   if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
        !          2033:     {
        !          2034:       if (IS_DEBUG_OSPF_EVENT)
        !          2035:        zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
        !          2036:                   inet_ntoa (ei->p.prefix));
        !          2037:       return NULL;
        !          2038:     }
        !          2039: 
        !          2040:   /* Install newly created LSA into Type-5 LSDB, lock = 1. */
        !          2041:   ospf_lsa_install (ospf, NULL, new);
        !          2042: 
        !          2043:   /* Update LSA origination count. */
        !          2044:   ospf->lsa_originate_count++;
        !          2045: 
        !          2046:   /* Flooding new LSA. only to AS (non-NSSA/STUB) */
        !          2047:   ospf_flood_through_as (ospf, NULL, new);
        !          2048: 
        !          2049:   /* If there is any attached NSSA, do special handling */
        !          2050:   if (ospf->anyNSSA &&
        !          2051:       /* stay away from translated LSAs! */
        !          2052:       !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
        !          2053:     ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
        !          2054: 
        !          2055:   /* Debug logging. */
        !          2056:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          2057:     {
        !          2058:       zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
        !          2059:                 new->data->type, inet_ntoa (new->data->id), new);
        !          2060:       ospf_lsa_header_dump (new->data);
        !          2061:     }
        !          2062: 
        !          2063:   return new;
        !          2064: }
        !          2065: 
        !          2066: /* Originate AS-external-LSA from external info with initial flag. */
        !          2067: int
        !          2068: ospf_external_lsa_originate_timer (struct thread *thread)
        !          2069: {
        !          2070:   struct ospf *ospf = THREAD_ARG (thread);
        !          2071:   struct route_node *rn;
        !          2072:   struct external_info *ei;
        !          2073:   struct route_table *rt;
        !          2074:   int type = THREAD_VAL (thread);
        !          2075: 
        !          2076:   ospf->t_external_lsa = NULL;
        !          2077: 
        !          2078:   /* Originate As-external-LSA from all type of distribute source. */
        !          2079:   if ((rt = EXTERNAL_INFO (type)))
        !          2080:     for (rn = route_top (rt); rn; rn = route_next (rn))
        !          2081:       if ((ei = rn->info) != NULL)
        !          2082:        if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
        !          2083:          if (!ospf_external_lsa_originate (ospf, ei))
        !          2084:            zlog_warn ("LSA: AS-external-LSA was not originated.");
        !          2085:   
        !          2086:   return 0;
        !          2087: }
        !          2088: 
        !          2089: static struct external_info *
        !          2090: ospf_default_external_info (struct ospf *ospf)
        !          2091: {
        !          2092:   int type;
        !          2093:   struct route_node *rn;
        !          2094:   struct prefix_ipv4 p;
        !          2095:   
        !          2096:   p.family = AF_INET;
        !          2097:   p.prefix.s_addr = 0;
        !          2098:   p.prefixlen = 0;
        !          2099: 
        !          2100:   /* First, lookup redistributed default route. */
        !          2101:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
        !          2102:     if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
        !          2103:       {
        !          2104:        rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
        !          2105:        if (rn != NULL)
        !          2106:          {
        !          2107:            route_unlock_node (rn);
        !          2108:            assert (rn->info);
        !          2109:            if (ospf_redistribute_check (ospf, rn->info, NULL))
        !          2110:              return rn->info;
        !          2111:          }
        !          2112:       }
        !          2113: 
        !          2114:   return NULL;
        !          2115: }
        !          2116: 
        !          2117: int
        !          2118: ospf_default_originate_timer (struct thread *thread)
        !          2119: {
        !          2120:   struct prefix_ipv4 p;
        !          2121:   struct in_addr nexthop;
        !          2122:   struct external_info *ei;
        !          2123:   struct ospf *ospf;
        !          2124:   
        !          2125:   ospf = THREAD_ARG (thread);
        !          2126: 
        !          2127:   p.family = AF_INET;
        !          2128:   p.prefix.s_addr = 0;
        !          2129:   p.prefixlen = 0;
        !          2130: 
        !          2131:   if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
        !          2132:     {
        !          2133:       /* If there is no default route via redistribute,
        !          2134:         then originate AS-external-LSA with nexthop 0 (self). */
        !          2135:       nexthop.s_addr = 0;
        !          2136:       ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
        !          2137:     }
        !          2138: 
        !          2139:   if ((ei = ospf_default_external_info (ospf)))
        !          2140:     ospf_external_lsa_originate (ospf, ei);
        !          2141:   
        !          2142:   return 0;
        !          2143: }
        !          2144: 
        !          2145: /* Flush any NSSA LSAs for given prefix */
        !          2146: void
        !          2147: ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
        !          2148: {
        !          2149:   struct listnode *node, *nnode;
        !          2150:   struct ospf_lsa *lsa;
        !          2151:   struct ospf_area *area;
        !          2152: 
        !          2153:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
        !          2154:   {
        !          2155:     if (area->external_routing == OSPF_AREA_NSSA)
        !          2156:     {
        !          2157:       if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
        !          2158:                                 ospf->router_id))) 
        !          2159:       {
        !          2160:         if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) 
        !          2161:           zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
        !          2162:                     inet_ntoa (p->prefix), p->prefixlen);
        !          2163:         continue;
        !          2164:       }
        !          2165:       ospf_ls_retransmit_delete_nbr_area (area, lsa);
        !          2166:       if (!IS_LSA_MAXAGE (lsa)) 
        !          2167:       {
        !          2168:         ospf_refresher_unregister_lsa (ospf, lsa);
        !          2169:         ospf_lsa_flush_area (lsa, area);
        !          2170:       }
        !          2171:     }
        !          2172:   }
        !          2173: }
        !          2174: 
        !          2175: /* Flush an AS-external-LSA from LSDB and routing domain. */
        !          2176: void
        !          2177: ospf_external_lsa_flush (struct ospf *ospf,
        !          2178:                         u_char type, struct prefix_ipv4 *p,
        !          2179:                         unsigned int ifindex /*, struct in_addr nexthop */)
        !          2180: {
        !          2181:   struct ospf_lsa *lsa;
        !          2182: 
        !          2183:   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2184:     zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
        !          2185:               inet_ntoa (p->prefix), p->prefixlen);
        !          2186: 
        !          2187:   /* First lookup LSA from LSDB. */
        !          2188:   if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
        !          2189:     {
        !          2190:       if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2191:        zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
        !          2192:                   inet_ntoa (p->prefix), p->prefixlen);
        !          2193:       return;
        !          2194:     }
        !          2195: 
        !          2196:   /* If LSA is selforiginated, not a translated LSA, and there is 
        !          2197:    * NSSA area, flush Type-7 LSA's at first. 
        !          2198:    */
        !          2199:   if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
        !          2200:       && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
        !          2201:     ospf_nssa_lsa_flush (ospf, p);
        !          2202: 
        !          2203:   /* Sweep LSA from Link State Retransmit List. */
        !          2204:   ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
        !          2205: 
        !          2206:   /* There must be no self-originated LSA in rtrs_external. */
        !          2207: #if 0
        !          2208:   /* Remove External route from Zebra. */
        !          2209:   ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
        !          2210: #endif
        !          2211: 
        !          2212:   if (!IS_LSA_MAXAGE (lsa))
        !          2213:     {
        !          2214:       /* Unregister LSA from Refresh queue. */
        !          2215:       ospf_refresher_unregister_lsa (ospf, lsa);
        !          2216: 
        !          2217:       /* Flush AS-external-LSA through AS. */
        !          2218:       ospf_lsa_flush_as (ospf, lsa);
        !          2219:     }
        !          2220: 
        !          2221:   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2222:     zlog_debug ("ospf_external_lsa_flush(): stop");
        !          2223: }
        !          2224: 
        !          2225: void
        !          2226: ospf_external_lsa_refresh_default (struct ospf *ospf)
        !          2227: {
        !          2228:   struct prefix_ipv4 p;
        !          2229:   struct external_info *ei;
        !          2230:   struct ospf_lsa *lsa;
        !          2231: 
        !          2232:   p.family = AF_INET;
        !          2233:   p.prefixlen = 0;
        !          2234:   p.prefix.s_addr = 0;
        !          2235: 
        !          2236:   ei = ospf_default_external_info (ospf);
        !          2237:   lsa = ospf_external_info_find_lsa (ospf, &p);
        !          2238: 
        !          2239:   if (ei)
        !          2240:     {
        !          2241:       if (lsa)
        !          2242:        {
        !          2243:          if (IS_DEBUG_OSPF_EVENT)
        !          2244:            zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
        !          2245:          ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
        !          2246:        }
        !          2247:       else
        !          2248:        {
        !          2249:          if (IS_DEBUG_OSPF_EVENT)
        !          2250:            zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
        !          2251:          ospf_external_lsa_originate (ospf, ei);
        !          2252:        }
        !          2253:     }
        !          2254:   else
        !          2255:     {
        !          2256:       if (lsa)
        !          2257:        {
        !          2258:          if (IS_DEBUG_OSPF_EVENT)
        !          2259:            zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
        !          2260:           ospf_refresher_unregister_lsa (ospf, lsa);
        !          2261:          ospf_lsa_flush_as (ospf, lsa);
        !          2262:        }
        !          2263:     }
        !          2264: }
        !          2265: 
        !          2266: void
        !          2267: ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
        !          2268: {
        !          2269:   struct route_node *rn;
        !          2270:   struct external_info *ei;
        !          2271: 
        !          2272:   if (type != DEFAULT_ROUTE)
        !          2273:     if (EXTERNAL_INFO(type))
        !          2274:       /* Refresh each redistributed AS-external-LSAs. */
        !          2275:       for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
        !          2276:        if ((ei = rn->info))
        !          2277:          if (!is_prefix_default (&ei->p))
        !          2278:            {
        !          2279:              struct ospf_lsa *lsa;
        !          2280: 
        !          2281:              if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
        !          2282:                ospf_external_lsa_refresh (ospf, lsa, ei, force);
        !          2283:              else
        !          2284:                ospf_external_lsa_originate (ospf, ei);
        !          2285:            }
        !          2286: }
        !          2287: 
        !          2288: /* Refresh AS-external-LSA. */
        !          2289: struct ospf_lsa *
        !          2290: ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
        !          2291:                           struct external_info *ei, int force)
        !          2292: {
        !          2293:   struct ospf_lsa *new;
        !          2294:   int changed;
        !          2295:   
        !          2296:   /* Check the AS-external-LSA should be originated. */
        !          2297:   if (!ospf_redistribute_check (ospf, ei, &changed))
        !          2298:     {
        !          2299:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          2300:         zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
        !          2301:                    "redist check fail", 
        !          2302:                    lsa->data->type, inet_ntoa (lsa->data->id));
        !          2303:       ospf_external_lsa_flush (ospf, ei->type, &ei->p,
        !          2304:                               ei->ifindex /*, ei->nexthop */);
        !          2305:       return NULL;
        !          2306:     }
        !          2307: 
        !          2308:   if (!changed && !force)
        !          2309:     {
        !          2310:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          2311:         zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
        !          2312:                    lsa->data->type, inet_ntoa (lsa->data->id));
        !          2313:       return NULL;
        !          2314:     }
        !          2315: 
        !          2316:   /* Delete LSA from neighbor retransmit-list. */
        !          2317:   ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
        !          2318: 
        !          2319:   /* Unregister AS-external-LSA from refresh-list. */
        !          2320:   ospf_refresher_unregister_lsa (ospf, lsa);
        !          2321: 
        !          2322:   new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
        !          2323:   
        !          2324:   if (new == NULL)
        !          2325:     {
        !          2326:       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          2327:        zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
        !          2328:                   inet_ntoa (lsa->data->id));
        !          2329:       return NULL;
        !          2330:     }
        !          2331:   
        !          2332:   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
        !          2333: 
        !          2334:   ospf_lsa_install (ospf, NULL, new);  /* As type-5. */
        !          2335: 
        !          2336:   /* Flood LSA through AS. */
        !          2337:   ospf_flood_through_as (ospf, NULL, new);
        !          2338: 
        !          2339:   /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
        !          2340:   if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
        !          2341:     ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
        !          2342: 
        !          2343:   /* Register self-originated LSA to refresh queue. 
        !          2344:    * Translated LSAs should not be registered, but refreshed upon 
        !          2345:    * refresh of the Type-7
        !          2346:    */
        !          2347:   if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
        !          2348:     ospf_refresher_register_lsa (ospf, new);
        !          2349: 
        !          2350:   /* Debug logging. */
        !          2351:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          2352:     {
        !          2353:       zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
        !          2354:                  new->data->type, inet_ntoa (new->data->id));
        !          2355:       ospf_lsa_header_dump (new->data);
        !          2356:     }
        !          2357: 
        !          2358:   return new;
        !          2359: }
        !          2360: 
        !          2361: 
        !          2362: /* LSA installation functions. */
        !          2363: 
        !          2364: /* Install router-LSA to an area. */
        !          2365: static struct ospf_lsa *
        !          2366: ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
        !          2367:                          int rt_recalc)
        !          2368: {
        !          2369:   struct ospf_area *area = new->area;
        !          2370: 
        !          2371:   /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
        !          2372:      The entire routing table must be recalculated, starting with
        !          2373:      the shortest path calculations for each area (not just the
        !          2374:      area whose link-state database has changed). 
        !          2375:   */
        !          2376: 
        !          2377:   if (IS_LSA_SELF (new))
        !          2378:     {
        !          2379: 
        !          2380:       /* Only install LSA if it is originated/refreshed by us.
        !          2381:        * If LSA was received by flooding, the RECEIVED flag is set so do
        !          2382:        * not link the LSA */
        !          2383:       if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
        !          2384:        return new; /* ignore stale LSA */
        !          2385: 
        !          2386:       /* Set self-originated router-LSA. */
        !          2387:       ospf_lsa_unlock (&area->router_lsa_self);
        !          2388:       area->router_lsa_self = ospf_lsa_lock (new);
        !          2389: 
        !          2390:       ospf_refresher_register_lsa (ospf, new);
        !          2391:     }
        !          2392:   if (rt_recalc)
        !          2393:     ospf_spf_calculate_schedule (ospf);
        !          2394: 
        !          2395:   return new;
        !          2396: }
        !          2397: 
        !          2398: #define OSPF_INTERFACE_TIMER_ON(T,F,V) \
        !          2399:        if (!(T)) \
        !          2400:          (T) = thread_add_timer (master, (F), oi, (V))
        !          2401: 
        !          2402: /* Install network-LSA to an area. */
        !          2403: static struct ospf_lsa *
        !          2404: ospf_network_lsa_install (struct ospf *ospf,
        !          2405:                          struct ospf_interface *oi, 
        !          2406:                          struct ospf_lsa *new,
        !          2407:                          int rt_recalc)
        !          2408: {
        !          2409: 
        !          2410:   /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
        !          2411:      The entire routing table must be recalculated, starting with
        !          2412:      the shortest path calculations for each area (not just the
        !          2413:      area whose link-state database has changed). 
        !          2414:   */
        !          2415:   if (IS_LSA_SELF (new))
        !          2416:     {
        !          2417:       /* We supposed that when LSA is originated by us, we pass the int
        !          2418:         for which it was originated. If LSA was received by flooding,
        !          2419:         the RECEIVED flag is set, so we do not link the LSA to the int. */
        !          2420:       if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
        !          2421:        return new; /* ignore stale LSA */
        !          2422: 
        !          2423:       ospf_lsa_unlock (&oi->network_lsa_self);
        !          2424:       oi->network_lsa_self = ospf_lsa_lock (new);
        !          2425:       ospf_refresher_register_lsa (ospf, new);
        !          2426:     }
        !          2427:   if (rt_recalc)
        !          2428:     ospf_spf_calculate_schedule (ospf);
        !          2429: 
        !          2430:   return new;
        !          2431: }
        !          2432: 
        !          2433: /* Install summary-LSA to an area. */
        !          2434: static struct ospf_lsa *
        !          2435: ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
        !          2436:                          int rt_recalc)
        !          2437: {
        !          2438:   if (rt_recalc && !IS_LSA_SELF (new))
        !          2439:     {
        !          2440:       /* RFC 2328 Section 13.2 Summary-LSAs
        !          2441:         The best route to the destination described by the summary-
        !          2442:         LSA must be recalculated (see Section 16.5).  If this
        !          2443:         destination is an AS boundary router, it may also be
        !          2444:         necessary to re-examine all the AS-external-LSAs.
        !          2445:       */
        !          2446: 
        !          2447: #if 0
        !          2448:       /* This doesn't exist yet... */
        !          2449:       ospf_summary_incremental_update(new); */
        !          2450: #else /* #if 0 */
        !          2451:       ospf_spf_calculate_schedule (ospf);
        !          2452: #endif /* #if 0 */
        !          2453:  
        !          2454:       if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
        !          2455:        zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
        !          2456:     }
        !          2457: 
        !          2458:   if (IS_LSA_SELF (new))
        !          2459:     ospf_refresher_register_lsa (ospf, new);
        !          2460: 
        !          2461:   return new;
        !          2462: }
        !          2463: 
        !          2464: /* Install ASBR-summary-LSA to an area. */
        !          2465: static struct ospf_lsa *
        !          2466: ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
        !          2467:                               int rt_recalc)
        !          2468: {
        !          2469:   if (rt_recalc && !IS_LSA_SELF (new))
        !          2470:     {
        !          2471:       /* RFC 2328 Section 13.2 Summary-LSAs
        !          2472:         The best route to the destination described by the summary-
        !          2473:         LSA must be recalculated (see Section 16.5).  If this
        !          2474:         destination is an AS boundary router, it may also be
        !          2475:         necessary to re-examine all the AS-external-LSAs.
        !          2476:       */
        !          2477: #if 0
        !          2478:       /* These don't exist yet... */
        !          2479:       ospf_summary_incremental_update(new);
        !          2480:       /* Isn't this done by the above call? 
        !          2481:         - RFC 2328 Section 16.5 implies it should be */
        !          2482:       /* ospf_ase_calculate_schedule(); */
        !          2483: #else  /* #if 0 */
        !          2484:       ospf_spf_calculate_schedule (ospf);
        !          2485: #endif /* #if 0 */
        !          2486:     }
        !          2487: 
        !          2488:   /* register LSA to refresh-list. */
        !          2489:   if (IS_LSA_SELF (new))
        !          2490:     ospf_refresher_register_lsa (ospf, new);
        !          2491: 
        !          2492:   return new;
        !          2493: }
        !          2494: 
        !          2495: /* Install AS-external-LSA. */
        !          2496: static struct ospf_lsa *
        !          2497: ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
        !          2498:                           int rt_recalc)
        !          2499: {
        !          2500:   ospf_ase_register_external_lsa (new, ospf);
        !          2501:   /* If LSA is not self-originated, calculate an external route. */
        !          2502:   if (rt_recalc)
        !          2503:     {
        !          2504:       /* RFC 2328 Section 13.2 AS-external-LSAs
        !          2505:             The best route to the destination described by the AS-
        !          2506:             external-LSA must be recalculated (see Section 16.6).
        !          2507:       */
        !          2508: 
        !          2509:       if (!IS_LSA_SELF (new))
        !          2510:         ospf_ase_incremental_update (ospf, new);
        !          2511:     }
        !          2512: 
        !          2513:   if (new->data->type == OSPF_AS_NSSA_LSA)
        !          2514:     {
        !          2515:       /* There is no point to register selforiginate Type-7 LSA for
        !          2516:        * refreshing. We rely on refreshing Type-5 LSA's 
        !          2517:        */
        !          2518:       if (IS_LSA_SELF (new))
        !          2519:         return new;
        !          2520:       else
        !          2521:         {
        !          2522:           /* Try refresh type-5 translated LSA for this LSA, if one exists.
        !          2523:            * New translations will be taken care of by the abr_task.
        !          2524:            */ 
        !          2525:           ospf_translated_nssa_refresh (ospf, new, NULL);
        !          2526:         }
        !          2527:     }
        !          2528: 
        !          2529:   /* Register self-originated LSA to refresh queue. 
        !          2530:    * Leave Translated LSAs alone if NSSA is enabled
        !          2531:    */
        !          2532:   if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
        !          2533:     ospf_refresher_register_lsa (ospf, new);
        !          2534: 
        !          2535:   return new;
        !          2536: }
        !          2537: 
        !          2538: void
        !          2539: ospf_discard_from_db (struct ospf *ospf,
        !          2540:                      struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
        !          2541: {
        !          2542:   struct ospf_lsa *old;
        !          2543:   
        !          2544:   if (!lsdb)
        !          2545:     {
        !          2546:       zlog_warn ("%s: Called with NULL lsdb!", __func__);
        !          2547:       if (!lsa)
        !          2548:         zlog_warn ("%s: and NULL LSA!", __func__);
        !          2549:       else
        !          2550:         zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
        !          2551:                    lsa->data->type, inet_ntoa (lsa->data->id));
        !          2552:       return;
        !          2553:     }
        !          2554:   
        !          2555:   old = ospf_lsdb_lookup (lsdb, lsa);
        !          2556: 
        !          2557:   if (!old)
        !          2558:     return;
        !          2559: 
        !          2560:   if (old->refresh_list >= 0)
        !          2561:     ospf_refresher_unregister_lsa (ospf, old);
        !          2562: 
        !          2563:   switch (old->data->type)
        !          2564:     {
        !          2565:     case OSPF_AS_EXTERNAL_LSA:
        !          2566:       ospf_ase_unregister_external_lsa (old, ospf);
        !          2567:       ospf_ls_retransmit_delete_nbr_as (ospf, old);
        !          2568:       break;
        !          2569: #ifdef HAVE_OPAQUE_LSA
        !          2570:     case OSPF_OPAQUE_AS_LSA:
        !          2571:       ospf_ls_retransmit_delete_nbr_as (ospf, old);
        !          2572:       break;
        !          2573: #endif /* HAVE_OPAQUE_LSA */
        !          2574:     case OSPF_AS_NSSA_LSA:
        !          2575:       ospf_ls_retransmit_delete_nbr_area (old->area, old);
        !          2576:       ospf_ase_unregister_external_lsa (old, ospf);
        !          2577:       break;
        !          2578:     default:
        !          2579:       ospf_ls_retransmit_delete_nbr_area (old->area, old);
        !          2580:       break;
        !          2581:     }
        !          2582: 
        !          2583:   ospf_lsa_maxage_delete (ospf, old);
        !          2584:   ospf_lsa_discard (old);
        !          2585: }
        !          2586: 
        !          2587: struct ospf_lsa *
        !          2588: ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
        !          2589:                  struct ospf_lsa *lsa)
        !          2590: {
        !          2591:   struct ospf_lsa *new = NULL;
        !          2592:   struct ospf_lsa *old = NULL;
        !          2593:   struct ospf_lsdb *lsdb = NULL;
        !          2594:   int rt_recalc;
        !          2595: 
        !          2596:   /* Set LSDB. */
        !          2597:   switch (lsa->data->type)
        !          2598:     {
        !          2599:       /* kevinm */
        !          2600:     case OSPF_AS_NSSA_LSA:
        !          2601:       if (lsa->area)
        !          2602:        lsdb = lsa->area->lsdb;
        !          2603:       else
        !          2604:        lsdb = ospf->lsdb;
        !          2605:       break;
        !          2606:     case OSPF_AS_EXTERNAL_LSA:
        !          2607: #ifdef HAVE_OPAQUE_LSA
        !          2608:     case OSPF_OPAQUE_AS_LSA:
        !          2609: #endif /* HAVE_OPAQUE_LSA */
        !          2610:       lsdb = ospf->lsdb;
        !          2611:       break;
        !          2612:     default:
        !          2613:       lsdb = lsa->area->lsdb;
        !          2614:       break;
        !          2615:     }
        !          2616: 
        !          2617:   assert (lsdb);
        !          2618: 
        !          2619:   /*  RFC 2328 13.2.  Installing LSAs in the database
        !          2620: 
        !          2621:         Installing a new LSA in the database, either as the result of
        !          2622:         flooding or a newly self-originated LSA, may cause the OSPF
        !          2623:         routing table structure to be recalculated.  The contents of the
        !          2624:         new LSA should be compared to the old instance, if present.  If
        !          2625:         there is no difference, there is no need to recalculate the
        !          2626:         routing table. When comparing an LSA to its previous instance,
        !          2627:         the following are all considered to be differences in contents:
        !          2628: 
        !          2629:             o   The LSA's Options field has changed.
        !          2630: 
        !          2631:             o   One of the LSA instances has LS age set to MaxAge, and
        !          2632:                 the other does not.
        !          2633: 
        !          2634:             o   The length field in the LSA header has changed.
        !          2635: 
        !          2636:             o   The body of the LSA (i.e., anything outside the 20-byte
        !          2637:                 LSA header) has changed. Note that this excludes changes
        !          2638:                 in LS Sequence Number and LS Checksum.
        !          2639: 
        !          2640:   */
        !          2641:   /* Look up old LSA and determine if any SPF calculation or incremental
        !          2642:      update is needed */
        !          2643:   old = ospf_lsdb_lookup (lsdb, lsa);
        !          2644: 
        !          2645:   /* Do comparision and record if recalc needed. */
        !          2646:   rt_recalc = 0;
        !          2647:   if (  old == NULL || ospf_lsa_different(old, lsa))
        !          2648:     rt_recalc = 1;
        !          2649: 
        !          2650:   /*
        !          2651:      Sequence number check (Section 14.1 of rfc 2328)
        !          2652:      "Premature aging is used when it is time for a self-originated
        !          2653:       LSA's sequence number field to wrap.  At this point, the current
        !          2654:       LSA instance (having LS sequence number MaxSequenceNumber) must
        !          2655:       be prematurely aged and flushed from the routing domain before a
        !          2656:       new instance with sequence number equal to InitialSequenceNumber
        !          2657:       can be originated. "
        !          2658:    */
        !          2659: 
        !          2660:   if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
        !          2661:     {
        !          2662:       if (ospf_lsa_is_self_originated(ospf, lsa))
        !          2663:         {
        !          2664:           lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
        !          2665:           
        !          2666:           if (!IS_LSA_MAXAGE(lsa))
        !          2667:             lsa->flags |= OSPF_LSA_PREMATURE_AGE;
        !          2668:           lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
        !          2669:        
        !          2670:           if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          2671:             {
        !          2672:              zlog_debug ("ospf_lsa_install() Premature Aging "
        !          2673:                         "lsa 0x%p, seqnum 0x%x",
        !          2674:                         lsa, ntohl(lsa->data->ls_seqnum));
        !          2675:              ospf_lsa_header_dump (lsa->data);
        !          2676:             }
        !          2677:         }
        !          2678:       else
        !          2679:         {
        !          2680:           if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          2681:             {
        !          2682:              zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
        !          2683:                         "that was not self originated. Ignoring\n");
        !          2684:              ospf_lsa_header_dump (lsa->data);
        !          2685:             }
        !          2686:          return old;
        !          2687:         }
        !          2688:     }
        !          2689: 
        !          2690:   /* discard old LSA from LSDB */
        !          2691:   if (old != NULL)
        !          2692:     ospf_discard_from_db (ospf, lsdb, lsa);
        !          2693: 
        !          2694:   /* Calculate Checksum if self-originated?. */
        !          2695:   if (IS_LSA_SELF (lsa))
        !          2696:     ospf_lsa_checksum (lsa->data);
        !          2697: 
        !          2698:   /* Insert LSA to LSDB. */
        !          2699:   ospf_lsdb_add (lsdb, lsa);
        !          2700:   lsa->lsdb = lsdb;
        !          2701: 
        !          2702:   /* Do LSA specific installation process. */
        !          2703:   switch (lsa->data->type)
        !          2704:     {
        !          2705:     case OSPF_ROUTER_LSA:
        !          2706:       new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
        !          2707:       break;
        !          2708:     case OSPF_NETWORK_LSA:
        !          2709:       assert (oi);
        !          2710:       new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
        !          2711:       break;
        !          2712:     case OSPF_SUMMARY_LSA:
        !          2713:       new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
        !          2714:       break;
        !          2715:     case OSPF_ASBR_SUMMARY_LSA:
        !          2716:       new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
        !          2717:       break;
        !          2718:     case OSPF_AS_EXTERNAL_LSA:
        !          2719:       new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
        !          2720:       break;
        !          2721: #ifdef HAVE_OPAQUE_LSA
        !          2722:     case OSPF_OPAQUE_LINK_LSA:
        !          2723:       if (IS_LSA_SELF (lsa))
        !          2724:        lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
        !          2725:       else
        !          2726:        ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
        !          2727:       /* Fallthrough */
        !          2728:     case OSPF_OPAQUE_AREA_LSA:
        !          2729:     case OSPF_OPAQUE_AS_LSA:
        !          2730:       new = ospf_opaque_lsa_install (lsa, rt_recalc);
        !          2731:       break;
        !          2732: #endif /* HAVE_OPAQUE_LSA */
        !          2733:     case OSPF_AS_NSSA_LSA:
        !          2734:       new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
        !          2735:     default: /* type-6,8,9....nothing special */
        !          2736:       break;
        !          2737:     }
        !          2738: 
        !          2739:   if (new == NULL)
        !          2740:     return new;  /* Installation failed, cannot proceed further -- endo. */
        !          2741: 
        !          2742:   /* Debug logs. */
        !          2743:   if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
        !          2744:     {
        !          2745:       char area_str[INET_ADDRSTRLEN];
        !          2746: 
        !          2747:       switch (lsa->data->type)
        !          2748:         {
        !          2749:         case OSPF_AS_EXTERNAL_LSA:
        !          2750: #ifdef HAVE_OPAQUE_LSA
        !          2751:         case OSPF_OPAQUE_AS_LSA:
        !          2752: #endif /* HAVE_OPAQUE_LSA */
        !          2753:         case OSPF_AS_NSSA_LSA:
        !          2754:           zlog_debug ("LSA[%s]: Install %s",
        !          2755:                  dump_lsa_key (new),
        !          2756:                  LOOKUP (ospf_lsa_type_msg, new->data->type));
        !          2757:           break;
        !          2758:         default:
        !          2759:          strcpy (area_str, inet_ntoa (new->area->area_id));
        !          2760:           zlog_debug ("LSA[%s]: Install %s to Area %s",
        !          2761:                  dump_lsa_key (new),
        !          2762:                  LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
        !          2763:           break;
        !          2764:         }
        !          2765:     }
        !          2766: 
        !          2767:   /* 
        !          2768:      If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
        !          2769:      (it's getting flushed out of the area), set LSA on MaxAge LSA list. 
        !          2770:    */
        !          2771:   if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
        !          2772:       (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
        !          2773:     {
        !          2774:       if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
        !          2775:         zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
        !          2776:                    new->data->type, 
        !          2777:                    inet_ntoa (new->data->id), 
        !          2778:                    lsa);
        !          2779:       ospf_lsa_flush (ospf, lsa);
        !          2780:     }
        !          2781: 
        !          2782:   return new;
        !          2783: }
        !          2784: 
        !          2785: 
        !          2786: static int
        !          2787: ospf_check_nbr_status (struct ospf *ospf)
        !          2788: {
        !          2789:   struct listnode *node, *nnode;
        !          2790:   struct ospf_interface *oi;
        !          2791:   
        !          2792:   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
        !          2793:     {
        !          2794:       struct route_node *rn;
        !          2795:       struct ospf_neighbor *nbr;
        !          2796: 
        !          2797:       if (ospf_if_is_enable (oi))
        !          2798:        for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
        !          2799:           if ((nbr = rn->info) != NULL)
        !          2800:            if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
        !          2801:              {
        !          2802:                route_unlock_node (rn);
        !          2803:                return 0;
        !          2804:              }
        !          2805:     }
        !          2806: 
        !          2807:   return 1;
        !          2808: }
        !          2809: 
        !          2810: 
        !          2811: 
        !          2812: static int
        !          2813: ospf_maxage_lsa_remover (struct thread *thread)
        !          2814: {
        !          2815:   struct ospf *ospf = THREAD_ARG (thread);
        !          2816:   struct ospf_lsa *lsa;
        !          2817:   struct listnode *node, *nnode;
        !          2818:   int reschedule = 0;
        !          2819: 
        !          2820:   ospf->t_maxage = NULL;
        !          2821: 
        !          2822:   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2823:     zlog_debug ("LSA[MaxAge]: remover Start");
        !          2824: 
        !          2825:   reschedule = !ospf_check_nbr_status (ospf);
        !          2826: 
        !          2827:   if (!reschedule)
        !          2828:     for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
        !          2829:       {
        !          2830:         if (lsa->retransmit_counter > 0)
        !          2831:           {
        !          2832:             reschedule = 1;
        !          2833:             continue;
        !          2834:           }
        !          2835:         
        !          2836:         /* TODO: maybe convert this function to a work-queue */
        !          2837:         if (thread_should_yield (thread))
        !          2838:           OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
        !          2839:           
        !          2840:         /* Remove LSA from the LSDB */
        !          2841:         if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
        !          2842:           if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2843:             zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
        !          2844:                        lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
        !          2845: 
        !          2846:         if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2847:           zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
        !          2848:                      lsa->data->type, inet_ntoa (lsa->data->id));
        !          2849: 
        !          2850:        if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
        !          2851:           {
        !          2852:             if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2853:               zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
        !          2854:             ospf_lsa_refresh (ospf, lsa);
        !          2855:           }
        !          2856: 
        !          2857:        /* Remove from lsdb. */
        !          2858:        if (lsa->lsdb)
        !          2859:          {
        !          2860:            ospf_discard_from_db (ospf, lsa->lsdb, lsa);
        !          2861:            ospf_lsdb_delete (lsa->lsdb, lsa);
        !          2862:           }
        !          2863:         else
        !          2864:           zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
        !          2865:                      lsa->data->type, inet_ntoa (lsa->data->id));
        !          2866:       }
        !          2867: 
        !          2868:   /*    A MaxAge LSA must be removed immediately from the router's link
        !          2869:         state database as soon as both a) it is no longer contained on any
        !          2870:         neighbor Link state retransmission lists and b) none of the router's
        !          2871:         neighbors are in states Exchange or Loading. */
        !          2872:   if (reschedule)
        !          2873:     OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
        !          2874:                    ospf->maxage_delay);
        !          2875: 
        !          2876:   return 0;
        !          2877: }
        !          2878: 
        !          2879: void
        !          2880: ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
        !          2881: {
        !          2882:   struct listnode *n;
        !          2883: 
        !          2884:   if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
        !          2885:     {
        !          2886:       list_delete_node (ospf->maxage_lsa, n);
        !          2887:       UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
        !          2888:       ospf_lsa_unlock (&lsa); /* maxage_lsa */
        !          2889:     }
        !          2890: }
        !          2891: 
        !          2892: /* Add LSA onto the MaxAge list, and schedule for removal.
        !          2893:  * This does *not* lead to the LSA being flooded, that must be taken
        !          2894:  * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
        !          2895:  * function).
        !          2896:  */
        !          2897: void
        !          2898: ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
        !          2899: {
        !          2900:   /* When we saw a MaxAge LSA flooded to us, we put it on the list
        !          2901:      and schedule the MaxAge LSA remover. */
        !          2902:   if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
        !          2903:     {
        !          2904:       if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2905:        zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
        !          2906:                   lsa->data->type, inet_ntoa (lsa->data->id), lsa);
        !          2907:       return;
        !          2908:     }
        !          2909: 
        !          2910:   listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
        !          2911:   SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
        !          2912: 
        !          2913:   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2914:     zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
        !          2915: 
        !          2916:   OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
        !          2917:                  ospf->maxage_delay);
        !          2918: }
        !          2919: 
        !          2920: static int
        !          2921: ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
        !          2922: {
        !          2923:   /* Stay away from any Local Translated Type-7 LSAs */
        !          2924:   if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
        !          2925:     return 0;
        !          2926: 
        !          2927:   if (IS_LSA_MAXAGE (lsa))
        !          2928:     /* Self-originated LSAs should NOT time-out instead,
        !          2929:        they're flushed and submitted to the max_age list explicitly. */
        !          2930:     if (!ospf_lsa_is_self_originated (ospf, lsa))
        !          2931:       {
        !          2932:        if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
        !          2933:          zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
        !          2934: 
        !          2935:         switch (lsa->data->type)
        !          2936:           {
        !          2937: #ifdef HAVE_OPAQUE_LSA
        !          2938:           case OSPF_OPAQUE_LINK_LSA:
        !          2939:           case OSPF_OPAQUE_AREA_LSA:
        !          2940:           case OSPF_OPAQUE_AS_LSA:
        !          2941:             /*
        !          2942:              * As a general rule, whenever network topology has changed
        !          2943:              * (due to an LSA removal in this case), routing recalculation
        !          2944:              * should be triggered. However, this is not true for opaque
        !          2945:              * LSAs. Even if an opaque LSA instance is going to be removed
        !          2946:              * from the routing domain, it does not mean a change in network
        !          2947:              * topology, and thus, routing recalculation is not needed here.
        !          2948:              */
        !          2949:             break;
        !          2950: #endif /* HAVE_OPAQUE_LSA */
        !          2951:           case OSPF_AS_EXTERNAL_LSA:
        !          2952:           case OSPF_AS_NSSA_LSA:
        !          2953:            ospf_ase_incremental_update (ospf, lsa);
        !          2954:             break;
        !          2955:           default:
        !          2956:            ospf_spf_calculate_schedule (ospf);
        !          2957:             break;
        !          2958:           }
        !          2959:        ospf_lsa_maxage (ospf, lsa);
        !          2960:       }
        !          2961: 
        !          2962:   if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
        !          2963:     if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
        !          2964:       printf ("Eek! Shouldn't happen!\n");
        !          2965: 
        !          2966:   return 0;
        !          2967: }
        !          2968: 
        !          2969: /* Periodical check of MaxAge LSA. */
        !          2970: int
        !          2971: ospf_lsa_maxage_walker (struct thread *thread)
        !          2972: {
        !          2973:   struct ospf *ospf = THREAD_ARG (thread);
        !          2974:   struct route_node *rn;
        !          2975:   struct ospf_lsa *lsa;
        !          2976:   struct ospf_area *area;
        !          2977:   struct listnode *node, *nnode;
        !          2978: 
        !          2979:   ospf->t_maxage_walker = NULL;
        !          2980: 
        !          2981:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
        !          2982:     {
        !          2983:       LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
        !          2984:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2985:       LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
        !          2986:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2987:       LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
        !          2988:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2989:       LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
        !          2990:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2991: #ifdef HAVE_OPAQUE_LSA
        !          2992:       LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
        !          2993:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2994:       LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
        !          2995:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2996: #endif /* HAVE_OPAQUE_LSA */
        !          2997:       LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
        !          2998:         ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          2999:     }
        !          3000: 
        !          3001:   /* for AS-external-LSAs. */
        !          3002:   if (ospf->lsdb)
        !          3003:     {
        !          3004:       LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
        !          3005:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          3006: #ifdef HAVE_OPAQUE_LSA
        !          3007:       LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
        !          3008:        ospf_lsa_maxage_walker_remover (ospf, lsa);
        !          3009: #endif /* HAVE_OPAQUE_LSA */
        !          3010:     }
        !          3011: 
        !          3012:   OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
        !          3013:                 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
        !          3014:   return 0;
        !          3015: }
        !          3016: 
        !          3017: struct ospf_lsa *
        !          3018: ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
        !          3019:                           struct prefix_ipv4 *p, struct in_addr router_id)
        !          3020: {
        !          3021:   struct ospf_lsa *lsa;
        !          3022:   struct in_addr mask, id;
        !          3023:   struct lsa_header_mask
        !          3024:   {
        !          3025:     struct lsa_header header;
        !          3026:     struct in_addr mask;
        !          3027:   } *hmask;
        !          3028: 
        !          3029:   lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
        !          3030:   if (lsa == NULL)
        !          3031:     return NULL;
        !          3032: 
        !          3033:   masklen2ip (p->prefixlen, &mask);
        !          3034: 
        !          3035:   hmask = (struct lsa_header_mask *) lsa->data;
        !          3036: 
        !          3037:   if (mask.s_addr != hmask->mask.s_addr)
        !          3038:     {
        !          3039:       id.s_addr = p->prefix.s_addr | (~mask.s_addr);
        !          3040:       lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
        !          3041:       if (!lsa)
        !          3042:         return NULL;
        !          3043:     }
        !          3044: 
        !          3045:   return lsa;
        !          3046: }
        !          3047: 
        !          3048: struct ospf_lsa *
        !          3049: ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
        !          3050:                  struct in_addr id, struct in_addr adv_router)
        !          3051: {
        !          3052:   struct ospf *ospf = ospf_lookup();
        !          3053:   assert(ospf);
        !          3054: 
        !          3055:   switch (type)
        !          3056:     {
        !          3057:     case OSPF_ROUTER_LSA:
        !          3058:     case OSPF_NETWORK_LSA:
        !          3059:     case OSPF_SUMMARY_LSA:
        !          3060:     case OSPF_ASBR_SUMMARY_LSA:
        !          3061:     case OSPF_AS_NSSA_LSA:
        !          3062: #ifdef HAVE_OPAQUE_LSA
        !          3063:     case OSPF_OPAQUE_LINK_LSA:
        !          3064:     case OSPF_OPAQUE_AREA_LSA:
        !          3065: #endif /* HAVE_OPAQUE_LSA */
        !          3066:       return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
        !          3067:     case OSPF_AS_EXTERNAL_LSA:
        !          3068: #ifdef HAVE_OPAQUE_LSA
        !          3069:     case OSPF_OPAQUE_AS_LSA:
        !          3070: #endif /* HAVE_OPAQUE_LSA */
        !          3071:       return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
        !          3072:     default:
        !          3073:       break;
        !          3074:     }
        !          3075: 
        !          3076:   return NULL;
        !          3077: }
        !          3078: 
        !          3079: struct ospf_lsa *
        !          3080: ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type, 
        !          3081:                        struct in_addr id)
        !          3082: {
        !          3083:   struct ospf_lsa *lsa;
        !          3084:   struct route_node *rn;
        !          3085: 
        !          3086:   switch (type)
        !          3087:     {
        !          3088:     case OSPF_ROUTER_LSA:
        !          3089:       return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
        !          3090:     case OSPF_NETWORK_LSA:
        !          3091:       for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
        !          3092:        if ((lsa = rn->info))
        !          3093:          if (IPV4_ADDR_SAME (&lsa->data->id, &id))
        !          3094:            {
        !          3095:              route_unlock_node (rn);
        !          3096:              return lsa;
        !          3097:            }
        !          3098:       break;
        !          3099:     case OSPF_SUMMARY_LSA:
        !          3100:     case OSPF_ASBR_SUMMARY_LSA:
        !          3101:       /* Currently not used. */
        !          3102:       assert (1);
        !          3103:       return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
        !          3104:     case OSPF_AS_EXTERNAL_LSA:
        !          3105:     case OSPF_AS_NSSA_LSA:
        !          3106: #ifdef HAVE_OPAQUE_LSA
        !          3107:     case OSPF_OPAQUE_LINK_LSA:
        !          3108:     case OSPF_OPAQUE_AREA_LSA:
        !          3109:     case OSPF_OPAQUE_AS_LSA:
        !          3110:       /* Currently not used. */
        !          3111:       break;
        !          3112: #endif /* HAVE_OPAQUE_LSA */
        !          3113:     default:
        !          3114:       break;
        !          3115:     }
        !          3116: 
        !          3117:   return NULL;
        !          3118: }
        !          3119: 
        !          3120: struct ospf_lsa *
        !          3121: ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
        !          3122: {
        !          3123:   struct ospf_lsa *match;
        !          3124: 
        !          3125: #ifdef HAVE_OPAQUE_LSA
        !          3126:   /*
        !          3127:    * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
        !          3128:    * is redefined to have two subfields; opaque-type and opaque-id.
        !          3129:    * However, it is harmless to treat the two sub fields together, as if
        !          3130:    * they two were forming a unique LSA-ID.
        !          3131:    */
        !          3132: #endif /* HAVE_OPAQUE_LSA */
        !          3133: 
        !          3134:   match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
        !          3135: 
        !          3136:   if (match == NULL)
        !          3137:     if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
        !          3138:       zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
        !          3139:                 lsah->type, inet_ntoa (lsah->id));
        !          3140: 
        !          3141:   return match;
        !          3142: }
        !          3143: 
        !          3144: /* return +n, l1 is more recent.
        !          3145:    return -n, l2 is more recent.
        !          3146:    return 0, l1 and l2 is identical. */
        !          3147: int
        !          3148: ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
        !          3149: {
        !          3150:   int r;
        !          3151:   int x, y;
        !          3152: 
        !          3153:   if (l1 == NULL && l2 == NULL)
        !          3154:     return 0;
        !          3155:   if (l1 == NULL)
        !          3156:     return -1;
        !          3157:   if (l2 == NULL)
        !          3158:     return 1;
        !          3159: 
        !          3160:   /* compare LS sequence number. */
        !          3161:   x = (int) ntohl (l1->data->ls_seqnum);
        !          3162:   y = (int) ntohl (l2->data->ls_seqnum);
        !          3163:   if (x > y)
        !          3164:     return 1;
        !          3165:   if (x < y)
        !          3166:     return -1;
        !          3167: 
        !          3168:   /* compare LS checksum. */
        !          3169:   r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
        !          3170:   if (r)
        !          3171:     return r;
        !          3172: 
        !          3173:   /* compare LS age. */
        !          3174:   if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
        !          3175:     return 1;
        !          3176:   else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
        !          3177:     return -1;
        !          3178: 
        !          3179:   /* compare LS age with MaxAgeDiff. */
        !          3180:   if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
        !          3181:     return -1;
        !          3182:   else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
        !          3183:     return 1;
        !          3184: 
        !          3185:   /* LSAs are identical. */
        !          3186:   return 0;
        !          3187: }
        !          3188: 
        !          3189: /* If two LSAs are different, return 1, otherwise return 0. */
        !          3190: int
        !          3191: ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
        !          3192: {
        !          3193:   char *p1, *p2;
        !          3194:   assert (l1);
        !          3195:   assert (l2);
        !          3196:   assert (l1->data);
        !          3197:   assert (l2->data);
        !          3198: 
        !          3199:   if (l1->data->options != l2->data->options)
        !          3200:     return 1;
        !          3201: 
        !          3202:   if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
        !          3203:     return 1;
        !          3204: 
        !          3205:   if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
        !          3206:     return 1;
        !          3207: 
        !          3208:   if (l1->data->length != l2->data->length)
        !          3209:     return 1;
        !          3210: 
        !          3211:   if (l1->data->length ==  0)
        !          3212:     return 1;
        !          3213: 
        !          3214:   if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
        !          3215:     return 1; /* May be a stale LSA in the LSBD */
        !          3216: 
        !          3217:   assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
        !          3218: 
        !          3219:   p1 = (char *) l1->data;
        !          3220:   p2 = (char *) l2->data;
        !          3221: 
        !          3222:   if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
        !          3223:               ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
        !          3224:     return 1;
        !          3225: 
        !          3226:   return 0;
        !          3227: }
        !          3228: 
        !          3229: #ifdef ORIGINAL_CODING
        !          3230: void
        !          3231: ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
        !          3232:                                 struct ospf_lsa *self,
        !          3233:                                 struct ospf_lsa *new)
        !          3234: {
        !          3235:   u_int32_t seqnum;
        !          3236: 
        !          3237:   /* Adjust LS Sequence Number. */
        !          3238:   seqnum = ntohl (new->data->ls_seqnum) + 1;
        !          3239:   self->data->ls_seqnum = htonl (seqnum);
        !          3240: 
        !          3241:   /* Recalculate LSA checksum. */
        !          3242:   ospf_lsa_checksum (self->data);
        !          3243: 
        !          3244:   /* Reflooding LSA. */
        !          3245:   /*  RFC2328  Section 13.3
        !          3246:            On non-broadcast networks, separate Link State Update
        !          3247:            packets must be sent, as unicasts, to each adjacent neighbor
        !          3248:            (i.e., those in state Exchange or greater).  The destination
        !          3249:            IP addresses for these packets are the neighbors' IP
        !          3250:            addresses.   */
        !          3251:   if (nbr->oi->type == OSPF_IFTYPE_NBMA)
        !          3252:     {
        !          3253:       struct route_node *rn;
        !          3254:       struct ospf_neighbor *onbr;
        !          3255: 
        !          3256:       for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
        !          3257:        if ((onbr = rn->info) != NULL)
        !          3258:          if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
        !          3259:            ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
        !          3260:     }
        !          3261:   else
        !          3262:   ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
        !          3263: 
        !          3264:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          3265:     zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
        !          3266:               self->data->type, inet_ntoa (self->data->id));
        !          3267: }
        !          3268: #else /* ORIGINAL_CODING */
        !          3269: static int
        !          3270: ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
        !          3271: {
        !          3272:   if (lsa == NULL || !IS_LSA_SELF (lsa))
        !          3273:     return 0;
        !          3274: 
        !          3275:   if (IS_DEBUG_OSPF_EVENT)
        !          3276:     zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
        !          3277: 
        !          3278:   /* Force given lsa's age to MaxAge. */
        !          3279:   lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
        !          3280: 
        !          3281:   switch (lsa->data->type)
        !          3282:     {
        !          3283: #ifdef HAVE_OPAQUE_LSA
        !          3284:     /* Opaque wants to be notified of flushes */
        !          3285:     case OSPF_OPAQUE_LINK_LSA:
        !          3286:     case OSPF_OPAQUE_AREA_LSA:
        !          3287:     case OSPF_OPAQUE_AS_LSA:
        !          3288:       ospf_opaque_lsa_refresh (lsa);
        !          3289:       break;
        !          3290: #endif /* HAVE_OPAQUE_LSA */
        !          3291:     default:
        !          3292:       ospf_refresher_unregister_lsa (ospf, lsa);
        !          3293:       ospf_lsa_flush (ospf, lsa);
        !          3294:       break;
        !          3295:     }
        !          3296: 
        !          3297:   return 0;
        !          3298: }
        !          3299: 
        !          3300: void
        !          3301: ospf_flush_self_originated_lsas_now (struct ospf *ospf)
        !          3302: {
        !          3303:   struct listnode *node, *nnode;
        !          3304:   struct listnode *node2, *nnode2;
        !          3305:   struct ospf_area *area;
        !          3306:   struct ospf_interface *oi;
        !          3307:   struct ospf_lsa *lsa;
        !          3308:   struct route_node *rn;
        !          3309:   int need_to_flush_ase = 0;
        !          3310: 
        !          3311:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
        !          3312:     {
        !          3313:       if ((lsa = area->router_lsa_self) != NULL)
        !          3314:         {
        !          3315:           if (IS_DEBUG_OSPF_EVENT)
        !          3316:             zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
        !          3317:                         lsa->data->type, inet_ntoa (lsa->data->id));
        !          3318:           
        !          3319:           ospf_refresher_unregister_lsa (ospf, lsa);
        !          3320:           ospf_lsa_flush_area (lsa, area);
        !          3321:           ospf_lsa_unlock (&area->router_lsa_self);
        !          3322:           area->router_lsa_self = NULL;
        !          3323:         }
        !          3324: 
        !          3325:       for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
        !          3326:         {
        !          3327:           if ((lsa = oi->network_lsa_self) != NULL
        !          3328:                &&   oi->state == ISM_DR
        !          3329:                &&   oi->full_nbrs > 0)
        !          3330:             {
        !          3331:               if (IS_DEBUG_OSPF_EVENT)
        !          3332:                 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
        !          3333:                             lsa->data->type, inet_ntoa (lsa->data->id));
        !          3334:               
        !          3335:               ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
        !          3336:               ospf_lsa_flush_area (oi->network_lsa_self, area);
        !          3337:               ospf_lsa_unlock (&oi->network_lsa_self);
        !          3338:               oi->network_lsa_self = NULL;
        !          3339:             }
        !          3340: 
        !          3341:           if (oi->type != OSPF_IFTYPE_VIRTUALLINK
        !          3342:           &&  area->external_routing == OSPF_AREA_DEFAULT)
        !          3343:             need_to_flush_ase = 1;
        !          3344:         }
        !          3345: 
        !          3346:       LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
        !          3347:        ospf_lsa_flush_schedule (ospf, lsa);
        !          3348:       LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
        !          3349:        ospf_lsa_flush_schedule (ospf, lsa);
        !          3350: #ifdef HAVE_OPAQUE_LSA
        !          3351:       LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
        !          3352:        ospf_lsa_flush_schedule (ospf, lsa);
        !          3353:       LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
        !          3354:        ospf_lsa_flush_schedule (ospf, lsa);
        !          3355: #endif /* HAVE_OPAQUE_LSA */
        !          3356:     }
        !          3357: 
        !          3358:   if (need_to_flush_ase)
        !          3359:     {
        !          3360:       LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
        !          3361:        ospf_lsa_flush_schedule (ospf, lsa);
        !          3362: #ifdef HAVE_OPAQUE_LSA
        !          3363:       LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
        !          3364:        ospf_lsa_flush_schedule (ospf, lsa);
        !          3365: #endif /* HAVE_OPAQUE_LSA */
        !          3366:     }
        !          3367: 
        !          3368:   /*
        !          3369:    * Make sure that the MaxAge LSA remover is executed immediately,
        !          3370:    * without conflicting to other threads.
        !          3371:    */
        !          3372:   if (ospf->t_maxage != NULL)
        !          3373:     {
        !          3374:       OSPF_TIMER_OFF (ospf->t_maxage);
        !          3375:       thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
        !          3376:     }
        !          3377: 
        !          3378:   return;
        !          3379: }
        !          3380: #endif /* ORIGINAL_CODING */
        !          3381: 
        !          3382: /* If there is self-originated LSA, then return 1, otherwise return 0. */
        !          3383: /* An interface-independent version of ospf_lsa_is_self_originated */
        !          3384: int 
        !          3385: ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
        !          3386: {
        !          3387:   struct listnode *node;
        !          3388:   struct ospf_interface *oi;
        !          3389: 
        !          3390:   /* This LSA is already checked. */
        !          3391:   if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
        !          3392:     return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
        !          3393: 
        !          3394:   /* Make sure LSA is self-checked. */
        !          3395:   SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
        !          3396: 
        !          3397:   /* AdvRouter and Router ID is the same. */
        !          3398:   if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
        !          3399:     SET_FLAG (lsa->flags, OSPF_LSA_SELF);
        !          3400: 
        !          3401:   /* LSA is router-LSA. */
        !          3402:   else if (lsa->data->type == OSPF_ROUTER_LSA &&
        !          3403:       IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
        !          3404:     SET_FLAG (lsa->flags, OSPF_LSA_SELF);
        !          3405: 
        !          3406:   /* LSA is network-LSA.  Compare Link ID with all interfaces. */
        !          3407:   else if (lsa->data->type == OSPF_NETWORK_LSA)
        !          3408:     for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
        !          3409:       {
        !          3410:        /* Ignore virtual link. */
        !          3411:         if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
        !          3412:          if (oi->address->family == AF_INET)
        !          3413:            if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
        !          3414:              {
        !          3415:                /* to make it easier later */
        !          3416:                SET_FLAG (lsa->flags, OSPF_LSA_SELF);
        !          3417:                return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
        !          3418:              }
        !          3419:       }
        !          3420: 
        !          3421:   return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
        !          3422: }
        !          3423: 
        !          3424: /* Get unique Link State ID. */
        !          3425: struct in_addr
        !          3426: ospf_lsa_unique_id (struct ospf *ospf,
        !          3427:                    struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
        !          3428: {
        !          3429:   struct ospf_lsa *lsa;
        !          3430:   struct in_addr mask, id;
        !          3431: 
        !          3432:   id = p->prefix;
        !          3433: 
        !          3434:   /* Check existence of LSA instance. */
        !          3435:   lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
        !          3436:   if (lsa)
        !          3437:     {
        !          3438:       struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
        !          3439:       if (ip_masklen (al->mask) == p->prefixlen)
        !          3440:        {
        !          3441:          if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          3442:            zlog_debug ("ospf_lsa_unique_id(): "
        !          3443:                       "Can't get Link State ID for %s/%d",
        !          3444:                       inet_ntoa (p->prefix), p->prefixlen);
        !          3445:          /*      id.s_addr = 0; */
        !          3446:          id.s_addr = 0xffffffff;
        !          3447:          return id;
        !          3448:        }
        !          3449:       /* Masklen differs, then apply wildcard mask to Link State ID. */
        !          3450:       else
        !          3451:        {
        !          3452:          masklen2ip (p->prefixlen, &mask);
        !          3453: 
        !          3454:          id.s_addr = p->prefix.s_addr | (~mask.s_addr);
        !          3455:          lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
        !          3456:                                       id, ospf->router_id);
        !          3457:          if (lsa)
        !          3458:            {
        !          3459:              if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        !          3460:                zlog_debug ("ospf_lsa_unique_id(): "
        !          3461:                           "Can't get Link State ID for %s/%d",
        !          3462:                           inet_ntoa (p->prefix), p->prefixlen);
        !          3463:              /*              id.s_addr = 0; */
        !          3464:              id.s_addr = 0xffffffff;
        !          3465:              return id;
        !          3466:            }
        !          3467:        }
        !          3468:     }
        !          3469: 
        !          3470:   return id;
        !          3471: }
        !          3472: 
        !          3473: 
        !          3474: #define LSA_ACTION_FLOOD_AREA 1
        !          3475: #define LSA_ACTION_FLUSH_AREA 2
        !          3476: 
        !          3477: struct lsa_action
        !          3478: {
        !          3479:   u_char action;
        !          3480:   struct ospf_area *area;
        !          3481:   struct ospf_lsa *lsa;
        !          3482: };
        !          3483: 
        !          3484: static int
        !          3485: ospf_lsa_action (struct thread *t)
        !          3486: {
        !          3487:   struct lsa_action *data;
        !          3488: 
        !          3489:   data = THREAD_ARG (t);
        !          3490: 
        !          3491:   if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
        !          3492:     zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
        !          3493:               data->action);
        !          3494: 
        !          3495:   switch (data->action)
        !          3496:     {
        !          3497:     case LSA_ACTION_FLOOD_AREA:
        !          3498:       ospf_flood_through_area (data->area, NULL, data->lsa);
        !          3499:       break;
        !          3500:     case LSA_ACTION_FLUSH_AREA:
        !          3501:       ospf_lsa_flush_area (data->lsa, data->area);
        !          3502:       break;
        !          3503:     }
        !          3504: 
        !          3505:   ospf_lsa_unlock (&data->lsa); /* Message */
        !          3506:   XFREE (MTYPE_OSPF_MESSAGE, data);
        !          3507:   return 0;
        !          3508: }
        !          3509: 
        !          3510: void
        !          3511: ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
        !          3512: {
        !          3513:   struct lsa_action *data;
        !          3514: 
        !          3515:   data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
        !          3516:   data->action = LSA_ACTION_FLOOD_AREA;
        !          3517:   data->area = area;
        !          3518:   data->lsa  = ospf_lsa_lock (lsa); /* Message / Flood area */
        !          3519: 
        !          3520:   thread_add_event (master, ospf_lsa_action, data, 0);
        !          3521: }
        !          3522: 
        !          3523: void
        !          3524: ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
        !          3525: {
        !          3526:   struct lsa_action *data;
        !          3527: 
        !          3528:   data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
        !          3529:   data->action = LSA_ACTION_FLUSH_AREA;
        !          3530:   data->area = area;
        !          3531:   data->lsa  = ospf_lsa_lock (lsa); /* Message / Flush area */
        !          3532: 
        !          3533:   thread_add_event (master, ospf_lsa_action, data, 0);
        !          3534: }
        !          3535: 
        !          3536: 
        !          3537: /* LSA Refreshment functions. */
        !          3538: struct ospf_lsa *
        !          3539: ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
        !          3540: {
        !          3541:   struct external_info *ei;
        !          3542:   struct ospf_lsa *new = NULL;
        !          3543:   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
        !          3544:   assert (lsa->lock > 0);
        !          3545: 
        !          3546:   switch (lsa->data->type)
        !          3547:     {
        !          3548:       /* Router and Network LSAs are processed differently. */
        !          3549:     case OSPF_ROUTER_LSA:
        !          3550:       new = ospf_router_lsa_refresh (lsa);
        !          3551:       break;
        !          3552:     case OSPF_NETWORK_LSA: 
        !          3553:       new = ospf_network_lsa_refresh (lsa);
        !          3554:       break;
        !          3555:     case OSPF_SUMMARY_LSA:
        !          3556:       new = ospf_summary_lsa_refresh (ospf, lsa);
        !          3557:       break;
        !          3558:     case OSPF_ASBR_SUMMARY_LSA:
        !          3559:       new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
        !          3560:       break;
        !          3561:     case OSPF_AS_EXTERNAL_LSA:
        !          3562:       /* Translated from NSSA Type-5s are refreshed when 
        !          3563:        * from refresh of Type-7 - do not refresh these directly.
        !          3564:        */
        !          3565:       if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
        !          3566:         break;
        !          3567:       ei = ospf_external_info_check (lsa);
        !          3568:       if (ei)
        !          3569:         new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
        !          3570:       else
        !          3571:         ospf_lsa_flush_as (ospf, lsa);
        !          3572:       break;
        !          3573: #ifdef HAVE_OPAQUE_LSA
        !          3574:     case OSPF_OPAQUE_LINK_LSA:
        !          3575:     case OSPF_OPAQUE_AREA_LSA:
        !          3576:     case OSPF_OPAQUE_AS_LSA:
        !          3577:       new = ospf_opaque_lsa_refresh (lsa);
        !          3578:       break;
        !          3579: #endif /* HAVE_OPAQUE_LSA */
        !          3580:     default:
        !          3581:       break;
        !          3582:     }
        !          3583:   return new;
        !          3584: }
        !          3585: 
        !          3586: void
        !          3587: ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
        !          3588: {
        !          3589:   u_int16_t index, current_index;
        !          3590:   
        !          3591:   assert (lsa->lock > 0);
        !          3592:   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
        !          3593: 
        !          3594:   if (lsa->refresh_list < 0)
        !          3595:     {
        !          3596:       int delay;
        !          3597: 
        !          3598:       if (LS_AGE (lsa) == 0 &&
        !          3599:          ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
        !          3600:        /* Randomize first update by  OSPF_LS_REFRESH_SHIFT factor */ 
        !          3601:        delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
        !          3602:       else
        !          3603:        /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
        !          3604:        delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
        !          3605:          + (random () % (2*OSPF_LS_REFRESH_JITTER)); 
        !          3606: 
        !          3607:       if (delay < 0)
        !          3608:        delay = 0;
        !          3609: 
        !          3610:       current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
        !          3611:                 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
        !          3612:       
        !          3613:       index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
        !          3614:              % (OSPF_LSA_REFRESHER_SLOTS);
        !          3615: 
        !          3616:       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3617:        zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
        !          3618:                   inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
        !          3619:       if (!ospf->lsa_refresh_queue.qs[index])
        !          3620:        ospf->lsa_refresh_queue.qs[index] = list_new ();
        !          3621:       listnode_add (ospf->lsa_refresh_queue.qs[index],
        !          3622:                     ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
        !          3623:       lsa->refresh_list = index;
        !          3624:       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3625:         zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
        !          3626:                    "setting refresh_list on lsa %p (slod %d)", 
        !          3627:                    inet_ntoa (lsa->data->id), lsa, index);
        !          3628:     }
        !          3629: }
        !          3630: 
        !          3631: void
        !          3632: ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
        !          3633: {
        !          3634:   assert (lsa->lock > 0);
        !          3635:   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
        !          3636:   if (lsa->refresh_list >= 0)
        !          3637:     {
        !          3638:       struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
        !          3639:       listnode_delete (refresh_list, lsa);
        !          3640:       if (!listcount (refresh_list))
        !          3641:        {
        !          3642:          list_free (refresh_list);
        !          3643:          ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
        !          3644:        }
        !          3645:       ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
        !          3646:       lsa->refresh_list = -1;
        !          3647:     }
        !          3648: }
        !          3649: 
        !          3650: int
        !          3651: ospf_lsa_refresh_walker (struct thread *t)
        !          3652: {
        !          3653:   struct list *refresh_list;
        !          3654:   struct listnode *node, *nnode;
        !          3655:   struct ospf *ospf = THREAD_ARG (t);
        !          3656:   struct ospf_lsa *lsa;
        !          3657:   int i;
        !          3658:   struct list *lsa_to_refresh = list_new ();
        !          3659: 
        !          3660:   if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3661:     zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
        !          3662: 
        !          3663:   
        !          3664:   i = ospf->lsa_refresh_queue.index;
        !          3665:   
        !          3666:   /* Note: if clock has jumped backwards, then time change could be negative,
        !          3667:      so we are careful to cast the expression to unsigned before taking
        !          3668:      modulus. */
        !          3669:   ospf->lsa_refresh_queue.index =
        !          3670:    ((unsigned long)(ospf->lsa_refresh_queue.index +
        !          3671:                    (quagga_time (NULL) - ospf->lsa_refresher_started)
        !          3672:                    / OSPF_LSA_REFRESHER_GRANULARITY))
        !          3673:                    % OSPF_LSA_REFRESHER_SLOTS;
        !          3674: 
        !          3675:   if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3676:     zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
        !          3677:               ospf->lsa_refresh_queue.index);
        !          3678: 
        !          3679:   for (;i != ospf->lsa_refresh_queue.index;
        !          3680:        i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
        !          3681:     {
        !          3682:       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3683:        zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
        !          3684:                   "refresh index %d", i);
        !          3685: 
        !          3686:       refresh_list = ospf->lsa_refresh_queue.qs [i];
        !          3687:       
        !          3688:       assert (i >= 0);
        !          3689: 
        !          3690:       ospf->lsa_refresh_queue.qs [i] = NULL;
        !          3691: 
        !          3692:       if (refresh_list)
        !          3693:        {
        !          3694:          for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
        !          3695:            {
        !          3696:              if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3697:                zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
        !          3698:                           "refresh lsa %p (slot %d)", 
        !          3699:                           inet_ntoa (lsa->data->id), lsa, i);
        !          3700:              
        !          3701:              assert (lsa->lock > 0);
        !          3702:              list_delete_node (refresh_list, node);
        !          3703:              lsa->refresh_list = -1;
        !          3704:              listnode_add (lsa_to_refresh, lsa);
        !          3705:            }
        !          3706:          list_free (refresh_list);
        !          3707:        }
        !          3708:     }
        !          3709: 
        !          3710:   ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
        !          3711:                                           ospf, ospf->lsa_refresh_interval);
        !          3712:   ospf->lsa_refresher_started = quagga_time (NULL);
        !          3713: 
        !          3714:   for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
        !          3715:     {
        !          3716:       ospf_lsa_refresh (ospf, lsa);
        !          3717:       assert (lsa->lock > 0);
        !          3718:       ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
        !          3719:     }
        !          3720:   
        !          3721:   list_delete (lsa_to_refresh);
        !          3722:   
        !          3723:   if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        !          3724:     zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
        !          3725:   
        !          3726:   return 0;
        !          3727: }
        !          3728: 

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