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

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

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