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

1.1       misho       1: /*
                      2:  * Copyright (C) 2003 Yasuhiro Ohara
                      3:  *
                      4:  * This file is part of GNU Zebra.
                      5:  *
                      6:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2, or (at your option) any
                      9:  * later version.
                     10:  *
                     11:  * GNU Zebra is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
                     18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
                     19:  * Boston, MA 02111-1307, USA.  
                     20:  */
                     21: 
                     22: #include <zebra.h>
                     23: 
                     24: #include "log.h"
                     25: #include "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>