/*
 * OSPF Flooding -- RFC2328 Section 13.
 * Copyright (C) 1999, 2000 Toshiaki Takada
 *
 * This file is part of GNU Zebra.
 * 
 * GNU Zebra is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <zebra.h>

#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "command.h"
#include "table.h"
#include "thread.h"
#include "memory.h"
#include "log.h"
#include "zclient.h"

#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"

extern struct zclient *zclient;

/* Do the LSA acking specified in table 19, Section 13.5, row 2
 * This get called from ospf_flood_out_interface. Declared inline 
 * for speed. */
static void
ospf_flood_delayed_lsa_ack (struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
{
  /* LSA is more recent than database copy, but was not
     flooded back out receiving interface.  Delayed
     acknowledgment sent. If interface is in Backup state
     delayed acknowledgment sent only if advertisement
     received from Designated Router, otherwise do nothing See
     RFC 2328 Section 13.5 */

  /* Whether LSA is more recent or not, and whether this is in
     response to the LSA being sent out recieving interface has been 
     worked out previously */

  /* Deal with router as BDR */
  if (inbr->oi->state == ISM_Backup && ! NBR_IS_DR (inbr))
    return;

  /* Schedule a delayed LSA Ack to be sent */ 
  listnode_add (inbr->oi->ls_ack, ospf_lsa_lock (lsa)); /* delayed LSA Ack */
}

/* Check LSA is related to external info. */
struct external_info *
ospf_external_info_check (struct ospf_lsa *lsa)
{
  struct as_external_lsa *al;
  struct prefix_ipv4 p;
  struct route_node *rn;
  int type;

  al = (struct as_external_lsa *) lsa->data;

  p.family = AF_INET;
  p.prefix = lsa->data->id;
  p.prefixlen = ip_masklen (al->mask);

  for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
    {
      int redist_type = is_prefix_default (&p) ? DEFAULT_ROUTE : type;
      if (ospf_is_type_redistributed (redist_type))
	if (EXTERNAL_INFO (type))
	  {
	    rn = route_node_lookup (EXTERNAL_INFO (type),
				    (struct prefix *) &p);
	    if (rn)
	      {
		route_unlock_node (rn);
		if (rn->info != NULL)
		  return (struct external_info *) rn->info;
	      }
	  }
    }

  return NULL;
}

static void
ospf_process_self_originated_lsa (struct ospf *ospf,
				  struct ospf_lsa *new, struct ospf_area *area)
{
  struct ospf_interface *oi;
  struct external_info *ei;
  struct listnode *node;
  
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("LSA[Type%d:%s]: Process self-originated LSA seq 0x%x",
	       new->data->type, inet_ntoa (new->data->id), 
	       ntohl(new->data->ls_seqnum));

  /* If we're here, we installed a self-originated LSA that we received
     from a neighbor, i.e. it's more recent.  We must see whether we want
     to originate it.
     If yes, we should use this LSA's sequence number and reoriginate
     a new instance.
     if not --- we must flush this LSA from the domain. */
  switch (new->data->type)
    {
    case OSPF_ROUTER_LSA:
      /* Originate a new instance and schedule flooding */
      if (area->router_lsa_self)
	area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
      ospf_router_lsa_update_area (area);
      return;
    case OSPF_NETWORK_LSA:
#ifdef HAVE_OPAQUE_LSA
    case OSPF_OPAQUE_LINK_LSA:
#endif /* HAVE_OPAQUE_LSA */
      /* We must find the interface the LSA could belong to.
	 If the interface is no more a broadcast type or we are no more
	 the DR, we flush the LSA otherwise -- create the new instance and
	 schedule flooding. */

      /* Look through all interfaces, not just area, since interface
	 could be moved from one area to another. */
      for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
	/* These are sanity check. */
        if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &new->data->id))
          {
            if (oi->area != area ||
                oi->type != OSPF_IFTYPE_BROADCAST ||
                !IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)))
              {
                ospf_schedule_lsa_flush_area (area, new);
                return;
              }
            
#ifdef HAVE_OPAQUE_LSA
            if (new->data->type == OSPF_OPAQUE_LINK_LSA)
              {
                ospf_opaque_lsa_refresh (new);
                return;
              }
#endif /* HAVE_OPAQUE_LSA */

            if (oi->network_lsa_self)
	      oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
            /* Schedule network-LSA origination. */
            ospf_network_lsa_update (oi);
            return;
          }
      break;
    case OSPF_SUMMARY_LSA:
    case OSPF_ASBR_SUMMARY_LSA:
      ospf_schedule_abr_task (ospf);
      break;
    case OSPF_AS_EXTERNAL_LSA :
    case OSPF_AS_NSSA_LSA:
       if ( (new->data->type == OSPF_AS_EXTERNAL_LSA)
             && CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT))
         {
           ospf_translated_nssa_refresh (ospf, NULL, new);
           return;
         }
      ei = ospf_external_info_check (new);
      if (ei)
        ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE);
      else
        ospf_lsa_flush_as (ospf, new);
      break;
#ifdef HAVE_OPAQUE_LSA
    case OSPF_OPAQUE_AREA_LSA:
      ospf_opaque_lsa_refresh (new);
      break;
    case OSPF_OPAQUE_AS_LSA:
      ospf_opaque_lsa_refresh (new); /* Reconsideration may needed. *//* XXX */
      break;
#endif /* HAVE_OPAQUE_LSA */
    default:
      break;
    }
}

/* OSPF LSA flooding -- RFC2328 Section 13.(5). */

/* Now Updated for NSSA operation, as follows:


	Type-5's have no change.  Blocked to STUB or NSSA.

	Type-7's can be received, and if a DR
	they will also flood the local NSSA Area as Type-7's

	If a Self-Originated LSA (now an ASBR), 
	The LSDB will be updated as Type-5's, (for continual re-fresh)

	    If an NSSA-IR it is installed/flooded as Type-7, P-bit on.
	    if an NSSA-ABR it is installed/flooded as Type-7, P-bit off.

	Later, during the ABR TASK, if the ABR is the Elected NSSA
	translator, then All Type-7s (with P-bit ON) are Translated to
	Type-5's and flooded to all non-NSSA/STUB areas.

	During ASE Calculations, 
	    non-ABRs calculate external routes from Type-7's
	    ABRs calculate external routes from Type-5's and non-self Type-7s
*/
int
ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr,
	    struct ospf_lsa *current, struct ospf_lsa *new)
{
  struct ospf_interface *oi;
  int lsa_ack_flag;

  /* Type-7 LSA's will be flooded throughout their native NSSA area,
     but will also be flooded as Type-5's into ABR capable links.  */

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]",
               inet_ntoa (nbr->router_id),
               LOOKUP (ospf_nsm_state_msg, nbr->state),
               current,
               dump_lsa_key (new));

  lsa_ack_flag = 0;
  oi = nbr->oi;

  /* If there is already a database copy, and if the
     database copy was received via flooding and installed less
     than MinLSArrival seconds ago, discard the new LSA
     (without acknowledging it). */
  if (current != NULL)		/* -- endo. */
    {
      if (IS_LSA_SELF (current)
      && (ntohs (current->data->ls_age)    == 0
      &&  ntohl (current->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER))
        {
          if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("LSA[Flooding]: Got a self-originated LSA, "
		       "while local one is initial instance.");
          ; /* Accept this LSA for quick LSDB resynchronization. */
        }
      else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv),
	               int2tv (OSPF_MIN_LS_ARRIVAL)) < 0)
        {
          if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("LSA[Flooding]: LSA is received recently.");
          return -1;
        }
    }

  /* Flood the new LSA out some subset of the router's interfaces.
     In some cases (e.g., the state of the receiving interface is
     DR and the LSA was received from a router other than the
     Backup DR) the LSA will be flooded back out the receiving
     interface. */
  lsa_ack_flag = ospf_flood_through (ospf, nbr, new);

#ifdef HAVE_OPAQUE_LSA
  /* Remove the current database copy from all neighbors' Link state
     retransmission lists.  AS_EXTERNAL and AS_EXTERNAL_OPAQUE does
                                        ^^^^^^^^^^^^^^^^^^^^^^^
     not have area ID.
     All other (even NSSA's) do have area ID.  */
#else /* HAVE_OPAQUE_LSA */
  /* Remove the current database copy from all neighbors' Link state
     retransmission lists.  Only AS_EXTERNAL does not have area ID.
     All other (even NSSA's) do have area ID.  */
#endif /* HAVE_OPAQUE_LSA */
  if (current)
    {
      switch (current->data->type)
        {
        case OSPF_AS_EXTERNAL_LSA:
#ifdef HAVE_OPAQUE_LSA
        case OSPF_OPAQUE_AS_LSA:
#endif /* HAVE_OPAQUE_LSA */
          ospf_ls_retransmit_delete_nbr_as (ospf, current);
          break;
        default:
          ospf_ls_retransmit_delete_nbr_area (nbr->oi->area, current);
          break;
        }
    }

  /* Do some internal house keeping that is needed here */
  SET_FLAG (new->flags, OSPF_LSA_RECEIVED);
  ospf_lsa_is_self_originated (ospf, new); /* Let it set the flag */

  /* Install the new LSA in the link state database
     (replacing the current database copy).  This may cause the
     routing table calculation to be scheduled.  In addition,
     timestamp the new LSA with the current time.  The flooding
     procedure cannot overwrite the newly installed LSA until
     MinLSArrival seconds have elapsed. */  

  if (! (new = ospf_lsa_install (ospf, nbr->oi, new)))
    return -1; /* unknown LSA type or any other error condition */

  /* Acknowledge the receipt of the LSA by sending a Link State
     Acknowledgment packet back out the receiving interface. */
  if (lsa_ack_flag)
    ospf_flood_delayed_lsa_ack (nbr, new);     

  /* If this new LSA indicates that it was originated by the
     receiving router itself, the router must take special action,
     either updating the LSA or in some cases flushing it from
     the routing domain. */
  if (ospf_lsa_is_self_originated (ospf, new))
    ospf_process_self_originated_lsa (ospf, new, oi->area);
  else
    /* Update statistics value for OSPF-MIB. */
    ospf->rx_lsa_count++;

  return 0;
}

/* OSPF LSA flooding -- RFC2328 Section 13.3. */
static int
ospf_flood_through_interface (struct ospf_interface *oi,
			      struct ospf_neighbor *inbr,
			      struct ospf_lsa *lsa)
{
  struct ospf_neighbor *onbr;
  struct route_node *rn;
  int retx_flag;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_flood_through_interface(): "
	       "considering int %s, INBR(%s), LSA[%s]",
	       IF_NAME (oi), inbr ? inet_ntoa (inbr->router_id) : "NULL",
               dump_lsa_key (lsa));

  if (!ospf_if_is_enable (oi))
    return 0;

  /* Remember if new LSA is aded to a retransmit list. */
  retx_flag = 0;

  /* Each of the neighbors attached to this interface are examined,
     to determine whether they must receive the new LSA.  The following
     steps are executed for each neighbor: */
  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    {
      struct ospf_lsa *ls_req;
 
      if (rn->info == NULL)
	continue;

      onbr = rn->info;
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_flood_through_interface(): considering nbr %s (%s)",
		   inet_ntoa (onbr->router_id),
                   LOOKUP (ospf_nsm_state_msg, onbr->state));

      /* If the neighbor is in a lesser state than Exchange, it
	 does not participate in flooding, and the next neighbor
	 should be examined. */
      if (onbr->state < NSM_Exchange)
	continue;

      /* If the adjacency is not yet full (neighbor state is
	 Exchange or Loading), examine the Link state request
	 list associated with this adjacency.  If there is an
	 instance of the new LSA on the list, it indicates that
	 the neighboring router has an instance of the LSA
	 already.  Compare the new LSA to the neighbor's copy: */
      if (onbr->state < NSM_Full)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("ospf_flood_through_interface(): nbr adj is not Full");
	  ls_req = ospf_ls_request_lookup (onbr, lsa);
	  if (ls_req != NULL)
	    {
	      int ret;

	      ret = ospf_lsa_more_recent (ls_req, lsa);
	      /* The new LSA is less recent. */
	      if (ret > 0)
		continue;
	      /* The two copies are the same instance, then delete
		 the LSA from the Link state request list. */
	      else if (ret == 0)
		{
		  ospf_ls_request_delete (onbr, ls_req);
		  ospf_check_nbr_loading (onbr);
		  continue;
		}
	      /* The new LSA is more recent.  Delete the LSA
		 from the Link state request list. */
	      else
		{
		  ospf_ls_request_delete (onbr, ls_req);
		  ospf_check_nbr_loading (onbr);
		}
	    }
	}

#ifdef HAVE_OPAQUE_LSA
      if (IS_OPAQUE_LSA (lsa->data->type))
        {
          if (! CHECK_FLAG (onbr->options, OSPF_OPTION_O))
            {
              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
                zlog_debug ("Skip this neighbor: Not Opaque-capable.");
              continue;
            }

          if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (oi->ospf->opaque)
          &&  IS_LSA_SELF (lsa)
          &&  onbr->state == NSM_Full)
            {
              /* Small attempt to reduce unnecessary retransmission. */
              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
                zlog_debug ("Skip this neighbor: Initial flushing done.");
              continue;
            }
        }
#endif /* HAVE_OPAQUE_LSA */

      /* If the new LSA was received from this neighbor,
	 examine the next neighbor. */
#ifdef ORIGINAL_CODING
      if (inbr)
	if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id))
	  continue;
#else /* ORIGINAL_CODING */
      if (inbr)
        {
          /*
           * Triggered by LSUpd message parser "ospf_ls_upd ()".
           * E.g., all LSAs handling here is received via network.
           */
          if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id))
            {
              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
                zlog_debug ("Skip this neighbor: inbr == onbr");
              continue;
            }
        }
      else
        {
          /*
           * Triggered by MaxAge remover, so far.
           * NULL "inbr" means flooding starts from this node.
           */
          if (IPV4_ADDR_SAME (&lsa->data->adv_router, &onbr->router_id))
            {
              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
                zlog_debug ("Skip this neighbor: lsah->adv_router == onbr");
              continue;
            }
        }
#endif /* ORIGINAL_CODING */

      /* Add the new LSA to the Link state retransmission list
	 for the adjacency. The LSA will be retransmitted
	 at intervals until an acknowledgment is seen from
	 the neighbor. */
      ospf_ls_retransmit_add (onbr, lsa);
      retx_flag = 1;
    }

  /* If in the previous step, the LSA was NOT added to any of
     the Link state retransmission lists, there is no need to
     flood the LSA out the interface. */
  if (retx_flag == 0) 
    {
      return (inbr && inbr->oi == oi);
    }

  /* if we've received the lsa on this interface we need to perform
     additional checking */
  if (inbr && (inbr->oi == oi))
    {
      /* If the new LSA was received on this interface, and it was
	 received from either the Designated Router or the Backup
	 Designated Router, chances are that all the neighbors have
	 received the LSA already. */
      if (NBR_IS_DR (inbr) || NBR_IS_BDR (inbr))
	{
	  if (IS_DEBUG_OSPF_NSSA)
	    zlog_debug ("ospf_flood_through_interface(): "
		       "DR/BDR NOT SEND to int %s", IF_NAME (oi));
	  return 1;
	}
	  
      /* If the new LSA was received on this interface, and the
	 interface state is Backup, examine the next interface.  The
	 Designated Router will do the flooding on this interface.
	 However, if the Designated Router fails the router will
	 end up retransmitting the updates. */

      if (oi->state == ISM_Backup)
	{
	  if (IS_DEBUG_OSPF_NSSA)
	    zlog_debug ("ospf_flood_through_interface(): "
		       "ISM_Backup NOT SEND to int %s", IF_NAME (oi));
	  return 1;
	}
    }

  /* The LSA must be flooded out the interface. Send a Link State
     Update packet (including the new LSA as contents) out the
     interface.  The LSA's LS age must be incremented by InfTransDelay
     (which	must be	> 0) when it is copied into the outgoing Link
     State Update packet (until the LS age field reaches the maximum
     value of MaxAge). */
  /* XXX HASSO: Is this IS_DEBUG_OSPF_NSSA really correct? */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_flood_through_interface(): "
	       "DR/BDR sending upd to int %s", IF_NAME (oi));

  /*  RFC2328  Section 13.3
      On non-broadcast networks, separate	Link State Update
      packets must be sent, as unicasts, to each adjacent	neighbor
      (i.e., those in state Exchange or greater).	 The destination
      IP addresses for these packets are the neighbors' IP
      addresses.   */
  if (oi->type == OSPF_IFTYPE_NBMA)
    {
      struct route_node *rn;
      struct ospf_neighbor *nbr;

      for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
        if ((nbr = rn->info) != NULL)
	  if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
	    ospf_ls_upd_send_lsa (nbr, lsa, OSPF_SEND_PACKET_DIRECT);
    }
  else
    ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT);

  return 0;
}

int
ospf_flood_through_area (struct ospf_area *area,
			 struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
{
  struct listnode *node, *nnode;
  struct ospf_interface *oi;
  int lsa_ack_flag = 0;

  /* All other types are specific to a single area (Area A).  The
     eligible interfaces are all those interfaces attaching to the
     Area A.  If Area A is the backbone, this includes all the virtual
     links.  */
  for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
    {
      if (area->area_id.s_addr != OSPF_AREA_BACKBONE &&
	  oi->type ==  OSPF_IFTYPE_VIRTUALLINK) 
	continue;

#ifdef HAVE_OPAQUE_LSA
      if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) && (lsa->oi != oi))
        {
          /*
           * Link local scoped Opaque-LSA should only be flooded
           * for the link on which the LSA has received.
           */
          if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
            zlog_debug ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", lsa->oi, oi);
          continue;
        }
#endif /* HAVE_OPAQUE_LSA */

      if (ospf_flood_through_interface (oi, inbr, lsa))
	lsa_ack_flag = 1;
    }

  return (lsa_ack_flag);
}

int
ospf_flood_through_as (struct ospf *ospf, struct ospf_neighbor *inbr,
		       struct ospf_lsa *lsa)
{
  struct listnode *node;
  struct ospf_area *area;
  int lsa_ack_flag;

  lsa_ack_flag = 0;

  /* The incoming LSA is type 5 or type 7  (AS-EXTERNAL or AS-NSSA )

    Divert the Type-5 LSA's to all non-NSSA/STUB areas

    Divert the Type-7 LSA's to all NSSA areas

     AS-external-LSAs are flooded throughout the entire AS, with the
     exception of stub areas (see Section 3.6).  The eligible
     interfaces are all the router's interfaces, excluding virtual
     links and those interfaces attaching to stub areas.  */

  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7  */
    if (IS_DEBUG_OSPF_NSSA)
      zlog_debug ("Flood/AS: NSSA TRANSLATED LSA");

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      int continue_flag = 0;
      struct listnode *if_node;
      struct ospf_interface *oi;

      switch (area->external_routing)
	{
	  /* Don't send AS externals into stub areas.  Various types
             of support for partial stub areas can be implemented
             here.  NSSA's will receive Type-7's that have areas
             matching the originl LSA. */
	case OSPF_AREA_NSSA:	/* Sending Type 5 or 7 into NSSA area */
	  /* Type-7, flood NSSA area */
          if (lsa->data->type == OSPF_AS_NSSA_LSA
	      && area == lsa->area)
	    /* We will send it. */
	    continue_flag = 0;
          else
	    continue_flag = 1;  /* Skip this NSSA area for Type-5's et al */
          break;

	case OSPF_AREA_TYPE_MAX:
	case OSPF_AREA_STUB:
	  continue_flag = 1;	/* Skip this area. */
	  break;

	case OSPF_AREA_DEFAULT:
	default:
	  /* No Type-7 into normal area */
          if (lsa->data->type == OSPF_AS_NSSA_LSA) 
	    continue_flag = 1; /* skip Type-7 */
          else
	    continue_flag = 0;	/* Do this area. */
	  break;
	}
      
      /* Do continue for above switch.  Saves a big if then mess */
      if (continue_flag) 
	continue; /* main for-loop */
      
      /* send to every interface in this area */

      for (ALL_LIST_ELEMENTS_RO (area->oiflist, if_node, oi))
	{
	  /* Skip virtual links */
	  if (oi->type !=  OSPF_IFTYPE_VIRTUALLINK)
	    if (ospf_flood_through_interface (oi, inbr, lsa)) /* lsa */
	      lsa_ack_flag = 1;
	}
    } /* main area for-loop */
  
  return (lsa_ack_flag);
}

int
ospf_flood_through (struct ospf *ospf,
		    struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
{
  int lsa_ack_flag = 0;
  
  /* Type-7 LSA's for NSSA are flooded throughout the AS here, and
     upon return are updated in the LSDB for Type-7's.  Later,
     re-fresh will re-send them (and also, if ABR, packet code will
     translate to Type-5's)
  
     As usual, Type-5 LSA's (if not DISCARDED because we are STUB or
     NSSA) are flooded throughout the AS, and are updated in the
     global table.  */
#ifdef ORIGINAL_CODING
  switch (lsa->data->type)
    {
    case OSPF_ROUTER_LSA:
    case OSPF_NETWORK_LSA:
    case OSPF_SUMMARY_LSA:
    case OSPF_ASBR_SUMMARY_LSA:
#ifdef HAVE_OPAQUE_LSA
    case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */
    case OSPF_OPAQUE_AREA_LSA:
#endif /* HAVE_OPAQUE_LSA */
      lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa);
      break;
    case OSPF_AS_EXTERNAL_LSA: /* Type-5 */
#ifdef HAVE_OPAQUE_LSA
    case OSPF_OPAQUE_AS_LSA:
#endif /* HAVE_OPAQUE_LSA */
      lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa);
      break;
      /* Type-7 Only received within NSSA, then flooded */
    case OSPF_AS_NSSA_LSA:
      /* Any P-bit was installed with the Type-7. */
      lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa);

      if (IS_DEBUG_OSPF_NSSA)
	zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7.");
      break;
    default:
      break;
    }
#else /* ORIGINAL_CODING */
  /*
   * At the common sub-sub-function "ospf_flood_through_interface()",
   * a parameter "inbr" will be used to distinguish the called context
   * whether the given LSA was received from the neighbor, or the
   * flooding for the LSA starts from this node (e.g. the LSA was self-
   * originated, or the LSA is going to be flushed from routing domain).
   *
   * So, for consistency reasons, this function "ospf_flood_through()"
   * should also allow the usage that the given "inbr" parameter to be
   * NULL. If we do so, corresponding AREA parameter should be referred
   * by "lsa->area", instead of "inbr->oi->area".
   */
  switch (lsa->data->type)
    {
    case OSPF_AS_EXTERNAL_LSA: /* Type-5 */
#ifdef HAVE_OPAQUE_LSA
    case OSPF_OPAQUE_AS_LSA:
#endif /* HAVE_OPAQUE_LSA */
      lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa);
      break;
      /* Type-7 Only received within NSSA, then flooded */
    case OSPF_AS_NSSA_LSA:
      /* Any P-bit was installed with the Type-7. */

      if (IS_DEBUG_OSPF_NSSA)
	zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7.");
      /* Fallthrough */
    default:
      lsa_ack_flag = ospf_flood_through_area (lsa->area, inbr, lsa);
      break;
    }
#endif /* ORIGINAL_CODING */
  
  return (lsa_ack_flag);
}



/* Management functions for neighbor's Link State Request list. */
void
ospf_ls_request_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
  /*
   * We cannot make use of the newly introduced callback function
   * "lsdb->new_lsa_hook" to replace debug output below, just because
   * it seems no simple and smart way to pass neighbor information to
   * the common function "ospf_lsdb_add()" -- endo.
   */
  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
      zlog_debug ("RqstL(%lu)++, NBR(%s), LSA[%s]",
                  ospf_ls_request_count (nbr),
                  inet_ntoa (nbr->router_id), dump_lsa_key (lsa));

  ospf_lsdb_add (&nbr->ls_req, lsa);
}

unsigned long
ospf_ls_request_count (struct ospf_neighbor *nbr)
{
  return ospf_lsdb_count_all (&nbr->ls_req);
}

int
ospf_ls_request_isempty (struct ospf_neighbor *nbr)
{
  return ospf_lsdb_isempty (&nbr->ls_req);
}

/* Remove LSA from neighbor's ls-request list. */
void
ospf_ls_request_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
  if (nbr->ls_req_last == lsa)
    {
      ospf_lsa_unlock (&nbr->ls_req_last);
      nbr->ls_req_last = NULL;
    }

  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))	/* -- endo. */
      zlog_debug ("RqstL(%lu)--, NBR(%s), LSA[%s]",
                  ospf_ls_request_count (nbr),
                  inet_ntoa (nbr->router_id), dump_lsa_key (lsa));

  ospf_lsdb_delete (&nbr->ls_req, lsa);
}

/* Remove all LSA from neighbor's ls-requenst list. */
void
ospf_ls_request_delete_all (struct ospf_neighbor *nbr)
{
  ospf_lsa_unlock (&nbr->ls_req_last);
  nbr->ls_req_last = NULL;
  ospf_lsdb_delete_all (&nbr->ls_req);
}

/* Lookup LSA from neighbor's ls-request list. */
struct ospf_lsa *
ospf_ls_request_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
  return ospf_lsdb_lookup (&nbr->ls_req, lsa);
}

struct ospf_lsa *
ospf_ls_request_new (struct lsa_header *lsah)
{
  struct ospf_lsa *new;

  new = ospf_lsa_new ();
  new->data = ospf_lsa_data_new (OSPF_LSA_HEADER_SIZE);
  memcpy (new->data, lsah, OSPF_LSA_HEADER_SIZE);

  return new;
}


/* Management functions for neighbor's ls-retransmit list. */
unsigned long
ospf_ls_retransmit_count (struct ospf_neighbor *nbr)
{
  return ospf_lsdb_count_all (&nbr->ls_rxmt);
}

unsigned long
ospf_ls_retransmit_count_self (struct ospf_neighbor *nbr, int lsa_type)
{
  return ospf_lsdb_count_self (&nbr->ls_rxmt, lsa_type);
}

int
ospf_ls_retransmit_isempty (struct ospf_neighbor *nbr)
{
  return ospf_lsdb_isempty (&nbr->ls_rxmt);
}

/* Add LSA to be retransmitted to neighbor's ls-retransmit list. */
void
ospf_ls_retransmit_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
  struct ospf_lsa *old;

  old = ospf_ls_retransmit_lookup (nbr, lsa);

  if (ospf_lsa_more_recent (old, lsa) < 0)
    {
      if (old)
	{
	  old->retransmit_counter--;
	  ospf_lsdb_delete (&nbr->ls_rxmt, old);
	}
      lsa->retransmit_counter++;
      /*
       * We cannot make use of the newly introduced callback function
       * "lsdb->new_lsa_hook" to replace debug output below, just because
       * it seems no simple and smart way to pass neighbor information to
       * the common function "ospf_lsdb_add()" -- endo.
       */
      if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
	  zlog_debug ("RXmtL(%lu)++, NBR(%s), LSA[%s]",
                     ospf_ls_retransmit_count (nbr),
		     inet_ntoa (nbr->router_id), dump_lsa_key (lsa));
      ospf_lsdb_add (&nbr->ls_rxmt, lsa);
    }
}

/* Remove LSA from neibghbor's ls-retransmit list. */
void
ospf_ls_retransmit_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
  if (ospf_ls_retransmit_lookup (nbr, lsa))
    {
      lsa->retransmit_counter--;  
      if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))		/* -- endo. */
	  zlog_debug ("RXmtL(%lu)--, NBR(%s), LSA[%s]",
                     ospf_ls_retransmit_count (nbr),
		     inet_ntoa (nbr->router_id), dump_lsa_key (lsa));
      ospf_lsdb_delete (&nbr->ls_rxmt, lsa);
    }
}

/* Clear neighbor's ls-retransmit list. */
void
ospf_ls_retransmit_clear (struct ospf_neighbor *nbr)
{
  struct ospf_lsdb *lsdb;
  int i;

  lsdb = &nbr->ls_rxmt;

  for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
    {
      struct route_table *table = lsdb->type[i].db;
      struct route_node *rn;
      struct ospf_lsa *lsa;

      for (rn = route_top (table); rn; rn = route_next (rn))
	if ((lsa = rn->info) != NULL)
	  ospf_ls_retransmit_delete (nbr, lsa);
    }

  ospf_lsa_unlock (&nbr->ls_req_last);
  nbr->ls_req_last = NULL;
}

/* Lookup LSA from neighbor's ls-retransmit list. */
struct ospf_lsa *
ospf_ls_retransmit_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
  return ospf_lsdb_lookup (&nbr->ls_rxmt, lsa);
}

static void
ospf_ls_retransmit_delete_nbr_if (struct ospf_interface *oi,
				  struct ospf_lsa *lsa)
{
  struct route_node *rn;
  struct ospf_neighbor *nbr;
  struct ospf_lsa *lsr;

  if (ospf_if_is_enable (oi))
    for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
      /* If LSA find in LS-retransmit list, then remove it. */
      if ((nbr = rn->info) != NULL)
	{
	  lsr = ospf_ls_retransmit_lookup (nbr, lsa);
	     
	  /* If LSA find in ls-retransmit list, remove it. */
	  if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
	    ospf_ls_retransmit_delete (nbr, lsr);
	}
}

void
ospf_ls_retransmit_delete_nbr_area (struct ospf_area *area,
				    struct ospf_lsa *lsa)
{
  struct listnode *node, *nnode;
  struct ospf_interface *oi;

  for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
    ospf_ls_retransmit_delete_nbr_if (oi, lsa);
}

void
ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct listnode *node, *nnode;
  struct ospf_interface *oi;

  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
    ospf_ls_retransmit_delete_nbr_if (oi, lsa);
}


/* Sets ls_age to MaxAge and floods throu the area. 
   When we implement ASE routing, there will be anothe function
   flushing an LSA from the whole domain. */
void
ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area)
{
  /* Reset the lsa origination time such that it gives
     more time for the ACK to be received and avoid
     retransmissions */
  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
  lsa->tv_recv = recent_relative_time ();
  lsa->tv_orig = lsa->tv_recv;
  ospf_flood_through_area (area, NULL, lsa);
  ospf_lsa_maxage (area->ospf, lsa);
}

void
ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)
{
  /* Reset the lsa origination time such that it gives
     more time for the ACK to be received and avoid
     retransmissions */
  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
  lsa->tv_recv = recent_relative_time ();
  lsa->tv_orig = lsa->tv_recv;
  ospf_flood_through_as (ospf, NULL, lsa);
  ospf_lsa_maxage (ospf, lsa);
}

void
ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa)
{
  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
  
  switch (lsa->data->type)
    {
      case OSPF_ROUTER_LSA:
      case OSPF_NETWORK_LSA:
      case OSPF_SUMMARY_LSA:
      case OSPF_ASBR_SUMMARY_LSA:
      case OSPF_AS_NSSA_LSA:
#ifdef HAVE_OPAQUE_LSA
      case OSPF_OPAQUE_LINK_LSA:
      case OSPF_OPAQUE_AREA_LSA:
#endif /* HAVE_OPAQUE_LSA */
        ospf_lsa_flush_area (lsa, lsa->area);
        break;
      case OSPF_AS_EXTERNAL_LSA:
#ifdef HAVE_OPAQUE_LSA
      case OSPF_OPAQUE_AS_LSA:
#endif /* HAVE_OPAQUE_LSA */
        ospf_lsa_flush_as (ospf, lsa);
        break;
      default:
        zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type);
        break;
    }
}
