Annotation of embedaddon/quagga/ospf6d/ospf6_intra.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2003 Yasuhiro Ohara
        !             3:  *
        !             4:  * This file is part of GNU Zebra.
        !             5:  *
        !             6:  * GNU Zebra is free software; you can redistribute it and/or modify it
        !             7:  * under the terms of the GNU General Public License as published by the
        !             8:  * Free Software Foundation; either version 2, or (at your option) any
        !             9:  * later version.
        !            10:  *
        !            11:  * GNU Zebra is distributed in the hope that it will be useful, but
        !            12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            14:  * General Public License for more details.
        !            15:  *
        !            16:  * You should have received a copy of the GNU General Public License
        !            17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
        !            18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
        !            19:  * Boston, MA 02111-1307, USA.  
        !            20:  */
        !            21: 
        !            22: #include <zebra.h>
        !            23: 
        !            24: #include "log.h"
        !            25: #include "linklist.h"
        !            26: #include "thread.h"
        !            27: #include "memory.h"
        !            28: #include "if.h"
        !            29: #include "prefix.h"
        !            30: #include "table.h"
        !            31: #include "vty.h"
        !            32: #include "command.h"
        !            33: 
        !            34: #include "ospf6_proto.h"
        !            35: #include "ospf6_message.h"
        !            36: #include "ospf6_route.h"
        !            37: #include "ospf6_lsa.h"
        !            38: #include "ospf6_lsdb.h"
        !            39: 
        !            40: #include "ospf6_top.h"
        !            41: #include "ospf6_area.h"
        !            42: #include "ospf6_interface.h"
        !            43: #include "ospf6_neighbor.h"
        !            44: #include "ospf6_intra.h"
        !            45: #include "ospf6_asbr.h"
        !            46: #include "ospf6_abr.h"
        !            47: #include "ospf6_flood.h"
        !            48: #include "ospf6d.h"
        !            49: 
        !            50: 
        !            51: unsigned char conf_debug_ospf6_brouter = 0;
        !            52: u_int32_t conf_debug_ospf6_brouter_specific_router_id;
        !            53: u_int32_t conf_debug_ospf6_brouter_specific_area_id;
        !            54: 
        !            55: /******************************/
        !            56: /* RFC2740 3.4.3.1 Router-LSA */
        !            57: /******************************/
        !            58: 
        !            59: static int
        !            60: ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
        !            61: {
        !            62:   char *start, *end, *current;
        !            63:   char buf[32], name[32], bits[16], options[32];
        !            64:   struct ospf6_router_lsa *router_lsa;
        !            65:   struct ospf6_router_lsdesc *lsdesc;
        !            66: 
        !            67:   router_lsa = (struct ospf6_router_lsa *)
        !            68:     ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
        !            69: 
        !            70:   ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
        !            71:   ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
        !            72:   vty_out (vty, "    Bits: %s Options: %s%s", bits, options, VNL);
        !            73: 
        !            74:   start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
        !            75:   end = (char *) lsa->header + ntohs (lsa->header->length);
        !            76:   for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
        !            77:        current += sizeof (struct ospf6_router_lsdesc))
        !            78:     {
        !            79:       lsdesc = (struct ospf6_router_lsdesc *) current;
        !            80: 
        !            81:       if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
        !            82:         snprintf (name, sizeof (name), "Point-To-Point");
        !            83:       else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
        !            84:         snprintf (name, sizeof (name), "Transit-Network");
        !            85:       else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
        !            86:         snprintf (name, sizeof (name), "Stub-Network");
        !            87:       else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
        !            88:         snprintf (name, sizeof (name), "Virtual-Link");
        !            89:       else
        !            90:         snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
        !            91: 
        !            92:       vty_out (vty, "    Type: %s Metric: %d%s",
        !            93:                name, ntohs (lsdesc->metric), VNL);
        !            94:       vty_out (vty, "    Interface ID: %s%s",
        !            95:                inet_ntop (AF_INET, &lsdesc->interface_id,
        !            96:                           buf, sizeof (buf)), VNL);
        !            97:       vty_out (vty, "    Neighbor Interface ID: %s%s",
        !            98:                inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
        !            99:                           buf, sizeof (buf)), VNL);
        !           100:       vty_out (vty, "    Neighbor Router ID: %s%s",
        !           101:                inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
        !           102:                           buf, sizeof (buf)), VNL);
        !           103:     }
        !           104:   return 0;
        !           105: }
        !           106: 
        !           107: int
        !           108: ospf6_router_lsa_originate (struct thread *thread)
        !           109: {
        !           110:   struct ospf6_area *oa;
        !           111: 
        !           112:   char buffer [OSPF6_MAX_LSASIZE];
        !           113:   struct ospf6_lsa_header *lsa_header;
        !           114:   struct ospf6_lsa *lsa;
        !           115: 
        !           116:   u_int32_t link_state_id = 0;
        !           117:   struct listnode *node, *nnode;
        !           118:   struct listnode *j;
        !           119:   struct ospf6_interface *oi;
        !           120:   struct ospf6_neighbor *on, *drouter = NULL;
        !           121:   struct ospf6_router_lsa *router_lsa;
        !           122:   struct ospf6_router_lsdesc *lsdesc;
        !           123:   u_int16_t type;
        !           124:   u_int32_t router;
        !           125:   int count;
        !           126: 
        !           127:   oa = (struct ospf6_area *) THREAD_ARG (thread);
        !           128:   oa->thread_router_lsa = NULL;
        !           129: 
        !           130:   if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
        !           131:     zlog_debug ("Originate Router-LSA for Area %s", oa->name);
        !           132: 
        !           133:   memset (buffer, 0, sizeof (buffer));
        !           134:   lsa_header = (struct ospf6_lsa_header *) buffer;
        !           135:   router_lsa = (struct ospf6_router_lsa *)
        !           136:     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
        !           137: 
        !           138:   OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
        !           139:   OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
        !           140:   OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
        !           141:   OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
        !           142:   OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
        !           143:   OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
        !           144: 
        !           145:   if (ospf6_is_router_abr (ospf6))
        !           146:     SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
        !           147:   else
        !           148:     UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
        !           149:   if (ospf6_asbr_is_asbr (ospf6))
        !           150:     SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
        !           151:   else
        !           152:     UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
        !           153:   UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
        !           154:   UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
        !           155: 
        !           156:   /* describe links for each interfaces */
        !           157:   lsdesc = (struct ospf6_router_lsdesc *)
        !           158:     ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
        !           159: 
        !           160:   for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
        !           161:     {
        !           162:       /* Interfaces in state Down or Loopback are not described */
        !           163:       if (oi->state == OSPF6_INTERFACE_DOWN ||
        !           164:           oi->state == OSPF6_INTERFACE_LOOPBACK)
        !           165:         continue;
        !           166: 
        !           167:       /* Nor are interfaces without any full adjacencies described */
        !           168:       count = 0;
        !           169:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
        !           170:         if (on->state == OSPF6_NEIGHBOR_FULL)
        !           171:           count++;
        !           172:       
        !           173:       if (count == 0)
        !           174:         continue;
        !           175: 
        !           176:       /* Multiple Router-LSA instance according to size limit setting */
        !           177:       if ( (oa->router_lsa_size_limit != 0)
        !           178:           && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
        !           179:              /* XXX warning: comparison between signed and unsigned */
        !           180:               (caddr_t) buffer > oa->router_lsa_size_limit))
        !           181:         {
        !           182:           if ((caddr_t) lsdesc == (caddr_t) router_lsa +
        !           183:                                   sizeof (struct ospf6_router_lsa))
        !           184:             {
        !           185:               if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
        !           186:                 zlog_debug ("Size limit setting for Router-LSA too short");
        !           187:               return 0;
        !           188:             }
        !           189: 
        !           190:           /* Fill LSA Header */
        !           191:           lsa_header->age = 0;
        !           192:           lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
        !           193:           lsa_header->id = htonl (link_state_id);
        !           194:           lsa_header->adv_router = oa->ospf6->router_id;
        !           195:           lsa_header->seqnum =
        !           196:             ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
        !           197:                                  lsa_header->adv_router, oa->lsdb);
        !           198:           lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
        !           199: 
        !           200:           /* LSA checksum */
        !           201:           ospf6_lsa_checksum (lsa_header);
        !           202: 
        !           203:           /* create LSA */
        !           204:           lsa = ospf6_lsa_create (lsa_header);
        !           205: 
        !           206:           /* Originate */
        !           207:           ospf6_lsa_originate_area (lsa, oa);
        !           208: 
        !           209:           /* Reset setting for consecutive origination */
        !           210:           memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
        !           211:                   0, (caddr_t) lsdesc - (caddr_t) router_lsa);
        !           212:           lsdesc = (struct ospf6_router_lsdesc *)
        !           213:             ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
        !           214:           link_state_id ++;
        !           215:         }
        !           216: 
        !           217:       /* Point-to-Point interfaces */
        !           218:       if (if_is_pointopoint (oi->interface))
        !           219:         {
        !           220:           for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
        !           221:             {
        !           222:               if (on->state != OSPF6_NEIGHBOR_FULL)
        !           223:                 continue;
        !           224: 
        !           225:               lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
        !           226:               lsdesc->metric = htons (oi->cost);
        !           227:               lsdesc->interface_id = htonl (oi->interface->ifindex);
        !           228:               lsdesc->neighbor_interface_id = htonl (on->ifindex);
        !           229:               lsdesc->neighbor_router_id = on->router_id;
        !           230: 
        !           231:               lsdesc++;
        !           232:             }
        !           233:         }
        !           234: 
        !           235:       /* Broadcast and NBMA interfaces */
        !           236:       if (if_is_broadcast (oi->interface))
        !           237:         {
        !           238:           /* If this router is not DR,
        !           239:              and If this router not fully adjacent with DR,
        !           240:              this interface is not transit yet: ignore. */
        !           241:           if (oi->state != OSPF6_INTERFACE_DR)
        !           242:             {
        !           243:               drouter = ospf6_neighbor_lookup (oi->drouter, oi);
        !           244:               if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
        !           245:                 continue;
        !           246:             }
        !           247: 
        !           248:           lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
        !           249:           lsdesc->metric = htons (oi->cost);
        !           250:           lsdesc->interface_id = htonl (oi->interface->ifindex);
        !           251:           if (oi->state != OSPF6_INTERFACE_DR)
        !           252:             {
        !           253:               lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
        !           254:               lsdesc->neighbor_router_id = drouter->router_id;
        !           255:             }
        !           256:           else
        !           257:             {
        !           258:               lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
        !           259:               lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
        !           260:             }
        !           261: 
        !           262:           lsdesc++;
        !           263:         }
        !           264: 
        !           265:       /* Virtual links */
        !           266:         /* xxx */
        !           267:       /* Point-to-Multipoint interfaces */
        !           268:         /* xxx */
        !           269:     }
        !           270: 
        !           271:   if ((caddr_t) lsdesc != (caddr_t) router_lsa +
        !           272:                           sizeof (struct ospf6_router_lsa))
        !           273:     {
        !           274:       /* Fill LSA Header */
        !           275:       lsa_header->age = 0;
        !           276:       lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
        !           277:       lsa_header->id = htonl (link_state_id);
        !           278:       lsa_header->adv_router = oa->ospf6->router_id;
        !           279:       lsa_header->seqnum =
        !           280:         ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
        !           281:                              lsa_header->adv_router, oa->lsdb);
        !           282:       lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
        !           283: 
        !           284:       /* LSA checksum */
        !           285:       ospf6_lsa_checksum (lsa_header);
        !           286: 
        !           287:       /* create LSA */
        !           288:       lsa = ospf6_lsa_create (lsa_header);
        !           289: 
        !           290:       /* Originate */
        !           291:       ospf6_lsa_originate_area (lsa, oa);
        !           292: 
        !           293:       link_state_id ++;
        !           294:     }
        !           295:   else
        !           296:     {
        !           297:       if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
        !           298:         zlog_debug ("Nothing to describe in Router-LSA, suppress");
        !           299:     }
        !           300: 
        !           301:   /* Do premature-aging of rest, undesired Router-LSAs */
        !           302:   type = ntohs (OSPF6_LSTYPE_ROUTER);
        !           303:   router = oa->ospf6->router_id;
        !           304:   for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
        !           305:        lsa = ospf6_lsdb_type_router_next (type, router, lsa))
        !           306:     {
        !           307:       if (ntohl (lsa->header->id) < link_state_id)
        !           308:         continue;
        !           309:       ospf6_lsa_purge (lsa);
        !           310:     }
        !           311: 
        !           312:   return 0;
        !           313: }
        !           314: 
        !           315: /*******************************/
        !           316: /* RFC2740 3.4.3.2 Network-LSA */
        !           317: /*******************************/
        !           318: 
        !           319: static int
        !           320: ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
        !           321: {
        !           322:   char *start, *end, *current;
        !           323:   struct ospf6_network_lsa *network_lsa;
        !           324:   struct ospf6_network_lsdesc *lsdesc;
        !           325:   char buf[128], options[32];
        !           326: 
        !           327:   network_lsa = (struct ospf6_network_lsa *)
        !           328:     ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
        !           329: 
        !           330:   ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
        !           331:   vty_out (vty, "     Options: %s%s", options, VNL);
        !           332: 
        !           333:   start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
        !           334:   end = (char *) lsa->header + ntohs (lsa->header->length);
        !           335:   for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
        !           336:        current += sizeof (struct ospf6_network_lsdesc))
        !           337:     {
        !           338:       lsdesc = (struct ospf6_network_lsdesc *) current;
        !           339:       inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
        !           340:       vty_out (vty, "     Attached Router: %s%s", buf, VNL);
        !           341:     }
        !           342:   return 0;
        !           343: }
        !           344: 
        !           345: int
        !           346: ospf6_network_lsa_originate (struct thread *thread)
        !           347: {
        !           348:   struct ospf6_interface *oi;
        !           349: 
        !           350:   char buffer [OSPF6_MAX_LSASIZE];
        !           351:   struct ospf6_lsa_header *lsa_header;
        !           352: 
        !           353:   int count;
        !           354:   struct ospf6_lsa *old, *lsa;
        !           355:   struct ospf6_network_lsa *network_lsa;
        !           356:   struct ospf6_network_lsdesc *lsdesc;
        !           357:   struct ospf6_neighbor *on;
        !           358:   struct ospf6_link_lsa *link_lsa;
        !           359:   struct listnode *i;
        !           360:   u_int16_t type;
        !           361: 
        !           362:   oi = (struct ospf6_interface *) THREAD_ARG (thread);
        !           363:   oi->thread_network_lsa = NULL;
        !           364: 
        !           365:   /* The interface must be enabled until here. A Network-LSA of a
        !           366:      disabled interface (but was once enabled) should be flushed
        !           367:      by ospf6_lsa_refresh (), and does not come here. */
        !           368:   assert (oi->area);
        !           369: 
        !           370:   old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
        !           371:                            htonl (oi->interface->ifindex),
        !           372:                            oi->area->ospf6->router_id, oi->area->lsdb);
        !           373: 
        !           374:   /* Do not originate Network-LSA if not DR */
        !           375:   if (oi->state != OSPF6_INTERFACE_DR)
        !           376:     {
        !           377:       if (old)
        !           378:         ospf6_lsa_purge (old);
        !           379:       return 0;
        !           380:     }
        !           381: 
        !           382:   if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
        !           383:     zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
        !           384: 
        !           385:   /* If none of neighbor is adjacent to us */
        !           386:   count = 0;
        !           387:   
        !           388:   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
        !           389:     if (on->state == OSPF6_NEIGHBOR_FULL)
        !           390:       count++;
        !           391:   
        !           392:   if (count == 0)
        !           393:     {
        !           394:       if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
        !           395:         zlog_debug ("Interface stub, ignore");
        !           396:       if (old)
        !           397:         ospf6_lsa_purge (old);
        !           398:       return 0;
        !           399:     }
        !           400: 
        !           401:   /* prepare buffer */
        !           402:   memset (buffer, 0, sizeof (buffer));
        !           403:   lsa_header = (struct ospf6_lsa_header *) buffer;
        !           404:   network_lsa = (struct ospf6_network_lsa *)
        !           405:     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
        !           406: 
        !           407:   /* Collect the interface's Link-LSAs to describe
        !           408:      network's optional capabilities */
        !           409:   type = htons (OSPF6_LSTYPE_LINK);
        !           410:   for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
        !           411:        lsa = ospf6_lsdb_type_next (type, lsa))
        !           412:     {
        !           413:       link_lsa = (struct ospf6_link_lsa *)
        !           414:         ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
        !           415:       network_lsa->options[0] |= link_lsa->options[0];
        !           416:       network_lsa->options[1] |= link_lsa->options[1];
        !           417:       network_lsa->options[2] |= link_lsa->options[2];
        !           418:     }
        !           419: 
        !           420:   lsdesc = (struct ospf6_network_lsdesc *)
        !           421:     ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
        !           422: 
        !           423:   /* set Link Description to the router itself */
        !           424:   lsdesc->router_id = oi->area->ospf6->router_id;
        !           425:   lsdesc++;
        !           426: 
        !           427:   /* Walk through the neighbors */
        !           428:   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
        !           429:     {
        !           430:       if (on->state != OSPF6_NEIGHBOR_FULL)
        !           431:         continue;
        !           432: 
        !           433:       /* set this neighbor's Router-ID to LSA */
        !           434:       lsdesc->router_id = on->router_id;
        !           435:       lsdesc++;
        !           436:     }
        !           437: 
        !           438:   /* Fill LSA Header */
        !           439:   lsa_header->age = 0;
        !           440:   lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
        !           441:   lsa_header->id = htonl (oi->interface->ifindex);
        !           442:   lsa_header->adv_router = oi->area->ospf6->router_id;
        !           443:   lsa_header->seqnum =
        !           444:     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
        !           445:                          lsa_header->adv_router, oi->area->lsdb);
        !           446:   lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
        !           447: 
        !           448:   /* LSA checksum */
        !           449:   ospf6_lsa_checksum (lsa_header);
        !           450: 
        !           451:   /* create LSA */
        !           452:   lsa = ospf6_lsa_create (lsa_header);
        !           453: 
        !           454:   /* Originate */
        !           455:   ospf6_lsa_originate_area (lsa, oi->area);
        !           456: 
        !           457:   return 0;
        !           458: }
        !           459: 
        !           460: 
        !           461: /****************************/
        !           462: /* RFC2740 3.4.3.6 Link-LSA */
        !           463: /****************************/
        !           464: 
        !           465: static int
        !           466: ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
        !           467: {
        !           468:   char *start, *end, *current;
        !           469:   struct ospf6_link_lsa *link_lsa;
        !           470:   int prefixnum;
        !           471:   char buf[128], options[32];
        !           472:   struct ospf6_prefix *prefix;
        !           473:   const char *p, *mc, *la, *nu;
        !           474:   struct in6_addr in6;
        !           475: 
        !           476:   link_lsa = (struct ospf6_link_lsa *)
        !           477:     ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
        !           478: 
        !           479:   ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
        !           480:   inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
        !           481:   prefixnum = ntohl (link_lsa->prefix_num);
        !           482: 
        !           483:   vty_out (vty, "     Priority: %d Options: %s%s",
        !           484:            link_lsa->priority, options, VNL);
        !           485:   vty_out (vty, "     LinkLocal Address: %s%s", buf, VNL);
        !           486:   vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VNL);
        !           487: 
        !           488:   start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
        !           489:   end = (char *) lsa->header + ntohs (lsa->header->length); 
        !           490:   for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
        !           491:     {
        !           492:       prefix = (struct ospf6_prefix *) current;
        !           493:       if (prefix->prefix_length == 0 ||
        !           494:           current + OSPF6_PREFIX_SIZE (prefix) > end)
        !           495:         break;
        !           496: 
        !           497:       p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
        !           498:            "P" : "--");
        !           499:       mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
        !           500:            "MC" : "--");
        !           501:       la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
        !           502:            "LA" : "--");
        !           503:       nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
        !           504:            "NU" : "--");
        !           505:       vty_out (vty, "     Prefix Options: %s|%s|%s|%s%s",
        !           506:                p, mc, la, nu, VNL);
        !           507: 
        !           508:       memset (&in6, 0, sizeof (in6));
        !           509:       memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
        !           510:               OSPF6_PREFIX_SPACE (prefix->prefix_length));
        !           511:       inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
        !           512:       vty_out (vty, "     Prefix: %s/%d%s",
        !           513:                buf, prefix->prefix_length, VNL);
        !           514:     }
        !           515: 
        !           516:   return 0;
        !           517: }
        !           518: 
        !           519: int
        !           520: ospf6_link_lsa_originate (struct thread *thread)
        !           521: {
        !           522:   struct ospf6_interface *oi;
        !           523: 
        !           524:   char buffer[OSPF6_MAX_LSASIZE];
        !           525:   struct ospf6_lsa_header *lsa_header;
        !           526:   struct ospf6_lsa *old, *lsa;
        !           527: 
        !           528:   struct ospf6_link_lsa *link_lsa;
        !           529:   struct ospf6_route *route;
        !           530:   struct ospf6_prefix *op;
        !           531: 
        !           532:   oi = (struct ospf6_interface *) THREAD_ARG (thread);
        !           533:   oi->thread_link_lsa = NULL;
        !           534: 
        !           535:   assert (oi->area);
        !           536: 
        !           537:   /* find previous LSA */
        !           538:   old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
        !           539:                            htonl (oi->interface->ifindex),
        !           540:                            oi->area->ospf6->router_id, oi->lsdb);
        !           541: 
        !           542:   if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
        !           543:     {
        !           544:       if (old)
        !           545:         ospf6_lsa_purge (old);
        !           546:       return 0;
        !           547:     }
        !           548: 
        !           549:   if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
        !           550:     zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
        !           551: 
        !           552:   /* can't make Link-LSA if linklocal address not set */
        !           553:   if (oi->linklocal_addr == NULL)
        !           554:     {
        !           555:       if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
        !           556:         zlog_debug ("No Linklocal address on %s, defer originating",
        !           557:                    oi->interface->name);
        !           558:       if (old)
        !           559:         ospf6_lsa_purge (old);
        !           560:       return 0;
        !           561:     }
        !           562: 
        !           563:   /* prepare buffer */
        !           564:   memset (buffer, 0, sizeof (buffer));
        !           565:   lsa_header = (struct ospf6_lsa_header *) buffer;
        !           566:   link_lsa = (struct ospf6_link_lsa *)
        !           567:     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
        !           568: 
        !           569:   /* Fill Link-LSA */
        !           570:   link_lsa->priority = oi->priority;
        !           571:   memcpy (link_lsa->options, oi->area->options, 3);
        !           572:   memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
        !           573:           sizeof (struct in6_addr));
        !           574:   link_lsa->prefix_num = htonl (oi->route_connected->count);
        !           575: 
        !           576:   op = (struct ospf6_prefix *)
        !           577:     ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
        !           578: 
        !           579:   /* connected prefix to advertise */
        !           580:   for (route = ospf6_route_head (oi->route_connected); route;
        !           581:        route = ospf6_route_next (route))
        !           582:     {
        !           583:       op->prefix_length = route->prefix.prefixlen;
        !           584:       op->prefix_options = route->path.prefix_options;
        !           585:       op->prefix_metric = htons (0);
        !           586:       memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
        !           587:               OSPF6_PREFIX_SPACE (op->prefix_length));
        !           588:       op = OSPF6_PREFIX_NEXT (op);
        !           589:     }
        !           590: 
        !           591:   /* Fill LSA Header */
        !           592:   lsa_header->age = 0;
        !           593:   lsa_header->type = htons (OSPF6_LSTYPE_LINK);
        !           594:   lsa_header->id = htonl (oi->interface->ifindex);
        !           595:   lsa_header->adv_router = oi->area->ospf6->router_id;
        !           596:   lsa_header->seqnum =
        !           597:     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
        !           598:                          lsa_header->adv_router, oi->lsdb);
        !           599:   lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
        !           600: 
        !           601:   /* LSA checksum */
        !           602:   ospf6_lsa_checksum (lsa_header);
        !           603: 
        !           604:   /* create LSA */
        !           605:   lsa = ospf6_lsa_create (lsa_header);
        !           606: 
        !           607:   /* Originate */
        !           608:   ospf6_lsa_originate_interface (lsa, oi);
        !           609: 
        !           610:   return 0;
        !           611: }
        !           612: 
        !           613: 
        !           614: /*****************************************/
        !           615: /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
        !           616: /*****************************************/
        !           617: 
        !           618: static int
        !           619: ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
        !           620: {
        !           621:   char *start, *end, *current;
        !           622:   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
        !           623:   int prefixnum;
        !           624:   char buf[128];
        !           625:   struct ospf6_prefix *prefix;
        !           626:   char id[16], adv_router[16];
        !           627:   const char *p, *mc, *la, *nu;
        !           628:   struct in6_addr in6;
        !           629: 
        !           630:   intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
        !           631:     ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
        !           632: 
        !           633:   prefixnum = ntohs (intra_prefix_lsa->prefix_num);
        !           634: 
        !           635:   vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VNL);
        !           636: 
        !           637:   inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
        !           638:   inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
        !           639:              adv_router, sizeof (adv_router));
        !           640:   vty_out (vty, "     Reference: %s Id: %s Adv: %s%s",
        !           641:            ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
        !           642:            VNL);
        !           643: 
        !           644:   start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
        !           645:   end = (char *) lsa->header + ntohs (lsa->header->length); 
        !           646:   for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
        !           647:     {
        !           648:       prefix = (struct ospf6_prefix *) current;
        !           649:       if (prefix->prefix_length == 0 ||
        !           650:           current + OSPF6_PREFIX_SIZE (prefix) > end)
        !           651:         break;
        !           652: 
        !           653:       p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
        !           654:            "P" : "--");
        !           655:       mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
        !           656:            "MC" : "--");
        !           657:       la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
        !           658:            "LA" : "--");
        !           659:       nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
        !           660:            "NU" : "--");
        !           661:       vty_out (vty, "     Prefix Options: %s|%s|%s|%s%s",
        !           662:                p, mc, la, nu, VNL);
        !           663: 
        !           664:       memset (&in6, 0, sizeof (in6));
        !           665:       memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
        !           666:               OSPF6_PREFIX_SPACE (prefix->prefix_length));
        !           667:       inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
        !           668:       vty_out (vty, "     Prefix: %s/%d%s",
        !           669:                buf, prefix->prefix_length, VNL);
        !           670:     }
        !           671: 
        !           672:   return 0;
        !           673: }
        !           674: 
        !           675: int
        !           676: ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
        !           677: {
        !           678:   struct ospf6_area *oa;
        !           679: 
        !           680:   char buffer[OSPF6_MAX_LSASIZE];
        !           681:   struct ospf6_lsa_header *lsa_header;
        !           682:   struct ospf6_lsa *old, *lsa;
        !           683: 
        !           684:   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
        !           685:   struct ospf6_interface *oi;
        !           686:   struct ospf6_neighbor *on;
        !           687:   struct ospf6_route *route;
        !           688:   struct ospf6_prefix *op;
        !           689:   struct listnode *i, *j;
        !           690:   int full_count = 0;
        !           691:   unsigned short prefix_num = 0;
        !           692:   char buf[BUFSIZ];
        !           693:   struct ospf6_route_table *route_advertise;
        !           694: 
        !           695:   oa = (struct ospf6_area *) THREAD_ARG (thread);
        !           696:   oa->thread_intra_prefix_lsa = NULL;
        !           697: 
        !           698:   /* find previous LSA */
        !           699:   old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
        !           700:                            htonl (0), oa->ospf6->router_id, oa->lsdb);
        !           701: 
        !           702:   if (! IS_AREA_ENABLED (oa))
        !           703:     {
        !           704:       if (old)
        !           705:         ospf6_lsa_purge (old);
        !           706:       return 0;
        !           707:     }
        !           708: 
        !           709:   if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           710:     zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
        !           711:                oa->name);
        !           712: 
        !           713:   /* prepare buffer */
        !           714:   memset (buffer, 0, sizeof (buffer));
        !           715:   lsa_header = (struct ospf6_lsa_header *) buffer;
        !           716:   intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
        !           717:     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
        !           718: 
        !           719:   /* Fill Intra-Area-Prefix-LSA */
        !           720:   intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
        !           721:   intra_prefix_lsa->ref_id = htonl (0);
        !           722:   intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
        !           723: 
        !           724:   route_advertise = ospf6_route_table_create (0, 0);
        !           725: 
        !           726:   for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
        !           727:     {
        !           728:       if (oi->state == OSPF6_INTERFACE_DOWN)
        !           729:         {
        !           730:           if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           731:             zlog_debug ("  Interface %s is down, ignore", oi->interface->name);
        !           732:           continue;
        !           733:         }
        !           734: 
        !           735:       full_count = 0;
        !           736: 
        !           737:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
        !           738:         if (on->state == OSPF6_NEIGHBOR_FULL)
        !           739:           full_count++;
        !           740: 
        !           741:       if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
        !           742:           oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
        !           743:           full_count != 0)
        !           744:         {
        !           745:           if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           746:             zlog_debug ("  Interface %s is not stub, ignore",
        !           747:                        oi->interface->name);
        !           748:           continue;
        !           749:         }
        !           750: 
        !           751:       if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           752:         zlog_debug ("  Interface %s:", oi->interface->name);
        !           753: 
        !           754:       /* connected prefix to advertise */
        !           755:       for (route = ospf6_route_head (oi->route_connected); route;
        !           756:            route = ospf6_route_best_next (route))
        !           757:         {
        !           758:           if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           759:             {
        !           760:               prefix2str (&route->prefix, buf, sizeof (buf));
        !           761:               zlog_debug ("    include %s", buf);
        !           762:             }
        !           763:           ospf6_route_add (ospf6_route_copy (route), route_advertise);
        !           764:         }
        !           765:     }
        !           766: 
        !           767:   if (route_advertise->count == 0)
        !           768:     {
        !           769:       if (old)
        !           770:         ospf6_lsa_purge (old);
        !           771:       ospf6_route_table_delete (route_advertise);
        !           772:       return 0;
        !           773:     }
        !           774: 
        !           775:   /* put prefixes to advertise */
        !           776:   prefix_num = 0;
        !           777:   op = (struct ospf6_prefix *)
        !           778:     ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
        !           779:   for (route = ospf6_route_head (route_advertise); route;
        !           780:        route = ospf6_route_best_next (route))
        !           781:     {
        !           782:       op->prefix_length = route->prefix.prefixlen;
        !           783:       op->prefix_options = route->path.prefix_options;
        !           784:       op->prefix_metric = htons (route->path.cost);
        !           785:       memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
        !           786:               OSPF6_PREFIX_SPACE (op->prefix_length));
        !           787:       op = OSPF6_PREFIX_NEXT (op);
        !           788:       prefix_num++;
        !           789:     }
        !           790: 
        !           791:   ospf6_route_table_delete (route_advertise);
        !           792: 
        !           793:   if (prefix_num == 0)
        !           794:     {
        !           795:       if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           796:         zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
        !           797:       return 0;
        !           798:     }
        !           799: 
        !           800:   intra_prefix_lsa->prefix_num = htons (prefix_num);
        !           801: 
        !           802:   /* Fill LSA Header */
        !           803:   lsa_header->age = 0;
        !           804:   lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
        !           805:   lsa_header->id = htonl (0);
        !           806:   lsa_header->adv_router = oa->ospf6->router_id;
        !           807:   lsa_header->seqnum =
        !           808:     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
        !           809:                          lsa_header->adv_router, oa->lsdb);
        !           810:   lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
        !           811: 
        !           812:   /* LSA checksum */
        !           813:   ospf6_lsa_checksum (lsa_header);
        !           814: 
        !           815:   /* create LSA */
        !           816:   lsa = ospf6_lsa_create (lsa_header);
        !           817: 
        !           818:   /* Originate */
        !           819:   ospf6_lsa_originate_area (lsa, oa);
        !           820: 
        !           821:   return 0;
        !           822: }
        !           823: 
        !           824: 
        !           825: int
        !           826: ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
        !           827: {
        !           828:   struct ospf6_interface *oi;
        !           829: 
        !           830:   char buffer[OSPF6_MAX_LSASIZE];
        !           831:   struct ospf6_lsa_header *lsa_header;
        !           832:   struct ospf6_lsa *old, *lsa;
        !           833: 
        !           834:   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
        !           835:   struct ospf6_neighbor *on;
        !           836:   struct ospf6_route *route;
        !           837:   struct ospf6_prefix *op;
        !           838:   struct listnode *i;
        !           839:   int full_count = 0;
        !           840:   unsigned short prefix_num = 0;
        !           841:   struct ospf6_route_table *route_advertise;
        !           842:   struct ospf6_link_lsa *link_lsa;
        !           843:   char *start, *end, *current;
        !           844:   u_int16_t type;
        !           845:   char buf[BUFSIZ];
        !           846: 
        !           847:   oi = (struct ospf6_interface *) THREAD_ARG (thread);
        !           848:   oi->thread_intra_prefix_lsa = NULL;
        !           849: 
        !           850:   assert (oi->area);
        !           851: 
        !           852:   /* find previous LSA */
        !           853:   old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
        !           854:                            htonl (oi->interface->ifindex),
        !           855:                            oi->area->ospf6->router_id, oi->area->lsdb);
        !           856: 
        !           857:   if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
        !           858:     {
        !           859:       if (old)
        !           860:         ospf6_lsa_purge (old);
        !           861:       return 0;
        !           862:     }
        !           863: 
        !           864:   if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           865:     zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
        !           866:                oi->interface->name);
        !           867: 
        !           868:   /* prepare buffer */
        !           869:   memset (buffer, 0, sizeof (buffer));
        !           870:   lsa_header = (struct ospf6_lsa_header *) buffer;
        !           871:   intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
        !           872:     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
        !           873: 
        !           874:   /* Fill Intra-Area-Prefix-LSA */
        !           875:   intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
        !           876:   intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
        !           877:   intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
        !           878: 
        !           879:   if (oi->state != OSPF6_INTERFACE_DR)
        !           880:     {
        !           881:       if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           882:         zlog_debug ("  Interface is not DR");
        !           883:       if (old)
        !           884:         ospf6_lsa_purge (old);
        !           885:       return 0;
        !           886:     }
        !           887: 
        !           888:   full_count = 0;
        !           889:   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
        !           890:     if (on->state == OSPF6_NEIGHBOR_FULL)
        !           891:       full_count++;
        !           892:   
        !           893:   if (full_count == 0)
        !           894:     {
        !           895:       if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           896:         zlog_debug ("  Interface is stub");
        !           897:       if (old)
        !           898:         ospf6_lsa_purge (old);
        !           899:       return 0;
        !           900:     }
        !           901: 
        !           902:   /* connected prefix to advertise */
        !           903:   route_advertise = ospf6_route_table_create (0, 0);
        !           904: 
        !           905:   type = ntohs (OSPF6_LSTYPE_LINK);
        !           906:   for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
        !           907:        lsa = ospf6_lsdb_type_next (type, lsa))
        !           908:     {
        !           909:       if (OSPF6_LSA_IS_MAXAGE (lsa))
        !           910:         continue;
        !           911: 
        !           912:       if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           913:         zlog_debug ("  include prefix from %s", lsa->name);
        !           914: 
        !           915:       if (lsa->header->adv_router != oi->area->ospf6->router_id)
        !           916:         {
        !           917:           on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
        !           918:           if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
        !           919:             {
        !           920:               if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           921:                 zlog_debug ("    Neighbor not found or not Full, ignore");
        !           922:               continue;
        !           923:             }
        !           924:         }
        !           925: 
        !           926:       link_lsa = (struct ospf6_link_lsa *)
        !           927:         ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
        !           928: 
        !           929:       prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
        !           930:       start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
        !           931:       end = (char *) lsa->header + ntohs (lsa->header->length); 
        !           932:       for (current = start; current < end && prefix_num;
        !           933:            current += OSPF6_PREFIX_SIZE (op))
        !           934:         {
        !           935:           op = (struct ospf6_prefix *) current;
        !           936:           if (op->prefix_length == 0 ||
        !           937:               current + OSPF6_PREFIX_SIZE (op) > end)
        !           938:             break;
        !           939: 
        !           940:           route = ospf6_route_create ();
        !           941: 
        !           942:           route->type = OSPF6_DEST_TYPE_NETWORK;
        !           943:           route->prefix.family = AF_INET6;
        !           944:           route->prefix.prefixlen = op->prefix_length;
        !           945:           memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
        !           946:           memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
        !           947:                   OSPF6_PREFIX_SPACE (op->prefix_length));
        !           948: 
        !           949:           route->path.origin.type = lsa->header->type;
        !           950:           route->path.origin.id = lsa->header->id;
        !           951:           route->path.origin.adv_router = lsa->header->adv_router;
        !           952:           route->path.options[0] = link_lsa->options[0];
        !           953:           route->path.options[1] = link_lsa->options[1];
        !           954:           route->path.options[2] = link_lsa->options[2];
        !           955:           route->path.prefix_options = op->prefix_options;
        !           956:           route->path.area_id = oi->area->area_id;
        !           957:           route->path.type = OSPF6_PATH_TYPE_INTRA;
        !           958: 
        !           959:           if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           960:             {
        !           961:               prefix2str (&route->prefix, buf, sizeof (buf));
        !           962:               zlog_debug ("    include %s", buf);
        !           963:             }
        !           964: 
        !           965:           ospf6_route_add (route, route_advertise);
        !           966:           prefix_num--;
        !           967:         }
        !           968:       if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           969:         zlog_debug ("Trailing garbage in %s", lsa->name);
        !           970:     }
        !           971: 
        !           972:   op = (struct ospf6_prefix *)
        !           973:     ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
        !           974: 
        !           975:   prefix_num = 0;
        !           976:   for (route = ospf6_route_head (route_advertise); route;
        !           977:        route = ospf6_route_best_next (route))
        !           978:     {
        !           979:       op->prefix_length = route->prefix.prefixlen;
        !           980:       op->prefix_options = route->path.prefix_options;
        !           981:       op->prefix_metric = htons (0);
        !           982:       memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
        !           983:               OSPF6_PREFIX_SPACE (op->prefix_length));
        !           984:       op = OSPF6_PREFIX_NEXT (op);
        !           985:       prefix_num++;
        !           986:     }
        !           987: 
        !           988:   ospf6_route_table_delete (route_advertise);
        !           989: 
        !           990:   if (prefix_num == 0)
        !           991:     {
        !           992:       if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        !           993:         zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
        !           994:       return 0;
        !           995:     }
        !           996: 
        !           997:   intra_prefix_lsa->prefix_num = htons (prefix_num);
        !           998: 
        !           999:   /* Fill LSA Header */
        !          1000:   lsa_header->age = 0;
        !          1001:   lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
        !          1002:   lsa_header->id = htonl (oi->interface->ifindex);
        !          1003:   lsa_header->adv_router = oi->area->ospf6->router_id;
        !          1004:   lsa_header->seqnum =
        !          1005:     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
        !          1006:                          lsa_header->adv_router, oi->area->lsdb);
        !          1007:   lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
        !          1008: 
        !          1009:   /* LSA checksum */
        !          1010:   ospf6_lsa_checksum (lsa_header);
        !          1011: 
        !          1012:   /* create LSA */
        !          1013:   lsa = ospf6_lsa_create (lsa_header);
        !          1014: 
        !          1015:   /* Originate */
        !          1016:   ospf6_lsa_originate_area (lsa, oi->area);
        !          1017: 
        !          1018:   return 0;
        !          1019: }
        !          1020: 
        !          1021: void
        !          1022: ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
        !          1023: {
        !          1024:   struct ospf6_area *oa;
        !          1025:   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
        !          1026:   struct prefix ls_prefix;
        !          1027:   struct ospf6_route *route, *ls_entry;
        !          1028:   int i, prefix_num;
        !          1029:   struct ospf6_prefix *op;
        !          1030:   char *start, *current, *end;
        !          1031:   char buf[64];
        !          1032: 
        !          1033:   if (OSPF6_LSA_IS_MAXAGE (lsa))
        !          1034:     return;
        !          1035: 
        !          1036:   if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1037:     zlog_debug ("%s found", lsa->name);
        !          1038: 
        !          1039:   oa = OSPF6_AREA (lsa->lsdb->data);
        !          1040: 
        !          1041:   intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
        !          1042:     OSPF6_LSA_HEADER_END (lsa->header);
        !          1043:   if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
        !          1044:     ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
        !          1045:                             htonl (0), &ls_prefix);
        !          1046:   else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
        !          1047:     ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
        !          1048:                             intra_prefix_lsa->ref_id, &ls_prefix);
        !          1049:   else
        !          1050:     {
        !          1051:       if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1052:         zlog_debug ("Unknown reference LS-type: %#hx",
        !          1053:                    ntohs (intra_prefix_lsa->ref_type));
        !          1054:       return;
        !          1055:     }
        !          1056: 
        !          1057:   ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
        !          1058:   if (ls_entry == NULL)
        !          1059:     {
        !          1060:       if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1061:         {
        !          1062:           ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
        !          1063:           zlog_debug ("LS entry does not exist: %s", buf);
        !          1064:         }
        !          1065:       return;
        !          1066:     }
        !          1067: 
        !          1068:   prefix_num = ntohs (intra_prefix_lsa->prefix_num);
        !          1069:   start = (caddr_t) intra_prefix_lsa +
        !          1070:           sizeof (struct ospf6_intra_prefix_lsa);
        !          1071:   end = OSPF6_LSA_END (lsa->header);
        !          1072:   for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
        !          1073:     {
        !          1074:       op = (struct ospf6_prefix *) current;
        !          1075:       if (prefix_num == 0)
        !          1076:         break;
        !          1077:       if (end < current + OSPF6_PREFIX_SIZE (op))
        !          1078:         break;
        !          1079: 
        !          1080:       route = ospf6_route_create ();
        !          1081: 
        !          1082:       memset (&route->prefix, 0, sizeof (struct prefix));
        !          1083:       route->prefix.family = AF_INET6;
        !          1084:       route->prefix.prefixlen = op->prefix_length;
        !          1085:       ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
        !          1086: 
        !          1087:       route->type = OSPF6_DEST_TYPE_NETWORK;
        !          1088:       route->path.origin.type = lsa->header->type;
        !          1089:       route->path.origin.id = lsa->header->id;
        !          1090:       route->path.origin.adv_router = lsa->header->adv_router;
        !          1091:       route->path.prefix_options = op->prefix_options;
        !          1092:       route->path.area_id = oa->area_id;
        !          1093:       route->path.type = OSPF6_PATH_TYPE_INTRA;
        !          1094:       route->path.metric_type = 1;
        !          1095:       route->path.cost = ls_entry->path.cost +
        !          1096:                          ntohs (op->prefix_metric);
        !          1097: 
        !          1098:       for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
        !          1099:            i < OSPF6_MULTI_PATH_LIMIT; i++)
        !          1100:         ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
        !          1101: 
        !          1102:       if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1103:         {
        !          1104:           prefix2str (&route->prefix, buf, sizeof (buf));
        !          1105:           zlog_debug ("  add %s", buf);
        !          1106:         }
        !          1107: 
        !          1108:       ospf6_route_add (route, oa->route_table);
        !          1109:       prefix_num--;
        !          1110:     }
        !          1111: 
        !          1112:   if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1113:     zlog_debug ("Trailing garbage ignored");
        !          1114: }
        !          1115: 
        !          1116: void
        !          1117: ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
        !          1118: {
        !          1119:   struct ospf6_area *oa;
        !          1120:   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
        !          1121:   struct prefix prefix;
        !          1122:   struct ospf6_route *route;
        !          1123:   int prefix_num;
        !          1124:   struct ospf6_prefix *op;
        !          1125:   char *start, *current, *end;
        !          1126:   char buf[64];
        !          1127: 
        !          1128:   if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1129:     zlog_debug ("%s disappearing", lsa->name);
        !          1130: 
        !          1131:   oa = OSPF6_AREA (lsa->lsdb->data);
        !          1132: 
        !          1133:   intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
        !          1134:     OSPF6_LSA_HEADER_END (lsa->header);
        !          1135: 
        !          1136:   prefix_num = ntohs (intra_prefix_lsa->prefix_num);
        !          1137:   start = (caddr_t) intra_prefix_lsa +
        !          1138:           sizeof (struct ospf6_intra_prefix_lsa);
        !          1139:   end = OSPF6_LSA_END (lsa->header);
        !          1140:   for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
        !          1141:     {
        !          1142:       op = (struct ospf6_prefix *) current;
        !          1143:       if (prefix_num == 0)
        !          1144:         break;
        !          1145:       if (end < current + OSPF6_PREFIX_SIZE (op))
        !          1146:         break;
        !          1147:       prefix_num--;
        !          1148: 
        !          1149:       memset (&prefix, 0, sizeof (struct prefix));
        !          1150:       prefix.family = AF_INET6;
        !          1151:       prefix.prefixlen = op->prefix_length;
        !          1152:       ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
        !          1153: 
        !          1154:       route = ospf6_route_lookup (&prefix, oa->route_table);
        !          1155:       if (route == NULL)
        !          1156:         continue;
        !          1157: 
        !          1158:       for (ospf6_route_lock (route);
        !          1159:            route && ospf6_route_is_prefix (&prefix, route);
        !          1160:            route = ospf6_route_next (route))
        !          1161:         {
        !          1162:           if (route->type != OSPF6_DEST_TYPE_NETWORK)
        !          1163:             continue;
        !          1164:           if (route->path.area_id != oa->area_id)
        !          1165:             continue;
        !          1166:           if (route->path.type != OSPF6_PATH_TYPE_INTRA)
        !          1167:             continue;
        !          1168:           if (route->path.origin.type != lsa->header->type ||
        !          1169:               route->path.origin.id != lsa->header->id ||
        !          1170:               route->path.origin.adv_router != lsa->header->adv_router)
        !          1171:             continue;
        !          1172: 
        !          1173:           if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1174:             {
        !          1175:               prefix2str (&route->prefix, buf, sizeof (buf));
        !          1176:               zlog_debug ("remove %s", buf);
        !          1177:             }
        !          1178:           ospf6_route_remove (route, oa->route_table);
        !          1179:         }
        !          1180:       if (route)
        !          1181:        ospf6_route_unlock (route);
        !          1182:     }
        !          1183: 
        !          1184:   if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1185:     zlog_debug ("Trailing garbage ignored");
        !          1186: }
        !          1187: 
        !          1188: void
        !          1189: ospf6_intra_route_calculation (struct ospf6_area *oa)
        !          1190: {
        !          1191:   struct ospf6_route *route;
        !          1192:   u_int16_t type;
        !          1193:   struct ospf6_lsa *lsa;
        !          1194:   void (*hook_add) (struct ospf6_route *) = NULL;
        !          1195:   void (*hook_remove) (struct ospf6_route *) = NULL;
        !          1196: 
        !          1197:   if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1198:     zlog_debug ("Re-examin intra-routes for area %s", oa->name);
        !          1199: 
        !          1200:   hook_add = oa->route_table->hook_add;
        !          1201:   hook_remove = oa->route_table->hook_remove;
        !          1202:   oa->route_table->hook_add = NULL;
        !          1203:   oa->route_table->hook_remove = NULL;
        !          1204: 
        !          1205:   for (route = ospf6_route_head (oa->route_table); route;
        !          1206:        route = ospf6_route_next (route))
        !          1207:     route->flag = OSPF6_ROUTE_REMOVE;
        !          1208: 
        !          1209:   type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
        !          1210:   for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
        !          1211:        lsa = ospf6_lsdb_type_next (type, lsa))
        !          1212:     ospf6_intra_prefix_lsa_add (lsa);
        !          1213: 
        !          1214:   oa->route_table->hook_add = hook_add;
        !          1215:   oa->route_table->hook_remove = hook_remove;
        !          1216: 
        !          1217:   for (route = ospf6_route_head (oa->route_table); route;
        !          1218:        route = ospf6_route_next (route))
        !          1219:     {
        !          1220:       if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
        !          1221:           CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
        !          1222:         {
        !          1223:           UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
        !          1224:           UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
        !          1225:         }
        !          1226: 
        !          1227:       if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
        !          1228:         ospf6_route_remove (route, oa->route_table);
        !          1229:       else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
        !          1230:                CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
        !          1231:         {
        !          1232:           if (hook_add)
        !          1233:             (*hook_add) (route);
        !          1234:         }
        !          1235: 
        !          1236:       route->flag = 0;
        !          1237:     }
        !          1238: 
        !          1239:   if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        !          1240:     zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
        !          1241: }
        !          1242: 
        !          1243: static void
        !          1244: ospf6_brouter_debug_print (struct ospf6_route *brouter)
        !          1245: {
        !          1246:   u_int32_t brouter_id;
        !          1247:   char brouter_name[16];
        !          1248:   char area_name[16];
        !          1249:   char destination[64];
        !          1250:   char installed[16], changed[16];
        !          1251:   struct timeval now, res;
        !          1252:   char id[16], adv_router[16];
        !          1253:   char capa[16], options[16];
        !          1254: 
        !          1255:   brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
        !          1256:   inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
        !          1257:   inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
        !          1258:   ospf6_linkstate_prefix2str (&brouter->prefix, destination,
        !          1259:                               sizeof (destination));
        !          1260: 
        !          1261:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
        !          1262:   timersub (&now, &brouter->installed, &res);
        !          1263:   timerstring (&res, installed, sizeof (installed));
        !          1264: 
        !          1265:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
        !          1266:   timersub (&now, &brouter->changed, &res);
        !          1267:   timerstring (&res, changed, sizeof (changed));
        !          1268: 
        !          1269:   inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
        !          1270:   inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
        !          1271:              sizeof (adv_router));
        !          1272: 
        !          1273:   ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
        !          1274:   ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
        !          1275: 
        !          1276:   zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
        !          1277:   zlog_info ("  memory: prev: %p this: %p next: %p parent rnode: %p",
        !          1278:              brouter->prev, brouter, brouter->next, brouter->rnode);
        !          1279:   zlog_info ("  type: %d prefix: %s installed: %s changed: %s",
        !          1280:              brouter->type, destination, installed, changed);
        !          1281:   zlog_info ("  lock: %d flags: %s%s%s%s", brouter->lock,
        !          1282:            (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST)   ? "B" : "-"),
        !          1283:            (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD)    ? "A" : "-"),
        !          1284:            (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
        !          1285:            (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
        !          1286:   zlog_info ("  path type: %s ls-origin %s id: %s adv-router %s",
        !          1287:              OSPF6_PATH_TYPE_NAME (brouter->path.type),
        !          1288:              ospf6_lstype_name (brouter->path.origin.type),
        !          1289:              id, adv_router);
        !          1290:   zlog_info ("  options: %s router-bits: %s metric-type: %d metric: %d/%d",
        !          1291:              options, capa, brouter->path.metric_type,
        !          1292:              brouter->path.cost, brouter->path.cost_e2);
        !          1293: }
        !          1294: 
        !          1295: void
        !          1296: ospf6_intra_brouter_calculation (struct ospf6_area *oa)
        !          1297: {
        !          1298:   struct ospf6_route *brouter, *copy;
        !          1299:   void (*hook_add) (struct ospf6_route *) = NULL;
        !          1300:   void (*hook_remove) (struct ospf6_route *) = NULL;
        !          1301:   u_int32_t brouter_id;
        !          1302:   char brouter_name[16];
        !          1303:   
        !          1304:   if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
        !          1305:     zlog_info ("border-router calculation for area %s", oa->name);
        !          1306:   
        !          1307:   hook_add = oa->ospf6->brouter_table->hook_add;
        !          1308:   hook_remove = oa->ospf6->brouter_table->hook_remove;
        !          1309:   oa->ospf6->brouter_table->hook_add = NULL;
        !          1310:   oa->ospf6->brouter_table->hook_remove = NULL;
        !          1311: 
        !          1312:   /* withdraw the previous router entries for the area */
        !          1313:   for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
        !          1314:        brouter = ospf6_route_next (brouter))
        !          1315:     {
        !          1316:       brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
        !          1317:       inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
        !          1318:       if (brouter->path.area_id != oa->area_id)
        !          1319:         continue;
        !          1320:       brouter->flag = OSPF6_ROUTE_REMOVE;
        !          1321: 
        !          1322:       if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
        !          1323:           IS_OSPF6_DEBUG_ROUTE (MEMORY))
        !          1324:         {
        !          1325:           zlog_info ("%p: mark as removing: area %s brouter %s",
        !          1326:                      brouter, oa->name, brouter_name);
        !          1327:           ospf6_brouter_debug_print (brouter);
        !          1328:         }
        !          1329:     }
        !          1330: 
        !          1331:   for (brouter = ospf6_route_head (oa->spf_table); brouter;
        !          1332:        brouter = ospf6_route_next (brouter))
        !          1333:     {
        !          1334:       brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
        !          1335:       inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
        !          1336: 
        !          1337:       if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
        !          1338:         continue;
        !          1339:       if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
        !          1340:         continue;
        !          1341:       if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
        !          1342:           ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
        !          1343:         continue;
        !          1344: 
        !          1345:       copy = ospf6_route_copy (brouter);
        !          1346:       copy->type = OSPF6_DEST_TYPE_ROUTER;
        !          1347:       copy->path.area_id = oa->area_id;
        !          1348:       ospf6_route_add (copy, oa->ospf6->brouter_table);
        !          1349: 
        !          1350:       if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
        !          1351:           IS_OSPF6_DEBUG_ROUTE (MEMORY))
        !          1352:         {
        !          1353:           zlog_info ("%p: transfer: area %s brouter %s",
        !          1354:                      brouter, oa->name, brouter_name);
        !          1355:           ospf6_brouter_debug_print (brouter);
        !          1356:         }
        !          1357:     }
        !          1358: 
        !          1359:   oa->ospf6->brouter_table->hook_add = hook_add;
        !          1360:   oa->ospf6->brouter_table->hook_remove = hook_remove;
        !          1361: 
        !          1362:   for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
        !          1363:        brouter = ospf6_route_next (brouter))
        !          1364:     {
        !          1365:       brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
        !          1366:       inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
        !          1367:       
        !          1368:       if (brouter->path.area_id != oa->area_id)
        !          1369:         continue;
        !          1370: 
        !          1371:       if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
        !          1372:         continue;
        !          1373: 
        !          1374:       if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
        !          1375:           CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
        !          1376:         {
        !          1377:           UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
        !          1378:           UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
        !          1379:         }
        !          1380: 
        !          1381:       if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
        !          1382:         {
        !          1383:           if (IS_OSPF6_DEBUG_BROUTER ||
        !          1384:               IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
        !          1385:               IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
        !          1386:             zlog_info ("brouter %s disappears via area %s",
        !          1387:                        brouter_name, oa->name);
        !          1388:           ospf6_route_remove (brouter, oa->ospf6->brouter_table);
        !          1389:         }
        !          1390:       else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
        !          1391:                CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
        !          1392:         {
        !          1393:           if (IS_OSPF6_DEBUG_BROUTER ||
        !          1394:               IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
        !          1395:               IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
        !          1396:             zlog_info ("brouter %s appears via area %s",
        !          1397:                        brouter_name, oa->name);
        !          1398: 
        !          1399:           /* newly added */
        !          1400:           if (hook_add)
        !          1401:             (*hook_add) (brouter);
        !          1402:         }
        !          1403:       else
        !          1404:         {
        !          1405:           if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
        !          1406:               IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
        !          1407:             zlog_info ("brouter %s still exists via area %s",
        !          1408:                        brouter_name, oa->name);
        !          1409:         }
        !          1410: 
        !          1411:       brouter->flag = 0;
        !          1412:     }
        !          1413: 
        !          1414:   if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
        !          1415:     zlog_info ("border-router calculation for area %s: done", oa->name);
        !          1416: }
        !          1417: 
        !          1418: struct ospf6_lsa_handler router_handler =
        !          1419: {
        !          1420:   OSPF6_LSTYPE_ROUTER,
        !          1421:   "Router",
        !          1422:   ospf6_router_lsa_show
        !          1423: };
        !          1424: 
        !          1425: struct ospf6_lsa_handler network_handler =
        !          1426: {
        !          1427:   OSPF6_LSTYPE_NETWORK,
        !          1428:   "Network",
        !          1429:   ospf6_network_lsa_show
        !          1430: };
        !          1431: 
        !          1432: struct ospf6_lsa_handler link_handler =
        !          1433: {
        !          1434:   OSPF6_LSTYPE_LINK,
        !          1435:   "Link",
        !          1436:   ospf6_link_lsa_show
        !          1437: };
        !          1438: 
        !          1439: struct ospf6_lsa_handler intra_prefix_handler =
        !          1440: {
        !          1441:   OSPF6_LSTYPE_INTRA_PREFIX,
        !          1442:   "Intra-Prefix",
        !          1443:   ospf6_intra_prefix_lsa_show
        !          1444: };
        !          1445: 
        !          1446: void
        !          1447: ospf6_intra_init (void)
        !          1448: {
        !          1449:   ospf6_install_lsa_handler (&router_handler);
        !          1450:   ospf6_install_lsa_handler (&network_handler);
        !          1451:   ospf6_install_lsa_handler (&link_handler);
        !          1452:   ospf6_install_lsa_handler (&intra_prefix_handler);
        !          1453: }
        !          1454: 
        !          1455: DEFUN (debug_ospf6_brouter,
        !          1456:        debug_ospf6_brouter_cmd,
        !          1457:        "debug ospf6 border-routers",
        !          1458:        DEBUG_STR
        !          1459:        OSPF6_STR
        !          1460:        "Debug border router\n"
        !          1461:       )
        !          1462: {
        !          1463:   OSPF6_DEBUG_BROUTER_ON ();
        !          1464:   return CMD_SUCCESS;
        !          1465: }
        !          1466: 
        !          1467: DEFUN (no_debug_ospf6_brouter,
        !          1468:        no_debug_ospf6_brouter_cmd,
        !          1469:        "no debug ospf6 border-routers",
        !          1470:        NO_STR
        !          1471:        DEBUG_STR
        !          1472:        OSPF6_STR
        !          1473:        "Debug border router\n"
        !          1474:       )
        !          1475: {
        !          1476:   OSPF6_DEBUG_BROUTER_OFF ();
        !          1477:   return CMD_SUCCESS;
        !          1478: }
        !          1479: 
        !          1480: DEFUN (debug_ospf6_brouter_router,
        !          1481:        debug_ospf6_brouter_router_cmd,
        !          1482:        "debug ospf6 border-routers router-id A.B.C.D",
        !          1483:        DEBUG_STR
        !          1484:        OSPF6_STR
        !          1485:        "Debug border router\n"
        !          1486:        "Debug specific border router\n"
        !          1487:        "Specify border-router's router-id\n"
        !          1488:       )
        !          1489: {
        !          1490:   u_int32_t router_id;
        !          1491:   inet_pton (AF_INET, argv[0], &router_id);
        !          1492:   OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
        !          1493:   return CMD_SUCCESS;
        !          1494: }
        !          1495: 
        !          1496: DEFUN (no_debug_ospf6_brouter_router,
        !          1497:        no_debug_ospf6_brouter_router_cmd,
        !          1498:        "no debug ospf6 border-routers router-id",
        !          1499:        NO_STR
        !          1500:        DEBUG_STR
        !          1501:        OSPF6_STR
        !          1502:        "Debug border router\n"
        !          1503:        "Debug specific border router\n"
        !          1504:       )
        !          1505: {
        !          1506:   OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
        !          1507:   return CMD_SUCCESS;
        !          1508: }
        !          1509: 
        !          1510: DEFUN (debug_ospf6_brouter_area,
        !          1511:        debug_ospf6_brouter_area_cmd,
        !          1512:        "debug ospf6 border-routers area-id A.B.C.D",
        !          1513:        DEBUG_STR
        !          1514:        OSPF6_STR
        !          1515:        "Debug border router\n"
        !          1516:        "Debug border routers in specific Area\n"
        !          1517:        "Specify Area-ID\n"
        !          1518:       )
        !          1519: {
        !          1520:   u_int32_t area_id;
        !          1521:   inet_pton (AF_INET, argv[0], &area_id);
        !          1522:   OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
        !          1523:   return CMD_SUCCESS;
        !          1524: }
        !          1525: 
        !          1526: DEFUN (no_debug_ospf6_brouter_area,
        !          1527:        no_debug_ospf6_brouter_area_cmd,
        !          1528:        "no debug ospf6 border-routers area-id",
        !          1529:        NO_STR
        !          1530:        DEBUG_STR
        !          1531:        OSPF6_STR
        !          1532:        "Debug border router\n"
        !          1533:        "Debug border routers in specific Area\n"
        !          1534:       )
        !          1535: {
        !          1536:   OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
        !          1537:   return CMD_SUCCESS;
        !          1538: }
        !          1539: 
        !          1540: int
        !          1541: config_write_ospf6_debug_brouter (struct vty *vty)
        !          1542: {
        !          1543:   char buf[16];
        !          1544:   if (IS_OSPF6_DEBUG_BROUTER)
        !          1545:     vty_out (vty, "debug ospf6 border-routers%s", VNL);
        !          1546:   if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
        !          1547:     {
        !          1548:       inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
        !          1549:                  buf, sizeof (buf));
        !          1550:       vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
        !          1551:     }
        !          1552:   if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
        !          1553:     {
        !          1554:       inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
        !          1555:                  buf, sizeof (buf));
        !          1556:       vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
        !          1557:     }
        !          1558:   return 0;
        !          1559: }
        !          1560: 
        !          1561: void
        !          1562: install_element_ospf6_debug_brouter (void)
        !          1563: {
        !          1564:   install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
        !          1565:   install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
        !          1566:   install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
        !          1567:   install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
        !          1568:   install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
        !          1569:   install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
        !          1570:   install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
        !          1571:   install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
        !          1572:   install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
        !          1573:   install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
        !          1574:   install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
        !          1575:   install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
        !          1576: }
        !          1577: 
        !          1578: 

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