File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_intra.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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