File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_packet.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>