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

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"
1.1.1.2 ! misho      49: #include "ospf6_spf.h"
1.1       misho      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: 
1.1.1.2 ! misho      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: 
1.1       misho      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
1.1.1.2 ! misho     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
1.1       misho     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)
1.1.1.2 ! misho     237:           && ((size_t)((char *)lsdesc - buffer)
        !           238:                  + sizeof (struct ospf6_router_lsdesc)
        !           239:                > oa->router_lsa_size_limit))
1.1       misho     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 */
1.1.1.2 ! misho     277:       if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1.1       misho     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 */
1.1.1.2 ! misho     295:       else if (oi->type == OSPF_IFTYPE_BROADCAST)
1.1       misho     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:         }
1.1.1.2 ! misho     323:       else
        !           324:        {
        !           325:          assert (0);           /* Unknown interface type */
        !           326:        }
1.1       misho     327: 
                    328:       /* Virtual links */
                    329:         /* xxx */
                    330:       /* Point-to-Multipoint interfaces */
                    331:         /* xxx */
                    332:     }
                    333: 
1.1.1.2 ! misho     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);
1.1       misho     343: 
1.1.1.2 ! misho     344:   /* LSA checksum */
        !           345:   ospf6_lsa_checksum (lsa_header);
        !           346: 
        !           347:   /* create LSA */
        !           348:   lsa = ospf6_lsa_create (lsa_header);
1.1       misho     349: 
1.1.1.2 ! misho     350:   /* Originate */
        !           351:   ospf6_lsa_originate_area (lsa, oa);
1.1       misho     352: 
1.1.1.2 ! misho     353:   link_state_id ++;
1.1       misho     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: 
1.1.1.2 ! misho     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: 
1.1       misho     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: 
1.1.1.2 ! misho     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: 
1.1       misho     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: /*****************************************/
1.1.1.2 ! misho     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: }
1.1       misho     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];
1.1.1.2 ! misho    1221:   struct interface *ifp;
        !          1222:   int direct_connect = 0;
1.1       misho    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: 
1.1.1.2 ! misho    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: 
1.1       misho    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: 
1.1.1.2 ! misho    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: 
1.1       misho    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: 
1.1.1.2 ! misho    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:         }
1.1       misho    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",
1.1.1.2 ! misho    1498:              (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
        !          1499:              (void *)brouter->rnode);
1.1       misho    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",
1.1.1.2 ! misho    1547:                      (void *)brouter, oa->name, brouter_name);
1.1       misho    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: 
1.1.1.2 ! misho    1566:       if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) ||
        !          1567:          ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R))
        !          1568:        continue;
        !          1569: 
1.1       misho    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",
1.1.1.2 ! misho    1579:                      (void *)brouter, oa->name, brouter_name);
1.1       misho    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",
1.1.1.2 ! misho    1647:   "Rtr",
        !          1648:   ospf6_router_lsa_show,
        !          1649:   ospf6_router_lsa_get_nbr_id
1.1       misho    1650: };
                   1651: 
                   1652: struct ospf6_lsa_handler network_handler =
                   1653: {
                   1654:   OSPF6_LSTYPE_NETWORK,
                   1655:   "Network",
1.1.1.2 ! misho    1656:   "Net",
        !          1657:   ospf6_network_lsa_show,
        !          1658:   ospf6_network_lsa_get_ar_id
1.1       misho    1659: };
                   1660: 
                   1661: struct ospf6_lsa_handler link_handler =
                   1662: {
                   1663:   OSPF6_LSTYPE_LINK,
                   1664:   "Link",
1.1.1.2 ! misho    1665:   "Lnk",
        !          1666:   ospf6_link_lsa_show,
        !          1667:   ospf6_link_lsa_get_prefix_str
1.1       misho    1668: };
                   1669: 
                   1670: struct ospf6_lsa_handler intra_prefix_handler =
                   1671: {
                   1672:   OSPF6_LSTYPE_INTRA_PREFIX,
                   1673:   "Intra-Prefix",
1.1.1.2 ! misho    1674:   "INP",
        !          1675:   ospf6_intra_prefix_lsa_show,
        !          1676:   ospf6_intra_prefix_lsa_get_prefix_str
1.1       misho    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>