Annotation of embedaddon/quagga/ospfd/ospf_packet.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * OSPF Sending and Receiving OSPF Packets.
                      3:  * Copyright (C) 1999, 2000 Toshiaki Takada
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2, or (at your option) any
                     10:  * later version.
                     11:  *
                     12:  * GNU Zebra is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     20:  * 02111-1307, USA.
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "thread.h"
                     26: #include "memory.h"
                     27: #include "linklist.h"
                     28: #include "prefix.h"
                     29: #include "if.h"
                     30: #include "table.h"
                     31: #include "sockunion.h"
                     32: #include "stream.h"
                     33: #include "log.h"
                     34: #include "sockopt.h"
                     35: #include "checksum.h"
                     36: #include "md5.h"
                     37: 
                     38: #include "ospfd/ospfd.h"
                     39: #include "ospfd/ospf_network.h"
                     40: #include "ospfd/ospf_interface.h"
                     41: #include "ospfd/ospf_ism.h"
                     42: #include "ospfd/ospf_asbr.h"
                     43: #include "ospfd/ospf_lsa.h"
                     44: #include "ospfd/ospf_lsdb.h"
                     45: #include "ospfd/ospf_neighbor.h"
                     46: #include "ospfd/ospf_nsm.h"
                     47: #include "ospfd/ospf_packet.h"
                     48: #include "ospfd/ospf_spf.h"
                     49: #include "ospfd/ospf_flood.h"
                     50: #include "ospfd/ospf_dump.h"
                     51: 
                     52: /* Packet Type String. */
                     53: const char *ospf_packet_type_str[] =
                     54: {
                     55:   "unknown",
                     56:   "Hello",
                     57:   "Database Description",
                     58:   "Link State Request",
                     59:   "Link State Update",
                     60:   "Link State Acknowledgment",
                     61: };
                     62: 
                     63: /* OSPF authentication checking function */
                     64: static int
                     65: ospf_auth_type (struct ospf_interface *oi)
                     66: {
                     67:   int auth_type;
                     68: 
                     69:   if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
                     70:     auth_type = oi->area->auth_type;
                     71:   else
                     72:     auth_type = OSPF_IF_PARAM (oi, auth_type);
                     73: 
                     74:   /* Handle case where MD5 key list is not configured aka Cisco */
                     75:   if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
                     76:       list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
                     77:     return OSPF_AUTH_NULL;
                     78:   
                     79:   return auth_type;
                     80: 
                     81: }
                     82: 
                     83: struct ospf_packet *
                     84: ospf_packet_new (size_t size)
                     85: {
                     86:   struct ospf_packet *new;
                     87: 
                     88:   new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
                     89:   new->s = stream_new (size);
                     90: 
                     91:   return new;
                     92: }
                     93: 
                     94: void
                     95: ospf_packet_free (struct ospf_packet *op)
                     96: {
                     97:   if (op->s)
                     98:     stream_free (op->s);
                     99: 
                    100:   XFREE (MTYPE_OSPF_PACKET, op);
                    101: 
                    102:   op = NULL;
                    103: }
                    104: 
                    105: struct ospf_fifo *
                    106: ospf_fifo_new ()
                    107: {
                    108:   struct ospf_fifo *new;
                    109: 
                    110:   new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
                    111:   return new;
                    112: }
                    113: 
                    114: /* Add new packet to fifo. */
                    115: void
                    116: ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
                    117: {
                    118:   if (fifo->tail)
                    119:     fifo->tail->next = op;
                    120:   else
                    121:     fifo->head = op;
                    122: 
                    123:   fifo->tail = op;
                    124: 
                    125:   fifo->count++;
                    126: }
                    127: 
                    128: /* Add new packet to head of fifo. */
                    129: static void
                    130: ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
                    131: {
                    132:   op->next = fifo->head;
                    133:   
                    134:   if (fifo->tail == NULL)
                    135:     fifo->tail = op;
                    136:   
                    137:   fifo->head = op;
                    138:   
                    139:   fifo->count++;
                    140: }
                    141: 
                    142: /* Delete first packet from fifo. */
                    143: struct ospf_packet *
                    144: ospf_fifo_pop (struct ospf_fifo *fifo)
                    145: {
                    146:   struct ospf_packet *op;
                    147: 
                    148:   op = fifo->head;
                    149: 
                    150:   if (op)
                    151:     {
                    152:       fifo->head = op->next;
                    153: 
                    154:       if (fifo->head == NULL)
                    155:        fifo->tail = NULL;
                    156: 
                    157:       fifo->count--;
                    158:     }
                    159: 
                    160:   return op;
                    161: }
                    162: 
                    163: /* Return first fifo entry. */
                    164: struct ospf_packet *
                    165: ospf_fifo_head (struct ospf_fifo *fifo)
                    166: {
                    167:   return fifo->head;
                    168: }
                    169: 
                    170: /* Flush ospf packet fifo. */
                    171: void
                    172: ospf_fifo_flush (struct ospf_fifo *fifo)
                    173: {
                    174:   struct ospf_packet *op;
                    175:   struct ospf_packet *next;
                    176: 
                    177:   for (op = fifo->head; op; op = next)
                    178:     {
                    179:       next = op->next;
                    180:       ospf_packet_free (op);
                    181:     }
                    182:   fifo->head = fifo->tail = NULL;
                    183:   fifo->count = 0;
                    184: }
                    185: 
                    186: /* Free ospf packet fifo. */
                    187: void
                    188: ospf_fifo_free (struct ospf_fifo *fifo)
                    189: {
                    190:   ospf_fifo_flush (fifo);
                    191: 
                    192:   XFREE (MTYPE_OSPF_FIFO, fifo);
                    193: }
                    194: 
                    195: void
                    196: ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
                    197: {
                    198:   if (!oi->obuf)
                    199:     {
                    200:       zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
                    201:               "destination %s) called with NULL obuf, ignoring "
                    202:               "(please report this bug)!\n",
                    203:               IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
                    204:               ospf_packet_type_str[stream_getc_from(op->s, 1)],
                    205:               inet_ntoa (op->dst));
                    206:       return;
                    207:     }
                    208: 
                    209:   /* Add packet to end of queue. */
                    210:   ospf_fifo_push (oi->obuf, op);
                    211: 
                    212:   /* Debug of packet fifo*/
                    213:   /* ospf_fifo_debug (oi->obuf); */
                    214: }
                    215: 
                    216: static void
                    217: ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
                    218: {
                    219:   if (!oi->obuf)
                    220:     {
                    221:       zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
                    222:               "destination %s) called with NULL obuf, ignoring "
                    223:               "(please report this bug)!\n",
                    224:               IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
                    225:               ospf_packet_type_str[stream_getc_from(op->s, 1)],
                    226:               inet_ntoa (op->dst));
                    227:       return;
                    228:     }
                    229: 
                    230:   /* Add packet to head of queue. */
                    231:   ospf_fifo_push_head (oi->obuf, op);
                    232: 
                    233:   /* Debug of packet fifo*/
                    234:   /* ospf_fifo_debug (oi->obuf); */
                    235: }
                    236: 
                    237: void
                    238: ospf_packet_delete (struct ospf_interface *oi)
                    239: {
                    240:   struct ospf_packet *op;
                    241:   
                    242:   op = ospf_fifo_pop (oi->obuf);
                    243: 
                    244:   if (op)
                    245:     ospf_packet_free (op);
                    246: }
                    247: 
                    248: struct ospf_packet *
                    249: ospf_packet_dup (struct ospf_packet *op)
                    250: {
                    251:   struct ospf_packet *new;
                    252: 
                    253:   if (stream_get_endp(op->s) != op->length)
                    254:     /* XXX size_t */
                    255:     zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
                    256:               (u_long)STREAM_SIZE(op->s), op->length);
                    257: 
                    258:   /* Reserve space for MD5 authentication that may be added later. */
                    259:   new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
                    260:   stream_copy (new->s, op->s);
                    261: 
                    262:   new->dst = op->dst;
                    263:   new->length = op->length;
                    264: 
                    265:   return new;
                    266: }
                    267: 
                    268: /* XXX inline */
                    269: static inline unsigned int
                    270: ospf_packet_authspace (struct ospf_interface *oi)
                    271: {
                    272:   int auth = 0;
                    273: 
                    274:   if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
                    275:     auth = OSPF_AUTH_MD5_SIZE;
                    276: 
                    277:   return auth;
                    278: }
                    279: 
                    280: static unsigned int
                    281: ospf_packet_max (struct ospf_interface *oi)
                    282: {
                    283:   int max;
                    284: 
                    285:   max = oi->ifp->mtu - ospf_packet_authspace(oi);
                    286: 
                    287:   max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
                    288: 
                    289:   return max;
                    290: }
                    291: 
                    292: 
                    293: static int
                    294: ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
                    295:                        u_int16_t length)
                    296: {
                    297:   unsigned char *ibuf;
                    298:   MD5_CTX ctx;
                    299:   unsigned char digest[OSPF_AUTH_MD5_SIZE];
                    300:   unsigned char *pdigest;
                    301:   struct crypt_key *ck;
                    302:   struct ospf_header *ospfh;
                    303:   struct ospf_neighbor *nbr;
                    304:   
                    305: 
                    306:   ibuf = STREAM_PNT (s);
                    307:   ospfh = (struct ospf_header *) ibuf;
                    308: 
                    309:   /* Get pointer to the end of the packet. */
                    310:   pdigest = ibuf + length;
                    311: 
                    312:   /* Get secret key. */
                    313:   ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
                    314:                              ospfh->u.crypt.key_id);
                    315:   if (ck == NULL)
                    316:     {
                    317:       zlog_warn ("interface %s: ospf_check_md5 no key %d",
                    318:                 IF_NAME (oi), ospfh->u.crypt.key_id);
                    319:       return 0;
                    320:     }
                    321: 
                    322:   /* check crypto seqnum. */
                    323:   nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
                    324: 
                    325:   if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
                    326:     {
                    327:       zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
                    328:                 IF_NAME (oi),
                    329:                 ntohl(ospfh->u.crypt.crypt_seqnum),
                    330:                 ntohl(nbr->crypt_seqnum));
                    331:       return 0;
                    332:     }
                    333:       
                    334:   /* Generate a digest for the ospf packet - their digest + our digest. */
                    335:   memset(&ctx, 0, sizeof(ctx));
                    336:   MD5Init(&ctx);
                    337:   MD5Update(&ctx, ibuf, length);
                    338:   MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
                    339:   MD5Final(digest, &ctx);
                    340: 
                    341:   /* compare the two */
                    342:   if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
                    343:     {
                    344:       zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
                    345:                 IF_NAME (oi));
                    346:       return 0;
                    347:     }
                    348: 
                    349:   /* save neighbor's crypt_seqnum */
                    350:   if (nbr)
                    351:     nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
                    352:   return 1;
                    353: }
                    354: 
                    355: /* This function is called from ospf_write(), it will detect the
                    356:    authentication scheme and if it is MD5, it will change the sequence
                    357:    and update the MD5 digest. */
                    358: static int
                    359: ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
                    360: {
                    361:   struct ospf_header *ospfh;
                    362:   unsigned char digest[OSPF_AUTH_MD5_SIZE];
                    363:   MD5_CTX ctx;
                    364:   void *ibuf;
                    365:   u_int32_t t;
                    366:   struct crypt_key *ck;
                    367:   const u_int8_t *auth_key;
                    368: 
                    369:   ibuf = STREAM_DATA (op->s);
                    370:   ospfh = (struct ospf_header *) ibuf;
                    371: 
                    372:   if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
                    373:     return 0;
                    374: 
                    375:   /* We do this here so when we dup a packet, we don't have to
                    376:      waste CPU rewriting other headers.
                    377:      
                    378:      Note that quagga_time /deliberately/ is not used here */
                    379:   t = (time(NULL) & 0xFFFFFFFF);
                    380:   if (t > oi->crypt_seqnum)
                    381:     oi->crypt_seqnum = t;
                    382:   else
                    383:     oi->crypt_seqnum++;
                    384:   
                    385:   ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum); 
                    386: 
                    387:   /* Get MD5 Authentication key from auth_key list. */
                    388:   if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
                    389:     auth_key = (const u_int8_t *) "";
                    390:   else
                    391:     {
                    392:       ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
                    393:       auth_key = ck->auth_key;
                    394:     }
                    395: 
                    396:   /* Generate a digest for the entire packet + our secret key. */
                    397:   memset(&ctx, 0, sizeof(ctx));
                    398:   MD5Init(&ctx);
                    399:   MD5Update(&ctx, ibuf, ntohs (ospfh->length));
                    400:   MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
                    401:   MD5Final(digest, &ctx);
                    402: 
                    403:   /* Append md5 digest to the end of the stream. */
                    404:   stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
                    405: 
                    406:   /* We do *NOT* increment the OSPF header length. */
                    407:   op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
                    408: 
                    409:   if (stream_get_endp(op->s) != op->length)
                    410:     /* XXX size_t */
                    411:     zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
                    412:              (u_long)stream_get_endp(op->s), op->length);
                    413: 
                    414:   return OSPF_AUTH_MD5_SIZE;
                    415: }
                    416: 
                    417: 
                    418: static int
                    419: ospf_ls_req_timer (struct thread *thread)
                    420: {
                    421:   struct ospf_neighbor *nbr;
                    422: 
                    423:   nbr = THREAD_ARG (thread);
                    424:   nbr->t_ls_req = NULL;
                    425: 
                    426:   /* Send Link State Request. */
                    427:   if (ospf_ls_request_count (nbr))
                    428:     ospf_ls_req_send (nbr);
                    429: 
                    430:   /* Set Link State Request retransmission timer. */
                    431:   OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
                    432: 
                    433:   return 0;
                    434: }
                    435: 
                    436: void
                    437: ospf_ls_req_event (struct ospf_neighbor *nbr)
                    438: {
                    439:   if (nbr->t_ls_req)
                    440:     {
                    441:       thread_cancel (nbr->t_ls_req);
                    442:       nbr->t_ls_req = NULL;
                    443:     }
                    444:   nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
                    445: }
                    446: 
                    447: /* Cyclic timer function.  Fist registered in ospf_nbr_new () in
                    448:    ospf_neighbor.c  */
                    449: int
                    450: ospf_ls_upd_timer (struct thread *thread)
                    451: {
                    452:   struct ospf_neighbor *nbr;
                    453: 
                    454:   nbr = THREAD_ARG (thread);
                    455:   nbr->t_ls_upd = NULL;
                    456: 
                    457:   /* Send Link State Update. */
                    458:   if (ospf_ls_retransmit_count (nbr) > 0)
                    459:     {
                    460:       struct list *update;
                    461:       struct ospf_lsdb *lsdb;
                    462:       int i;
                    463:       int retransmit_interval;
                    464: 
                    465:       retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
                    466: 
                    467:       lsdb = &nbr->ls_rxmt;
                    468:       update = list_new ();
                    469: 
                    470:       for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                    471:        {
                    472:          struct route_table *table = lsdb->type[i].db;
                    473:          struct route_node *rn;
                    474:          
                    475:          for (rn = route_top (table); rn; rn = route_next (rn))
                    476:            {
                    477:              struct ospf_lsa *lsa;
                    478:              
                    479:              if ((lsa = rn->info) != NULL)
                    480:                /* Don't retransmit an LSA if we received it within
                    481:                  the last RxmtInterval seconds - this is to allow the
                    482:                  neighbour a chance to acknowledge the LSA as it may
                    483:                  have ben just received before the retransmit timer
                    484:                  fired.  This is a small tweak to what is in the RFC,
                    485:                  but it will cut out out a lot of retransmit traffic
                    486:                  - MAG */
                    487:                if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv), 
                    488:                            int2tv (retransmit_interval)) >= 0)
                    489:                  listnode_add (update, rn->info);
                    490:            }
                    491:        }
                    492: 
                    493:       if (listcount (update) > 0)
                    494:        ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
                    495:       list_delete (update);
                    496:     }
                    497: 
                    498:   /* Set LS Update retransmission timer. */
                    499:   OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
                    500: 
                    501:   return 0;
                    502: }
                    503: 
                    504: int
                    505: ospf_ls_ack_timer (struct thread *thread)
                    506: {
                    507:   struct ospf_interface *oi;
                    508: 
                    509:   oi = THREAD_ARG (thread);
                    510:   oi->t_ls_ack = NULL;
                    511: 
                    512:   /* Send Link State Acknowledgment. */
                    513:   if (listcount (oi->ls_ack) > 0)
                    514:     ospf_ls_ack_send_delayed (oi);
                    515: 
                    516:   /* Set LS Ack timer. */
                    517:   OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
                    518: 
                    519:   return 0;
                    520: }
                    521: 
                    522: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    523: static void
                    524: ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph, 
                    525:                   struct msghdr *msg, unsigned int maxdatasize, 
                    526:                   unsigned int mtu, int flags, u_char type)
                    527: {
                    528: #define OSPF_WRITE_FRAG_SHIFT 3
                    529:   u_int16_t offset;
                    530:   struct iovec *iovp;
                    531:   int ret;
                    532: 
                    533:   assert ( op->length == stream_get_endp(op->s) );
                    534:   assert (msg->msg_iovlen == 2);
                    535: 
                    536:   /* we can but try.
                    537:    *
                    538:    * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
                    539:    * well as the IP_MF flag, making this all quite pointless.
                    540:    *
                    541:    * However, for a system on which IP_MF is left alone, and ip_id left
                    542:    * alone or else which sets same ip_id for each fragment this might
                    543:    * work, eg linux.
                    544:    *
                    545:    * XXX-TODO: It would be much nicer to have the kernel's use their
                    546:    * existing fragmentation support to do this for us. Bugs/RFEs need to
                    547:    * be raised against the various kernels.
                    548:    */
                    549:   
                    550:   /* set More Frag */
                    551:   iph->ip_off |= IP_MF;
                    552:   
                    553:   /* ip frag offset is expressed in units of 8byte words */
                    554:   offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
                    555:   
                    556:   iovp = &msg->msg_iov[1];
                    557:   
                    558:   while ( (stream_get_endp(op->s) - stream_get_getp (op->s)) 
                    559:          > maxdatasize )
                    560:     {
                    561:       /* data length of this frag is to next offset value */
                    562:       iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
                    563:       iph->ip_len = iovp->iov_len + sizeof (struct ip);
                    564:       assert (iph->ip_len <= mtu);
                    565: 
                    566:       sockopt_iphdrincl_swab_htosys (iph);
                    567: 
                    568:       ret = sendmsg (fd, msg, flags);
                    569:       
                    570:       sockopt_iphdrincl_swab_systoh (iph);
                    571:       
                    572:       if (ret < 0)
                    573:         zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
                    574:                   " id %d, off %d, len %d, mtu %u failed with %s",
                    575:                   inet_ntoa (iph->ip_dst),
                    576:                   iph->ip_id,
                    577:                   iph->ip_off,
                    578:                   iph->ip_len,
                    579:                   mtu,
                    580:                   safe_strerror (errno));
                    581:       
                    582:       if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
                    583:         {
                    584:           zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
                    585:                      iph->ip_id, iph->ip_off, iph->ip_len,
                    586:                      inet_ntoa (iph->ip_dst));
                    587:           if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
                    588:             {
                    589:               zlog_debug ("-----------------IP Header Dump----------------------");
                    590:               ospf_ip_header_dump (iph);
                    591:               zlog_debug ("-----------------------------------------------------");
                    592:             }
                    593:         }
                    594:       
                    595:       iph->ip_off += offset;
                    596:       stream_forward_getp (op->s, iovp->iov_len);
                    597:       iovp->iov_base = STREAM_PNT (op->s); 
                    598:     }
                    599:     
                    600:   /* setup for final fragment */
                    601:   iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
                    602:   iph->ip_len = iovp->iov_len + sizeof (struct ip);
                    603:   iph->ip_off &= (~IP_MF);
                    604: }
                    605: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    606: 
                    607: static int
                    608: ospf_write (struct thread *thread)
                    609: {
                    610:   struct ospf *ospf = THREAD_ARG (thread);
                    611:   struct ospf_interface *oi;
                    612:   struct ospf_packet *op;
                    613:   struct sockaddr_in sa_dst;
                    614:   struct ip iph;
                    615:   struct msghdr msg;
                    616:   struct iovec iov[2];
                    617:   u_char type;
                    618:   int ret;
                    619:   int flags = 0;
                    620:   struct listnode *node;
                    621: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    622:   static u_int16_t ipid = 0;
                    623: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    624:   u_int16_t maxdatasize;
                    625: #define OSPF_WRITE_IPHL_SHIFT 2
                    626:   
                    627:   ospf->t_write = NULL;
                    628: 
                    629:   node = listhead (ospf->oi_write_q);
                    630:   assert (node);
                    631:   oi = listgetdata (node);
                    632:   assert (oi);
                    633: 
                    634: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    635:   /* seed ipid static with low order bits of time */
                    636:   if (ipid == 0)
                    637:     ipid = (time(NULL) & 0xffff);
                    638: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    639: 
                    640:   /* convenience - max OSPF data per packet,
                    641:    * and reliability - not more data, than our
                    642:    * socket can accept
                    643:    */
                    644:   maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
                    645:     sizeof (struct ip);
                    646:   
                    647:   /* Get one packet from queue. */
                    648:   op = ospf_fifo_head (oi->obuf);
                    649:   assert (op);
                    650:   assert (op->length >= OSPF_HEADER_SIZE);
                    651: 
                    652:   if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
                    653:       || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
                    654:       ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
                    655:     
                    656:   /* Rewrite the md5 signature & update the seq */
                    657:   ospf_make_md5_digest (oi, op);
                    658: 
                    659:   /* Retrieve OSPF packet type. */
                    660:   stream_set_getp (op->s, 1);
                    661:   type = stream_getc (op->s);
                    662:   
                    663:   /* reset get pointer */
                    664:   stream_set_getp (op->s, 0);
                    665: 
                    666:   memset (&iph, 0, sizeof (struct ip));
                    667:   memset (&sa_dst, 0, sizeof (sa_dst));
                    668:   
                    669:   sa_dst.sin_family = AF_INET;
                    670: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                    671:   sa_dst.sin_len = sizeof(sa_dst);
                    672: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                    673:   sa_dst.sin_addr = op->dst;
                    674:   sa_dst.sin_port = htons (0);
                    675: 
                    676:   /* Set DONTROUTE flag if dst is unicast. */
                    677:   if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
                    678:     if (!IN_MULTICAST (htonl (op->dst.s_addr)))
                    679:       flags = MSG_DONTROUTE;
                    680: 
                    681:   iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
                    682:   /* it'd be very strange for header to not be 4byte-word aligned but.. */
                    683:   if ( sizeof (struct ip) 
                    684:         > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
                    685:     iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
                    686:   
                    687:   iph.ip_v = IPVERSION;
                    688:   iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
                    689:   iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
                    690: 
                    691: #if defined(__DragonFly__)
                    692:   /*
                    693:    * DragonFly's raw socket expects ip_len/ip_off in network byte order.
                    694:    */
                    695:   iph.ip_len = htons(iph.ip_len);
                    696: #endif
                    697: 
                    698: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    699:   /* XXX-MT: not thread-safe at all..
                    700:    * XXX: this presumes this is only programme sending OSPF packets 
                    701:    * otherwise, no guarantee ipid will be unique
                    702:    */
                    703:   iph.ip_id = ++ipid;
                    704: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    705: 
                    706:   iph.ip_off = 0;
                    707:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                    708:     iph.ip_ttl = OSPF_VL_IP_TTL;
                    709:   else
                    710:     iph.ip_ttl = OSPF_IP_TTL;
                    711:   iph.ip_p = IPPROTO_OSPFIGP;
                    712:   iph.ip_sum = 0;
                    713:   iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
                    714:   iph.ip_dst.s_addr = op->dst.s_addr;
                    715: 
                    716:   memset (&msg, 0, sizeof (msg));
                    717:   msg.msg_name = (caddr_t) &sa_dst;
                    718:   msg.msg_namelen = sizeof (sa_dst); 
                    719:   msg.msg_iov = iov;
                    720:   msg.msg_iovlen = 2;
                    721:   iov[0].iov_base = (char*)&iph;
                    722:   iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
                    723:   iov[1].iov_base = STREAM_PNT (op->s);
                    724:   iov[1].iov_len = op->length;
                    725:   
                    726:   /* Sadly we can not rely on kernels to fragment packets because of either
                    727:    * IP_HDRINCL and/or multicast destination being set.
                    728:    */
                    729: #ifdef WANT_OSPF_WRITE_FRAGMENT
                    730:   if ( op->length > maxdatasize )
                    731:     ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize, 
                    732:                       oi->ifp->mtu, flags, type);
                    733: #endif /* WANT_OSPF_WRITE_FRAGMENT */
                    734: 
                    735:   /* send final fragment (could be first) */
                    736:   sockopt_iphdrincl_swab_htosys (&iph);
                    737:   ret = sendmsg (ospf->fd, &msg, flags);
                    738:   sockopt_iphdrincl_swab_systoh (&iph);
                    739:   
                    740:   if (ret < 0)
                    741:     zlog_warn ("*** sendmsg in ospf_write failed to %s, "
                    742:               "id %d, off %d, len %d, interface %s, mtu %u: %s",
                    743:               inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
                    744:               oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
                    745: 
                    746:   /* Show debug sending packet. */
                    747:   if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
                    748:     {
                    749:       if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
                    750:        {
                    751:          zlog_debug ("-----------------------------------------------------");
                    752:          ospf_ip_header_dump (&iph);
                    753:          stream_set_getp (op->s, 0);
                    754:          ospf_packet_dump (op->s);
                    755:        }
                    756: 
                    757:       zlog_debug ("%s sent to [%s] via [%s].",
                    758:                 ospf_packet_type_str[type], inet_ntoa (op->dst),
                    759:                 IF_NAME (oi));
                    760: 
                    761:       if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
                    762:        zlog_debug ("-----------------------------------------------------");
                    763:     }
                    764: 
                    765:   /* Now delete packet from queue. */
                    766:   ospf_packet_delete (oi);
                    767: 
                    768:   if (ospf_fifo_head (oi->obuf) == NULL)
                    769:     {
                    770:       oi->on_write_q = 0;
                    771:       list_delete_node (ospf->oi_write_q, node);
                    772:     }
                    773:   
                    774:   /* If packets still remain in queue, call write thread. */
                    775:   if (!list_isempty (ospf->oi_write_q))
                    776:     ospf->t_write =                                              
                    777:       thread_add_write (master, ospf_write, ospf, ospf->fd);
                    778: 
                    779:   return 0;
                    780: }
                    781: 
                    782: /* OSPF Hello message read -- RFC2328 Section 10.5. */
                    783: static void
                    784: ospf_hello (struct ip *iph, struct ospf_header *ospfh,
                    785:            struct stream * s, struct ospf_interface *oi, int size)
                    786: {
                    787:   struct ospf_hello *hello;
                    788:   struct ospf_neighbor *nbr;
                    789:   int old_state;
                    790:   struct prefix p;
                    791: 
                    792:   /* increment statistics. */
                    793:   oi->hello_in++;
                    794: 
                    795:   hello = (struct ospf_hello *) STREAM_PNT (s);
                    796: 
                    797:   /* If Hello is myself, silently discard. */
                    798:   if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
                    799:     {
                    800:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                    801:         {
                    802:           zlog_debug ("ospf_header[%s/%s]: selforiginated, "
                    803:                      "dropping.",
                    804:                      ospf_packet_type_str[ospfh->type],
                    805:                      inet_ntoa (iph->ip_src));
                    806:         }
                    807:       return;
                    808:     }
                    809: 
                    810:   /* get neighbor prefix. */
                    811:   p.family = AF_INET;
                    812:   p.prefixlen = ip_masklen (hello->network_mask);
                    813:   p.u.prefix4 = iph->ip_src;
                    814: 
                    815:   /* Compare network mask. */
                    816:   /* Checking is ignored for Point-to-Point and Virtual link. */
                    817:   if (oi->type != OSPF_IFTYPE_POINTOPOINT 
                    818:       && oi->type != OSPF_IFTYPE_VIRTUALLINK)
                    819:     if (oi->address->prefixlen != p.prefixlen)
                    820:       {
                    821:        zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
                    822:                   inet_ntoa(ospfh->router_id), IF_NAME(oi),
                    823:                   (int)oi->address->prefixlen, (int)p.prefixlen);
                    824:        return;
                    825:       }
                    826: 
                    827:   /* Compare Router Dead Interval. */
                    828:   if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
                    829:     {
                    830:       zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
                    831:                 "(expected %u, but received %u).",
                    832:                 inet_ntoa(ospfh->router_id),
                    833:                 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
                    834:       return;
                    835:     }
                    836: 
                    837:   /* Compare Hello Interval - ignored if fast-hellos are set. */
                    838:   if (OSPF_IF_PARAM (oi, fast_hello) == 0)
                    839:     {
                    840:       if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
                    841:         {
                    842:           zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
                    843:                     "(expected %u, but received %u).",
                    844:                     inet_ntoa(ospfh->router_id),
                    845:                     OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
                    846:           return;
                    847:         }
                    848:     }
                    849:   
                    850:   if (IS_DEBUG_OSPF_EVENT)
                    851:     zlog_debug ("Packet %s [Hello:RECV]: Options %s",
                    852:               inet_ntoa (ospfh->router_id),
                    853:               ospf_options_dump (hello->options));
                    854: 
                    855:   /* Compare options. */
                    856: #define REJECT_IF_TBIT_ON      1 /* XXX */
                    857: #ifdef REJECT_IF_TBIT_ON
                    858:   if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
                    859:     {
                    860:       /*
                    861:        * This router does not support non-zero TOS.
                    862:        * Drop this Hello packet not to establish neighbor relationship.
                    863:        */
                    864:       zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
                    865:                 inet_ntoa (ospfh->router_id));
                    866:       return;
                    867:     }
                    868: #endif /* REJECT_IF_TBIT_ON */
                    869: 
                    870: #ifdef HAVE_OPAQUE_LSA
                    871:   if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
                    872:       && CHECK_FLAG (hello->options, OSPF_OPTION_O))
                    873:     {
                    874:       /*
                    875:        * This router does know the correct usage of O-bit
                    876:        * the bit should be set in DD packet only.
                    877:        */
                    878:       zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
                    879:                 inet_ntoa (ospfh->router_id));
                    880: #ifdef STRICT_OBIT_USAGE_CHECK
                    881:       return;                                     /* Reject this packet. */
                    882: #else /* STRICT_OBIT_USAGE_CHECK */
                    883:       UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
                    884: #endif /* STRICT_OBIT_USAGE_CHECK */
                    885:     }
                    886: #endif /* HAVE_OPAQUE_LSA */
                    887: 
                    888:   /* new for NSSA is to ensure that NP is on and E is off */
                    889: 
                    890:   if (oi->area->external_routing == OSPF_AREA_NSSA) 
                    891:     {
                    892:       if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
                    893:             && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
                    894:             && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
                    895:             && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
                    896:        {
                    897:          zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
                    898:          return;
                    899:        }
                    900:       if (IS_DEBUG_OSPF_NSSA)
                    901:         zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
                    902:     }
                    903:   else    
                    904:     /* The setting of the E-bit found in the Hello Packet's Options
                    905:        field must match this area's ExternalRoutingCapability A
                    906:        mismatch causes processing to stop and the packet to be
                    907:        dropped. The setting of the rest of the bits in the Hello
                    908:        Packet's Options field should be ignored. */
                    909:     if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
                    910:        CHECK_FLAG (hello->options, OSPF_OPTION_E))
                    911:       {
                    912:        zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
                    913:                   inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
                    914:        return;
                    915:       }
                    916:   
                    917:   /* get neighbour struct */
                    918:   nbr = ospf_nbr_get (oi, ospfh, iph, &p);
                    919: 
                    920:   /* neighbour must be valid, ospf_nbr_get creates if none existed */
                    921:   assert (nbr);
                    922: 
                    923:   old_state = nbr->state;
                    924: 
                    925:   /* Add event to thread. */
                    926:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                    927: 
                    928:   /*  RFC2328  Section 9.5.1
                    929:       If the router is not eligible to become Designated Router,
                    930:       (snip)   It      must also send an Hello Packet in reply to an
                    931:       Hello Packet received from any eligible neighbor (other than
                    932:       the      current Designated Router and Backup Designated Router).  */
                    933:   if (oi->type == OSPF_IFTYPE_NBMA)
                    934:     if (PRIORITY(oi) == 0 && hello->priority > 0
                    935:        && IPV4_ADDR_CMP(&DR(oi),  &iph->ip_src)
                    936:        && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
                    937:       OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
                    938:                         OSPF_HELLO_REPLY_DELAY);
                    939: 
                    940:   /* on NBMA network type, it happens to receive bidirectional Hello packet
                    941:      without advance 1-Way Received event.
                    942:      To avoid incorrect DR-seletion, raise 1-Way Received event.*/
                    943:   if (oi->type == OSPF_IFTYPE_NBMA &&
                    944:       (old_state == NSM_Down || old_state == NSM_Attempt))
                    945:     {
                    946:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
                    947:       nbr->priority = hello->priority;
                    948:       nbr->d_router = hello->d_router;
                    949:       nbr->bd_router = hello->bd_router;
                    950:       return;
                    951:     }
                    952: 
                    953:   if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
                    954:                              size - OSPF_HELLO_MIN_SIZE))
                    955:     {
                    956:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
                    957:       nbr->options |= hello->options;
                    958:     }
                    959:   else
                    960:     {
                    961:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
                    962:       /* Set neighbor information. */
                    963:       nbr->priority = hello->priority;
                    964:       nbr->d_router = hello->d_router;
                    965:       nbr->bd_router = hello->bd_router;
                    966:       return;
                    967:     }
                    968: 
                    969:   /* If neighbor itself declares DR and no BDR exists,
                    970:      cause event BackupSeen */
                    971:   if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
                    972:     if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
                    973:       OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
                    974: 
                    975:   /* neighbor itself declares BDR. */
                    976:   if (oi->state == ISM_Waiting &&
                    977:       IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
                    978:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
                    979: 
                    980:   /* had not previously. */
                    981:   if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
                    982:        IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
                    983:       (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
                    984:        IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
                    985:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
                    986: 
                    987:   /* had not previously. */
                    988:   if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
                    989:        IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
                    990:       (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
                    991:        IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
                    992:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
                    993: 
                    994:   /* Neighbor priority check. */
                    995:   if (nbr->priority >= 0 && nbr->priority != hello->priority)
                    996:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
                    997: 
                    998:   /* Set neighbor information. */
                    999:   nbr->priority = hello->priority;
                   1000:   nbr->d_router = hello->d_router;
                   1001:   nbr->bd_router = hello->bd_router;
                   1002: }
                   1003: 
                   1004: /* Save DD flags/options/Seqnum received. */
                   1005: static void
                   1006: ospf_db_desc_save_current (struct ospf_neighbor *nbr,
                   1007:                           struct ospf_db_desc *dd)
                   1008: {
                   1009:   nbr->last_recv.flags = dd->flags;
                   1010:   nbr->last_recv.options = dd->options;
                   1011:   nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
                   1012: }
                   1013: 
                   1014: /* Process rest of DD packet. */
                   1015: static void
                   1016: ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
                   1017:                   struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
                   1018:                   u_int16_t size)
                   1019: {
                   1020:   struct ospf_lsa *new, *find;
                   1021:   struct lsa_header *lsah;
                   1022: 
                   1023:   stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
                   1024:   for (size -= OSPF_DB_DESC_MIN_SIZE;
                   1025:        size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE) 
                   1026:     {
                   1027:       lsah = (struct lsa_header *) STREAM_PNT (s);
                   1028:       stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
                   1029: 
                   1030:       /* Unknown LS type. */
                   1031:       if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
                   1032:        {
                   1033:          zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
                   1034:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1035:          return;
                   1036:        }
                   1037: 
                   1038: #ifdef HAVE_OPAQUE_LSA
                   1039:       if (IS_OPAQUE_LSA (lsah->type)
                   1040:       &&  ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
                   1041:         {
                   1042:           zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
                   1043:           OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1044:           return;
                   1045:         }
                   1046: #endif /* HAVE_OPAQUE_LSA */
                   1047: 
                   1048:       switch (lsah->type)
                   1049:         {
                   1050:         case OSPF_AS_EXTERNAL_LSA:
                   1051: #ifdef HAVE_OPAQUE_LSA
                   1052:        case OSPF_OPAQUE_AS_LSA:
                   1053: #endif /* HAVE_OPAQUE_LSA */
                   1054:           /* Check for stub area.  Reject if AS-External from stub but
                   1055:              allow if from NSSA. */
                   1056:           if (oi->area->external_routing == OSPF_AREA_STUB)
                   1057:             {
                   1058:               zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
                   1059:                          lsah->type, inet_ntoa (lsah->id),
                   1060:                          (oi->area->external_routing == OSPF_AREA_STUB) ?\
                   1061:                          "STUB" : "NSSA");
                   1062:               OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1063:               return;
                   1064:             }
                   1065:           break;
                   1066:        default:
                   1067:          break;
                   1068:         }
                   1069: 
                   1070:       /* Create LS-request object. */
                   1071:       new = ospf_ls_request_new (lsah);
                   1072: 
                   1073:       /* Lookup received LSA, then add LS request list. */
                   1074:       find = ospf_lsa_lookup_by_header (oi->area, lsah);
                   1075:       
                   1076:       /* ospf_lsa_more_recent is fine with NULL pointers */
                   1077:       switch (ospf_lsa_more_recent (find, new))
                   1078:         {
                   1079:           case -1:
                   1080:             /* Neighbour has a more recent LSA, we must request it */
                   1081:             ospf_ls_request_add (nbr, new);
                   1082:           case 0:
                   1083:             /* If we have a copy of this LSA, it's either less recent
                   1084:              * and we're requesting it from neighbour (the case above), or
                   1085:              * it's as recent and we both have same copy (this case).
                   1086:              *
                   1087:              * In neither of these two cases is there any point in
                   1088:              * describing our copy of the LSA to the neighbour in a
                   1089:              * DB-Summary packet, if we're still intending to do so.
                   1090:              *
                   1091:              * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
                   1092:              * backward compatible optimisation to OSPF DB Exchange /
                   1093:              * DB Description process implemented here.
                   1094:              */
                   1095:             if (find)
                   1096:               ospf_lsdb_delete (&nbr->db_sum, find);
                   1097:             ospf_lsa_discard (new);
                   1098:             break;
                   1099:           default:
                   1100:             /* We have the more recent copy, nothing specific to do:
                   1101:              * - no need to request neighbours stale copy
                   1102:              * - must leave DB summary list copy alone
                   1103:              */
                   1104:             if (IS_DEBUG_OSPF_EVENT)
                   1105:               zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
                   1106:                          "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
                   1107:             ospf_lsa_discard (new);
                   1108:         }
                   1109:     }
                   1110: 
                   1111:   /* Master */
                   1112:   if (IS_SET_DD_MS (nbr->dd_flags))
                   1113:     {
                   1114:       nbr->dd_seqnum++;
                   1115: 
                   1116:       /* Both sides have no More, then we're done with Exchange */
                   1117:       if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
                   1118:        OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
                   1119:       else
                   1120:        ospf_db_desc_send (nbr);
                   1121:     }
                   1122:   /* Slave */
                   1123:   else
                   1124:     {
                   1125:       nbr->dd_seqnum = ntohl (dd->dd_seqnum);
                   1126: 
                   1127:       /* Send DD packet in reply. 
                   1128:        * 
                   1129:        * Must be done to acknowledge the Master's DD, regardless of
                   1130:        * whether we have more LSAs ourselves to describe.
                   1131:        *
                   1132:        * This function will clear the 'More' bit, if after this DD
                   1133:        * we have no more LSAs to describe to the master..
                   1134:        */
                   1135:       ospf_db_desc_send (nbr);
                   1136:       
                   1137:       /* Slave can raise ExchangeDone now, if master is also done */
                   1138:       if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
                   1139:        OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
                   1140:     }
                   1141:   
                   1142:   /* Save received neighbor values from DD. */
                   1143:   ospf_db_desc_save_current (nbr, dd);
                   1144: }
                   1145: 
                   1146: static int
                   1147: ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
                   1148: {
                   1149:   /* Is DD duplicated? */
                   1150:   if (dd->options == nbr->last_recv.options &&
                   1151:       dd->flags == nbr->last_recv.flags &&
                   1152:       dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
                   1153:     return 1;
                   1154: 
                   1155:   return 0;
                   1156: }
                   1157: 
                   1158: /* OSPF Database Description message read -- RFC2328 Section 10.6. */
                   1159: static void
                   1160: ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
                   1161:              struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   1162: {
                   1163:   struct ospf_db_desc *dd;
                   1164:   struct ospf_neighbor *nbr;
                   1165: 
                   1166:   /* Increment statistics. */
                   1167:   oi->db_desc_in++;
                   1168: 
                   1169:   dd = (struct ospf_db_desc *) STREAM_PNT (s);
                   1170: 
                   1171:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   1172:   if (nbr == NULL)
                   1173:     {
                   1174:       zlog_warn ("Packet[DD]: Unknown Neighbor %s",
                   1175:                 inet_ntoa (ospfh->router_id));
                   1176:       return;
                   1177:     }
                   1178: 
                   1179:   /* Check MTU. */
                   1180:   if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) && 
                   1181:       (ntohs (dd->mtu) > oi->ifp->mtu))
                   1182:     {
                   1183:       zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
                   1184:                 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
                   1185:                 IF_NAME (oi), oi->ifp->mtu);
                   1186:       return;
                   1187:     }
                   1188: 
                   1189:   /* 
                   1190:    * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
                   1191:    * required. In fact at least JunOS sends DD packets with P bit clear. 
                   1192:    * Until proper solution is developped, this hack should help.
                   1193:    *
                   1194:    * Update: According to the RFCs, N bit is specified /only/ for Hello
                   1195:    * options, unfortunately its use in DD options is not specified. Hence some
                   1196:    * implementations follow E-bit semantics and set it in DD options, and some
                   1197:    * treat it as unspecified and hence follow the directive "default for 
                   1198:    * options is clear", ie unset.
                   1199:    *
                   1200:    * Reset the flag, as ospfd follows E-bit semantics.
                   1201:    */
                   1202:   if ( (oi->area->external_routing == OSPF_AREA_NSSA)
                   1203:        && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
                   1204:        && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
                   1205:     {
                   1206:       if (IS_DEBUG_OSPF_EVENT) 
                   1207:         zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
                   1208:                     inet_ntoa (nbr->router_id) );
                   1209:       SET_FLAG (dd->options, OSPF_OPTION_NP);
                   1210:     }
                   1211: 
                   1212: #ifdef REJECT_IF_TBIT_ON
                   1213:   if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
                   1214:     {
                   1215:       /*
                   1216:        * In Hello protocol, optional capability must have checked
                   1217:        * to prevent this T-bit enabled router be my neighbor.
                   1218:        */
                   1219:       zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
                   1220:       return;
                   1221:     }
                   1222: #endif /* REJECT_IF_TBIT_ON */
                   1223: 
                   1224: #ifdef HAVE_OPAQUE_LSA
                   1225:   if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
                   1226:       && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
                   1227:     {
                   1228:       /*
                   1229:        * This node is not configured to handle O-bit, for now.
                   1230:        * Clear it to ignore unsupported capability proposed by neighbor.
                   1231:        */
                   1232:       UNSET_FLAG (dd->options, OSPF_OPTION_O);
                   1233:     }
                   1234: #endif /* HAVE_OPAQUE_LSA */
                   1235: 
                   1236:   /* Add event to thread. */
                   1237:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   1238: 
                   1239:   /* Process DD packet by neighbor status. */
                   1240:   switch (nbr->state)
                   1241:     {
                   1242:     case NSM_Down:
                   1243:     case NSM_Attempt:
                   1244:     case NSM_TwoWay:
                   1245:       zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
                   1246:                 inet_ntoa(nbr->router_id),
                   1247:                 LOOKUP (ospf_nsm_state_msg, nbr->state));
                   1248:       break;
                   1249:     case NSM_Init:
                   1250:       OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
                   1251:       /* If the new state is ExStart, the processing of the current
                   1252:         packet should then continue in this new state by falling
                   1253:         through to case ExStart below.  */
                   1254:       if (nbr->state != NSM_ExStart)
                   1255:        break;
                   1256:     case NSM_ExStart:
                   1257:       /* Initial DBD */
                   1258:       if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
                   1259:          (size == OSPF_DB_DESC_MIN_SIZE))
                   1260:        {
                   1261:          if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
                   1262:            {
                   1263:              /* We're Slave---obey */
                   1264:              zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
                   1265:                         inet_ntoa(nbr->router_id));
                   1266:              nbr->dd_seqnum = ntohl (dd->dd_seqnum);
                   1267:              
                   1268:              /* Reset I/MS */
                   1269:              UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
                   1270:            }
                   1271:          else
                   1272:            {
                   1273:              /* We're Master, ignore the initial DBD from Slave */
                   1274:              zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
                   1275:                         "ignoring.", inet_ntoa(nbr->router_id));
                   1276:              break;
                   1277:            }
                   1278:        }
                   1279:       /* Ack from the Slave */
                   1280:       else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
                   1281:               ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
                   1282:               IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
                   1283:        {
                   1284:          zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
                   1285:                     inet_ntoa(nbr->router_id));
                   1286:           /* Reset I, leaving MS */
                   1287:           UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
                   1288:        }
                   1289:       else
                   1290:        {
                   1291:          zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
                   1292:                     inet_ntoa(nbr->router_id));
                   1293:          break;
                   1294:        }
                   1295:       
                   1296:       /* This is where the real Options are saved */
                   1297:       nbr->options = dd->options;
                   1298: 
                   1299: #ifdef HAVE_OPAQUE_LSA
                   1300:       if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
                   1301:         {
                   1302:           if (IS_DEBUG_OSPF_EVENT)
                   1303:             zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
                   1304:                       inet_ntoa (nbr->router_id),
                   1305:                       CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
                   1306: 
                   1307:           if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
                   1308:           &&  IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
                   1309:             {
                   1310:               zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
                   1311:                          "Opaque-LSAs cannot be reliably advertised "
                   1312:                          "in this network.",
                   1313:                          inet_ntoa (nbr->router_id));
                   1314:               /* This situation is undesirable, but not a real error. */
                   1315:             }
                   1316:         }
                   1317: #endif /* HAVE_OPAQUE_LSA */
                   1318: 
                   1319:       OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
                   1320: 
                   1321:       /* continue processing rest of packet. */
                   1322:       ospf_db_desc_proc (s, oi, nbr, dd, size);
                   1323:       break;
                   1324:     case NSM_Exchange:
                   1325:       if (ospf_db_desc_is_dup (dd, nbr))
                   1326:        {
                   1327:          if (IS_SET_DD_MS (nbr->dd_flags))
                   1328:            /* Master: discard duplicated DD packet. */
                   1329:            zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
                   1330:                       inet_ntoa (nbr->router_id));
                   1331:          else
                   1332:            /* Slave: cause to retransmit the last Database Description. */
                   1333:            {
                   1334:              zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
                   1335:                         inet_ntoa (nbr->router_id));
                   1336:              ospf_db_desc_resend (nbr);
                   1337:            }
                   1338:          break;
                   1339:        }
                   1340: 
                   1341:       /* Otherwise DD packet should be checked. */
                   1342:       /* Check Master/Slave bit mismatch */
                   1343:       if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
                   1344:        {
                   1345:          zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
                   1346:                     inet_ntoa(nbr->router_id));
                   1347:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1348:          if (IS_DEBUG_OSPF_EVENT)
                   1349:            zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
                   1350:                        dd->flags, nbr->dd_flags);
                   1351:          break;
                   1352:        }
                   1353: 
                   1354:       /* Check initialize bit is set. */
                   1355:       if (IS_SET_DD_I (dd->flags))
                   1356:        {
                   1357:          zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
                   1358:                     inet_ntoa(nbr->router_id));
                   1359:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1360:          break;
                   1361:        }
                   1362: 
                   1363:       /* Check DD Options. */
                   1364:       if (dd->options != nbr->options)
                   1365:        {
                   1366: #ifdef ORIGINAL_CODING
                   1367:          /* Save the new options for debugging */
                   1368:          nbr->options = dd->options;
                   1369: #endif /* ORIGINAL_CODING */
                   1370:          zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
                   1371:                     inet_ntoa(nbr->router_id));
                   1372:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1373:          break;
                   1374:        }
                   1375: 
                   1376:       /* Check DD sequence number. */
                   1377:       if ((IS_SET_DD_MS (nbr->dd_flags) &&
                   1378:           ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
                   1379:          (!IS_SET_DD_MS (nbr->dd_flags) &&
                   1380:           ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
                   1381:        {
                   1382:          zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
                   1383:                     inet_ntoa(nbr->router_id));
                   1384:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1385:          break;
                   1386:        }
                   1387: 
                   1388:       /* Continue processing rest of packet. */
                   1389:       ospf_db_desc_proc (s, oi, nbr, dd, size);
                   1390:       break;
                   1391:     case NSM_Loading:
                   1392:     case NSM_Full:
                   1393:       if (ospf_db_desc_is_dup (dd, nbr))
                   1394:        {
                   1395:          if (IS_SET_DD_MS (nbr->dd_flags))
                   1396:            {
                   1397:              /* Master should discard duplicate DD packet. */
                   1398:              zlog_info ("Packet[DD]: Neighbor %s duplicated, "
                   1399:                         "packet discarded.",
                   1400:                        inet_ntoa(nbr->router_id));
                   1401:              break;
                   1402:            }
                   1403:          else
                   1404:            {
                   1405:              struct timeval t, now;
                   1406:              quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                   1407:              t = tv_sub (now, nbr->last_send_ts);
                   1408:              if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
                   1409:                {
                   1410:                  /* In states Loading and Full the slave must resend
                   1411:                     its last Database Description packet in response to
                   1412:                     duplicate Database Description packets received
                   1413:                     from the master.  For this reason the slave must
                   1414:                     wait RouterDeadInterval seconds before freeing the
                   1415:                     last Database Description packet.  Reception of a
                   1416:                     Database Description packet from the master after
                   1417:                     this interval will generate a SeqNumberMismatch
                   1418:                     neighbor event. RFC2328 Section 10.8 */
                   1419:                  ospf_db_desc_resend (nbr);
                   1420:                  break;
                   1421:                }
                   1422:            }
                   1423:        }
                   1424: 
                   1425:       OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
                   1426:       break;
                   1427:     default:
                   1428:       zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
                   1429:                 inet_ntoa(nbr->router_id), nbr->state);
                   1430:       break;
                   1431:     }
                   1432: }
                   1433: 
                   1434: #define OSPF_LSA_KEY_SIZE       12 /* type(4) + id(4) + ar(4) */
                   1435: 
                   1436: /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
                   1437: static void
                   1438: ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
                   1439:             struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   1440: {
                   1441:   struct ospf_neighbor *nbr;
                   1442:   u_int32_t ls_type;
                   1443:   struct in_addr ls_id;
                   1444:   struct in_addr adv_router;
                   1445:   struct ospf_lsa *find;
                   1446:   struct list *ls_upd;
                   1447:   unsigned int length;
                   1448: 
                   1449:   /* Increment statistics. */
                   1450:   oi->ls_req_in++;
                   1451: 
                   1452:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   1453:   if (nbr == NULL)
                   1454:     {
                   1455:       zlog_warn ("Link State Request: Unknown Neighbor %s.",
                   1456:                 inet_ntoa (ospfh->router_id));
                   1457:       return;
                   1458:     }
                   1459: 
                   1460:   /* Add event to thread. */
                   1461:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   1462: 
                   1463:   /* Neighbor State should be Exchange or later. */
                   1464:   if (nbr->state != NSM_Exchange &&
                   1465:       nbr->state != NSM_Loading &&
                   1466:       nbr->state != NSM_Full)
                   1467:     {
                   1468:       zlog_warn ("Link State Request received from %s: "
                   1469:                 "Neighbor state is %s, packet discarded.",
                   1470:                 inet_ntoa (ospfh->router_id),
                   1471:                 LOOKUP (ospf_nsm_state_msg, nbr->state));
                   1472:       return;
                   1473:     }
                   1474: 
                   1475:   /* Send Link State Update for ALL requested LSAs. */
                   1476:   ls_upd = list_new ();
                   1477:   length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
                   1478: 
                   1479:   while (size >= OSPF_LSA_KEY_SIZE)
                   1480:     {
                   1481:       /* Get one slice of Link State Request. */
                   1482:       ls_type = stream_getl (s);
                   1483:       ls_id.s_addr = stream_get_ipv4 (s);
                   1484:       adv_router.s_addr = stream_get_ipv4 (s);
                   1485: 
                   1486:       /* Verify LSA type. */
                   1487:       if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
                   1488:        {
                   1489:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
                   1490:          list_delete (ls_upd);
                   1491:          return;
                   1492:        }
                   1493: 
                   1494:       /* Search proper LSA in LSDB. */
                   1495:       find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
                   1496:       if (find == NULL)
                   1497:        {
                   1498:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
                   1499:          list_delete (ls_upd);
                   1500:          return;
                   1501:        }
                   1502: 
                   1503:       /* Packet overflows MTU size, send immediately. */
                   1504:       if (length + ntohs (find->data->length) > ospf_packet_max (oi))
                   1505:        {
                   1506:          if (oi->type == OSPF_IFTYPE_NBMA)
                   1507:            ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
                   1508:          else
                   1509:            ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
                   1510: 
                   1511:          /* Only remove list contents.  Keep ls_upd. */
                   1512:          list_delete_all_node (ls_upd);
                   1513: 
                   1514:          length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
                   1515:        }
                   1516: 
                   1517:       /* Append LSA to update list. */
                   1518:       listnode_add (ls_upd, find);
                   1519:       length += ntohs (find->data->length);
                   1520: 
                   1521:       size -= OSPF_LSA_KEY_SIZE;
                   1522:     }
                   1523: 
                   1524:   /* Send rest of Link State Update. */
                   1525:   if (listcount (ls_upd) > 0)
                   1526:     {
                   1527:       if (oi->type == OSPF_IFTYPE_NBMA)
                   1528:        ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
                   1529:       else
                   1530:        ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
                   1531: 
                   1532:       list_delete (ls_upd);
                   1533:     }
                   1534:   else
                   1535:     list_free (ls_upd);
                   1536: }
                   1537: 
                   1538: /* Get the list of LSAs from Link State Update packet.
                   1539:    And process some validation -- RFC2328 Section 13. (1)-(2). */
                   1540: static struct list *
                   1541: ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
                   1542:                       struct ospf_interface *oi, size_t size)
                   1543: {
                   1544:   u_int16_t count, sum;
                   1545:   u_int32_t length;
                   1546:   struct lsa_header *lsah;
                   1547:   struct ospf_lsa *lsa;
                   1548:   struct list *lsas;
                   1549: 
                   1550:   lsas = list_new ();
                   1551: 
                   1552:   count = stream_getl (s);
                   1553:   size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
                   1554: 
                   1555:   for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
                   1556:        size -= length, stream_forward_getp (s, length), count--)
                   1557:     {
                   1558:       lsah = (struct lsa_header *) STREAM_PNT (s);
                   1559:       length = ntohs (lsah->length);
                   1560: 
                   1561:       if (length > size)
                   1562:        {
                   1563:          zlog_warn ("Link State Update: LSA length exceeds packet size.");
                   1564:          break;
                   1565:        }
                   1566: 
                   1567:       /* Validate the LSA's LS checksum. */
                   1568:       sum = lsah->checksum;
                   1569:       if (sum != ospf_lsa_checksum (lsah))
                   1570:        {
                   1571:          zlog_warn ("Link State Update: LSA checksum error %x, %x.",
                   1572:                     sum, lsah->checksum);
                   1573:          continue;
                   1574:        }
                   1575: 
                   1576:       /* Examine the LSA's LS type. */
                   1577:       if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
                   1578:        {
                   1579:          zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
                   1580:          continue;
                   1581:        }
                   1582: 
                   1583:       /*
                   1584:        * What if the received LSA's age is greater than MaxAge?
                   1585:        * Treat it as a MaxAge case -- endo.
                   1586:        */
                   1587:       if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
                   1588:         lsah->ls_age = htons (OSPF_LSA_MAXAGE);
                   1589: 
                   1590: #ifdef HAVE_OPAQUE_LSA
                   1591:       if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
                   1592:         {
                   1593: #ifdef STRICT_OBIT_USAGE_CHECK
                   1594:          if ((IS_OPAQUE_LSA(lsah->type) &&
                   1595:                ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
                   1596:          ||  (! IS_OPAQUE_LSA(lsah->type) &&
                   1597:                CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
                   1598:             {
                   1599:               /*
                   1600:                * This neighbor must know the exact usage of O-bit;
                   1601:                * the bit will be set in Type-9,10,11 LSAs only.
                   1602:                */
                   1603:               zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
                   1604:               continue;
                   1605:             }
                   1606: #endif /* STRICT_OBIT_USAGE_CHECK */
                   1607: 
                   1608:           /* Do not take in AS External Opaque-LSAs if we are a stub. */
                   1609:           if (lsah->type == OSPF_OPAQUE_AS_LSA
                   1610:              && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT) 
                   1611:             {
                   1612:               if (IS_DEBUG_OSPF_EVENT)
                   1613:                 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
                   1614:               continue;
                   1615:             }
                   1616:         }
                   1617:       else if (IS_OPAQUE_LSA(lsah->type))
                   1618:         {
                   1619:           zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
                   1620:           continue;
                   1621:         }
                   1622: #endif /* HAVE_OPAQUE_LSA */
                   1623: 
                   1624:       /* Create OSPF LSA instance. */
                   1625:       lsa = ospf_lsa_new ();
                   1626: 
                   1627:       /* We may wish to put some error checking if type NSSA comes in
                   1628:          and area not in NSSA mode */
                   1629:       switch (lsah->type)
                   1630:         {
                   1631:         case OSPF_AS_EXTERNAL_LSA:
                   1632: #ifdef HAVE_OPAQUE_LSA
                   1633:         case OSPF_OPAQUE_AS_LSA:
                   1634:           lsa->area = NULL;
                   1635:           break;
                   1636:         case OSPF_OPAQUE_LINK_LSA:
                   1637:           lsa->oi = oi; /* Remember incoming interface for flooding control. */
                   1638:           /* Fallthrough */
                   1639: #endif /* HAVE_OPAQUE_LSA */
                   1640:         default:
                   1641:           lsa->area = oi->area;
                   1642:           break;
                   1643:         }
                   1644: 
                   1645:       lsa->data = ospf_lsa_data_new (length);
                   1646:       memcpy (lsa->data, lsah, length);
                   1647: 
                   1648:       if (IS_DEBUG_OSPF_EVENT)
                   1649:        zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
                   1650:                  lsa->data->type, inet_ntoa (lsa->data->id), lsa);
                   1651:       listnode_add (lsas, lsa);
                   1652:     }
                   1653: 
                   1654:   return lsas;
                   1655: }
                   1656: 
                   1657: /* Cleanup Update list. */
                   1658: static void
                   1659: ospf_upd_list_clean (struct list *lsas)
                   1660: {
                   1661:   struct listnode *node, *nnode;
                   1662:   struct ospf_lsa *lsa;
                   1663: 
                   1664:   for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
                   1665:     ospf_lsa_discard (lsa);
                   1666: 
                   1667:   list_delete (lsas);
                   1668: }
                   1669: 
                   1670: /* OSPF Link State Update message read -- RFC2328 Section 13. */
                   1671: static void
                   1672: ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
                   1673:             struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   1674: {
                   1675:   struct ospf_neighbor *nbr;
                   1676:   struct list *lsas;
                   1677:   struct listnode *node, *nnode;
                   1678:   struct ospf_lsa *lsa = NULL;
                   1679:   /* unsigned long ls_req_found = 0; */
                   1680: 
                   1681:   /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
                   1682: 
                   1683:   /* Increment statistics. */
                   1684:   oi->ls_upd_in++;
                   1685: 
                   1686:   /* Check neighbor. */
                   1687:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   1688:   if (nbr == NULL)
                   1689:     {
                   1690:       zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
                   1691:                 inet_ntoa (ospfh->router_id), IF_NAME (oi));
                   1692:       return;
                   1693:     }
                   1694: 
                   1695:   /* Add event to thread. */
                   1696:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   1697: 
                   1698:   /* Check neighbor state. */
                   1699:   if (nbr->state < NSM_Exchange)
                   1700:     {
                   1701:       zlog_warn ("Link State Update: "
                   1702:                 "Neighbor[%s] state %s is less than Exchange",
                   1703:                 inet_ntoa (ospfh->router_id),
                   1704:                 LOOKUP(ospf_nsm_state_msg, nbr->state));
                   1705:       return;
                   1706:     }
                   1707: 
                   1708:   /* Get list of LSAs from Link State Update packet. - Also perorms Stages 
                   1709:    * 1 (validate LSA checksum) and 2 (check for LSA consistent type) 
                   1710:    * of section 13. 
                   1711:    */
                   1712:   lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
                   1713: 
                   1714: #ifdef HAVE_OPAQUE_LSA
                   1715:   /*
                   1716:    * If self-originated Opaque-LSAs that have flooded before restart
                   1717:    * are contained in the received LSUpd message, corresponding LSReq
                   1718:    * messages to be sent may have to be modified.
                   1719:    * To eliminate possible race conditions such that flushing and normal
                   1720:    * updating for the same LSA would take place alternately, this trick
                   1721:    * must be done before entering to the loop below.
                   1722:    */
                   1723:    /* XXX: Why is this Opaque specific? Either our core code is deficient
                   1724:     * and this should be fixed generally, or Opaque is inventing strawman
                   1725:     * problems */
                   1726:    ospf_opaque_adjust_lsreq (nbr, lsas);
                   1727: #endif /* HAVE_OPAQUE_LSA */
                   1728: 
                   1729: #define DISCARD_LSA(L,N) {\
                   1730:         if (IS_DEBUG_OSPF_EVENT) \
                   1731:           zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
                   1732:         ospf_lsa_discard (L); \
                   1733:        continue; }
                   1734: 
                   1735:   /* Process each LSA received in the one packet. */
                   1736:   for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
                   1737:     {
                   1738:       struct ospf_lsa *ls_ret, *current;
                   1739:       int ret = 1;
                   1740: 
                   1741:       if (IS_DEBUG_OSPF_NSSA)
                   1742:        {
                   1743:          char buf1[INET_ADDRSTRLEN];
                   1744:          char buf2[INET_ADDRSTRLEN];
                   1745:          char buf3[INET_ADDRSTRLEN];
                   1746: 
                   1747:          zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
                   1748:                  lsa->data->type,
                   1749:                  inet_ntop (AF_INET, &ospfh->router_id,
                   1750:                             buf1, INET_ADDRSTRLEN),
                   1751:                  inet_ntop (AF_INET, &lsa->data->id,
                   1752:                             buf2, INET_ADDRSTRLEN),
                   1753:                  inet_ntop (AF_INET, &lsa->data->adv_router,
                   1754:                             buf3, INET_ADDRSTRLEN));
                   1755:        }
                   1756: 
                   1757:       listnode_delete (lsas, lsa); /* We don't need it in list anymore */
                   1758: 
                   1759:       /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
                   1760: 
                   1761:       /* LSA Type  - Done above by ospf_ls_upd_list_lsa() */
                   1762:    
                   1763:       /* Do not take in AS External LSAs if we are a stub or NSSA. */
                   1764: 
                   1765:       /* Do not take in AS NSSA if this neighbor and we are not NSSA */
                   1766: 
                   1767:       /* Do take in Type-7's if we are an NSSA  */ 
                   1768:  
                   1769:       /* If we are also an ABR, later translate them to a Type-5 packet */
                   1770:  
                   1771:       /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
                   1772:         translate them to a separate Type-5 packet.  */
                   1773: 
                   1774:       if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
                   1775:         /* Reject from STUB or NSSA */
                   1776:         if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT) 
                   1777:          {
                   1778:            if (IS_DEBUG_OSPF_NSSA)
                   1779:              zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
                   1780:            DISCARD_LSA (lsa, 1);
                   1781:          }
                   1782: 
                   1783:       if (lsa->data->type == OSPF_AS_NSSA_LSA)
                   1784:        if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
                   1785:          {
                   1786:            if (IS_DEBUG_OSPF_NSSA)
                   1787:              zlog_debug("Incoming NSSA LSA Discarded:  Not NSSA Area");
                   1788:            DISCARD_LSA (lsa,2);
                   1789:          }
                   1790: 
                   1791:       /* Find the LSA in the current database. */
                   1792: 
                   1793:       current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
                   1794: 
                   1795:       /* If the LSA's LS age is equal to MaxAge, and there is currently
                   1796:         no instance of the LSA in the router's link state database,
                   1797:         and none of router's neighbors are in states Exchange or Loading,
                   1798:         then take the following actions. */
                   1799: 
                   1800:       if (IS_LSA_MAXAGE (lsa) && !current &&
                   1801:          (ospf_nbr_count (oi, NSM_Exchange) +
                   1802:           ospf_nbr_count (oi, NSM_Loading)) == 0)
                   1803:        {
                   1804:          /* Response Link State Acknowledgment. */
                   1805:          ospf_ls_ack_send (nbr, lsa);
                   1806: 
                   1807:          /* Discard LSA. */      
                   1808:          zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
                   1809:                     dump_lsa_key(lsa));
                   1810:           DISCARD_LSA (lsa, 3);
                   1811:        }
                   1812: 
                   1813: #ifdef HAVE_OPAQUE_LSA
                   1814:       if (IS_OPAQUE_LSA (lsa->data->type)
                   1815:       &&  IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
                   1816:         {
                   1817:           /*
                   1818:            * Even if initial flushing seems to be completed, there might
                   1819:            * be a case that self-originated LSA with MaxAge still remain
                   1820:            * in the routing domain.
                   1821:            * Just send an LSAck message to cease retransmission.
                   1822:            */
                   1823:           if (IS_LSA_MAXAGE (lsa))
                   1824:             {
                   1825:               zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
                   1826:               ospf_ls_ack_send (nbr, lsa);
                   1827:               ospf_lsa_discard (lsa);
                   1828: 
                   1829:               if (current != NULL && ! IS_LSA_MAXAGE (current))
                   1830:                 ospf_opaque_lsa_refresh_schedule (current);
                   1831:               continue;
                   1832:             }
                   1833: 
                   1834:           /*
                   1835:            * If an instance of self-originated Opaque-LSA is not found
                   1836:            * in the LSDB, there are some possible cases here.
                   1837:            *
                   1838:            * 1) This node lost opaque-capability after restart.
                   1839:            * 2) Else, a part of opaque-type is no more supported.
                   1840:            * 3) Else, a part of opaque-id is no more supported.
                   1841:            *
                   1842:            * Anyway, it is still this node's responsibility to flush it.
                   1843:            * Otherwise, the LSA instance remains in the routing domain
                   1844:            * until its age reaches to MaxAge.
                   1845:            */
                   1846:           /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
                   1847:           if (current == NULL)
                   1848:             {
                   1849:               if (IS_DEBUG_OSPF_EVENT)
                   1850:                 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
                   1851:                             "not found in the LSDB.", dump_lsa_key (lsa));
                   1852: 
                   1853:               SET_FLAG (lsa->flags, OSPF_LSA_SELF);
                   1854:               
                   1855:               ospf_opaque_self_originated_lsa_received (nbr, lsa);
                   1856:               ospf_ls_ack_send (nbr, lsa);
                   1857:               
                   1858:               continue;
                   1859:             }
                   1860:         }
                   1861: #endif /* HAVE_OPAQUE_LSA */
                   1862: 
                   1863:       /* It might be happen that received LSA is self-originated network LSA, but
                   1864:        * router ID is cahnged. So, we should check if LSA is a network-LSA whose
                   1865:        * Link State ID is one of the router's own IP interface addresses but whose
                   1866:        * Advertising Router is not equal to the router's own Router ID
                   1867:        * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
                   1868:        */
                   1869: 
                   1870:       if(lsa->data->type == OSPF_NETWORK_LSA)
                   1871:       {
                   1872:         struct listnode *oinode, *oinnode;
                   1873:         struct ospf_interface *out_if;
                   1874:         int Flag = 0;
                   1875: 
                   1876:         for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
                   1877:         {
                   1878:           if(out_if == NULL)
                   1879:             break;
                   1880: 
                   1881:           if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
                   1882:               (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
                   1883:           {
                   1884:             if(out_if->network_lsa_self)
                   1885:             {
                   1886:               ospf_lsa_flush_area(lsa,out_if->area);
                   1887:               if(IS_DEBUG_OSPF_EVENT)
                   1888:                 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
                   1889:                             lsa, (int) lsa->data->type);
                   1890:               ospf_lsa_discard (lsa);
                   1891:               Flag = 1;
                   1892:             }
                   1893:             break;
                   1894:           }
                   1895:         }
                   1896:         if(Flag)
                   1897:           continue;
                   1898:       }
                   1899: 
                   1900:       /* (5) Find the instance of this LSA that is currently contained
                   1901:         in the router's link state database.  If there is no
                   1902:         database copy, or the received LSA is more recent than
                   1903:         the database copy the following steps must be performed. */
                   1904: 
                   1905:       if (current == NULL ||
                   1906:          (ret = ospf_lsa_more_recent (current, lsa)) < 0)
                   1907:        {
                   1908:          /* Actual flooding procedure. */
                   1909:          if (ospf_flood (oi->ospf, nbr, current, lsa) < 0)  /* Trap NSSA later. */
                   1910:            DISCARD_LSA (lsa, 4);
                   1911:          continue;
                   1912:        }
                   1913: 
                   1914:       /* (6) Else, If there is an instance of the LSA on the sending
                   1915:         neighbor's Link state request list, an error has occurred in
                   1916:         the Database Exchange process.  In this case, restart the
                   1917:         Database Exchange process by generating the neighbor event
                   1918:         BadLSReq for the sending neighbor and stop processing the
                   1919:         Link State Update packet. */
                   1920: 
                   1921:       if (ospf_ls_request_lookup (nbr, lsa))
                   1922:        {
                   1923:          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
                   1924:          zlog_warn("LSA[%s] instance exists on Link state request list",
                   1925:                    dump_lsa_key(lsa));
                   1926: 
                   1927:          /* Clean list of LSAs. */
                   1928:           ospf_upd_list_clean (lsas);
                   1929:          /* this lsa is not on lsas list already. */
                   1930:          ospf_lsa_discard (lsa);
                   1931:          return;
                   1932:        }
                   1933: 
                   1934:       /* If the received LSA is the same instance as the database copy
                   1935:         (i.e., neither one is more recent) the following two steps
                   1936:         should be performed: */
                   1937: 
                   1938:       if (ret == 0)
                   1939:        {
                   1940:          /* If the LSA is listed in the Link state retransmission list
                   1941:             for the receiving adjacency, the router itself is expecting
                   1942:             an acknowledgment for this LSA.  The router should treat the
                   1943:             received LSA as an acknowledgment by removing the LSA from
                   1944:             the Link state retransmission list.  This is termed an
                   1945:             "implied acknowledgment". */
                   1946: 
                   1947:          ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
                   1948: 
                   1949:          if (ls_ret != NULL)
                   1950:            {
                   1951:              ospf_ls_retransmit_delete (nbr, ls_ret);
                   1952: 
                   1953:              /* Delayed acknowledgment sent if advertisement received
                   1954:                 from Designated Router, otherwise do nothing. */
                   1955:              if (oi->state == ISM_Backup)
                   1956:                if (NBR_IS_DR (nbr))
                   1957:                  listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
                   1958: 
                   1959:               DISCARD_LSA (lsa, 5);
                   1960:            }
                   1961:          else
                   1962:            /* Acknowledge the receipt of the LSA by sending a
                   1963:               Link State Acknowledgment packet back out the receiving
                   1964:               interface. */
                   1965:            {
                   1966:              ospf_ls_ack_send (nbr, lsa);
                   1967:              DISCARD_LSA (lsa, 6);
                   1968:            }
                   1969:        }
                   1970: 
                   1971:       /* The database copy is more recent.  If the database copy
                   1972:         has LS age equal to MaxAge and LS sequence number equal to
                   1973:         MaxSequenceNumber, simply discard the received LSA without
                   1974:         acknowledging it. (In this case, the LSA's LS sequence number is
                   1975:         wrapping, and the MaxSequenceNumber LSA must be completely
                   1976:         flushed before any new LSA instance can be introduced). */
                   1977: 
                   1978:       else if (ret > 0)  /* Database copy is more recent */
                   1979:        { 
                   1980:          if (IS_LSA_MAXAGE (current) &&
                   1981:              current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
                   1982:            {
                   1983:              DISCARD_LSA (lsa, 7);
                   1984:            }
                   1985:          /* Otherwise, as long as the database copy has not been sent in a
                   1986:             Link State Update within the last MinLSArrival seconds, send the
                   1987:             database copy back to the sending neighbor, encapsulated within
                   1988:             a Link State Update Packet. The Link State Update Packet should
                   1989:             be sent directly to the neighbor. In so doing, do not put the
                   1990:             database copy of the LSA on the neighbor's link state
                   1991:             retransmission list, and do not acknowledge the received (less
                   1992:             recent) LSA instance. */
                   1993:          else
                   1994:            {
                   1995:              struct timeval now;
                   1996:              
                   1997:              quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                   1998:              
                   1999:              if (tv_cmp (tv_sub (now, current->tv_orig), 
                   2000:                          int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
                   2001:                /* Trap NSSA type later.*/
                   2002:                ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
                   2003:              DISCARD_LSA (lsa, 8);
                   2004:            }
                   2005:        }
                   2006:     }
                   2007: #undef DISCARD_LSA
                   2008: 
                   2009:   assert (listcount (lsas) == 0);
                   2010:   list_delete (lsas);
                   2011: }
                   2012: 
                   2013: /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
                   2014: static void
                   2015: ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
                   2016:             struct stream *s, struct ospf_interface *oi, u_int16_t size)
                   2017: {
                   2018:   struct ospf_neighbor *nbr;
                   2019:   
                   2020:   /* increment statistics. */
                   2021:   oi->ls_ack_in++;
                   2022: 
                   2023:   nbr = ospf_nbr_lookup (oi, iph, ospfh);
                   2024:   if (nbr == NULL)
                   2025:     {
                   2026:       zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
                   2027:                 inet_ntoa (ospfh->router_id));
                   2028:       return;
                   2029:     }
                   2030: 
                   2031:   /* Add event to thread. */
                   2032:   OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
                   2033: 
                   2034:   if (nbr->state < NSM_Exchange)
                   2035:     {
                   2036:       zlog_warn ("Link State Acknowledgment: "
                   2037:                 "Neighbor[%s] state %s is less than Exchange",
                   2038:                 inet_ntoa (ospfh->router_id),
                   2039:                 LOOKUP(ospf_nsm_state_msg, nbr->state));
                   2040:       return;
                   2041:     }
                   2042:   
                   2043:   while (size >= OSPF_LSA_HEADER_SIZE)
                   2044:     {
                   2045:       struct ospf_lsa *lsa, *lsr;
                   2046: 
                   2047:       lsa = ospf_lsa_new ();
                   2048:       lsa->data = (struct lsa_header *) STREAM_PNT (s);
                   2049: 
                   2050:       /* lsah = (struct lsa_header *) STREAM_PNT (s); */
                   2051:       size -= OSPF_LSA_HEADER_SIZE;
                   2052:       stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
                   2053: 
                   2054:       if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
                   2055:        {
                   2056:          lsa->data = NULL;
                   2057:          ospf_lsa_discard (lsa);
                   2058:          continue;
                   2059:        }
                   2060: 
                   2061:       lsr = ospf_ls_retransmit_lookup (nbr, lsa);
                   2062: 
                   2063:       if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
                   2064:         {
                   2065: #ifdef HAVE_OPAQUE_LSA
                   2066:           if (IS_OPAQUE_LSA (lsr->data->type))
                   2067:             ospf_opaque_ls_ack_received (nbr, lsr);
                   2068: #endif /* HAVE_OPAQUE_LSA */
                   2069: 
                   2070:           ospf_ls_retransmit_delete (nbr, lsr);
                   2071:         }
                   2072: 
                   2073:       lsa->data = NULL;
                   2074:       ospf_lsa_discard (lsa);
                   2075:     }
                   2076: 
                   2077:   return;
                   2078: }
                   2079: 
                   2080: static struct stream *
                   2081: ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
                   2082: {
                   2083:   int ret;
                   2084:   struct ip *iph;
                   2085:   u_int16_t ip_len;
                   2086:   unsigned int ifindex = 0;
                   2087:   struct iovec iov;
                   2088:   /* Header and data both require alignment. */
                   2089:   char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
                   2090:   struct msghdr msgh;
                   2091: 
                   2092:   memset (&msgh, 0, sizeof (struct msghdr));
                   2093:   msgh.msg_iov = &iov;
                   2094:   msgh.msg_iovlen = 1;
                   2095:   msgh.msg_control = (caddr_t) buff;
                   2096:   msgh.msg_controllen = sizeof (buff);
                   2097:   
                   2098:   ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
                   2099:   if (ret < 0)
                   2100:     {
                   2101:       zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
                   2102:       return NULL;
                   2103:     }
                   2104:   if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
                   2105:     {
                   2106:       zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
                   2107:                "(ip header size is %u)",
                   2108:                ret, (u_int)sizeof(iph));
                   2109:       return NULL;
                   2110:     }
                   2111:   
                   2112:   /* Note that there should not be alignment problems with this assignment
                   2113:      because this is at the beginning of the stream data buffer. */
                   2114:   iph = (struct ip *) STREAM_DATA(ibuf);
                   2115:   sockopt_iphdrincl_swab_systoh (iph);
                   2116:   
                   2117:   ip_len = iph->ip_len;
                   2118:   
                   2119: #if !defined(GNU_LINUX) && (OpenBSD < 200311)
                   2120:   /*
                   2121:    * Kernel network code touches incoming IP header parameters,
                   2122:    * before protocol specific processing.
                   2123:    *
                   2124:    *   1) Convert byteorder to host representation.
                   2125:    *      --> ip_len, ip_id, ip_off
                   2126:    *
                   2127:    *   2) Adjust ip_len to strip IP header size!
                   2128:    *      --> If user process receives entire IP packet via RAW
                   2129:    *          socket, it must consider adding IP header size to
                   2130:    *          the "ip_len" field of "ip" structure.
                   2131:    *
                   2132:    * For more details, see <netinet/ip_input.c>.
                   2133:    */
                   2134:   ip_len = ip_len + (iph->ip_hl << 2);
                   2135: #endif
                   2136:   
                   2137: #if defined(__DragonFly__)
                   2138:   /*
                   2139:    * in DragonFly's raw socket, ip_len/ip_off are read 
                   2140:    * in network byte order.
                   2141:    * As OpenBSD < 200311 adjust ip_len to strip IP header size!
                   2142:    */
                   2143:   ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
                   2144: #endif
                   2145: 
                   2146:   ifindex = getsockopt_ifindex (AF_INET, &msgh);
                   2147:   
                   2148:   *ifp = if_lookup_by_index (ifindex);
                   2149: 
                   2150:   if (ret != ip_len)
                   2151:     {
                   2152:       zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
                   2153:                         "but recvmsg returned %d", ip_len, ret);
                   2154:       return NULL;
                   2155:     }
                   2156:   
                   2157:   return ibuf;
                   2158: }
                   2159: 
                   2160: static struct ospf_interface *
                   2161: ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp, 
                   2162:                          struct ip *iph, struct ospf_header *ospfh)
                   2163: {
                   2164:   struct ospf_interface *rcv_oi;
                   2165:   struct ospf_vl_data *vl_data;
                   2166:   struct ospf_area *vl_area;
                   2167:   struct listnode *node;
                   2168: 
                   2169:   if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
                   2170:       !OSPF_IS_AREA_BACKBONE (ospfh))
                   2171:     return NULL;
                   2172: 
                   2173:   /* look for local OSPF interface matching the destination
                   2174:    * to determine Area ID. We presume therefore the destination address
                   2175:    * is unique, or at least (for "unnumbered" links), not used in other 
                   2176:    * areas
                   2177:    */
                   2178:   if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL, 
                   2179:                                               iph->ip_dst)) == NULL)
                   2180:     return NULL;
                   2181: 
                   2182:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
                   2183:     {
                   2184:       vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
                   2185:       if (!vl_area)
                   2186:        continue;
                   2187:       
                   2188:       if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
                   2189:          IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
                   2190:        {
                   2191:          if (IS_DEBUG_OSPF_EVENT)
                   2192:            zlog_debug ("associating packet with %s",
                   2193:                       IF_NAME (vl_data->vl_oi));
                   2194:          if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
                   2195:            {
                   2196:              if (IS_DEBUG_OSPF_EVENT)
                   2197:                zlog_debug ("This VL is not up yet, sorry");
                   2198:              return NULL;
                   2199:            }
                   2200:          
                   2201:          return vl_data->vl_oi;
                   2202:        }
                   2203:     }
                   2204: 
                   2205:   if (IS_DEBUG_OSPF_EVENT)
                   2206:     zlog_debug ("couldn't find any VL to associate the packet with");
                   2207:   
                   2208:   return NULL;
                   2209: }
                   2210: 
                   2211: static inline int
                   2212: ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
                   2213: {
                   2214:   /* Check match the Area ID of the receiving interface. */
                   2215:   if (OSPF_AREA_SAME (&oi->area, &ospfh))
                   2216:     return 1;
                   2217: 
                   2218:   return 0;
                   2219: }
                   2220: 
                   2221: /* Unbound socket will accept any Raw IP packets if proto is matched.
                   2222:    To prevent it, compare src IP address and i/f address with masking
                   2223:    i/f network mask. */
                   2224: static int
                   2225: ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
                   2226: {
                   2227:   struct in_addr mask, me, him;
                   2228: 
                   2229:   if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
                   2230:       oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   2231:     return 1;
                   2232: 
                   2233:   masklen2ip (oi->address->prefixlen, &mask);
                   2234: 
                   2235:   me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
                   2236:   him.s_addr = ip_src.s_addr & mask.s_addr;
                   2237: 
                   2238:  if (IPV4_ADDR_SAME (&me, &him))
                   2239:    return 1;
                   2240: 
                   2241:  return 0;
                   2242: }
                   2243: 
                   2244: static int
                   2245: ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
                   2246:                 struct ospf_header *ospfh)
                   2247: {
                   2248:   int ret = 0;
                   2249:   struct crypt_key *ck;
                   2250: 
                   2251:   switch (ntohs (ospfh->auth_type))
                   2252:     {
                   2253:     case OSPF_AUTH_NULL:
                   2254:       ret = 1;
                   2255:       break;
                   2256:     case OSPF_AUTH_SIMPLE:
                   2257:       if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
                   2258:        ret = 1;
                   2259:       else
                   2260:        ret = 0;
                   2261:       break;
                   2262:     case OSPF_AUTH_CRYPTOGRAPHIC:
                   2263:       if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
                   2264:        {
                   2265:          ret = 0;
                   2266:          break;
                   2267:        }
                   2268:       
                   2269:       /* This is very basic, the digest processing is elsewhere */
                   2270:       if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE && 
                   2271:           ospfh->u.crypt.key_id == ck->key_id &&
                   2272:           ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
                   2273:         ret = 1;
                   2274:       else
                   2275:         ret = 0;
                   2276:       break;
                   2277:     default:
                   2278:       ret = 0;
                   2279:       break;
                   2280:     }
                   2281: 
                   2282:   return ret;
                   2283: }
                   2284: 
                   2285: static int
                   2286: ospf_check_sum (struct ospf_header *ospfh)
                   2287: {
                   2288:   u_int32_t ret;
                   2289:   u_int16_t sum;
                   2290: 
                   2291:   /* clear auth_data for checksum. */
                   2292:   memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
                   2293: 
                   2294:   /* keep checksum and clear. */
                   2295:   sum = ospfh->checksum;
                   2296:   memset (&ospfh->checksum, 0, sizeof (u_int16_t));
                   2297: 
                   2298:   /* calculate checksum. */
                   2299:   ret = in_cksum (ospfh, ntohs (ospfh->length));
                   2300: 
                   2301:   if (ret != sum)
                   2302:     {
                   2303:       zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
                   2304:                 ret, sum);
                   2305:       return 0;
                   2306:     }
                   2307: 
                   2308:   return 1;
                   2309: }
                   2310: 
                   2311: /* OSPF Header verification. */
                   2312: static int
                   2313: ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
                   2314:                    struct ip *iph, struct ospf_header *ospfh)
                   2315: {
                   2316:   /* check version. */
                   2317:   if (ospfh->version != OSPF_VERSION)
                   2318:     {
                   2319:       zlog_warn ("interface %s: ospf_read version number mismatch.",
                   2320:                 IF_NAME (oi));
                   2321:       return -1;
                   2322:     }
                   2323: 
                   2324:   /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
                   2325:   if (ospfh->type < 1 || ospfh->type > 5)
                   2326:   {
                   2327:     zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
                   2328:     return -1;
                   2329:   }
                   2330: 
                   2331:   /* Check Area ID. */
                   2332:   if (!ospf_check_area_id (oi, ospfh))
                   2333:     {
                   2334:       zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
                   2335:                 IF_NAME (oi), inet_ntoa (ospfh->area_id));
                   2336:       return -1;
                   2337:     }
                   2338: 
                   2339:   /* Check network mask, Silently discarded. */
                   2340:   if (! ospf_check_network_mask (oi, iph->ip_src))
                   2341:     {
                   2342:       zlog_warn ("interface %s: ospf_read network address is not same [%s]",
                   2343:                 IF_NAME (oi), inet_ntoa (iph->ip_src));
                   2344:       return -1;
                   2345:     }
                   2346: 
                   2347:   /* Check authentication. */
                   2348:   if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
                   2349:     {
                   2350:       zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
                   2351:                 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
                   2352:       return -1;
                   2353:     }
                   2354: 
                   2355:   if (! ospf_check_auth (oi, ibuf, ospfh))
                   2356:     {
                   2357:       zlog_warn ("interface %s: ospf_read authentication failed.",
                   2358:                 IF_NAME (oi));
                   2359:       return -1;
                   2360:     }
                   2361: 
                   2362:   /* if check sum is invalid, packet is discarded. */
                   2363:   if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
                   2364:     {
                   2365:       if (! ospf_check_sum (ospfh))
                   2366:        {
                   2367:          zlog_warn ("interface %s: ospf_read packet checksum error %s",
                   2368:                     IF_NAME (oi), inet_ntoa (ospfh->router_id));
                   2369:          return -1;
                   2370:        }
                   2371:     }
                   2372:   else
                   2373:     {
                   2374:       if (ospfh->checksum != 0)
                   2375:        return -1;
                   2376:       if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
                   2377:        {
                   2378:          zlog_warn ("interface %s: ospf_read md5 authentication failed.",
                   2379:                     IF_NAME (oi));
                   2380:          return -1;
                   2381:        }
                   2382:     }
                   2383: 
                   2384:   return 0;
                   2385: }
                   2386: 
                   2387: /* Starting point of packet process function. */
                   2388: int
                   2389: ospf_read (struct thread *thread)
                   2390: {
                   2391:   int ret;
                   2392:   struct stream *ibuf;
                   2393:   struct ospf *ospf;
                   2394:   struct ospf_interface *oi;
                   2395:   struct ip *iph;
                   2396:   struct ospf_header *ospfh;
                   2397:   u_int16_t length;
                   2398:   struct interface *ifp;
                   2399: 
                   2400:   /* first of all get interface pointer. */
                   2401:   ospf = THREAD_ARG (thread);
                   2402: 
                   2403:   /* prepare for next packet. */
                   2404:   ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
                   2405: 
                   2406:   /* read OSPF packet. */
                   2407:   stream_reset(ospf->ibuf);
                   2408:   if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
                   2409:     return -1;
                   2410:   
                   2411:   /* Note that there should not be alignment problems with this assignment
                   2412:      because this is at the beginning of the stream data buffer. */
                   2413:   iph = (struct ip *) STREAM_DATA (ibuf);
                   2414:   /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
                   2415: 
                   2416:   if (ifp == NULL)
                   2417:     /* Handle cases where the platform does not support retrieving the ifindex,
                   2418:        and also platforms (such as Solaris 8) that claim to support ifindex
                   2419:        retrieval but do not. */
                   2420:     ifp = if_lookup_address (iph->ip_src);
                   2421:   
                   2422:   if (ifp == NULL)
                   2423:     return 0;
                   2424: 
                   2425:   /* IP Header dump. */
                   2426:     if (IS_DEBUG_OSPF_PACKET(0, RECV))
                   2427:            ospf_ip_header_dump (iph);
                   2428: 
                   2429:   /* Self-originated packet should be discarded silently. */
                   2430:   if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
                   2431:     {
                   2432:       if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2433:         {
                   2434:           zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
                   2435:                      inet_ntoa (iph->ip_src));
                   2436:         }
                   2437:       return 0;
                   2438:     }
                   2439: 
                   2440:   /* Advance from IP header to OSPF header (iph->ip_hl has been verified
                   2441:      by ospf_recv_packet() to be correct). */
                   2442:   stream_forward_getp (ibuf, iph->ip_hl * 4);
                   2443: 
                   2444:   /* Make sure the OSPF header is really there. */
                   2445:   if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE)
                   2446:   {
                   2447:     zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header",
                   2448:                 stream_get_endp (ibuf) - stream_get_getp (ibuf));
                   2449:     return -1;
                   2450:   }
                   2451: 
                   2452:   /* Now it is safe to access all fields of OSPF packet header. */
                   2453:   ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
                   2454: 
                   2455:   /* associate packet with ospf interface */
                   2456:   oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
                   2457: 
                   2458:   /* ospf_verify_header() relies on a valid "oi" and thus can be called only
                   2459:      after the passive/backbone/other checks below are passed. These checks
                   2460:      in turn access the fields of unverified "ospfh" structure for their own
                   2461:      purposes and must remain very accurate in doing this. */
                   2462: 
                   2463:   /* If incoming interface is passive one, ignore it. */
                   2464:   if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
                   2465:     {
                   2466:       char buf[3][INET_ADDRSTRLEN];
                   2467: 
                   2468:       if (IS_DEBUG_OSPF_EVENT)
                   2469:        zlog_debug ("ignoring packet from router %s sent to %s, "
                   2470:                    "received on a passive interface, %s",
                   2471:                    inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
                   2472:                    inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
                   2473:                    inet_ntop(AF_INET, &oi->address->u.prefix4,
                   2474:                              buf[2], sizeof(buf[2])));
                   2475: 
                   2476:       if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
                   2477:        {
                   2478:          /* Try to fix multicast membership.
                   2479:           * Some OS:es may have problems in this area,
                   2480:           * make sure it is removed.
                   2481:           */
                   2482:          OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
                   2483:          ospf_if_set_multicast(oi);
                   2484:        }
                   2485:       return 0;
                   2486:   }
                   2487: 
                   2488: 
                   2489:   /* if no local ospf_interface, 
                   2490:    * or header area is backbone but ospf_interface is not
                   2491:    * check for VLINK interface
                   2492:    */
                   2493:   if ( (oi == NULL) ||
                   2494:       (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
                   2495:       && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
                   2496:      )
                   2497:     {
                   2498:       if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
                   2499:         {
                   2500:           if (IS_DEBUG_OSPF_EVENT)
                   2501:             zlog_debug ("Packet from [%s] received on link %s"
                   2502:                         " but no ospf_interface",
                   2503:                         inet_ntoa (iph->ip_src), ifp->name);
                   2504:           return 0;
                   2505:         }
                   2506:     }
                   2507: 
                   2508:   /* else it must be a local ospf interface, check it was received on 
                   2509:    * correct link 
                   2510:    */
                   2511:   else if (oi->ifp != ifp)
                   2512:     {
                   2513:       if (IS_DEBUG_OSPF_EVENT)
                   2514:         zlog_warn ("Packet from [%s] received on wrong link %s",
                   2515:                    inet_ntoa (iph->ip_src), ifp->name); 
                   2516:       return 0;
                   2517:     }
                   2518:   else if (oi->state == ISM_Down)
                   2519:     {
                   2520:       char buf[2][INET_ADDRSTRLEN];
                   2521:       zlog_warn ("Ignoring packet from %s to %s received on interface that is "
                   2522:                 "down [%s]; interface flags are %s",
                   2523:                 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
                   2524:                 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
                   2525:                 ifp->name, if_flag_dump(ifp->flags));
                   2526:       /* Fix multicast memberships? */
                   2527:       if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
                   2528:         OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
                   2529:       else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
                   2530:        OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
                   2531:       if (oi->multicast_memberships)
                   2532:        ospf_if_set_multicast(oi);
                   2533:       return 0;
                   2534:     }
                   2535: 
                   2536:   /*
                   2537:    * If the received packet is destined for AllDRouters, the packet
                   2538:    * should be accepted only if the received ospf interface state is
                   2539:    * either DR or Backup -- endo.
                   2540:    */
                   2541:   if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
                   2542:   && (oi->state != ISM_DR && oi->state != ISM_Backup))
                   2543:     {
                   2544:       zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
                   2545:                  inet_ntoa (iph->ip_src), IF_NAME (oi),
                   2546:                  LOOKUP (ospf_ism_state_msg, oi->state));
                   2547:       /* Try to fix multicast membership. */
                   2548:       SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
                   2549:       ospf_if_set_multicast(oi);
                   2550:       return 0;
                   2551:     }
                   2552: 
                   2553:   /* Verify more OSPF header fields. */
                   2554:   ret = ospf_verify_header (ibuf, oi, iph, ospfh);
                   2555:   if (ret < 0)
                   2556:   {
                   2557:     if (IS_DEBUG_OSPF_PACKET (0, RECV))
                   2558:       zlog_debug ("ospf_read[%s]: Header check failed, "
                   2559:                   "dropping.",
                   2560:                   inet_ntoa (iph->ip_src));
                   2561:     return ret;
                   2562:   }
                   2563: 
                   2564:   /* Show debug receiving packet. */
                   2565:   if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
                   2566:     {
                   2567:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
                   2568:         {
                   2569:           zlog_debug ("-----------------------------------------------------");
                   2570:           ospf_packet_dump (ibuf);
                   2571:         }
                   2572: 
                   2573:       zlog_debug ("%s received from [%s] via [%s]",
                   2574:                  ospf_packet_type_str[ospfh->type],
                   2575:                  inet_ntoa (ospfh->router_id), IF_NAME (oi));
                   2576:       zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
                   2577:       zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
                   2578: 
                   2579:       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
                   2580:        zlog_debug ("-----------------------------------------------------");
                   2581:   }
                   2582: 
                   2583:   stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
                   2584: 
                   2585:   /* Adjust size to message length. */
                   2586:   length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
                   2587: 
                   2588:   /* Read rest of the packet and call each sort of packet routine. */
                   2589:   switch (ospfh->type)
                   2590:     {
                   2591:     case OSPF_MSG_HELLO:
                   2592:       ospf_hello (iph, ospfh, ibuf, oi, length);
                   2593:       break;
                   2594:     case OSPF_MSG_DB_DESC:
                   2595:       ospf_db_desc (iph, ospfh, ibuf, oi, length);
                   2596:       break;
                   2597:     case OSPF_MSG_LS_REQ:
                   2598:       ospf_ls_req (iph, ospfh, ibuf, oi, length);
                   2599:       break;
                   2600:     case OSPF_MSG_LS_UPD:
                   2601:       ospf_ls_upd (iph, ospfh, ibuf, oi, length);
                   2602:       break;
                   2603:     case OSPF_MSG_LS_ACK:
                   2604:       ospf_ls_ack (iph, ospfh, ibuf, oi, length);
                   2605:       break;
                   2606:     default:
                   2607:       zlog (NULL, LOG_WARNING,
                   2608:            "interface %s: OSPF packet header type %d is illegal",
                   2609:            IF_NAME (oi), ospfh->type);
                   2610:       break;
                   2611:     }
                   2612: 
                   2613:   return 0;
                   2614: }
                   2615: 
                   2616: /* Make OSPF header. */
                   2617: static void
                   2618: ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
                   2619: {
                   2620:   struct ospf_header *ospfh;
                   2621: 
                   2622:   ospfh = (struct ospf_header *) STREAM_DATA (s);
                   2623: 
                   2624:   ospfh->version = (u_char) OSPF_VERSION;
                   2625:   ospfh->type = (u_char) type;
                   2626: 
                   2627:   ospfh->router_id = oi->ospf->router_id;
                   2628: 
                   2629:   ospfh->checksum = 0;
                   2630:   ospfh->area_id = oi->area->area_id;
                   2631:   ospfh->auth_type = htons (ospf_auth_type (oi));
                   2632: 
                   2633:   memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
                   2634: 
                   2635:   stream_forward_endp (s, OSPF_HEADER_SIZE);
                   2636: }
                   2637: 
                   2638: /* Make Authentication Data. */
                   2639: static int
                   2640: ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
                   2641: {
                   2642:   struct crypt_key *ck;
                   2643: 
                   2644:   switch (ospf_auth_type (oi))
                   2645:     {
                   2646:     case OSPF_AUTH_NULL:
                   2647:       /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
                   2648:       break;
                   2649:     case OSPF_AUTH_SIMPLE:
                   2650:       memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
                   2651:              OSPF_AUTH_SIMPLE_SIZE);
                   2652:       break;
                   2653:     case OSPF_AUTH_CRYPTOGRAPHIC:
                   2654:       /* If key is not set, then set 0. */
                   2655:       if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
                   2656:        {
                   2657:          ospfh->u.crypt.zero = 0;
                   2658:          ospfh->u.crypt.key_id = 0;
                   2659:          ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
                   2660:        }
                   2661:       else
                   2662:        {
                   2663:          ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
                   2664:          ospfh->u.crypt.zero = 0;
                   2665:          ospfh->u.crypt.key_id = ck->key_id;
                   2666:          ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
                   2667:        }
                   2668:       /* note: the seq is done in ospf_make_md5_digest() */
                   2669:       break;
                   2670:     default:
                   2671:       /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
                   2672:       break;
                   2673:     }
                   2674: 
                   2675:   return 0;
                   2676: }
                   2677: 
                   2678: /* Fill rest of OSPF header. */
                   2679: static void
                   2680: ospf_fill_header (struct ospf_interface *oi,
                   2681:                  struct stream *s, u_int16_t length)
                   2682: {
                   2683:   struct ospf_header *ospfh;
                   2684: 
                   2685:   ospfh = (struct ospf_header *) STREAM_DATA (s);
                   2686: 
                   2687:   /* Fill length. */
                   2688:   ospfh->length = htons (length);
                   2689: 
                   2690:   /* Calculate checksum. */
                   2691:   if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
                   2692:     ospfh->checksum = in_cksum (ospfh, length);
                   2693:   else
                   2694:     ospfh->checksum = 0;
                   2695: 
                   2696:   /* Add Authentication Data. */
                   2697:   ospf_make_auth (oi, ospfh);
                   2698: }
                   2699: 
                   2700: static int
                   2701: ospf_make_hello (struct ospf_interface *oi, struct stream *s)
                   2702: {
                   2703:   struct ospf_neighbor *nbr;
                   2704:   struct route_node *rn;
                   2705:   u_int16_t length = OSPF_HELLO_MIN_SIZE;
                   2706:   struct in_addr mask;
                   2707:   unsigned long p;
                   2708:   int flag = 0;
                   2709: 
                   2710:   /* Set netmask of interface. */
                   2711:   if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
                   2712:       oi->type != OSPF_IFTYPE_VIRTUALLINK)
                   2713:     masklen2ip (oi->address->prefixlen, &mask);
                   2714:   else
                   2715:     memset ((char *) &mask, 0, sizeof (struct in_addr));
                   2716:   stream_put_ipv4 (s, mask.s_addr);
                   2717: 
                   2718:   /* Set Hello Interval. */
                   2719:   if (OSPF_IF_PARAM (oi, fast_hello) == 0)
                   2720:     stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
                   2721:   else
                   2722:     stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
                   2723: 
                   2724:   if (IS_DEBUG_OSPF_EVENT)
                   2725:     zlog_debug ("make_hello: options: %x, int: %s",
                   2726:               OPTIONS(oi), IF_NAME (oi));
                   2727: 
                   2728:   /* Set Options. */
                   2729:   stream_putc (s, OPTIONS (oi));
                   2730: 
                   2731:   /* Set Router Priority. */
                   2732:   stream_putc (s, PRIORITY (oi));
                   2733: 
                   2734:   /* Set Router Dead Interval. */
                   2735:   stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
                   2736: 
                   2737:   /* Set Designated Router. */
                   2738:   stream_put_ipv4 (s, DR (oi).s_addr);
                   2739: 
                   2740:   p = stream_get_endp (s);
                   2741: 
                   2742:   /* Set Backup Designated Router. */
                   2743:   stream_put_ipv4 (s, BDR (oi).s_addr);
                   2744: 
                   2745:   /* Add neighbor seen. */
                   2746:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   2747:     if ((nbr = rn->info))
                   2748:       if (nbr->router_id.s_addr != 0)  /* Ignore 0.0.0.0 node. */
                   2749:        if (nbr->state != NSM_Attempt)  /* Ignore Down neighbor. */
                   2750:        if (nbr->state != NSM_Down)     /* This is myself for DR election. */
                   2751:          if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
                   2752:            {
                   2753:              /* Check neighbor is sane? */
                   2754:              if (nbr->d_router.s_addr != 0
                   2755:                  && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
                   2756:                  && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
                   2757:                flag = 1;
                   2758: 
                   2759:              stream_put_ipv4 (s, nbr->router_id.s_addr);
                   2760:              length += 4;
                   2761:            }
                   2762: 
                   2763:   /* Let neighbor generate BackupSeen. */
                   2764:   if (flag == 1)
                   2765:     stream_putl_at (s, p, 0); /* ipv4 address, normally */
                   2766: 
                   2767:   return length;
                   2768: }
                   2769: 
                   2770: static int
                   2771: ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
                   2772:                   struct stream *s)
                   2773: {
                   2774:   struct ospf_lsa *lsa;
                   2775:   u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
                   2776:   u_char options;
                   2777:   unsigned long pp;
                   2778:   int i;
                   2779:   struct ospf_lsdb *lsdb;
                   2780:   
                   2781:   /* Set Interface MTU. */
                   2782:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   2783:     stream_putw (s, 0);
                   2784:   else
                   2785:     stream_putw (s, oi->ifp->mtu);
                   2786: 
                   2787:   /* Set Options. */
                   2788:   options = OPTIONS (oi);
                   2789: #ifdef HAVE_OPAQUE_LSA
                   2790:   if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
                   2791:     {
                   2792:       if (IS_SET_DD_I (nbr->dd_flags)
                   2793:       ||  CHECK_FLAG (nbr->options, OSPF_OPTION_O))
                   2794:         /*
                   2795:          * Set O-bit in the outgoing DD packet for capablity negotiation,
                   2796:          * if one of following case is applicable. 
                   2797:          *
                   2798:          * 1) WaitTimer expiration event triggered the neighbor state to
                   2799:          *    change to Exstart, but no (valid) DD packet has received
                   2800:          *    from the neighbor yet.
                   2801:          *
                   2802:          * 2) At least one DD packet with O-bit on has received from the
                   2803:          *    neighbor.
                   2804:          */
                   2805:         SET_FLAG (options, OSPF_OPTION_O);
                   2806:     }
                   2807: #endif /* HAVE_OPAQUE_LSA */
                   2808:   stream_putc (s, options);
                   2809: 
                   2810:   /* DD flags */
                   2811:   pp = stream_get_endp (s);
                   2812:   stream_putc (s, nbr->dd_flags);
                   2813: 
                   2814:   /* Set DD Sequence Number. */
                   2815:   stream_putl (s, nbr->dd_seqnum);
                   2816: 
                   2817:   /* shortcut unneeded walk of (empty) summary LSDBs */
                   2818:   if (ospf_db_summary_isempty (nbr))
                   2819:     goto empty;
                   2820: 
                   2821:   /* Describe LSA Header from Database Summary List. */
                   2822:   lsdb = &nbr->db_sum;
                   2823: 
                   2824:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                   2825:     {
                   2826:       struct route_table *table = lsdb->type[i].db;
                   2827:       struct route_node *rn;
                   2828: 
                   2829:       for (rn = route_top (table); rn; rn = route_next (rn))
                   2830:        if ((lsa = rn->info) != NULL)
                   2831:          {
                   2832: #ifdef HAVE_OPAQUE_LSA
                   2833:             if (IS_OPAQUE_LSA (lsa->data->type)
                   2834:             && (! CHECK_FLAG (options, OSPF_OPTION_O)))
                   2835:               {
                   2836:                 /* Suppress advertising opaque-informations. */
                   2837:                 /* Remove LSA from DB summary list. */
                   2838:                 ospf_lsdb_delete (lsdb, lsa);
                   2839:                 continue;
                   2840:               }
                   2841: #endif /* HAVE_OPAQUE_LSA */
                   2842: 
                   2843:            if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
                   2844:              {
                   2845:                struct lsa_header *lsah;
                   2846:                u_int16_t ls_age;
                   2847:                
                   2848:                /* DD packet overflows interface MTU. */
                   2849:                if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
                   2850:                  break;
                   2851:                
                   2852:                /* Keep pointer to LS age. */
                   2853:                lsah = (struct lsa_header *) (STREAM_DATA (s) +
                   2854:                                              stream_get_endp (s));
                   2855:                
                   2856:                /* Proceed stream pointer. */
                   2857:                stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
                   2858:                length += OSPF_LSA_HEADER_SIZE;
                   2859:                
                   2860:                /* Set LS age. */
                   2861:                ls_age = LS_AGE (lsa);
                   2862:                lsah->ls_age = htons (ls_age);
                   2863:                
                   2864:              }
                   2865:            
                   2866:            /* Remove LSA from DB summary list. */
                   2867:            ospf_lsdb_delete (lsdb, lsa);
                   2868:          }
                   2869:     }
                   2870: 
                   2871:   /* Update 'More' bit */
                   2872:   if (ospf_db_summary_isempty (nbr))
                   2873:     {
                   2874: empty:
                   2875:       if (nbr->state >= NSM_Exchange)
                   2876:         {
                   2877:           UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
                   2878:           /* Rewrite DD flags */
                   2879:           stream_putc_at (s, pp, nbr->dd_flags);
                   2880:         }
                   2881:       else
                   2882:         {
                   2883:           assert (IS_SET_DD_M(nbr->dd_flags));
                   2884:         }
                   2885:     }
                   2886:   return length;
                   2887: }
                   2888: 
                   2889: static int
                   2890: ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
                   2891:                       unsigned long delta, struct ospf_neighbor *nbr,
                   2892:                       struct ospf_lsa *lsa)
                   2893: {
                   2894:   struct ospf_interface *oi;
                   2895: 
                   2896:   oi = nbr->oi;
                   2897: 
                   2898:   /* LS Request packet overflows interface MTU. */
                   2899:   if (*length + delta > ospf_packet_max(oi))
                   2900:     return 0;
                   2901: 
                   2902:   stream_putl (s, lsa->data->type);
                   2903:   stream_put_ipv4 (s, lsa->data->id.s_addr);
                   2904:   stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
                   2905:   
                   2906:   ospf_lsa_unlock (&nbr->ls_req_last);
                   2907:   nbr->ls_req_last = ospf_lsa_lock (lsa);
                   2908:   
                   2909:   *length += 12;
                   2910:   return 1;
                   2911: }
                   2912: 
                   2913: static int
                   2914: ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
                   2915: {
                   2916:   struct ospf_lsa *lsa;
                   2917:   u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
                   2918:   unsigned long delta = stream_get_endp(s)+12;
                   2919:   struct route_table *table;
                   2920:   struct route_node *rn;
                   2921:   int i;
                   2922:   struct ospf_lsdb *lsdb;
                   2923: 
                   2924:   lsdb = &nbr->ls_req;
                   2925: 
                   2926:   for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
                   2927:     {
                   2928:       table = lsdb->type[i].db;
                   2929:       for (rn = route_top (table); rn; rn = route_next (rn))
                   2930:        if ((lsa = (rn->info)) != NULL)
                   2931:          if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
                   2932:            {
                   2933:              route_unlock_node (rn);
                   2934:              break;
                   2935:            }
                   2936:     }
                   2937:   return length;
                   2938: }
                   2939: 
                   2940: static int
                   2941: ls_age_increment (struct ospf_lsa *lsa, int delay)
                   2942: {
                   2943:   int age;
                   2944: 
                   2945:   age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
                   2946: 
                   2947:   return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
                   2948: }
                   2949: 
                   2950: static int
                   2951: ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
                   2952: {
                   2953:   struct ospf_lsa *lsa;
                   2954:   struct listnode *node;
                   2955:   u_int16_t length = 0;
                   2956:   unsigned int size_noauth;
                   2957:   unsigned long delta = stream_get_endp (s);
                   2958:   unsigned long pp;
                   2959:   int count = 0;
                   2960: 
                   2961:   if (IS_DEBUG_OSPF_EVENT)
                   2962:     zlog_debug ("ospf_make_ls_upd: Start");
                   2963: 
                   2964:   pp = stream_get_endp (s);
                   2965:   stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
                   2966:   length += OSPF_LS_UPD_MIN_SIZE;
                   2967: 
                   2968:   /* Calculate amount of packet usable for data. */
                   2969:   size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
                   2970: 
                   2971:   while ((node = listhead (update)) != NULL)
                   2972:     {
                   2973:       struct lsa_header *lsah;
                   2974:       u_int16_t ls_age;
                   2975: 
                   2976:       if (IS_DEBUG_OSPF_EVENT)
                   2977:         zlog_debug ("ospf_make_ls_upd: List Iteration");
                   2978: 
                   2979:       lsa = listgetdata (node);
                   2980: 
                   2981:       assert (lsa->data);
                   2982: 
                   2983:       /* Will it fit? */
                   2984:       if (length + delta + ntohs (lsa->data->length) > size_noauth)
                   2985:         break;
                   2986: 
                   2987:       /* Keep pointer to LS age. */
                   2988:       lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
                   2989: 
                   2990:       /* Put LSA to Link State Request. */
                   2991:       stream_put (s, lsa->data, ntohs (lsa->data->length));
                   2992: 
                   2993:       /* Set LS age. */
                   2994:       /* each hop must increment an lsa_age by transmit_delay 
                   2995:          of OSPF interface */
                   2996:       ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
                   2997:       lsah->ls_age = htons (ls_age);
                   2998: 
                   2999:       length += ntohs (lsa->data->length);
                   3000:       count++;
                   3001: 
                   3002:       list_delete_node (update, node);
                   3003:       ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
                   3004:     }
                   3005: 
                   3006:   /* Now set #LSAs. */
                   3007:   stream_putl_at (s, pp, count);
                   3008: 
                   3009:   if (IS_DEBUG_OSPF_EVENT)
                   3010:     zlog_debug ("ospf_make_ls_upd: Stop");
                   3011:   return length;
                   3012: }
                   3013: 
                   3014: static int
                   3015: ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
                   3016: {
                   3017:   struct listnode *node, *nnode;
                   3018:   u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
                   3019:   unsigned long delta = stream_get_endp(s) + 24;
                   3020:   struct ospf_lsa *lsa;
                   3021: 
                   3022:   for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
                   3023:     {
                   3024:       assert (lsa);
                   3025:       
                   3026:       if (length + delta > ospf_packet_max (oi))
                   3027:        break;
                   3028:       
                   3029:       stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
                   3030:       length += OSPF_LSA_HEADER_SIZE;
                   3031:       
                   3032:       listnode_delete (ack, lsa);
                   3033:       ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
                   3034:     }
                   3035:   
                   3036:   return length;
                   3037: }
                   3038: 
                   3039: static void
                   3040: ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
                   3041: {
                   3042:   struct ospf_packet *op;
                   3043:   u_int16_t length = OSPF_HEADER_SIZE;
                   3044: 
                   3045:   op = ospf_packet_new (oi->ifp->mtu);
                   3046: 
                   3047:   /* Prepare OSPF common header. */
                   3048:   ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
                   3049: 
                   3050:   /* Prepare OSPF Hello body. */
                   3051:   length += ospf_make_hello (oi, op->s);
                   3052: 
                   3053:   /* Fill OSPF header. */
                   3054:   ospf_fill_header (oi, op->s, length);
                   3055: 
                   3056:   /* Set packet length. */
                   3057:   op->length = length;
                   3058: 
                   3059:   op->dst.s_addr = addr;
                   3060: 
                   3061:   /* Add packet to the top of the interface output queue, so that they
                   3062:    * can't get delayed by things like long queues of LS Update packets
                   3063:    */
                   3064:   ospf_packet_add_top (oi, op);
                   3065: 
                   3066:   /* Hook thread to write packet. */
                   3067:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3068: }
                   3069: 
                   3070: static void
                   3071: ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
                   3072: {
                   3073:   struct ospf_interface *oi;
                   3074: 
                   3075:   oi = nbr_nbma->oi;
                   3076:   assert(oi);
                   3077: 
                   3078:   /* If this is passive interface, do not send OSPF Hello. */
                   3079:   if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
                   3080:     return;
                   3081: 
                   3082:   if (oi->type != OSPF_IFTYPE_NBMA)
                   3083:     return;
                   3084: 
                   3085:   if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
                   3086:     return;
                   3087: 
                   3088:   if (PRIORITY(oi) == 0)
                   3089:     return;
                   3090: 
                   3091:   if (nbr_nbma->priority == 0
                   3092:       && oi->state != ISM_DR && oi->state != ISM_Backup)
                   3093:     return;
                   3094: 
                   3095:   ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
                   3096: }
                   3097: 
                   3098: int
                   3099: ospf_poll_timer (struct thread *thread)
                   3100: {
                   3101:   struct ospf_nbr_nbma *nbr_nbma;
                   3102: 
                   3103:   nbr_nbma = THREAD_ARG (thread);
                   3104:   nbr_nbma->t_poll = NULL;
                   3105: 
                   3106:   if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
                   3107:     zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
                   3108:     IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
                   3109: 
                   3110:   ospf_poll_send (nbr_nbma);
                   3111: 
                   3112:   if (nbr_nbma->v_poll > 0)
                   3113:     OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
                   3114:                        nbr_nbma->v_poll);
                   3115: 
                   3116:   return 0;
                   3117: }
                   3118: 
                   3119: 
                   3120: int
                   3121: ospf_hello_reply_timer (struct thread *thread)
                   3122: {
                   3123:   struct ospf_neighbor *nbr;
                   3124: 
                   3125:   nbr = THREAD_ARG (thread);
                   3126:   nbr->t_hello_reply = NULL;
                   3127: 
                   3128:   assert (nbr->oi);
                   3129: 
                   3130:   if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
                   3131:     zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
                   3132:          IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
                   3133: 
                   3134:   ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
                   3135: 
                   3136:   return 0;
                   3137: }
                   3138: 
                   3139: /* Send OSPF Hello. */
                   3140: void
                   3141: ospf_hello_send (struct ospf_interface *oi)
                   3142: {
                   3143:   /* If this is passive interface, do not send OSPF Hello. */
                   3144:   if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
                   3145:     return;
                   3146: 
                   3147:   if (oi->type == OSPF_IFTYPE_NBMA)
                   3148:     {
                   3149:       struct ospf_neighbor *nbr;
                   3150:       struct route_node *rn;
                   3151: 
                   3152:       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   3153:        if ((nbr = rn->info))
                   3154:          if (nbr != oi->nbr_self)
                   3155:            if (nbr->state != NSM_Down)
                   3156:              {
                   3157:                /*  RFC 2328  Section 9.5.1
                   3158:                    If the router is not eligible to become Designated Router,
                   3159:                    it must periodically send Hello Packets to both the
                   3160:                    Designated Router and the Backup Designated Router (if they
                   3161:                    exist).  */
                   3162:                if (PRIORITY(oi) == 0 &&
                   3163:                    IPV4_ADDR_CMP(&DR(oi),  &nbr->address.u.prefix4) &&
                   3164:                    IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
                   3165:                  continue;
                   3166: 
                   3167:                /*  If the router is eligible to become Designated Router, it
                   3168:                    must periodically send Hello Packets to all neighbors that
                   3169:                    are also eligible. In addition, if the router is itself the
                   3170:                    Designated Router or Backup Designated Router, it must also
                   3171:                    send periodic Hello Packets to all other neighbors. */
                   3172: 
                   3173:                if (nbr->priority == 0 && oi->state == ISM_DROther)
                   3174:                  continue;
                   3175:                /* if oi->state == Waiting, send hello to all neighbors */
                   3176:                ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
                   3177:              }
                   3178:     }
                   3179:   else
                   3180:     {
                   3181:       /* Decide destination address. */
                   3182:       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3183:         ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
                   3184:       else
                   3185:         ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
                   3186:     }
                   3187: }
                   3188: 
                   3189: /* Send OSPF Database Description. */
                   3190: void
                   3191: ospf_db_desc_send (struct ospf_neighbor *nbr)
                   3192: {
                   3193:   struct ospf_interface *oi;
                   3194:   struct ospf_packet *op;
                   3195:   u_int16_t length = OSPF_HEADER_SIZE;
                   3196: 
                   3197:   oi = nbr->oi;
                   3198:   op = ospf_packet_new (oi->ifp->mtu);
                   3199: 
                   3200:   /* Prepare OSPF common header. */
                   3201:   ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
                   3202: 
                   3203:   /* Prepare OSPF Database Description body. */
                   3204:   length += ospf_make_db_desc (oi, nbr, op->s);
                   3205: 
                   3206:   /* Fill OSPF header. */
                   3207:   ospf_fill_header (oi, op->s, length);
                   3208: 
                   3209:   /* Set packet length. */
                   3210:   op->length = length;
                   3211: 
                   3212:   /* Decide destination address. */
                   3213:   if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3214:     op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3215:   else
                   3216:     op->dst = nbr->address.u.prefix4;
                   3217: 
                   3218:   /* Add packet to the interface output queue. */
                   3219:   ospf_packet_add (oi, op);
                   3220: 
                   3221:   /* Hook thread to write packet. */
                   3222:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3223: 
                   3224:   /* Remove old DD packet, then copy new one and keep in neighbor structure. */
                   3225:   if (nbr->last_send)
                   3226:     ospf_packet_free (nbr->last_send);
                   3227:   nbr->last_send = ospf_packet_dup (op);
                   3228:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
                   3229: }
                   3230: 
                   3231: /* Re-send Database Description. */
                   3232: void
                   3233: ospf_db_desc_resend (struct ospf_neighbor *nbr)
                   3234: {
                   3235:   struct ospf_interface *oi;
                   3236: 
                   3237:   oi = nbr->oi;
                   3238: 
                   3239:   /* Add packet to the interface output queue. */
                   3240:   ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
                   3241: 
                   3242:   /* Hook thread to write packet. */
                   3243:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3244: }
                   3245: 
                   3246: /* Send Link State Request. */
                   3247: void
                   3248: ospf_ls_req_send (struct ospf_neighbor *nbr)
                   3249: {
                   3250:   struct ospf_interface *oi;
                   3251:   struct ospf_packet *op;
                   3252:   u_int16_t length = OSPF_HEADER_SIZE;
                   3253: 
                   3254:   oi = nbr->oi;
                   3255:   op = ospf_packet_new (oi->ifp->mtu);
                   3256: 
                   3257:   /* Prepare OSPF common header. */
                   3258:   ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
                   3259: 
                   3260:   /* Prepare OSPF Link State Request body. */
                   3261:   length += ospf_make_ls_req (nbr, op->s);
                   3262:   if (length == OSPF_HEADER_SIZE)
                   3263:     {
                   3264:       ospf_packet_free (op);
                   3265:       return;
                   3266:     }
                   3267: 
                   3268:   /* Fill OSPF header. */
                   3269:   ospf_fill_header (oi, op->s, length);
                   3270: 
                   3271:   /* Set packet length. */
                   3272:   op->length = length;
                   3273: 
                   3274:   /* Decide destination address. */
                   3275:   if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3276:     op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3277:   else
                   3278:     op->dst = nbr->address.u.prefix4;
                   3279: 
                   3280:   /* Add packet to the interface output queue. */
                   3281:   ospf_packet_add (oi, op);
                   3282: 
                   3283:   /* Hook thread to write packet. */
                   3284:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3285: 
                   3286:   /* Add Link State Request Retransmission Timer. */
                   3287:   OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
                   3288: }
                   3289: 
                   3290: /* Send Link State Update with an LSA. */
                   3291: void
                   3292: ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
                   3293:                      int flag)
                   3294: {
                   3295:   struct list *update;
                   3296: 
                   3297:   update = list_new ();
                   3298: 
                   3299:   listnode_add (update, lsa);
                   3300:   ospf_ls_upd_send (nbr, update, flag);
                   3301: 
                   3302:   list_delete (update);
                   3303: }
                   3304: 
                   3305: /* Determine size for packet. Must be at least big enough to accomodate next
                   3306:  * LSA on list, which may be bigger than MTU size.
                   3307:  *
                   3308:  * Return pointer to new ospf_packet
                   3309:  * NULL if we can not allocate, eg because LSA is bigger than imposed limit
                   3310:  * on packet sizes (in which case offending LSA is deleted from update list)
                   3311:  */
                   3312: static struct ospf_packet *
                   3313: ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
                   3314: {
                   3315:   struct ospf_lsa *lsa;
                   3316:   struct listnode *ln;
                   3317:   size_t size;
                   3318:   static char warned = 0;
                   3319: 
                   3320:   lsa = listgetdata((ln = listhead (update)));
                   3321:   assert (lsa->data);
                   3322: 
                   3323:   if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
                   3324:       > ospf_packet_max (oi))
                   3325:     {
                   3326:       if (!warned)
                   3327:         {
                   3328:           zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
                   3329:                      "will need to fragment. Not optimal. Try divide up"
                   3330:                      " your network with areas. Use 'debug ospf packet send'"
                   3331:                      " to see details, or look at 'show ip ospf database ..'");
                   3332:           warned = 1;
                   3333:         }
                   3334: 
                   3335:       if (IS_DEBUG_OSPF_PACKET (0, SEND))
                   3336:         zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
                   3337:                    " %d bytes originated by %s, will be fragmented!",
                   3338:                    inet_ntoa (lsa->data->id),
                   3339:                    ntohs (lsa->data->length),
                   3340:                    inet_ntoa (lsa->data->adv_router));
                   3341: 
                   3342:       /* 
                   3343:        * Allocate just enough to fit this LSA only, to avoid including other
                   3344:        * LSAs in fragmented LSA Updates.
                   3345:        */
                   3346:       size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
                   3347:              + OSPF_LS_UPD_MIN_SIZE;
                   3348:     }
                   3349:   else
                   3350:     size = oi->ifp->mtu;
                   3351: 
                   3352:   if (size > OSPF_MAX_PACKET_SIZE)
                   3353:     {
                   3354:       zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
                   3355:                  " %d bytes, packet size %ld, dropping it completely."
                   3356:                  " OSPF routing is broken!",
                   3357:                  inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
                   3358:                  (long int) size);
                   3359:       list_delete_node (update, ln);
                   3360:       return NULL;
                   3361:     }
                   3362: 
                   3363:   /* IP header is built up separately by ospf_write(). This means, that we must
                   3364:    * reduce the "affordable" size just calculated by length of an IP header.
                   3365:    * This makes sure, that even if we manage to fill the payload with LSA data
                   3366:    * completely, the final packet (our data plus IP header) still fits into
                   3367:    * outgoing interface MTU. This correction isn't really meaningful for an
                   3368:    * oversized LSA, but for consistency the correction is done for both cases.
                   3369:    *
                   3370:    * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
                   3371:    */
                   3372:   return ospf_packet_new (size - sizeof (struct ip));
                   3373: }
                   3374: 
                   3375: static void
                   3376: ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
                   3377:                        struct in_addr addr)
                   3378: {
                   3379:   struct ospf_packet *op;
                   3380:   u_int16_t length = OSPF_HEADER_SIZE;
                   3381: 
                   3382:   if (IS_DEBUG_OSPF_EVENT)
                   3383:     zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
                   3384:   
                   3385:   op = ospf_ls_upd_packet_new (update, oi);
                   3386: 
                   3387:   /* Prepare OSPF common header. */
                   3388:   ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
                   3389: 
                   3390:   /* Prepare OSPF Link State Update body.
                   3391:    * Includes Type-7 translation. 
                   3392:    */
                   3393:   length += ospf_make_ls_upd (oi, update, op->s);
                   3394: 
                   3395:   /* Fill OSPF header. */
                   3396:   ospf_fill_header (oi, op->s, length);
                   3397: 
                   3398:   /* Set packet length. */
                   3399:   op->length = length;
                   3400: 
                   3401:   /* Decide destination address. */
                   3402:   if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3403:     op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3404:   else
                   3405:     op->dst.s_addr = addr.s_addr;
                   3406: 
                   3407:   /* Add packet to the interface output queue. */
                   3408:   ospf_packet_add (oi, op);
                   3409: 
                   3410:   /* Hook thread to write packet. */
                   3411:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3412: }
                   3413: 
                   3414: static int
                   3415: ospf_ls_upd_send_queue_event (struct thread *thread)
                   3416: {
                   3417:   struct ospf_interface *oi = THREAD_ARG(thread);
                   3418:   struct route_node *rn;
                   3419:   struct route_node *rnext;
                   3420:   struct list *update;
                   3421:   char again = 0;
                   3422:   
                   3423:   oi->t_ls_upd_event = NULL;
                   3424: 
                   3425:   if (IS_DEBUG_OSPF_EVENT)
                   3426:     zlog_debug ("ospf_ls_upd_send_queue start");
                   3427: 
                   3428:   for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
                   3429:     {
                   3430:       rnext = route_next (rn);
                   3431:       
                   3432:       if (rn->info == NULL)
                   3433:         continue;
                   3434:       
                   3435:       update = (struct list *)rn->info;
                   3436: 
                   3437:       ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
                   3438:       
                   3439:       /* list might not be empty. */
                   3440:       if (listcount(update) == 0)
                   3441:         {
                   3442:           list_delete (rn->info);
                   3443:           rn->info = NULL;
                   3444:           route_unlock_node (rn);
                   3445:         }
                   3446:       else
                   3447:         again = 1;
                   3448:     }
                   3449: 
                   3450:   if (again != 0)
                   3451:     {
                   3452:       if (IS_DEBUG_OSPF_EVENT)
                   3453:         zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
                   3454:                    " %d nodes to try again, raising new event", again);
                   3455:       oi->t_ls_upd_event = 
                   3456:         thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
                   3457:     }
                   3458: 
                   3459:   if (IS_DEBUG_OSPF_EVENT)
                   3460:     zlog_debug ("ospf_ls_upd_send_queue stop");
                   3461:   
                   3462:   return 0;
                   3463: }
                   3464: 
                   3465: void
                   3466: ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
                   3467: {
                   3468:   struct ospf_interface *oi;
                   3469:   struct ospf_lsa *lsa;
                   3470:   struct prefix_ipv4 p;
                   3471:   struct route_node *rn;
                   3472:   struct listnode *node;
                   3473:   
                   3474:   oi = nbr->oi;
                   3475: 
                   3476:   p.family = AF_INET;
                   3477:   p.prefixlen = IPV4_MAX_BITLEN;
                   3478:   
                   3479:   /* Decide destination address. */
                   3480:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3481:     p.prefix = oi->vl_data->peer_addr;
                   3482:   else if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
                   3483:      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3484:   else if (flag == OSPF_SEND_PACKET_DIRECT)
                   3485:      p.prefix = nbr->address.u.prefix4;
                   3486:   else if (oi->state == ISM_DR || oi->state == ISM_Backup)
                   3487:      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3488:   else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
                   3489:      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3490:   else
                   3491:      p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
                   3492: 
                   3493:   if (oi->type == OSPF_IFTYPE_NBMA)
                   3494:     {
                   3495:       if (flag == OSPF_SEND_PACKET_INDIRECT)
                   3496:        zlog_warn ("* LS-Update is directly sent on NBMA network.");
                   3497:       if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
                   3498:        zlog_warn ("* LS-Update is sent to myself.");
                   3499:     }
                   3500: 
                   3501:   rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
                   3502: 
                   3503:   if (rn->info == NULL)
                   3504:     rn->info = list_new ();
                   3505: 
                   3506:   for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
                   3507:     listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
                   3508: 
                   3509:   if (oi->t_ls_upd_event == NULL)
                   3510:     oi->t_ls_upd_event =
                   3511:       thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
                   3512: }
                   3513: 
                   3514: static void
                   3515: ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
                   3516:                       struct in_addr dst)
                   3517: {
                   3518:   struct ospf_packet *op;
                   3519:   u_int16_t length = OSPF_HEADER_SIZE;
                   3520: 
                   3521:   op = ospf_packet_new (oi->ifp->mtu);
                   3522: 
                   3523:   /* Prepare OSPF common header. */
                   3524:   ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
                   3525: 
                   3526:   /* Prepare OSPF Link State Acknowledgment body. */
                   3527:   length += ospf_make_ls_ack (oi, ack, op->s);
                   3528: 
                   3529:   /* Fill OSPF header. */
                   3530:   ospf_fill_header (oi, op->s, length);
                   3531: 
                   3532:   /* Set packet length. */
                   3533:   op->length = length;
                   3534: 
                   3535:   /* Set destination IP address. */
                   3536:   op->dst = dst;
                   3537:   
                   3538:   /* Add packet to the interface output queue. */
                   3539:   ospf_packet_add (oi, op);
                   3540: 
                   3541:   /* Hook thread to write packet. */
                   3542:   OSPF_ISM_WRITE_ON (oi->ospf);
                   3543: }
                   3544: 
                   3545: static int
                   3546: ospf_ls_ack_send_event (struct thread *thread)
                   3547: {
                   3548:   struct ospf_interface *oi = THREAD_ARG (thread);
                   3549: 
                   3550:   oi->t_ls_ack_direct = NULL;
                   3551:   
                   3552:   while (listcount (oi->ls_ack_direct.ls_ack))
                   3553:     ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
                   3554:                           oi->ls_ack_direct.dst);
                   3555: 
                   3556:   return 0;
                   3557: }
                   3558: 
                   3559: void
                   3560: ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
                   3561: {
                   3562:   struct ospf_interface *oi = nbr->oi;
                   3563: 
                   3564:   if (listcount (oi->ls_ack_direct.ls_ack) == 0)
                   3565:     oi->ls_ack_direct.dst = nbr->address.u.prefix4;
                   3566:   
                   3567:   listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
                   3568:   
                   3569:   if (oi->t_ls_ack_direct == NULL)
                   3570:     oi->t_ls_ack_direct =
                   3571:       thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
                   3572: }
                   3573: 
                   3574: /* Send Link State Acknowledgment delayed. */
                   3575: void
                   3576: ospf_ls_ack_send_delayed (struct ospf_interface *oi)
                   3577: {
                   3578:   struct in_addr dst;
                   3579:   
                   3580:   /* Decide destination address. */
                   3581:   /* RFC2328 Section 13.5                           On non-broadcast
                   3582:        networks, delayed Link State Acknowledgment packets must be
                   3583:        unicast separately over each adjacency (i.e., neighbor whose
                   3584:        state is >= Exchange).  */
                   3585:   if (oi->type == OSPF_IFTYPE_NBMA)
                   3586:     {
                   3587:       struct ospf_neighbor *nbr;
                   3588:       struct route_node *rn;
                   3589: 
                   3590:       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   3591:        if ((nbr = rn->info) != NULL)
                   3592:          if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
                   3593:            while (listcount (oi->ls_ack))
                   3594:              ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
                   3595:       return;
                   3596:     }
                   3597:   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                   3598:     dst.s_addr = oi->vl_data->peer_addr.s_addr;
                   3599:   else if (oi->state == ISM_DR || oi->state == ISM_Backup)
                   3600:     dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3601:   else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
                   3602:     dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3603:   else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
                   3604:     dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
                   3605:   else
                   3606:     dst.s_addr = htonl (OSPF_ALLDROUTERS);
                   3607: 
                   3608:   while (listcount (oi->ls_ack))
                   3609:     ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
                   3610: }

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