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

1.1       misho       1: /*
                      2:  * Copyright (C) 2003 Yasuhiro Ohara
                      3:  *
                      4:  * This file is part of GNU Zebra.
                      5:  *
                      6:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2, or (at your option) any
                      9:  * later version.
                     10:  *
                     11:  * GNU Zebra is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
                     18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
                     19:  * Boston, MA 02111-1307, USA.  
                     20:  */
                     21: 
                     22: #include <zebra.h>
                     23: 
                     24: #include "memory.h"
                     25: #include "log.h"
                     26: #include "vty.h"
                     27: #include "command.h"
                     28: #include "thread.h"
                     29: #include "linklist.h"
                     30: 
                     31: #include "ospf6_proto.h"
                     32: #include "ospf6_lsa.h"
                     33: #include "ospf6_lsdb.h"
                     34: #include "ospf6_network.h"
                     35: #include "ospf6_message.h"
                     36: 
                     37: #include "ospf6_top.h"
                     38: #include "ospf6_area.h"
                     39: #include "ospf6_neighbor.h"
                     40: #include "ospf6_interface.h"
                     41: 
                     42: /* for structures and macros ospf6_lsa_examin() needs */
                     43: #include "ospf6_abr.h"
                     44: #include "ospf6_asbr.h"
                     45: #include "ospf6_intra.h"
                     46: 
                     47: #include "ospf6_flood.h"
                     48: #include "ospf6d.h"
                     49: 
                     50: unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
                     51: const char *ospf6_message_type_str[] =
                     52:   { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };
                     53: 
                     54: /* Minimum (besides the standard OSPF packet header) lengths for OSPF
                     55:    packets of particular types, offset is the "type" field. */
                     56: const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] =
                     57: {
                     58:   0,
                     59:   OSPF6_HELLO_MIN_SIZE,
                     60:   OSPF6_DB_DESC_MIN_SIZE,
                     61:   OSPF6_LS_REQ_MIN_SIZE,
                     62:   OSPF6_LS_UPD_MIN_SIZE,
                     63:   OSPF6_LS_ACK_MIN_SIZE
                     64: };
                     65: 
                     66: /* Minimum (besides the standard LSA header) lengths for LSAs of particular
                     67:    types, offset is the "LSA function code" portion of "LSA type" field. */
                     68: const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] =
                     69: {
                     70:   0,
                     71:   /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE,
                     72:   /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE,
                     73:   /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
                     74:   /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE,
                     75:   /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
                     76:   /* 0x2006 */ 0,
                     77:   /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
                     78:   /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE,
                     79:   /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
                     80: };
                     81: 
                     82: /* print functions */
                     83: 
                     84: static void
                     85: ospf6_header_print (struct ospf6_header *oh)
                     86: {
                     87:   char router_id[16], area_id[16];
                     88:   inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id));
                     89:   inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id));
                     90: 
                     91:   zlog_debug ("    OSPFv%d Type:%d Len:%hu Router-ID:%s",
                     92:              oh->version, oh->type, ntohs (oh->length), router_id);
                     93:   zlog_debug ("    Area-ID:%s Cksum:%hx Instance-ID:%d",
                     94:              area_id, ntohs (oh->checksum), oh->instance_id);
                     95: }
                     96: 
                     97: void
                     98: ospf6_hello_print (struct ospf6_header *oh)
                     99: {
                    100:   struct ospf6_hello *hello;
                    101:   char options[16];
                    102:   char drouter[16], bdrouter[16], neighbor[16];
                    103:   char *p;
                    104: 
                    105:   ospf6_header_print (oh);
                    106:   assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
                    107: 
                    108:   hello = (struct ospf6_hello *)
                    109:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    110: 
                    111:   inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter));
                    112:   inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter));
                    113:   ospf6_options_printbuf (hello->options, options, sizeof (options));
                    114: 
                    115:   zlog_debug ("    I/F-Id:%ld Priority:%d Option:%s",
                    116:              (u_long) ntohl (hello->interface_id), hello->priority, options);
                    117:   zlog_debug ("    HelloInterval:%hu DeadInterval:%hu",
                    118:              ntohs (hello->hello_interval), ntohs (hello->dead_interval));
                    119:   zlog_debug ("    DR:%s BDR:%s", drouter, bdrouter);
                    120: 
                    121:   for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
                    122:        p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
                    123:        p += sizeof (u_int32_t))
                    124:     {
                    125:       inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
                    126:       zlog_debug ("    Neighbor: %s", neighbor);
                    127:     }
                    128: 
                    129:   if (p != OSPF6_MESSAGE_END (oh))
                    130:     zlog_debug ("Trailing garbage exists");
                    131: }
                    132: 
                    133: void
                    134: ospf6_dbdesc_print (struct ospf6_header *oh)
                    135: {
                    136:   struct ospf6_dbdesc *dbdesc;
                    137:   char options[16];
                    138:   char *p;
                    139: 
                    140:   ospf6_header_print (oh);
                    141:   assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
                    142: 
                    143:   dbdesc = (struct ospf6_dbdesc *)
                    144:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    145: 
                    146:   ospf6_options_printbuf (dbdesc->options, options, sizeof (options));
                    147: 
                    148:   zlog_debug ("    MBZ: %#x Option: %s IfMTU: %hu",
                    149:              dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
                    150:   zlog_debug ("    MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
                    151:              dbdesc->reserved2,
                    152:              (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
                    153:              (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
                    154:              (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
                    155:              (u_long) ntohl (dbdesc->seqnum));
                    156: 
                    157:   for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
                    158:        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
                    159:        p += sizeof (struct ospf6_lsa_header))
                    160:     ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
                    161: 
                    162:   if (p != OSPF6_MESSAGE_END (oh))
                    163:     zlog_debug ("Trailing garbage exists");
                    164: }
                    165: 
                    166: void
                    167: ospf6_lsreq_print (struct ospf6_header *oh)
                    168: {
                    169:   char id[16], adv_router[16];
                    170:   char *p;
                    171: 
                    172:   ospf6_header_print (oh);
                    173:   assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
                    174: 
                    175:   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
                    176:        p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
                    177:        p += sizeof (struct ospf6_lsreq_entry))
                    178:     {
                    179:       struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p;
                    180:       inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router));
                    181:       inet_ntop (AF_INET, &e->id, id, sizeof (id));
                    182:       zlog_debug ("    [%s Id:%s Adv:%s]",
                    183:                  ospf6_lstype_name (e->type), id, adv_router);
                    184:     }
                    185: 
                    186:   if (p != OSPF6_MESSAGE_END (oh))
                    187:     zlog_debug ("Trailing garbage exists");
                    188: }
                    189: 
                    190: void
                    191: ospf6_lsupdate_print (struct ospf6_header *oh)
                    192: {
                    193:   struct ospf6_lsupdate *lsupdate;
                    194:   u_long num;
                    195:   char *p;
                    196: 
                    197:   ospf6_header_print (oh);
                    198:   assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
                    199: 
                    200:   lsupdate = (struct ospf6_lsupdate *)
                    201:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    202: 
                    203:   num = ntohl (lsupdate->lsa_number);
                    204:   zlog_debug ("    Number of LSA: %ld", num);
                    205: 
                    206:   for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
                    207:        p < OSPF6_MESSAGE_END (oh) &&
                    208:        p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
                    209:        p += OSPF6_LSA_SIZE (p))
                    210:     {
                    211:       ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
                    212:       if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header))
                    213:         {
                    214:           zlog_debug ("    Malformed LSA length, quit printing");
                    215:           break;
                    216:         }
                    217:     }
                    218: 
                    219:   if (p != OSPF6_MESSAGE_END (oh))
                    220:     {
                    221:       char buf[32];
                    222: 
                    223:       int num = 0;
                    224:       memset (buf, 0, sizeof (buf));
                    225: 
                    226:       zlog_debug ("    Trailing garbage exists");
                    227:       while (p < OSPF6_MESSAGE_END (oh))
                    228:         {
                    229:           snprintf (buf, sizeof (buf), "%s %2x", buf, *p++);
                    230:           num++;
                    231:           if (num == 8)
                    232:             {
                    233:               zlog_debug ("    %s", buf);
                    234:               memset (buf, 0, sizeof (buf));
                    235:               num = 0;
                    236:             }
                    237:         }
                    238:       if (num)
                    239:         zlog_debug ("    %s", buf);
                    240:     }
                    241: }
                    242: 
                    243: void
                    244: ospf6_lsack_print (struct ospf6_header *oh)
                    245: {
                    246:   char *p;
                    247: 
                    248:   ospf6_header_print (oh);
                    249:   assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
                    250: 
                    251:   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
                    252:        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
                    253:        p += sizeof (struct ospf6_lsa_header))
                    254:     ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
                    255: 
                    256:   if (p != OSPF6_MESSAGE_END (oh))
                    257:     zlog_debug ("Trailing garbage exists");
                    258: }
                    259: 
                    260: static void
                    261: ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
                    262:                   struct ospf6_interface *oi, struct ospf6_header *oh)
                    263: {
                    264:   struct ospf6_hello *hello;
                    265:   struct ospf6_neighbor *on;
                    266:   char *p;
                    267:   int twoway = 0;
                    268:   int neighborchange = 0;
                    269:   int backupseen = 0;
                    270: 
                    271:   hello = (struct ospf6_hello *)
                    272:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    273: 
                    274:   /* HelloInterval check */
                    275:   if (ntohs (hello->hello_interval) != oi->hello_interval)
                    276:     {
                    277:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    278:         zlog_debug ("HelloInterval mismatch");
                    279:       return;
                    280:     }
                    281: 
                    282:   /* RouterDeadInterval check */
                    283:   if (ntohs (hello->dead_interval) != oi->dead_interval)
                    284:     {
                    285:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    286:         zlog_debug ("RouterDeadInterval mismatch");
                    287:       return;
                    288:     }
                    289: 
                    290:   /* E-bit check */
                    291:   if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
                    292:       OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
                    293:     {
                    294:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    295:         zlog_debug ("E-bit mismatch");
                    296:       return;
                    297:     }
                    298: 
                    299:   /* Find neighbor, create if not exist */
                    300:   on = ospf6_neighbor_lookup (oh->router_id, oi);
                    301:   if (on == NULL)
                    302:     {
                    303:       on = ospf6_neighbor_create (oh->router_id, oi);
                    304:       on->prev_drouter = on->drouter = hello->drouter;
                    305:       on->prev_bdrouter = on->bdrouter = hello->bdrouter;
                    306:       on->priority = hello->priority;
                    307:     }
                    308: 
                    309:   /* always override neighbor's source address and ifindex */
                    310:   on->ifindex = ntohl (hello->interface_id);
                    311:   memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr));
                    312: 
                    313:   /* TwoWay check */
                    314:   for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
                    315:        p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
                    316:        p += sizeof (u_int32_t))
                    317:     {
                    318:       u_int32_t *router_id = (u_int32_t *) p;
                    319: 
                    320:       if (*router_id == oi->area->ospf6->router_id)
                    321:         twoway++;
                    322:     }
                    323: 
                    324:   if (p != OSPF6_MESSAGE_END (oh))
                    325:     {
                    326:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    327:         zlog_debug ("Trailing garbage ignored");
                    328:     }
                    329: 
                    330:   /* RouterPriority check */
                    331:   if (on->priority != hello->priority)
                    332:     {
                    333:       on->priority = hello->priority;
                    334:       neighborchange++;
                    335:     }
                    336: 
                    337:   /* DR check */
                    338:   if (on->drouter != hello->drouter)
                    339:     {
                    340:       on->prev_drouter = on->drouter;
                    341:       on->drouter = hello->drouter;
                    342:       if (on->prev_drouter == on->router_id || on->drouter == on->router_id)
                    343:         neighborchange++;
                    344:     }
                    345: 
                    346:   /* BDR check */
                    347:   if (on->bdrouter != hello->bdrouter)
                    348:     {
                    349:       on->prev_bdrouter = on->bdrouter;
                    350:       on->bdrouter = hello->bdrouter;
                    351:       if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id)
                    352:         neighborchange++;
                    353:     }
                    354: 
                    355:   /* BackupSeen check */
                    356:   if (oi->state == OSPF6_INTERFACE_WAITING)
                    357:     {
                    358:       if (hello->bdrouter == on->router_id)
                    359:         backupseen++;
                    360:       else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
                    361:         backupseen++;
                    362:     }
                    363: 
                    364:   /* Execute neighbor events */
                    365:   thread_execute (master, hello_received, on, 0);
                    366:   if (twoway)
                    367:     thread_execute (master, twoway_received, on, 0);
                    368:   else
                    369:     thread_execute (master, oneway_received, on, 0);
                    370: 
                    371:   /* Schedule interface events */
                    372:   if (backupseen)
                    373:     thread_add_event (master, backup_seen, oi, 0);
                    374:   if (neighborchange)
                    375:     thread_add_event (master, neighbor_change, oi, 0);
                    376: }
                    377: 
                    378: static void
                    379: ospf6_dbdesc_recv_master (struct ospf6_header *oh,
                    380:                           struct ospf6_neighbor *on)
                    381: {
                    382:   struct ospf6_dbdesc *dbdesc;
                    383:   char *p;
                    384: 
                    385:   dbdesc = (struct ospf6_dbdesc *)
                    386:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    387: 
                    388:   if (on->state < OSPF6_NEIGHBOR_INIT)
                    389:     {
                    390:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    391:         zlog_debug ("Neighbor state less than Init, ignore");
                    392:       return;
                    393:     }
                    394: 
                    395:   switch (on->state)
                    396:     {
                    397:     case OSPF6_NEIGHBOR_TWOWAY:
                    398:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    399:         zlog_debug ("Neighbor state is 2-Way, ignore");
                    400:       return;
                    401: 
                    402:     case OSPF6_NEIGHBOR_INIT:
                    403:       thread_execute (master, twoway_received, on, 0);
                    404:       if (on->state != OSPF6_NEIGHBOR_EXSTART)
                    405:         {
                    406:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    407:             zlog_debug ("Neighbor state is not ExStart, ignore");
                    408:           return;
                    409:         }
                    410:       /* else fall through to ExStart */
                    411: 
                    412:     case OSPF6_NEIGHBOR_EXSTART:
                    413:       /* if neighbor obeys us as our slave, schedule negotiation_done
                    414:          and process LSA Headers. Otherwise, ignore this message */
                    415:       if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
                    416:           ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
                    417:           ntohl (dbdesc->seqnum) == on->dbdesc_seqnum)
                    418:         {
                    419:           /* execute NegotiationDone */
                    420:           thread_execute (master, negotiation_done, on, 0);
                    421: 
                    422:           /* Record neighbor options */
                    423:           memcpy (on->options, dbdesc->options, sizeof (on->options));
                    424:         }
                    425:       else
                    426:         {
                    427:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    428:             zlog_debug ("Negotiation failed");
                    429:           return;
                    430:         }
                    431:       /* fall through to exchange */
                    432: 
                    433:     case OSPF6_NEIGHBOR_EXCHANGE:
                    434:       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
                    435:         {
                    436:           /* Duplicated DatabaseDescription is dropped by master */
                    437:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    438:             zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
                    439:           return;
                    440:         }
                    441: 
                    442:       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
                    443:         {
                    444:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    445:             zlog_debug ("Master/Slave bit mismatch");
                    446:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    447:           return;
                    448:         }
                    449: 
                    450:       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
                    451:         {
                    452:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    453:             zlog_debug ("Initialize bit mismatch");
                    454:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    455:           return;
                    456:         }
                    457: 
                    458:       if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
                    459:         {
                    460:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    461:             zlog_debug ("Option field mismatch");
                    462:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    463:           return;
                    464:         }
                    465: 
                    466:       if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum)
                    467:         {
                    468:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    469:             zlog_debug ("Sequence number mismatch (%#lx expected)",
                    470:                        (u_long) on->dbdesc_seqnum);
                    471:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    472:           return;
                    473:         }
                    474:       break;
                    475: 
                    476:     case OSPF6_NEIGHBOR_LOADING:
                    477:     case OSPF6_NEIGHBOR_FULL:
                    478:       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
                    479:         {
                    480:           /* Duplicated DatabaseDescription is dropped by master */
                    481:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    482:             zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
                    483:           return;
                    484:         }
                    485: 
                    486:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    487:         zlog_debug ("Not duplicate dbdesc in state %s",
                    488:                    ospf6_neighbor_state_str[on->state]);
                    489:       thread_add_event (master, seqnumber_mismatch, on, 0);
                    490:       return;
                    491: 
                    492:     default:
                    493:       assert (0);
                    494:       break;
                    495:     }
                    496: 
                    497:   /* Process LSA headers */
                    498:   for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
                    499:        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
                    500:        p += sizeof (struct ospf6_lsa_header))
                    501:     {
                    502:       struct ospf6_lsa *his, *mine;
                    503:       struct ospf6_lsdb *lsdb = NULL;
                    504: 
                    505:       his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
                    506: 
                    507:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    508:         zlog_debug ("%s", his->name);
                    509: 
                    510:       switch (OSPF6_LSA_SCOPE (his->header->type))
                    511:         {
                    512:         case OSPF6_SCOPE_LINKLOCAL:
                    513:           lsdb = on->ospf6_if->lsdb;
                    514:           break;
                    515:         case OSPF6_SCOPE_AREA:
                    516:           lsdb = on->ospf6_if->area->lsdb;
                    517:           break;
                    518:         case OSPF6_SCOPE_AS:
                    519:           lsdb = on->ospf6_if->area->ospf6->lsdb;
                    520:           break;
                    521:         case OSPF6_SCOPE_RESERVED:
                    522:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    523:             zlog_debug ("Ignoring LSA of reserved scope");
                    524:           ospf6_lsa_delete (his);
                    525:           continue;
                    526:           break;
                    527:         }
                    528: 
                    529:       if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
                    530:           IS_AREA_STUB (on->ospf6_if->area))
                    531:         {
                    532:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    533:             zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
                    534:           ospf6_lsa_delete (his);
                    535:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    536:           return;
                    537:         }
                    538: 
                    539:       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
                    540:                                 his->header->adv_router, lsdb);
                    541:       if (mine == NULL)
                    542:         {
                    543:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    544:             zlog_debug ("Add request (No database copy)");
                    545:           ospf6_lsdb_add (his, on->request_list);
                    546:         }
                    547:       else if (ospf6_lsa_compare (his, mine) < 0)
                    548:         {
                    549:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    550:             zlog_debug ("Add request (Received MoreRecent)");
                    551:           ospf6_lsdb_add (his, on->request_list);
                    552:         }
                    553:       else
                    554:         {
                    555:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    556:             zlog_debug ("Discard (Existing MoreRecent)");
                    557:           ospf6_lsa_delete (his);
                    558:         }
                    559:     }
                    560: 
                    561:   if (p != OSPF6_MESSAGE_END (oh))
                    562:     {
                    563:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    564:         zlog_debug ("Trailing garbage ignored");
                    565:     }
                    566: 
                    567:   /* Increment sequence number */
                    568:   on->dbdesc_seqnum ++;
                    569: 
                    570:   /* schedule send lsreq */
                    571:   if (on->thread_send_lsreq == NULL)
                    572:     on->thread_send_lsreq =
                    573:       thread_add_event (master, ospf6_lsreq_send, on, 0);
                    574: 
                    575:   THREAD_OFF (on->thread_send_dbdesc);
                    576: 
                    577:   /* More bit check */
                    578:   if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
                    579:       ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
                    580:     thread_add_event (master, exchange_done, on, 0);
                    581:   else
                    582:     on->thread_send_dbdesc =
                    583:       thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
                    584: 
                    585:   /* save last received dbdesc */
                    586:   memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
                    587: }
                    588: 
                    589: static void
                    590: ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
                    591:                          struct ospf6_neighbor *on)
                    592: {
                    593:   struct ospf6_dbdesc *dbdesc;
                    594:   char *p;
                    595: 
                    596:   dbdesc = (struct ospf6_dbdesc *)
                    597:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    598: 
                    599:   if (on->state < OSPF6_NEIGHBOR_INIT)
                    600:     {
                    601:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    602:         zlog_debug ("Neighbor state less than Init, ignore");
                    603:       return;
                    604:     }
                    605: 
                    606:   switch (on->state)
                    607:     {
                    608:     case OSPF6_NEIGHBOR_TWOWAY:
                    609:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    610:         zlog_debug ("Neighbor state is 2-Way, ignore");
                    611:       return;
                    612: 
                    613:     case OSPF6_NEIGHBOR_INIT:
                    614:       thread_execute (master, twoway_received, on, 0);
                    615:       if (on->state != OSPF6_NEIGHBOR_EXSTART)
                    616:         {
                    617:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    618:             zlog_debug ("Neighbor state is not ExStart, ignore");
                    619:           return;
                    620:         }
                    621:       /* else fall through to ExStart */
                    622: 
                    623:     case OSPF6_NEIGHBOR_EXSTART:
                    624:       /* If the neighbor is Master, act as Slave. Schedule negotiation_done
                    625:          and process LSA Headers. Otherwise, ignore this message */
                    626:       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
                    627:           CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
                    628:           CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
                    629:           ntohs (oh->length) == sizeof (struct ospf6_header) +
                    630:                                 sizeof (struct ospf6_dbdesc))
                    631:         {
                    632:           /* set the master/slave bit to slave */
                    633:           UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
                    634: 
                    635:           /* set the DD sequence number to one specified by master */
                    636:           on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
                    637: 
                    638:           /* schedule NegotiationDone */
                    639:           thread_execute (master, negotiation_done, on, 0);
                    640: 
                    641:           /* Record neighbor options */
                    642:           memcpy (on->options, dbdesc->options, sizeof (on->options));
                    643:         }
                    644:       else
                    645:         {
                    646:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    647:             zlog_debug ("Negotiation failed");
                    648:           return;
                    649:         }
                    650:       break;
                    651: 
                    652:     case OSPF6_NEIGHBOR_EXCHANGE:
                    653:       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
                    654:         {
                    655:           /* Duplicated DatabaseDescription causes slave to retransmit */
                    656:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    657:             zlog_debug ("Duplicated dbdesc causes retransmit");
                    658:           THREAD_OFF (on->thread_send_dbdesc);
                    659:           on->thread_send_dbdesc =
                    660:             thread_add_event (master, ospf6_dbdesc_send, on, 0);
                    661:           return;
                    662:         }
                    663: 
                    664:       if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
                    665:         {
                    666:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    667:             zlog_debug ("Master/Slave bit mismatch");
                    668:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    669:           return;
                    670:         }
                    671: 
                    672:       if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
                    673:         {
                    674:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    675:             zlog_debug ("Initialize bit mismatch");
                    676:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    677:           return;
                    678:         }
                    679: 
                    680:       if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
                    681:         {
                    682:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    683:             zlog_debug ("Option field mismatch");
                    684:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    685:           return;
                    686:         }
                    687: 
                    688:       if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1)
                    689:         {
                    690:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    691:             zlog_debug ("Sequence number mismatch (%#lx expected)",
                    692:                        (u_long) on->dbdesc_seqnum + 1);
                    693:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    694:           return;
                    695:         }
                    696:       break;
                    697: 
                    698:     case OSPF6_NEIGHBOR_LOADING:
                    699:     case OSPF6_NEIGHBOR_FULL:
                    700:       if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
                    701:         {
                    702:           /* Duplicated DatabaseDescription causes slave to retransmit */
                    703:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    704:             zlog_debug ("Duplicated dbdesc causes retransmit");
                    705:           THREAD_OFF (on->thread_send_dbdesc);
                    706:           on->thread_send_dbdesc =
                    707:             thread_add_event (master, ospf6_dbdesc_send, on, 0);
                    708:           return;
                    709:         }
                    710: 
                    711:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    712:         zlog_debug ("Not duplicate dbdesc in state %s",
                    713:                    ospf6_neighbor_state_str[on->state]);
                    714:       thread_add_event (master, seqnumber_mismatch, on, 0);
                    715:       return;
                    716: 
                    717:     default:
                    718:       assert (0);
                    719:       break;
                    720:     }
                    721: 
                    722:   /* Process LSA headers */
                    723:   for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
                    724:        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
                    725:        p += sizeof (struct ospf6_lsa_header))
                    726:     {
                    727:       struct ospf6_lsa *his, *mine;
                    728:       struct ospf6_lsdb *lsdb = NULL;
                    729: 
                    730:       his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
                    731: 
                    732:       switch (OSPF6_LSA_SCOPE (his->header->type))
                    733:         {
                    734:         case OSPF6_SCOPE_LINKLOCAL:
                    735:           lsdb = on->ospf6_if->lsdb;
                    736:           break;
                    737:         case OSPF6_SCOPE_AREA:
                    738:           lsdb = on->ospf6_if->area->lsdb;
                    739:           break;
                    740:         case OSPF6_SCOPE_AS:
                    741:           lsdb = on->ospf6_if->area->ospf6->lsdb;
                    742:           break;
                    743:         case OSPF6_SCOPE_RESERVED:
                    744:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    745:             zlog_debug ("Ignoring LSA of reserved scope");
                    746:           ospf6_lsa_delete (his);
                    747:           continue;
                    748:           break;
                    749:         }
                    750: 
                    751:       if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
                    752:           IS_AREA_STUB (on->ospf6_if->area))
                    753:         {
                    754:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    755:             zlog_debug ("E-bit mismatch with LSA Headers");
                    756:           ospf6_lsa_delete (his);
                    757:           thread_add_event (master, seqnumber_mismatch, on, 0);
                    758:           return;
                    759:         }
                    760: 
                    761:       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
                    762:                                 his->header->adv_router, lsdb);
                    763:       if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
                    764:         {
                    765:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    766:             zlog_debug ("Add request-list: %s", his->name);
                    767:           ospf6_lsdb_add (his, on->request_list);
                    768:         }
                    769:       else
                    770:         ospf6_lsa_delete (his);
                    771:     }
                    772: 
                    773:   if (p != OSPF6_MESSAGE_END (oh))
                    774:     {
                    775:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    776:         zlog_debug ("Trailing garbage ignored");
                    777:     }
                    778: 
                    779:   /* Set sequence number to Master's */
                    780:   on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
                    781: 
                    782:   /* schedule send lsreq */
                    783:   if (on->thread_send_lsreq == NULL)
                    784:     on->thread_send_lsreq =
                    785:       thread_add_event (master, ospf6_lsreq_send, on, 0);
                    786: 
                    787:   THREAD_OFF (on->thread_send_dbdesc);
                    788:   on->thread_send_dbdesc =
                    789:     thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
                    790: 
                    791:   /* save last received dbdesc */
                    792:   memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
                    793: }
                    794: 
                    795: static void
                    796: ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
                    797:                    struct ospf6_interface *oi, struct ospf6_header *oh)
                    798: {
                    799:   struct ospf6_neighbor *on;
                    800:   struct ospf6_dbdesc *dbdesc;
                    801: 
                    802:   on = ospf6_neighbor_lookup (oh->router_id, oi);
                    803:   if (on == NULL)
                    804:     {
                    805:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    806:         zlog_debug ("Neighbor not found, ignore");
                    807:       return;
                    808:     }
                    809: 
                    810:   dbdesc = (struct ospf6_dbdesc *)
                    811:     ((caddr_t) oh + sizeof (struct ospf6_header));
                    812: 
                    813:   /* Interface MTU check */
                    814:   if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
                    815:     {
                    816:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    817:         zlog_debug ("I/F MTU mismatch");
                    818:       return;
                    819:     }
                    820: 
                    821:   if (dbdesc->reserved1 || dbdesc->reserved2)
                    822:     {
                    823:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    824:         zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
                    825:                    on->name);
                    826:       dbdesc->reserved1 = 0;
                    827:       dbdesc->reserved2 = 0;
                    828:     }
                    829: 
                    830:   if (ntohl (oh->router_id) < ntohl (ospf6->router_id))
                    831:     ospf6_dbdesc_recv_master (oh, on);
                    832:   else if (ntohl (ospf6->router_id) < ntohl (oh->router_id))
                    833:     ospf6_dbdesc_recv_slave (oh, on);
                    834:   else
                    835:     {
                    836:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    837:         zlog_debug ("Can't decide which is master, ignore");
                    838:     }
                    839: }
                    840: 
                    841: static void
                    842: ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
                    843:                   struct ospf6_interface *oi, struct ospf6_header *oh)
                    844: {
                    845:   struct ospf6_neighbor *on;
                    846:   char *p;
                    847:   struct ospf6_lsreq_entry *e;
                    848:   struct ospf6_lsdb *lsdb = NULL;
                    849:   struct ospf6_lsa *lsa;
                    850: 
                    851:   on = ospf6_neighbor_lookup (oh->router_id, oi);
                    852:   if (on == NULL)
                    853:     {
                    854:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    855:         zlog_debug ("Neighbor not found, ignore");
                    856:       return;
                    857:     }
                    858: 
                    859:   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
                    860:       on->state != OSPF6_NEIGHBOR_LOADING &&
                    861:       on->state != OSPF6_NEIGHBOR_FULL)
                    862:     {
                    863:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    864:         zlog_debug ("Neighbor state less than Exchange, ignore");
                    865:       return;
                    866:     }
                    867: 
                    868:   /* Process each request */
                    869:   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
                    870:        p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
                    871:        p += sizeof (struct ospf6_lsreq_entry))
                    872:     {
                    873:       e = (struct ospf6_lsreq_entry *) p;
                    874: 
                    875:       switch (OSPF6_LSA_SCOPE (e->type))
                    876:         {
                    877:         case OSPF6_SCOPE_LINKLOCAL:
                    878:           lsdb = on->ospf6_if->lsdb;
                    879:           break;
                    880:         case OSPF6_SCOPE_AREA:
                    881:           lsdb = on->ospf6_if->area->lsdb;
                    882:           break;
                    883:         case OSPF6_SCOPE_AS:
                    884:           lsdb = on->ospf6_if->area->ospf6->lsdb;
                    885:           break;
                    886:         default:
                    887:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    888:             zlog_debug ("Ignoring LSA of reserved scope");
                    889:           continue;
                    890:           break;
                    891:         }
                    892: 
                    893:       /* Find database copy */
                    894:       lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
                    895:       if (lsa == NULL)
                    896:         {
                    897:           char id[16], adv_router[16];
                    898:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    899:             {
                    900:               inet_ntop (AF_INET, &e->id, id, sizeof (id));
                    901:               inet_ntop (AF_INET, &e->adv_router, adv_router,
                    902:                      sizeof (adv_router));
                    903:               zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
                    904:                          ospf6_lstype_name (e->type), id, adv_router);
                    905:             }
                    906:           thread_add_event (master, bad_lsreq, on, 0);
                    907:           return;
                    908:         }
                    909: 
                    910:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
                    911:     }
                    912: 
                    913:   if (p != OSPF6_MESSAGE_END (oh))
                    914:     {
                    915:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                    916:         zlog_debug ("Trailing garbage ignored");
                    917:     }
                    918: 
                    919:   /* schedule send lsupdate */
                    920:   THREAD_OFF (on->thread_send_lsupdate);
                    921:   on->thread_send_lsupdate =
                    922:     thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
                    923: }
                    924: 
                    925: /* Verify, that the specified memory area contains exactly N valid IPv6
                    926:    prefixes as specified by RFC5340, A.4.1. */
                    927: static unsigned
                    928: ospf6_prefixes_examin
                    929: (
                    930:   struct ospf6_prefix *current, /* start of buffer    */
                    931:   unsigned length,
                    932:   const u_int32_t req_num_pfxs  /* always compared with the actual number of prefixes */
                    933: )
                    934: {
                    935:   u_char requested_pfx_bytes;
                    936:   u_int32_t real_num_pfxs = 0;
                    937: 
                    938:   while (length)
                    939:   {
                    940:     if (length < OSPF6_PREFIX_MIN_SIZE)
                    941:     {
                    942:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                    943:         zlog_debug ("%s: undersized IPv6 prefix header", __func__);
                    944:       return MSG_NG;
                    945:     }
                    946:     /* safe to look deeper */
                    947:     if (current->prefix_length > IPV6_MAX_BITLEN)
                    948:     {
                    949:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                    950:         zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length);
                    951:       return MSG_NG;
                    952:     }
                    953:     /* covers both fixed- and variable-sized fields */
                    954:     requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length);
                    955:     if (requested_pfx_bytes > length)
                    956:     {
                    957:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                    958:         zlog_debug ("%s: undersized IPv6 prefix", __func__);
                    959:       return MSG_NG;
                    960:     }
                    961:     /* next prefix */
                    962:     length -= requested_pfx_bytes;
                    963:     current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes);
                    964:     real_num_pfxs++;
                    965:   }
                    966:   if (real_num_pfxs != req_num_pfxs)
                    967:   {
                    968:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                    969:       zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)",
                    970:                   __func__, req_num_pfxs, real_num_pfxs);
                    971:     return MSG_NG;
                    972:   }
                    973:   return MSG_OK;
                    974: }
                    975: 
                    976: /* Verify an LSA to have a valid length and dispatch further (where
                    977:    appropriate) to check if the contents, including nested IPv6 prefixes,
                    978:    is properly sized/aligned within the LSA. Note that this function gets
                    979:    LSA type in network byte order, uses in host byte order and passes to
                    980:    ospf6_lstype_name() in network byte order again. */
                    981: static unsigned
                    982: ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly)
                    983: {
                    984:   struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
                    985:   struct ospf6_as_external_lsa *as_external_lsa;
                    986:   struct ospf6_link_lsa *link_lsa;
                    987:   unsigned exp_length;
                    988:   u_int8_t ltindex;
                    989:   u_int16_t lsatype;
                    990: 
                    991:   /* In case an additional minimum length constraint is defined for current
                    992:      LSA type, make sure that this constraint is met. */
                    993:   lsatype = ntohs (lsah->type);
                    994:   ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK;
                    995:   if
                    996:   (
                    997:     ltindex < OSPF6_LSTYPE_SIZE &&
                    998:     ospf6_lsa_minlen[ltindex] &&
                    999:     lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE
                   1000:   )
                   1001:   {
                   1002:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1003:       zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen);
                   1004:     return MSG_NG;
                   1005:   }
                   1006:   switch (lsatype)
                   1007:   {
                   1008:   case OSPF6_LSTYPE_ROUTER:
                   1009:     /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed
                   1010:        by N>=0 interface descriptions. */
                   1011:     if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE)
                   1012:     {
                   1013:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1014:         zlog_debug ("%s: interface description alignment error", __func__);
                   1015:       return MSG_NG;
                   1016:     }
                   1017:     break;
                   1018:   case OSPF6_LSTYPE_NETWORK:
                   1019:     /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
                   1020:        followed by N>=0 attached router descriptions. */
                   1021:     if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE)
                   1022:     {
                   1023:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1024:         zlog_debug ("%s: router description alignment error", __func__);
                   1025:       return MSG_NG;
                   1026:     }
                   1027:     break;
                   1028:   case OSPF6_LSTYPE_INTER_PREFIX:
                   1029:     /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes
                   1030:        followed by 3-4 fields of a single IPv6 prefix. */
                   1031:     if (headeronly)
                   1032:       break;
                   1033:     return ospf6_prefixes_examin
                   1034:     (
                   1035:       (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE),
                   1036:       lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
                   1037:       1
                   1038:     );
                   1039:   case OSPF6_LSTYPE_INTER_ROUTER:
                   1040:     /* RFC5340 A.4.6, fixed-size LSA. */
                   1041:     if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE)
                   1042:     {
                   1043:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1044:         zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen);
                   1045:       return MSG_NG;
                   1046:     }
                   1047:     break;
                   1048:   case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */
                   1049:   case OSPF6_LSTYPE_TYPE_7:
                   1050:     /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes
                   1051:        followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields:
                   1052:        16 bytes of forwarding address, 4 bytes of external route tag,
                   1053:        4 bytes of referenced link state ID. */
                   1054:     if (headeronly)
                   1055:       break;
                   1056:     as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
                   1057:     exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE;
                   1058:     /* To find out if the last optional field (Referenced Link State ID) is
                   1059:        assumed in this LSA, we need to access fixed fields of the IPv6
                   1060:        prefix before ospf6_prefix_examin() confirms its sizing. */
                   1061:     if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen)
                   1062:     {
                   1063:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1064:         zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
                   1065:       return MSG_NG;
                   1066:     }
                   1067:     /* forwarding address */
                   1068:     if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
                   1069:       exp_length += 16;
                   1070:     /* external route tag */
                   1071:     if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
                   1072:       exp_length += 4;
                   1073:     /* referenced link state ID */
                   1074:     if (as_external_lsa->prefix.u._prefix_referenced_lstype)
                   1075:       exp_length += 4;
                   1076:     /* All the fixed-size fields (mandatory and optional) must fit. I.e.,
                   1077:        this check does not include any IPv6 prefix fields. */
                   1078:     if (exp_length > lsalen)
                   1079:     {
                   1080:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1081:         zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
                   1082:       return MSG_NG;
                   1083:     }
                   1084:     /* The last call completely covers the remainder (IPv6 prefix). */
                   1085:     return ospf6_prefixes_examin
                   1086:     (
                   1087:       (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE),
                   1088:       lsalen - exp_length,
                   1089:       1
                   1090:     );
                   1091:   case OSPF6_LSTYPE_LINK:
                   1092:     /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed
                   1093:        by N>=0 IPv6 prefix blocks (with N declared beforehand). */
                   1094:     if (headeronly)
                   1095:       break;
                   1096:     link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
                   1097:     return ospf6_prefixes_examin
                   1098:     (
                   1099:       (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE),
                   1100:       lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE,
                   1101:       ntohl (link_lsa->prefix_num) /* 32 bits */
                   1102:     );
                   1103:   case OSPF6_LSTYPE_INTRA_PREFIX:
                   1104:   /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes
                   1105:      followed by N>=0 IPv6 prefixes (with N declared beforehand). */
                   1106:     if (headeronly)
                   1107:       break;
                   1108:     intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
                   1109:     return ospf6_prefixes_examin
                   1110:     (
                   1111:       (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE),
                   1112:       lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE,
                   1113:       ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */
                   1114:     );
                   1115:   }
                   1116:   /* No additional validation is possible for unknown LSA types, which are
                   1117:      themselves valid in OPSFv3, hence the default decision is to accept. */
                   1118:   return MSG_OK;
                   1119: }
                   1120: 
                   1121: /* Verify if the provided input buffer is a valid sequence of LSAs. This
                   1122:    includes verification of LSA blocks length/alignment and dispatching
                   1123:    of deeper-level checks. */
                   1124: static unsigned
                   1125: ospf6_lsaseq_examin
                   1126: (
                   1127:   struct ospf6_lsa_header *lsah, /* start of buffered data */
                   1128:   size_t length,
                   1129:   const u_char headeronly,
                   1130:   /* When declared_num_lsas is not 0, compare it to the real number of LSAs
                   1131:      and treat the difference as an error. */
                   1132:   const u_int32_t declared_num_lsas
                   1133: )
                   1134: {
                   1135:   u_int32_t counted_lsas = 0;
                   1136: 
                   1137:   while (length)
                   1138:   {
                   1139:     u_int16_t lsalen;
                   1140:     if (length < OSPF6_LSA_HEADER_SIZE)
                   1141:     {
                   1142:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1143:         zlog_debug ("%s: undersized (%u B) trailing (#%u) LSA header",
                   1144:                     __func__, length, counted_lsas);
                   1145:       return MSG_NG;
                   1146:     }
                   1147:     /* save on ntohs() calls here and in the LSA validator */
                   1148:     lsalen = OSPF6_LSA_SIZE (lsah);
                   1149:     if (lsalen < OSPF6_LSA_HEADER_SIZE)
                   1150:     {
                   1151:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1152:         zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
                   1153:                     __func__, counted_lsas, lsalen);
                   1154:       return MSG_NG;
                   1155:     }
                   1156:     if (headeronly)
                   1157:     {
                   1158:       /* less checks here and in ospf6_lsa_examin() */
                   1159:       if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1))
                   1160:       {
                   1161:         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1162:           zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__,
                   1163:                       ospf6_lstype_name (lsah->type), counted_lsas);
                   1164:         return MSG_NG;
                   1165:       }
                   1166:       lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
                   1167:       length -= OSPF6_LSA_HEADER_SIZE;
                   1168:     }
                   1169:     else
                   1170:     {
                   1171:       /* make sure the input buffer is deep enough before further checks */
                   1172:       if (lsalen > length)
                   1173:       {
                   1174:         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1175:           zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %u B",
                   1176:                       __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length);
                   1177:         return MSG_NG;
                   1178:       }
                   1179:       if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0))
                   1180:       {
                   1181:         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1182:           zlog_debug ("%s: anomaly in %s LSA #%u", __func__,
                   1183:                       ospf6_lstype_name (lsah->type), counted_lsas);
                   1184:         return MSG_NG;
                   1185:       }
                   1186:       lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen);
                   1187:       length -= lsalen;
                   1188:     }
                   1189:     counted_lsas++;
                   1190:   }
                   1191: 
                   1192:   if (declared_num_lsas && counted_lsas != declared_num_lsas)
                   1193:   {
                   1194:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1195:       zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
                   1196:                   __func__, declared_num_lsas, counted_lsas);
                   1197:     return MSG_NG;
                   1198:   }
                   1199:   return MSG_OK;
                   1200: }
                   1201: 
                   1202: /* Verify a complete OSPF packet for proper sizing/alignment. */
                   1203: static unsigned
                   1204: ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire)
                   1205: {
                   1206:   struct ospf6_lsupdate *lsupd;
                   1207:   unsigned test;
                   1208: 
                   1209:   /* length, 1st approximation */
                   1210:   if (bytesonwire < OSPF6_HEADER_SIZE)
                   1211:   {
                   1212:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1213:       zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
                   1214:     return MSG_NG;
                   1215:   }
                   1216:   /* Now it is safe to access header fields. */
                   1217:   if (bytesonwire != ntohs (oh->length))
                   1218:   {
                   1219:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1220:       zlog_debug ("%s: packet length error (%u real, %u declared)",
                   1221:                   __func__, bytesonwire, ntohs (oh->length));
                   1222:     return MSG_NG;
                   1223:   }
                   1224:   /* version check */
                   1225:   if (oh->version != OSPFV3_VERSION)
                   1226:   {
                   1227:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1228:       zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
                   1229:     return MSG_NG;
                   1230:   }
                   1231:   /* length, 2nd approximation */
                   1232:   if
                   1233:   (
                   1234:     oh->type < OSPF6_MESSAGE_TYPE_ALL &&
                   1235:     ospf6_packet_minlen[oh->type] &&
                   1236:     bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]
                   1237:   )
                   1238:   {
                   1239:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1240:       zlog_debug ("%s: undersized (%u B) %s packet", __func__,
                   1241:                   bytesonwire, ospf6_message_type_str[oh->type]);
                   1242:     return MSG_NG;
                   1243:   }
                   1244:   /* type-specific deeper validation */
                   1245:   switch (oh->type)
                   1246:   {
                   1247:   case OSPF6_MESSAGE_TYPE_HELLO:
                   1248:     /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed
                   1249:        by N>=0 router-IDs. */
                   1250:     if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4)
                   1251:       return MSG_OK;
                   1252:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1253:       zlog_debug ("%s: alignment error in %s packet",
                   1254:                   __func__, ospf6_message_type_str[oh->type]);
                   1255:     return MSG_NG;
                   1256:   case OSPF6_MESSAGE_TYPE_DBDESC:
                   1257:     /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed
                   1258:        by N>=0 header-only LSAs. */
                   1259:     test = ospf6_lsaseq_examin
                   1260:     (
                   1261:       (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE),
                   1262:       bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE,
                   1263:       1,
                   1264:       0
                   1265:     );
                   1266:     break;
                   1267:   case OSPF6_MESSAGE_TYPE_LSREQ:
                   1268:     /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
                   1269:     if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE)
                   1270:       return MSG_OK;
                   1271:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1272:       zlog_debug ("%s: alignment error in %s packet",
                   1273:                   __func__, ospf6_message_type_str[oh->type]);
                   1274:     return MSG_NG;
                   1275:   case OSPF6_MESSAGE_TYPE_LSUPDATE:
                   1276:     /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed
                   1277:        by N>=0 full LSAs (with N declared beforehand). */
                   1278:     lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE);
                   1279:     test = ospf6_lsaseq_examin
                   1280:     (
                   1281:       (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE),
                   1282:       bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE,
                   1283:       0,
                   1284:       ntohl (lsupd->lsa_number) /* 32 bits */
                   1285:     );
                   1286:     break;
                   1287:   case OSPF6_MESSAGE_TYPE_LSACK:
                   1288:     /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
                   1289:     test = ospf6_lsaseq_examin
                   1290:     (
                   1291:       (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE),
                   1292:       bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE,
                   1293:       1,
                   1294:       0
                   1295:     );
                   1296:     break;
                   1297:   default:
                   1298:     if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1299:       zlog_debug ("%s: invalid (%u) message type", __func__, oh->type);
                   1300:     return MSG_NG;
                   1301:   }
                   1302:   if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1303:     zlog_debug ("%s: anomaly in %s packet", __func__, ospf6_message_type_str[oh->type]);
                   1304:   return test;
                   1305: }
                   1306: 
                   1307: /* Verify particular fields of otherwise correct received OSPF packet to
                   1308:    meet the requirements of RFC. */
                   1309: static int
                   1310: ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire)
                   1311: {
                   1312:   char buf[2][INET_ADDRSTRLEN];
                   1313: 
                   1314:   if (MSG_OK != ospf6_packet_examin (oh, bytesonwire))
                   1315:     return MSG_NG;
                   1316: 
                   1317:   /* Area-ID check */
                   1318:   if (oh->area_id != oi->area->area_id)
                   1319:   {
                   1320:     if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1321:     {
                   1322:       if (oh->area_id == BACKBONE_AREA_ID)
                   1323:         zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__);
                   1324:       else
                   1325:         zlog_debug
                   1326:         (
                   1327:           "%s: Area-ID mismatch (my %s, rcvd %s)", __func__,
                   1328:           inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN),
                   1329:           inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN)
                   1330:          );
                   1331:     }
                   1332:     return MSG_NG;
                   1333:   }
                   1334: 
                   1335:   /* Instance-ID check */
                   1336:   if (oh->instance_id != oi->instance_id)
                   1337:   {
                   1338:     if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1339:       zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id);
                   1340:     return MSG_NG;
                   1341:   }
                   1342: 
                   1343:   /* Router-ID check */
                   1344:   if (oh->router_id == oi->area->ospf6->router_id)
                   1345:   {
                   1346:     zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN));
                   1347:     return MSG_NG;
                   1348:   }
                   1349:   return MSG_OK;
                   1350: }
                   1351: 
                   1352: static void
                   1353: ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
                   1354:                      struct ospf6_interface *oi, struct ospf6_header *oh)
                   1355: {
                   1356:   struct ospf6_neighbor *on;
                   1357:   struct ospf6_lsupdate *lsupdate;
                   1358:   unsigned long num;
                   1359:   char *p;
                   1360: 
                   1361:   on = ospf6_neighbor_lookup (oh->router_id, oi);
                   1362:   if (on == NULL)
                   1363:     {
                   1364:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1365:         zlog_debug ("Neighbor not found, ignore");
                   1366:       return;
                   1367:     }
                   1368: 
                   1369:   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
                   1370:       on->state != OSPF6_NEIGHBOR_LOADING &&
                   1371:       on->state != OSPF6_NEIGHBOR_FULL)
                   1372:     {
                   1373:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1374:         zlog_debug ("Neighbor state less than Exchange, ignore");
                   1375:       return;
                   1376:     }
                   1377: 
                   1378:   lsupdate = (struct ospf6_lsupdate *)
                   1379:     ((caddr_t) oh + sizeof (struct ospf6_header));
                   1380: 
                   1381:   num = ntohl (lsupdate->lsa_number);
                   1382: 
                   1383:   /* Process LSAs */
                   1384:   for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
                   1385:        p < OSPF6_MESSAGE_END (oh) &&
                   1386:        p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
                   1387:        p += OSPF6_LSA_SIZE (p))
                   1388:     {
                   1389:       if (num == 0)
                   1390:         break;
                   1391:       if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header))
                   1392:         {
                   1393:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1394:             zlog_debug ("Malformed LSA length, quit processing");
                   1395:           break;
                   1396:         }
                   1397: 
                   1398:       ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
                   1399:       num--;
                   1400:     }
                   1401: 
                   1402:   if (num != 0)
                   1403:     {
                   1404:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1405:         zlog_debug ("Malformed LSA number or LSA length");
                   1406:     }
                   1407:   if (p != OSPF6_MESSAGE_END (oh))
                   1408:     {
                   1409:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1410:         zlog_debug ("Trailing garbage ignored");
                   1411:     }
                   1412: 
                   1413:   /* RFC2328 Section 10.9: When the neighbor responds to these requests
                   1414:      with the proper Link State Update packet(s), the Link state request
                   1415:      list is truncated and a new Link State Request packet is sent. */
                   1416:   /* send new Link State Request packet if this LS Update packet
                   1417:      can be recognized as a response to our previous LS Request */
                   1418:   if (! IN6_IS_ADDR_MULTICAST (dst) &&
                   1419:       (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
                   1420:        on->state == OSPF6_NEIGHBOR_LOADING))
                   1421:     {
                   1422:       THREAD_OFF (on->thread_send_lsreq);
                   1423:       on->thread_send_lsreq =
                   1424:         thread_add_event (master, ospf6_lsreq_send, on, 0);
                   1425:     }
                   1426: }
                   1427: 
                   1428: static void
                   1429: ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
                   1430:                   struct ospf6_interface *oi, struct ospf6_header *oh)
                   1431: {
                   1432:   struct ospf6_neighbor *on;
                   1433:   char *p;
                   1434:   struct ospf6_lsa *his, *mine;
                   1435:   struct ospf6_lsdb *lsdb = NULL;
                   1436: 
                   1437:   assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
                   1438: 
                   1439:   on = ospf6_neighbor_lookup (oh->router_id, oi);
                   1440:   if (on == NULL)
                   1441:     {
                   1442:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1443:         zlog_debug ("Neighbor not found, ignore");
                   1444:       return;
                   1445:     }
                   1446: 
                   1447:   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
                   1448:       on->state != OSPF6_NEIGHBOR_LOADING &&
                   1449:       on->state != OSPF6_NEIGHBOR_FULL)
                   1450:     {
                   1451:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1452:         zlog_debug ("Neighbor state less than Exchange, ignore");
                   1453:       return;
                   1454:     }
                   1455: 
                   1456:   for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
                   1457:        p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
                   1458:        p += sizeof (struct ospf6_lsa_header))
                   1459:     {
                   1460:       his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
                   1461: 
                   1462:       switch (OSPF6_LSA_SCOPE (his->header->type))
                   1463:         {
                   1464:         case OSPF6_SCOPE_LINKLOCAL:
                   1465:           lsdb = on->ospf6_if->lsdb;
                   1466:           break;
                   1467:         case OSPF6_SCOPE_AREA:
                   1468:           lsdb = on->ospf6_if->area->lsdb;
                   1469:           break;
                   1470:         case OSPF6_SCOPE_AS:
                   1471:           lsdb = on->ospf6_if->area->ospf6->lsdb;
                   1472:           break;
                   1473:         case OSPF6_SCOPE_RESERVED:
                   1474:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1475:             zlog_debug ("Ignoring LSA of reserved scope");
                   1476:           ospf6_lsa_delete (his);
                   1477:           continue;
                   1478:           break;
                   1479:         }
                   1480: 
                   1481:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1482:         zlog_debug ("%s acknowledged by %s", his->name, on->name);
                   1483: 
                   1484:       /* Find database copy */
                   1485:       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
                   1486:                                 his->header->adv_router, lsdb);
                   1487:       if (mine == NULL)
                   1488:         {
                   1489:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1490:             zlog_debug ("No database copy");
                   1491:           ospf6_lsa_delete (his);
                   1492:           continue;
                   1493:         }
                   1494: 
                   1495:       /* Check if the LSA is on his retrans-list */
                   1496:       mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
                   1497:                                 his->header->adv_router, on->retrans_list);
                   1498:       if (mine == NULL)
                   1499:         {
                   1500:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1501:             zlog_debug ("Not on %s's retrans-list", on->name);
                   1502:           ospf6_lsa_delete (his);
                   1503:           continue;
                   1504:         }
                   1505: 
                   1506:       if (ospf6_lsa_compare (his, mine) != 0)
                   1507:         {
                   1508:           /* Log this questionable acknowledgement,
                   1509:              and examine the next one. */
                   1510:           if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1511:             zlog_debug ("Questionable acknowledgement");
                   1512:           ospf6_lsa_delete (his);
                   1513:           continue;
                   1514:         }
                   1515: 
                   1516:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1517:         zlog_debug ("Acknowledged, remove from %s's retrans-list",
                   1518:                    on->name);
                   1519: 
                   1520:       ospf6_decrement_retrans_count (mine);
                   1521:       if (OSPF6_LSA_IS_MAXAGE (mine))
                   1522:         ospf6_maxage_remove (on->ospf6_if->area->ospf6);
                   1523:       ospf6_lsdb_remove (mine, on->retrans_list);
                   1524:       ospf6_lsa_delete (his);
                   1525:     }
                   1526: 
                   1527:   if (p != OSPF6_MESSAGE_END (oh))
                   1528:     {
                   1529:       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1530:         zlog_debug ("Trailing garbage ignored");
                   1531:     }
                   1532: }
                   1533: 
                   1534: static u_char *recvbuf = NULL;
                   1535: static u_char *sendbuf = NULL;
                   1536: static unsigned int iobuflen = 0;
                   1537: 
                   1538: int
                   1539: ospf6_iobuf_size (unsigned int size)
                   1540: {
                   1541:   u_char *recvnew, *sendnew;
                   1542: 
                   1543:   if (size <= iobuflen)
                   1544:     return iobuflen;
                   1545: 
                   1546:   recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
                   1547:   sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
                   1548:   if (recvnew == NULL || sendnew == NULL)
                   1549:     {
                   1550:       if (recvnew)
                   1551:         XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
                   1552:       if (sendnew)
                   1553:         XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
                   1554:       zlog_debug ("Could not allocate I/O buffer of size %d.", size);
                   1555:       return iobuflen;
                   1556:     }
                   1557: 
                   1558:   if (recvbuf)
                   1559:     XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
                   1560:   if (sendbuf)
                   1561:     XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
                   1562:   recvbuf = recvnew;
                   1563:   sendbuf = sendnew;
                   1564:   iobuflen = size;
                   1565: 
                   1566:   return iobuflen;
                   1567: }
                   1568: 
                   1569: void
                   1570: ospf6_message_terminate (void)
                   1571: {
                   1572:   if (recvbuf)
                   1573:     {
                   1574:       XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
                   1575:       recvbuf = NULL;
                   1576:     }
                   1577: 
                   1578:   if (sendbuf)
                   1579:     {
                   1580:       XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
                   1581:       sendbuf = NULL;
                   1582:     }
                   1583: 
                   1584:   iobuflen = 0;
                   1585: }
                   1586: 
                   1587: int
                   1588: ospf6_receive (struct thread *thread)
                   1589: {
                   1590:   int sockfd;
                   1591:   unsigned int len;
                   1592:   char srcname[64], dstname[64];
                   1593:   struct in6_addr src, dst;
                   1594:   unsigned int ifindex;
                   1595:   struct iovec iovector[2];
                   1596:   struct ospf6_interface *oi;
                   1597:   struct ospf6_header *oh;
                   1598: 
                   1599:   /* add next read thread */
                   1600:   sockfd = THREAD_FD (thread);
                   1601:   thread_add_read (master, ospf6_receive, NULL, sockfd);
                   1602: 
                   1603:   /* initialize */
                   1604:   memset (&src, 0, sizeof (src));
                   1605:   memset (&dst, 0, sizeof (dst));
                   1606:   ifindex = 0;
                   1607:   memset (recvbuf, 0, iobuflen);
                   1608:   iovector[0].iov_base = recvbuf;
                   1609:   iovector[0].iov_len = iobuflen;
                   1610:   iovector[1].iov_base = NULL;
                   1611:   iovector[1].iov_len = 0;
                   1612: 
                   1613:   /* receive message */
                   1614:   len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
                   1615:   if (len > iobuflen)
                   1616:     {
                   1617:       zlog_err ("Excess message read");
                   1618:       return 0;
                   1619:     }
                   1620: 
                   1621:   oi = ospf6_interface_lookup_by_ifindex (ifindex);
                   1622:   if (oi == NULL || oi->area == NULL)
                   1623:     {
                   1624:       zlog_debug ("Message received on disabled interface");
                   1625:       return 0;
                   1626:     }
                   1627:   if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
                   1628:     {
                   1629:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1630:         zlog_debug ("%s: Ignore message on passive interface %s",
                   1631:                     __func__, oi->interface->name);
                   1632:       return 0;
                   1633:     }
                   1634: 
                   1635:   oh = (struct ospf6_header *) recvbuf;
                   1636:   if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK)
                   1637:     return 0;
                   1638: 
                   1639:   /* Being here means, that no sizing/alignment issues were detected in
                   1640:      the input packet. This renders the additional checks performed below
                   1641:      and also in the type-specific dispatching functions a dead code,
                   1642:      which can be dismissed in a cleanup-focused review round later. */
                   1643: 
                   1644:   /* Log */
                   1645:   if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
                   1646:     {
                   1647:       inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
                   1648:       inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
                   1649:       zlog_debug ("%s received on %s",
                   1650:                  OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
                   1651:       zlog_debug ("    src: %s", srcname);
                   1652:       zlog_debug ("    dst: %s", dstname);
                   1653:       if (len != ntohs (oh->length))
                   1654:         zlog_debug ("Message length does not match actually received: %d", len);
                   1655: 
                   1656:       switch (oh->type)
                   1657:         {
                   1658:           case OSPF6_MESSAGE_TYPE_HELLO:
                   1659:             ospf6_hello_print (oh);
                   1660:             break;
                   1661:           case OSPF6_MESSAGE_TYPE_DBDESC:
                   1662:             ospf6_dbdesc_print (oh);
                   1663:             break;
                   1664:           case OSPF6_MESSAGE_TYPE_LSREQ:
                   1665:             ospf6_lsreq_print (oh);
                   1666:             break;
                   1667:           case OSPF6_MESSAGE_TYPE_LSUPDATE:
                   1668:             ospf6_lsupdate_print (oh);
                   1669:             break;
                   1670:           case OSPF6_MESSAGE_TYPE_LSACK:
                   1671:             ospf6_lsack_print (oh);
                   1672:             break;
                   1673:           default:
                   1674:             zlog_debug ("Unknown message");
                   1675:             break;
                   1676:         }
                   1677:     }
                   1678: 
                   1679:   switch (oh->type)
                   1680:     {
                   1681:       case OSPF6_MESSAGE_TYPE_HELLO:
                   1682:         ospf6_hello_recv (&src, &dst, oi, oh);
                   1683:         break;
                   1684: 
                   1685:       case OSPF6_MESSAGE_TYPE_DBDESC:
                   1686:         ospf6_dbdesc_recv (&src, &dst, oi, oh);
                   1687:         break;
                   1688: 
                   1689:       case OSPF6_MESSAGE_TYPE_LSREQ:
                   1690:         ospf6_lsreq_recv (&src, &dst, oi, oh);
                   1691:         break;
                   1692: 
                   1693:       case OSPF6_MESSAGE_TYPE_LSUPDATE:
                   1694:         ospf6_lsupdate_recv (&src, &dst, oi, oh);
                   1695:         break;
                   1696: 
                   1697:       case OSPF6_MESSAGE_TYPE_LSACK:
                   1698:         ospf6_lsack_recv (&src, &dst, oi, oh);
                   1699:         break;
                   1700: 
                   1701:       default:
                   1702:         if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   1703:           zlog_debug ("Unknown message");
                   1704:         break;
                   1705:     }
                   1706: 
                   1707:   return 0;
                   1708: }
                   1709: 
                   1710: static void
                   1711: ospf6_send (struct in6_addr *src, struct in6_addr *dst,
                   1712:             struct ospf6_interface *oi, struct ospf6_header *oh)
                   1713: {
                   1714:   int len;
                   1715:   char srcname[64], dstname[64];
                   1716:   struct iovec iovector[2];
                   1717: 
                   1718:   /* initialize */
                   1719:   iovector[0].iov_base = (caddr_t) oh;
                   1720:   iovector[0].iov_len = ntohs (oh->length);
                   1721:   iovector[1].iov_base = NULL;
                   1722:   iovector[1].iov_len = 0;
                   1723: 
                   1724:   /* fill OSPF header */
                   1725:   oh->version = OSPFV3_VERSION;
                   1726:   /* message type must be set before */
                   1727:   /* message length must be set before */
                   1728:   oh->router_id = oi->area->ospf6->router_id;
                   1729:   oh->area_id = oi->area->area_id;
                   1730:   /* checksum is calculated by kernel */
                   1731:   oh->instance_id = oi->instance_id;
                   1732:   oh->reserved = 0;
                   1733: 
                   1734:   /* Log */
                   1735:   if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
                   1736:     {
                   1737:       inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
                   1738:       if (src)
                   1739:         inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
                   1740:       else
                   1741:         memset (srcname, 0, sizeof (srcname));
                   1742:       zlog_debug ("%s send on %s",
                   1743:                  OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
                   1744:       zlog_debug ("    src: %s", srcname);
                   1745:       zlog_debug ("    dst: %s", dstname);
                   1746: 
                   1747:       switch (oh->type)
                   1748:         {
                   1749:           case OSPF6_MESSAGE_TYPE_HELLO:
                   1750:             ospf6_hello_print (oh);
                   1751:             break;
                   1752:           case OSPF6_MESSAGE_TYPE_DBDESC:
                   1753:             ospf6_dbdesc_print (oh);
                   1754:             break;
                   1755:           case OSPF6_MESSAGE_TYPE_LSREQ:
                   1756:             ospf6_lsreq_print (oh);
                   1757:             break;
                   1758:           case OSPF6_MESSAGE_TYPE_LSUPDATE:
                   1759:             ospf6_lsupdate_print (oh);
                   1760:             break;
                   1761:           case OSPF6_MESSAGE_TYPE_LSACK:
                   1762:             ospf6_lsack_print (oh);
                   1763:             break;
                   1764:           default:
                   1765:             zlog_debug ("Unknown message");
                   1766:             assert (0);
                   1767:             break;
                   1768:         }
                   1769:     }
                   1770: 
                   1771:   /* send message */
                   1772:   len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
                   1773:   if (len != ntohs (oh->length))
                   1774:     zlog_err ("Could not send entire message");
                   1775: }
                   1776: 
                   1777: int
                   1778: ospf6_hello_send (struct thread *thread)
                   1779: {
                   1780:   struct ospf6_interface *oi;
                   1781:   struct ospf6_header *oh;
                   1782:   struct ospf6_hello *hello;
                   1783:   u_char *p;
                   1784:   struct listnode *node, *nnode;
                   1785:   struct ospf6_neighbor *on;
                   1786: 
                   1787:   oi = (struct ospf6_interface *) THREAD_ARG (thread);
                   1788:   oi->thread_send_hello = (struct thread *) NULL;
                   1789: 
                   1790:   if (oi->state <= OSPF6_INTERFACE_DOWN)
                   1791:     {
                   1792:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
                   1793:         zlog_debug ("Unable to send Hello on down interface %s",
                   1794:                    oi->interface->name);
                   1795:       return 0;
                   1796:     }
                   1797: 
                   1798:   /* set next thread */
                   1799:   oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
                   1800:                                             oi, oi->hello_interval);
                   1801: 
                   1802:   memset (sendbuf, 0, iobuflen);
                   1803:   oh = (struct ospf6_header *) sendbuf;
                   1804:   hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
                   1805: 
                   1806:   hello->interface_id = htonl (oi->interface->ifindex);
                   1807:   hello->priority = oi->priority;
                   1808:   hello->options[0] = oi->area->options[0];
                   1809:   hello->options[1] = oi->area->options[1];
                   1810:   hello->options[2] = oi->area->options[2];
                   1811:   hello->hello_interval = htons (oi->hello_interval);
                   1812:   hello->dead_interval = htons (oi->dead_interval);
                   1813:   hello->drouter = oi->drouter;
                   1814:   hello->bdrouter = oi->bdrouter;
                   1815: 
                   1816:   p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello));
                   1817: 
                   1818:   for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
                   1819:     {
                   1820:       if (on->state < OSPF6_NEIGHBOR_INIT)
                   1821:         continue;
                   1822: 
                   1823:       if (p - sendbuf + sizeof (u_int32_t) > oi->ifmtu)
                   1824:         {
                   1825:           if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
                   1826:             zlog_debug ("sending Hello message: exceeds I/F MTU");
                   1827:           break;
                   1828:         }
                   1829: 
                   1830:       memcpy (p, &on->router_id, sizeof (u_int32_t));
                   1831:       p += sizeof (u_int32_t);
                   1832:     }
                   1833: 
                   1834:   oh->type = OSPF6_MESSAGE_TYPE_HELLO;
                   1835:   oh->length = htons (p - sendbuf);
                   1836: 
                   1837:   ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
                   1838:   return 0;
                   1839: }
                   1840: 
                   1841: int
                   1842: ospf6_dbdesc_send (struct thread *thread)
                   1843: {
                   1844:   struct ospf6_neighbor *on;
                   1845:   struct ospf6_header *oh;
                   1846:   struct ospf6_dbdesc *dbdesc;
                   1847:   u_char *p;
                   1848:   struct ospf6_lsa *lsa;
                   1849: 
                   1850:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                   1851:   on->thread_send_dbdesc = (struct thread *) NULL;
                   1852: 
                   1853:   if (on->state < OSPF6_NEIGHBOR_EXSTART)
                   1854:     {
                   1855:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
                   1856:         zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
                   1857:                    on->name, ospf6_neighbor_state_str[on->state]);
                   1858:       return 0;
                   1859:     }
                   1860: 
                   1861:   /* set next thread if master */
                   1862:   if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
                   1863:     on->thread_send_dbdesc =
                   1864:       thread_add_timer (master, ospf6_dbdesc_send, on,
                   1865:                         on->ospf6_if->rxmt_interval);
                   1866: 
                   1867:   memset (sendbuf, 0, iobuflen);
                   1868:   oh = (struct ospf6_header *) sendbuf;
                   1869:   dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
                   1870:                                    sizeof (struct ospf6_header));
                   1871: 
                   1872:   /* if this is initial one, initialize sequence number for DbDesc */
                   1873:   if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
                   1874:     {
                   1875:       struct timeval tv;
                   1876:       if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
                   1877:         tv.tv_sec = 1;
                   1878:       on->dbdesc_seqnum = tv.tv_sec;
                   1879:     }
                   1880: 
                   1881:   dbdesc->options[0] = on->ospf6_if->area->options[0];
                   1882:   dbdesc->options[1] = on->ospf6_if->area->options[1];
                   1883:   dbdesc->options[2] = on->ospf6_if->area->options[2];
                   1884:   dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
                   1885:   dbdesc->bits = on->dbdesc_bits;
                   1886:   dbdesc->seqnum = htonl (on->dbdesc_seqnum);
                   1887: 
                   1888:   /* if this is not initial one, set LSA headers in dbdesc */
                   1889:   p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
                   1890:   if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
                   1891:     {
                   1892:       for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
                   1893:            lsa = ospf6_lsdb_next (lsa))
                   1894:         {
                   1895:           ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
                   1896: 
                   1897:           /* MTU check */
                   1898:           if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
                   1899:               on->ospf6_if->ifmtu)
                   1900:             {
                   1901:               ospf6_lsa_unlock (lsa);
                   1902:               break;
                   1903:             }
                   1904:           memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
                   1905:           p += sizeof (struct ospf6_lsa_header);
                   1906:         }
                   1907:     }
                   1908: 
                   1909:   oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
                   1910:   oh->length = htons (p - sendbuf);
                   1911: 
                   1912:   ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
                   1913:               on->ospf6_if, oh);
                   1914:   return 0;
                   1915: }
                   1916: 
                   1917: int
                   1918: ospf6_dbdesc_send_newone (struct thread *thread)
                   1919: {
                   1920:   struct ospf6_neighbor *on;
                   1921:   struct ospf6_lsa *lsa;
                   1922:   unsigned int size = 0;
                   1923: 
                   1924:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                   1925:   ospf6_lsdb_remove_all (on->dbdesc_list);
                   1926: 
                   1927:   /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
                   1928:      so that ospf6_send_dbdesc () can send those LSAs */
                   1929:   size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
                   1930:   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
                   1931:        lsa = ospf6_lsdb_next (lsa))
                   1932:     {
                   1933:       if (size + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
                   1934:         {
                   1935:           ospf6_lsa_unlock (lsa);
                   1936:           break;
                   1937:         }
                   1938: 
                   1939:       ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
                   1940:       ospf6_lsdb_remove (lsa, on->summary_list);
                   1941:       size += sizeof (struct ospf6_lsa_header);
                   1942:     }
                   1943: 
                   1944:   if (on->summary_list->count == 0)
                   1945:     UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
                   1946: 
                   1947:   /* If slave, More bit check must be done here */
                   1948:   if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
                   1949:       ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
                   1950:       ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
                   1951:     thread_add_event (master, exchange_done, on, 0);
                   1952: 
                   1953:   thread_execute (master, ospf6_dbdesc_send, on, 0);
                   1954:   return 0;
                   1955: }
                   1956: 
                   1957: int
                   1958: ospf6_lsreq_send (struct thread *thread)
                   1959: {
                   1960:   struct ospf6_neighbor *on;
                   1961:   struct ospf6_header *oh;
                   1962:   struct ospf6_lsreq_entry *e;
                   1963:   u_char *p;
                   1964:   struct ospf6_lsa *lsa;
                   1965: 
                   1966:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                   1967:   on->thread_send_lsreq = (struct thread *) NULL;
                   1968: 
                   1969:   /* LSReq will be sent only in ExStart or Loading */
                   1970:   if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
                   1971:       on->state != OSPF6_NEIGHBOR_LOADING)
                   1972:     {
                   1973:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
                   1974:         zlog_debug ("Quit to send LSReq to neighbor %s state %s",
                   1975:                    on->name, ospf6_neighbor_state_str[on->state]);
                   1976:       return 0;
                   1977:     }
                   1978: 
                   1979:   /* schedule loading_done if request list is empty */
                   1980:   if (on->request_list->count == 0)
                   1981:     {
                   1982:       thread_add_event (master, loading_done, on, 0);
                   1983:       return 0;
                   1984:     }
                   1985: 
                   1986:   /* set next thread */
                   1987:   on->thread_send_lsreq =
                   1988:     thread_add_timer (master, ospf6_lsreq_send, on,
                   1989:                       on->ospf6_if->rxmt_interval);
                   1990: 
                   1991:   memset (sendbuf, 0, iobuflen);
                   1992:   oh = (struct ospf6_header *) sendbuf;
                   1993: 
                   1994:   /* set Request entries in lsreq */
                   1995:   p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
                   1996:   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
                   1997:        lsa = ospf6_lsdb_next (lsa))
                   1998:     {
                   1999:       /* MTU check */
                   2000:       if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > on->ospf6_if->ifmtu)
                   2001:         {
                   2002:           ospf6_lsa_unlock (lsa);
                   2003:           break;
                   2004:         }
                   2005: 
                   2006:       e = (struct ospf6_lsreq_entry *) p;
                   2007:       e->type = lsa->header->type;
                   2008:       e->id = lsa->header->id;
                   2009:       e->adv_router = lsa->header->adv_router;
                   2010:       p += sizeof (struct ospf6_lsreq_entry);
                   2011:     }
                   2012: 
                   2013:   oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
                   2014:   oh->length = htons (p - sendbuf);
                   2015: 
                   2016:   ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
                   2017:               on->ospf6_if, oh);
                   2018:   return 0;
                   2019: }
                   2020: 
                   2021: int
                   2022: ospf6_lsupdate_send_neighbor (struct thread *thread)
                   2023: {
                   2024:   struct ospf6_neighbor *on;
                   2025:   struct ospf6_header *oh;
                   2026:   struct ospf6_lsupdate *lsupdate;
                   2027:   u_char *p;
                   2028:   int num;
                   2029:   struct ospf6_lsa *lsa;
                   2030: 
                   2031:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                   2032:   on->thread_send_lsupdate = (struct thread *) NULL;
                   2033: 
                   2034:   if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
                   2035:     zlog_debug ("LSUpdate to neighbor %s", on->name);
                   2036: 
                   2037:   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
                   2038:     {
                   2039:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
                   2040:         zlog_debug ("Quit to send (neighbor state %s)",
                   2041:                    ospf6_neighbor_state_str[on->state]);
                   2042:       return 0;
                   2043:     }
                   2044: 
                   2045:   /* if we have nothing to send, return */
                   2046:   if (on->lsupdate_list->count == 0 &&
                   2047:       on->retrans_list->count == 0)
                   2048:     {
                   2049:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
                   2050:         zlog_debug ("Quit to send (nothing to send)");
                   2051:       return 0;
                   2052:     }
                   2053: 
                   2054:   memset (sendbuf, 0, iobuflen);
                   2055:   oh = (struct ospf6_header *) sendbuf;
                   2056:   lsupdate = (struct ospf6_lsupdate *)
                   2057:     ((caddr_t) oh + sizeof (struct ospf6_header));
                   2058: 
                   2059:   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
                   2060:   num = 0;
                   2061: 
                   2062:   /* lsupdate_list lists those LSA which doesn't need to be
                   2063:      retransmitted. remove those from the list */
                   2064:   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
                   2065:        lsa = ospf6_lsdb_next (lsa))
                   2066:     {
                   2067:       /* MTU check */
                   2068:       if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
                   2069:           > on->ospf6_if->ifmtu)
                   2070:         {
                   2071:           ospf6_lsa_unlock (lsa);
                   2072:           break;
                   2073:         }
                   2074: 
                   2075:       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
                   2076:       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
                   2077:       p += OSPF6_LSA_SIZE (lsa->header);
                   2078:       num++;
                   2079: 
                   2080:       assert (lsa->lock == 2);
                   2081:       ospf6_lsdb_remove (lsa, on->lsupdate_list);
                   2082:     }
                   2083: 
                   2084:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                   2085:        lsa = ospf6_lsdb_next (lsa))
                   2086:     {
                   2087:       /* MTU check */
                   2088:       if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
                   2089:           > on->ospf6_if->ifmtu)
                   2090:         {
                   2091:           ospf6_lsa_unlock (lsa);
                   2092:           break;
                   2093:         }
                   2094: 
                   2095:       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
                   2096:       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
                   2097:       p += OSPF6_LSA_SIZE (lsa->header);
                   2098:       num++;
                   2099:     }
                   2100: 
                   2101:   lsupdate->lsa_number = htonl (num);
                   2102: 
                   2103:   oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
                   2104:   oh->length = htons (p - sendbuf);
                   2105: 
                   2106:   ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
                   2107:               on->ospf6_if, oh);
                   2108: 
                   2109:   if (on->lsupdate_list->count != 0 ||
                   2110:       on->retrans_list->count != 0)
                   2111:     {
                   2112:       if (on->lsupdate_list->count != 0)
                   2113:         on->thread_send_lsupdate =
                   2114:           thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
                   2115:       else
                   2116:         on->thread_send_lsupdate =
                   2117:           thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
                   2118:                             on->ospf6_if->rxmt_interval);
                   2119:     }
                   2120: 
                   2121:   return 0;
                   2122: }
                   2123: 
                   2124: int
                   2125: ospf6_lsupdate_send_interface (struct thread *thread)
                   2126: {
                   2127:   struct ospf6_interface *oi;
                   2128:   struct ospf6_header *oh;
                   2129:   struct ospf6_lsupdate *lsupdate;
                   2130:   u_char *p;
                   2131:   int num;
                   2132:   struct ospf6_lsa *lsa;
                   2133: 
                   2134:   oi = (struct ospf6_interface *) THREAD_ARG (thread);
                   2135:   oi->thread_send_lsupdate = (struct thread *) NULL;
                   2136: 
                   2137:   if (oi->state <= OSPF6_INTERFACE_WAITING)
                   2138:     {
                   2139:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
                   2140:         zlog_debug ("Quit to send LSUpdate to interface %s state %s",
                   2141:                    oi->interface->name, ospf6_interface_state_str[oi->state]);
                   2142:       return 0;
                   2143:     }
                   2144: 
                   2145:   /* if we have nothing to send, return */
                   2146:   if (oi->lsupdate_list->count == 0)
                   2147:     return 0;
                   2148: 
                   2149:   memset (sendbuf, 0, iobuflen);
                   2150:   oh = (struct ospf6_header *) sendbuf;
                   2151:   lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
                   2152:                                        sizeof (struct ospf6_header));
                   2153: 
                   2154:   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
                   2155:   num = 0;
                   2156: 
                   2157:   for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
                   2158:        lsa = ospf6_lsdb_next (lsa))
                   2159:     {
                   2160:       /* MTU check */
                   2161:       if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
                   2162:           > oi->ifmtu)
                   2163:         {
                   2164:           ospf6_lsa_unlock (lsa);
                   2165:           break;
                   2166:         }
                   2167: 
                   2168:       ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
                   2169:       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
                   2170:       p += OSPF6_LSA_SIZE (lsa->header);
                   2171:       num++;
                   2172: 
                   2173:       assert (lsa->lock == 2);
                   2174:       ospf6_lsdb_remove (lsa, oi->lsupdate_list);
                   2175:     }
                   2176: 
                   2177:   lsupdate->lsa_number = htonl (num);
                   2178: 
                   2179:   oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
                   2180:   oh->length = htons (p - sendbuf);
                   2181: 
                   2182:   if (oi->state == OSPF6_INTERFACE_DR ||
                   2183:       oi->state == OSPF6_INTERFACE_BDR)
                   2184:     ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
                   2185:   else
                   2186:     ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
                   2187: 
                   2188:   if (oi->lsupdate_list->count > 0)
                   2189:     {
                   2190:       oi->thread_send_lsupdate =
                   2191:         thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
                   2192:     }
                   2193: 
                   2194:   return 0;
                   2195: }
                   2196: 
                   2197: int
                   2198: ospf6_lsack_send_neighbor (struct thread *thread)
                   2199: {
                   2200:   struct ospf6_neighbor *on;
                   2201:   struct ospf6_header *oh;
                   2202:   u_char *p;
                   2203:   struct ospf6_lsa *lsa;
                   2204: 
                   2205:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                   2206:   on->thread_send_lsack = (struct thread *) NULL;
                   2207: 
                   2208:   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
                   2209:     {
                   2210:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
                   2211:         zlog_debug ("Quit to send LSAck to neighbor %s state %s",
                   2212:                    on->name, ospf6_neighbor_state_str[on->state]);
                   2213:       return 0;
                   2214:     }
                   2215: 
                   2216:   /* if we have nothing to send, return */
                   2217:   if (on->lsack_list->count == 0)
                   2218:     return 0;
                   2219: 
                   2220:   memset (sendbuf, 0, iobuflen);
                   2221:   oh = (struct ospf6_header *) sendbuf;
                   2222: 
                   2223:   p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
                   2224: 
                   2225:   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
                   2226:        lsa = ospf6_lsdb_next (lsa))
                   2227:     {
                   2228:       /* MTU check */
                   2229:       if (p - sendbuf + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
                   2230:         {
                   2231:           /* if we run out of packet size/space here,
                   2232:              better to try again soon. */
                   2233:           THREAD_OFF (on->thread_send_lsack);
                   2234:           on->thread_send_lsack =
                   2235:             thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
                   2236: 
                   2237:           ospf6_lsa_unlock (lsa);
                   2238:           break;
                   2239:         }
                   2240: 
                   2241:       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
                   2242:       memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
                   2243:       p += sizeof (struct ospf6_lsa_header);
                   2244: 
                   2245:       assert (lsa->lock == 2);
                   2246:       ospf6_lsdb_remove (lsa, on->lsack_list);
                   2247:     }
                   2248: 
                   2249:   oh->type = OSPF6_MESSAGE_TYPE_LSACK;
                   2250:   oh->length = htons (p - sendbuf);
                   2251: 
                   2252:   ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
                   2253:               on->ospf6_if, oh);
                   2254:   return 0;
                   2255: }
                   2256: 
                   2257: int
                   2258: ospf6_lsack_send_interface (struct thread *thread)
                   2259: {
                   2260:   struct ospf6_interface *oi;
                   2261:   struct ospf6_header *oh;
                   2262:   u_char *p;
                   2263:   struct ospf6_lsa *lsa;
                   2264: 
                   2265:   oi = (struct ospf6_interface *) THREAD_ARG (thread);
                   2266:   oi->thread_send_lsack = (struct thread *) NULL;
                   2267: 
                   2268:   if (oi->state <= OSPF6_INTERFACE_WAITING)
                   2269:     {
                   2270:       if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
                   2271:         zlog_debug ("Quit to send LSAck to interface %s state %s",
                   2272:                    oi->interface->name, ospf6_interface_state_str[oi->state]);
                   2273:       return 0;
                   2274:     }
                   2275: 
                   2276:   /* if we have nothing to send, return */
                   2277:   if (oi->lsack_list->count == 0)
                   2278:     return 0;
                   2279: 
                   2280:   memset (sendbuf, 0, iobuflen);
                   2281:   oh = (struct ospf6_header *) sendbuf;
                   2282: 
                   2283:   p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
                   2284: 
                   2285:   for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
                   2286:        lsa = ospf6_lsdb_next (lsa))
                   2287:     {
                   2288:       /* MTU check */
                   2289:       if (p - sendbuf + sizeof (struct ospf6_lsa_header) > oi->ifmtu)
                   2290:         {
                   2291:           /* if we run out of packet size/space here,
                   2292:              better to try again soon. */
                   2293:           THREAD_OFF (oi->thread_send_lsack);
                   2294:           oi->thread_send_lsack =
                   2295:             thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
                   2296: 
                   2297:           ospf6_lsa_unlock (lsa);
                   2298:           break;
                   2299:         }
                   2300: 
                   2301:       ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
                   2302:       memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
                   2303:       p += sizeof (struct ospf6_lsa_header);
                   2304: 
                   2305:       assert (lsa->lock == 2);
                   2306:       ospf6_lsdb_remove (lsa, oi->lsack_list);
                   2307:     }
                   2308: 
                   2309:   oh->type = OSPF6_MESSAGE_TYPE_LSACK;
                   2310:   oh->length = htons (p - sendbuf);
                   2311: 
                   2312:   if (oi->state == OSPF6_INTERFACE_DR ||
                   2313:       oi->state == OSPF6_INTERFACE_BDR)
                   2314:     ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
                   2315:   else
                   2316:     ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
                   2317: 
                   2318:   if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
                   2319:     {
                   2320:       oi->thread_send_lsack =
                   2321:         thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
                   2322:     }
                   2323: 
                   2324:   return 0;
                   2325: }
                   2326: 
                   2327: 
                   2328: /* Commands */
                   2329: DEFUN (debug_ospf6_message,
                   2330:        debug_ospf6_message_cmd,
                   2331:        "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
                   2332:        DEBUG_STR
                   2333:        OSPF6_STR
                   2334:        "Debug OSPFv3 message\n"
                   2335:        "Debug Unknown message\n"
                   2336:        "Debug Hello message\n"
                   2337:        "Debug Database Description message\n"
                   2338:        "Debug Link State Request message\n"
                   2339:        "Debug Link State Update message\n"
                   2340:        "Debug Link State Acknowledgement message\n"
                   2341:        "Debug All message\n"
                   2342:        )
                   2343: {
                   2344:   unsigned char level = 0;
                   2345:   int type = 0;
                   2346:   int i;
                   2347: 
                   2348:   assert (argc > 0);
                   2349: 
                   2350:   /* check type */
                   2351:   if (! strncmp (argv[0], "u", 1))
                   2352:     type = OSPF6_MESSAGE_TYPE_UNKNOWN;
                   2353:   else if (! strncmp (argv[0], "h", 1))
                   2354:     type = OSPF6_MESSAGE_TYPE_HELLO;
                   2355:   else if (! strncmp (argv[0], "d", 1))
                   2356:     type = OSPF6_MESSAGE_TYPE_DBDESC;
                   2357:   else if (! strncmp (argv[0], "lsr", 3))
                   2358:     type = OSPF6_MESSAGE_TYPE_LSREQ;
                   2359:   else if (! strncmp (argv[0], "lsu", 3))
                   2360:     type = OSPF6_MESSAGE_TYPE_LSUPDATE;
                   2361:   else if (! strncmp (argv[0], "lsa", 3))
                   2362:     type = OSPF6_MESSAGE_TYPE_LSACK;
                   2363:   else if (! strncmp (argv[0], "a", 1))
                   2364:     type = OSPF6_MESSAGE_TYPE_ALL;
                   2365: 
                   2366:   if (argc == 1)
                   2367:     level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
                   2368:   else if (! strncmp (argv[1], "s", 1))
                   2369:     level = OSPF6_DEBUG_MESSAGE_SEND;
                   2370:   else if (! strncmp (argv[1], "r", 1))
                   2371:     level = OSPF6_DEBUG_MESSAGE_RECV;
                   2372: 
                   2373:   if (type == OSPF6_MESSAGE_TYPE_ALL)
                   2374:     {
                   2375:       for (i = 0; i < 6; i++)
                   2376:         OSPF6_DEBUG_MESSAGE_ON (i, level);
                   2377:     }
                   2378:   else
                   2379:     OSPF6_DEBUG_MESSAGE_ON (type, level);
                   2380: 
                   2381:   return CMD_SUCCESS;
                   2382: }
                   2383: 
                   2384: ALIAS (debug_ospf6_message,
                   2385:        debug_ospf6_message_sendrecv_cmd,
                   2386:        "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
                   2387:        DEBUG_STR
                   2388:        OSPF6_STR
                   2389:        "Debug OSPFv3 message\n"
                   2390:        "Debug Unknown message\n"
                   2391:        "Debug Hello message\n"
                   2392:        "Debug Database Description message\n"
                   2393:        "Debug Link State Request message\n"
                   2394:        "Debug Link State Update message\n"
                   2395:        "Debug Link State Acknowledgement message\n"
                   2396:        "Debug All message\n"
                   2397:        "Debug only sending message\n"
                   2398:        "Debug only receiving message\n"
                   2399:        )
                   2400: 
                   2401: 
                   2402: DEFUN (no_debug_ospf6_message,
                   2403:        no_debug_ospf6_message_cmd,
                   2404:        "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
                   2405:        NO_STR
                   2406:        DEBUG_STR
                   2407:        OSPF6_STR
                   2408:        "Debug OSPFv3 message\n"
                   2409:        "Debug Unknown message\n"
                   2410:        "Debug Hello message\n"
                   2411:        "Debug Database Description message\n"
                   2412:        "Debug Link State Request message\n"
                   2413:        "Debug Link State Update message\n"
                   2414:        "Debug Link State Acknowledgement message\n"
                   2415:        "Debug All message\n"
                   2416:        )
                   2417: {
                   2418:   unsigned char level = 0;
                   2419:   int type = 0;
                   2420:   int i;
                   2421: 
                   2422:   assert (argc > 0);
                   2423: 
                   2424:   /* check type */
                   2425:   if (! strncmp (argv[0], "u", 1))
                   2426:     type = OSPF6_MESSAGE_TYPE_UNKNOWN;
                   2427:   else if (! strncmp (argv[0], "h", 1))
                   2428:     type = OSPF6_MESSAGE_TYPE_HELLO;
                   2429:   else if (! strncmp (argv[0], "d", 1))
                   2430:     type = OSPF6_MESSAGE_TYPE_DBDESC;
                   2431:   else if (! strncmp (argv[0], "lsr", 3))
                   2432:     type = OSPF6_MESSAGE_TYPE_LSREQ;
                   2433:   else if (! strncmp (argv[0], "lsu", 3))
                   2434:     type = OSPF6_MESSAGE_TYPE_LSUPDATE;
                   2435:   else if (! strncmp (argv[0], "lsa", 3))
                   2436:     type = OSPF6_MESSAGE_TYPE_LSACK;
                   2437:   else if (! strncmp (argv[0], "a", 1))
                   2438:     type = OSPF6_MESSAGE_TYPE_ALL;
                   2439: 
                   2440:   if (argc == 1)
                   2441:     level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
                   2442:   else if (! strncmp (argv[1], "s", 1))
                   2443:     level = OSPF6_DEBUG_MESSAGE_SEND;
                   2444:   else if (! strncmp (argv[1], "r", 1))
                   2445:     level = OSPF6_DEBUG_MESSAGE_RECV;
                   2446: 
                   2447:   if (type == OSPF6_MESSAGE_TYPE_ALL)
                   2448:     {
                   2449:       for (i = 0; i < 6; i++)
                   2450:         OSPF6_DEBUG_MESSAGE_OFF (i, level);
                   2451:     }
                   2452:   else
                   2453:     OSPF6_DEBUG_MESSAGE_OFF (type, level);
                   2454: 
                   2455:   return CMD_SUCCESS;
                   2456: }
                   2457: 
                   2458: ALIAS (no_debug_ospf6_message,
                   2459:        no_debug_ospf6_message_sendrecv_cmd,
                   2460:        "no debug ospf6 message "
                   2461:        "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
                   2462:        NO_STR
                   2463:        DEBUG_STR
                   2464:        OSPF6_STR
                   2465:        "Debug OSPFv3 message\n"
                   2466:        "Debug Unknown message\n"
                   2467:        "Debug Hello message\n"
                   2468:        "Debug Database Description message\n"
                   2469:        "Debug Link State Request message\n"
                   2470:        "Debug Link State Update message\n"
                   2471:        "Debug Link State Acknowledgement message\n"
                   2472:        "Debug All message\n"
                   2473:        "Debug only sending message\n"
                   2474:        "Debug only receiving message\n"
                   2475:        )
                   2476: 
                   2477: int
                   2478: config_write_ospf6_debug_message (struct vty *vty)
                   2479: {
                   2480:   const char *type_str[] = {"unknown", "hello", "dbdesc",
                   2481:                       "lsreq", "lsupdate", "lsack"};
                   2482:   unsigned char s = 0, r = 0;
                   2483:   int i;
                   2484: 
                   2485:   for (i = 0; i < 6; i++)
                   2486:     {
                   2487:       if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
                   2488:         s |= 1 << i;
                   2489:       if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
                   2490:         r |= 1 << i;
                   2491:     }
                   2492: 
                   2493:   if (s == 0x3f && r == 0x3f)
                   2494:     {
                   2495:       vty_out (vty, "debug ospf6 message all%s", VNL);
                   2496:       return 0;
                   2497:     }
                   2498: 
                   2499:   if (s == 0x3f && r == 0)
                   2500:     {
                   2501:       vty_out (vty, "debug ospf6 message all send%s", VNL);
                   2502:       return 0;
                   2503:     }
                   2504:   else if (s == 0 && r == 0x3f)
                   2505:     {
                   2506:       vty_out (vty, "debug ospf6 message all recv%s", VNL);
                   2507:       return 0;
                   2508:     }
                   2509: 
                   2510:   /* Unknown message is logged by default */
                   2511:   if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
                   2512:       ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   2513:     vty_out (vty, "no debug ospf6 message unknown%s", VNL);
                   2514:   else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
                   2515:     vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
                   2516:   else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
                   2517:     vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
                   2518: 
                   2519:   for (i = 1; i < 6; i++)
                   2520:     {
                   2521:       if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
                   2522:           IS_OSPF6_DEBUG_MESSAGE (i, RECV))
                   2523:         vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
                   2524:       else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
                   2525:         vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
                   2526:                  VNL);
                   2527:       else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
                   2528:         vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
                   2529:                  VNL);
                   2530:     }
                   2531: 
                   2532:   return 0;
                   2533: }
                   2534: 
                   2535: void
                   2536: install_element_ospf6_debug_message (void)
                   2537: {
                   2538:   install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
                   2539:   install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
                   2540:   install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
                   2541:   install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
                   2542:   install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
                   2543:   install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
                   2544:   install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
                   2545:   install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);
                   2546: }
                   2547: 
                   2548: 

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