/*
 * Copyright (C) 2003 Yasuhiro Ohara
 *
 * 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 "log.h"
#include "thread.h"
#include "linklist.h"
#include "vty.h"
#include "command.h"

#include "ospf6d.h"
#include "ospf6_proto.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_message.h"
#include "ospf6_route.h"
#include "ospf6_spf.h"

#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"

#include "ospf6_flood.h"

unsigned char conf_debug_ospf6_flooding;

struct ospf6_lsdb *
ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa)
{
  struct ospf6_lsdb *lsdb = NULL;
  switch (OSPF6_LSA_SCOPE (lsa->header->type))
    {
    case OSPF6_SCOPE_LINKLOCAL:
      lsdb = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb;
      break;
    case OSPF6_SCOPE_AREA:
      lsdb = OSPF6_AREA (lsa->lsdb->data)->lsdb;
      break;
    case OSPF6_SCOPE_AS:
      lsdb = OSPF6_PROCESS (lsa->lsdb->data)->lsdb;
      break;
    default:
      assert (0);
      break;
    }
  return lsdb;
}

struct ospf6_lsdb *
ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa)
{
  struct ospf6_lsdb *lsdb_self = NULL;
  switch (OSPF6_LSA_SCOPE (lsa->header->type))
    {
    case OSPF6_SCOPE_LINKLOCAL:
      lsdb_self = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb_self;
      break;
    case OSPF6_SCOPE_AREA:
      lsdb_self = OSPF6_AREA (lsa->lsdb->data)->lsdb_self;
      break;
    case OSPF6_SCOPE_AS:
      lsdb_self = OSPF6_PROCESS (lsa->lsdb->data)->lsdb_self;
      break;
    default:
      assert (0);
      break;
    }
  return lsdb_self;
}

void
ospf6_lsa_originate (struct ospf6_lsa *lsa)
{
  struct ospf6_lsa *old;
  struct ospf6_lsdb *lsdb_self;

  /* find previous LSA */
  old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                           lsa->header->adv_router, lsa->lsdb);

  /* if the new LSA does not differ from previous,
     suppress this update of the LSA */
  if (old && ! OSPF6_LSA_IS_DIFFER (lsa, old))
    {
      if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
        zlog_debug ("Suppress updating LSA: %s", lsa->name);
      ospf6_lsa_delete (lsa);
      return;
    }

  /* store it in the LSDB for self-originated LSAs */
  lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
  ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self);

  lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
                                   OSPF_LS_REFRESH_TIME);

  if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
      IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
    {
      zlog_debug ("LSA Originate:");
      ospf6_lsa_header_print (lsa);
    }

  if (old)
    ospf6_flood_clear (old);
  ospf6_flood (NULL, lsa);
  ospf6_install_lsa (lsa);
}

void
ospf6_lsa_originate_process (struct ospf6_lsa *lsa,
                             struct ospf6 *process)
{
  lsa->lsdb = process->lsdb;
  ospf6_lsa_originate (lsa);
}

void
ospf6_lsa_originate_area (struct ospf6_lsa *lsa,
                          struct ospf6_area *oa)
{
  lsa->lsdb = oa->lsdb;
  ospf6_lsa_originate (lsa);
}

void
ospf6_lsa_originate_interface (struct ospf6_lsa *lsa,
                               struct ospf6_interface *oi)
{
  lsa->lsdb = oi->lsdb;
  ospf6_lsa_originate (lsa);
}

void
ospf6_lsa_purge (struct ospf6_lsa *lsa)
{
  struct ospf6_lsa *self;
  struct ospf6_lsdb *lsdb_self;

  /* remove it from the LSDB for self-originated LSAs */
  lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
  self = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                            lsa->header->adv_router, lsdb_self);
  if (self)
    {
      THREAD_OFF (self->expire);
      THREAD_OFF (self->refresh);
      ospf6_lsdb_remove (self, lsdb_self);
    }

  ospf6_lsa_premature_aging (lsa);
}


void
ospf6_increment_retrans_count (struct ospf6_lsa *lsa)
{
  /* The LSA must be the original one (see the description
     in ospf6_decrement_retrans_count () below) */
  lsa->retrans_count++;
}

void
ospf6_decrement_retrans_count (struct ospf6_lsa *lsa)
{
  struct ospf6_lsdb *lsdb;
  struct ospf6_lsa *orig;

  /* The LSA must be on the retrans-list of a neighbor. It means
     the "lsa" is a copied one, and we have to decrement the
     retransmission count of the original one (instead of this "lsa"'s).
     In order to find the original LSA, first we have to find
     appropriate LSDB that have the original LSA. */
  lsdb = ospf6_get_scoped_lsdb (lsa);

  /* Find the original LSA of which the retrans_count should be decremented */
  orig = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                            lsa->header->adv_router, lsdb);
  if (orig)
    {
      orig->retrans_count--;
      assert (orig->retrans_count >= 0);
    }
}

/* RFC2328 section 13.2 Installing LSAs in the database */
void
ospf6_install_lsa (struct ospf6_lsa *lsa)
{
  struct ospf6_lsa *old;
  struct timeval now;

  if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
      IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
    zlog_debug ("Install LSA: %s", lsa->name);

  /* Remove the old instance from all neighbors' Link state
     retransmission list (RFC2328 13.2 last paragraph) */
  old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                           lsa->header->adv_router, lsa->lsdb);
  if (old)
    {
      THREAD_OFF (old->expire);
      ospf6_flood_clear (old);
    }

  quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  if (! OSPF6_LSA_IS_MAXAGE (lsa))
    lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
                                    OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec);
  else
    lsa->expire = NULL;

  /* actually install */
  lsa->installed = now;
  ospf6_lsdb_add (lsa, lsa->lsdb);

  return;
}

/* RFC2740 section 3.5.2. Sending Link State Update packets */
/* RFC2328 section 13.3 Next step in the flooding procedure */
static void
ospf6_flood_interface (struct ospf6_neighbor *from,
                       struct ospf6_lsa *lsa, struct ospf6_interface *oi)
{
  struct listnode *node, *nnode;
  struct ospf6_neighbor *on;
  struct ospf6_lsa *req;
  int retrans_added = 0;
  int is_debug = 0;

  if (IS_OSPF6_DEBUG_FLOODING ||
      IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
    {
      is_debug++;
      zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
    }

  /* (1) For each neighbor */
  for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
    {
      if (is_debug)
        zlog_debug ("To neighbor %s", on->name);

      /* (a) if neighbor state < Exchange, examin next */
      if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
        {
          if (is_debug)
            zlog_debug ("Neighbor state less than ExChange, next neighbor");
          continue;
        }

      /* (b) if neighbor not yet Full, check request-list */
      if (on->state != OSPF6_NEIGHBOR_FULL)
        {
          if (is_debug)
            zlog_debug ("Neighbor not yet Full");

          req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                                   lsa->header->adv_router, on->request_list);
          if (req == NULL)
            {
              if (is_debug)
                zlog_debug ("Not on request-list for this neighbor");
              /* fall through */
            }
          else
            {
              /* If new LSA less recent, examin next neighbor */
              if (ospf6_lsa_compare (lsa, req) > 0)
                {
                  if (is_debug)
                    zlog_debug ("Requesting is newer, next neighbor");
                  continue;
                }

              /* If the same instance, delete from request-list and
                 examin next neighbor */
              if (ospf6_lsa_compare (lsa, req) == 0)
                {
                  if (is_debug)
                    zlog_debug ("Requesting the same, remove it, next neighbor");
                  ospf6_lsdb_remove (req, on->request_list);
                  continue;
                }

              /* If the new LSA is more recent, delete from request-list */
              if (ospf6_lsa_compare (lsa, req) < 0)
                {
                  if (is_debug)
                    zlog_debug ("Received is newer, remove requesting");
                  ospf6_lsdb_remove (req, on->request_list);
                  /* fall through */
                }
            }
        }

      /* (c) If the new LSA was received from this neighbor,
         examin next neighbor */
      if (from == on)
        {
          if (is_debug)
            zlog_debug ("Received is from the neighbor, next neighbor");
          continue;
        }

      /* (d) add retrans-list, schedule retransmission */
      if (is_debug)
        zlog_debug ("Add retrans-list of this neighbor");
      ospf6_increment_retrans_count (lsa);
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
      if (on->thread_send_lsupdate == NULL)
        on->thread_send_lsupdate =
          thread_add_timer (master, ospf6_lsupdate_send_neighbor,
                            on, on->ospf6_if->rxmt_interval);
      retrans_added++;
    }

  /* (2) examin next interface if not added to retrans-list */
  if (retrans_added == 0)
    {
      if (is_debug)
        zlog_debug ("No retransmission scheduled, next interface");
      return;
    }

  /* (3) If the new LSA was received on this interface,
     and it was from DR or BDR, examin next interface */
  if (from && from->ospf6_if == oi &&
      (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
    {
      if (is_debug)
        zlog_debug ("Received is from the I/F's DR or BDR, next interface");
      return;
    }

  /* (4) If the new LSA was received on this interface,
     and the interface state is BDR, examin next interface */
  if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
    {
      if (is_debug)
        zlog_debug ("Received is from the I/F, itself BDR, next interface");
      return;
    }

  /* (5) flood the LSA out the interface. */
  if (is_debug)
    zlog_debug ("Schedule flooding for the interface");
  if (if_is_broadcast (oi->interface))
    {
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
      if (oi->thread_send_lsupdate == NULL)
        oi->thread_send_lsupdate =
          thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
    }
  else
    {
      /* reschedule retransmissions to all neighbors */
      for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
        {
          THREAD_OFF (on->thread_send_lsupdate);
          on->thread_send_lsupdate =
            thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
        }
    }
}

static void
ospf6_flood_area (struct ospf6_neighbor *from,
                  struct ospf6_lsa *lsa, struct ospf6_area *oa)
{
  struct listnode *node, *nnode;
  struct ospf6_interface *oi;

  for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
    {
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
          oi != OSPF6_INTERFACE (lsa->lsdb->data))
        continue;

#if 0
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
          ospf6_is_interface_virtual_link (oi))
        continue;
#endif/*0*/

      ospf6_flood_interface (from, lsa, oi);
    }
}

static void
ospf6_flood_process (struct ospf6_neighbor *from,
                     struct ospf6_lsa *lsa, struct ospf6 *process)
{
  struct listnode *node, *nnode;
  struct ospf6_area *oa;

  for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
    {
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
          oa != OSPF6_AREA (lsa->lsdb->data))
        continue;
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
          oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
        continue;

      if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
          IS_AREA_STUB (oa))
        continue;

      ospf6_flood_area (from, lsa, oa);
    }
}

void
ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
{
  ospf6_flood_process (from, lsa, ospf6);
}

static void
ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
{
  struct listnode *node, *nnode;
  struct ospf6_neighbor *on;
  struct ospf6_lsa *rem;

  for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
    {
      rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                               lsa->header->adv_router, on->retrans_list);
      if (rem && ! ospf6_lsa_compare (rem, lsa))
        {
          if (IS_OSPF6_DEBUG_FLOODING ||
              IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
            zlog_debug ("Remove %s from retrans_list of %s",
                       rem->name, on->name);
          ospf6_decrement_retrans_count (rem);
          ospf6_lsdb_remove (rem, on->retrans_list);
        }
    }
}

static void
ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
{
  struct listnode *node, *nnode;
  struct ospf6_interface *oi;

  for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
    {
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
          oi != OSPF6_INTERFACE (lsa->lsdb->data))
        continue;

#if 0
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
          ospf6_is_interface_virtual_link (oi))
        continue;
#endif/*0*/

      ospf6_flood_clear_interface (lsa, oi);
    }
}

static void
ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
{
  struct listnode *node, *nnode;
  struct ospf6_area *oa;

  for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
    {
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
          oa != OSPF6_AREA (lsa->lsdb->data))
        continue;
      if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
          oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
        continue;

      if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
          IS_AREA_STUB (oa))
        continue;

      ospf6_flood_clear_area (lsa, oa);
    }
}

void
ospf6_flood_clear (struct ospf6_lsa *lsa)
{
  ospf6_flood_clear_process (lsa, ospf6);
}


/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
static void
ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
                                struct ospf6_neighbor *from)
{
  struct ospf6_interface *oi;
  int is_debug = 0;

  if (IS_OSPF6_DEBUG_FLOODING ||
      IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
    is_debug++;

  assert (from && from->ospf6_if);
  oi = from->ospf6_if;

  /* LSA has been flood back out receiving interface.
     No acknowledgement sent. */
  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
    {
      if (is_debug)
        zlog_debug ("No acknowledgement (BDR & FloodBack)");
      return;
    }

  /* LSA is more recent than database copy, but was not flooded
     back out receiving interface. Delayed acknowledgement sent
     if advertisement received from Designated Router,
     otherwide do nothing. */
  if (ismore_recent < 0)
    {
      if (oi->drouter == from->router_id)
        {
          if (is_debug)
            zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
          /* Delayed acknowledgement */
          ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
          if (oi->thread_send_lsack == NULL)
            oi->thread_send_lsack =
              thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
        }
      else
        {
          if (is_debug)
            zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
        }
      return;
    }

  /* LSA is a duplicate, and was treated as an implied acknowledgement.
     Delayed acknowledgement sent if advertisement received from
     Designated Router, otherwise do nothing */
  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
      CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
    {
      if (oi->drouter == from->router_id)
        {
          if (is_debug)
            zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
          /* Delayed acknowledgement */
          ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
          if (oi->thread_send_lsack == NULL)
            oi->thread_send_lsack =
              thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
        }
      else
        {
          if (is_debug)
            zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
        }
      return;
    }

  /* LSA is a duplicate, and was not treated as an implied acknowledgement.
     Direct acknowledgement sent */
  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
      ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
    {
      if (is_debug)
        zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
      if (from->thread_send_lsack == NULL)
        from->thread_send_lsack =
          thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
      return;
    }

  /* LSA's LS age is equal to Maxage, and there is no current instance
     of the LSA in the link state database, and none of router's
     neighbors are in states Exchange or Loading */
  /* Direct acknowledgement sent, but this case is handled in
     early of ospf6_receive_lsa () */
}

static void
ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
                                struct ospf6_neighbor *from)
{
  struct ospf6_interface *oi;
  int is_debug = 0;

  if (IS_OSPF6_DEBUG_FLOODING ||
      IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
    is_debug++;

  assert (from && from->ospf6_if);
  oi = from->ospf6_if;

  /* LSA has been flood back out receiving interface.
     No acknowledgement sent. */
  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
    {
      if (is_debug)
        zlog_debug ("No acknowledgement (AllOther & FloodBack)");
      return;
    }

  /* LSA is more recent than database copy, but was not flooded
     back out receiving interface. Delayed acknowledgement sent. */
  if (ismore_recent < 0)
    {
      if (is_debug)
        zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
      /* Delayed acknowledgement */
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
      if (oi->thread_send_lsack == NULL)
        oi->thread_send_lsack =
          thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
      return;
    }

  /* LSA is a duplicate, and was treated as an implied acknowledgement.
     No acknowledgement sent. */
  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
      CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
    {
      if (is_debug)
        zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
      return;
    }

  /* LSA is a duplicate, and was not treated as an implied acknowledgement.
     Direct acknowledgement sent */
  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
      ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
    {
      if (is_debug)
        zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
      ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
      if (from->thread_send_lsack == NULL)
        from->thread_send_lsack =
          thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
      return;
    }

  /* LSA's LS age is equal to Maxage, and there is no current instance
     of the LSA in the link state database, and none of router's
     neighbors are in states Exchange or Loading */
  /* Direct acknowledgement sent, but this case is handled in
     early of ospf6_receive_lsa () */
}

static void
ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
                       struct ospf6_neighbor *from)
{
  struct ospf6_interface *oi;

  assert (from && from->ospf6_if);
  oi = from->ospf6_if;

  if (oi->state == OSPF6_INTERFACE_BDR)
    ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
  else
    ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
}

/* RFC2328 section 13 (4):
   if MaxAge LSA and if we have no instance, and no neighbor
   is in states Exchange or Loading
   returns 1 if match this case, else returns 0 */
static int
ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
{
  struct ospf6_neighbor *on;
  struct ospf6_interface *oi;
  struct ospf6_area *oa;
  struct ospf6 *process = NULL;
  struct listnode *i, *j, *k;
  int count = 0;

  if (! OSPF6_LSA_IS_MAXAGE (lsa))
    return 0;

  if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
                         lsa->header->adv_router, lsa->lsdb))
    return 0;

  process = from->ospf6_if->area->ospf6;

  for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
    for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
      for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
        if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
            on->state == OSPF6_NEIGHBOR_LOADING)
          count++;

  if (count == 0)
    return 1;
  return 0;
}

/* RFC2328 section 13 The Flooding Procedure */
void
ospf6_receive_lsa (struct ospf6_neighbor *from,
                   struct ospf6_lsa_header *lsa_header)
{
  struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
  int ismore_recent;
  int is_debug = 0;

  ismore_recent = 1;
  assert (from);

  /* make lsa structure for received lsa */
  new = ospf6_lsa_create (lsa_header);

  if (IS_OSPF6_DEBUG_FLOODING ||
      IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
    {
      is_debug++;
      zlog_debug ("LSA Receive from %s", from->name);
      ospf6_lsa_header_print (new);
    }

  /* (1) LSA Checksum */
  if (! ospf6_lsa_checksum_valid (new->header))
    {
      if (is_debug)
        zlog_debug ("Wrong LSA Checksum, discard");
      ospf6_lsa_delete (new);
      return;
    }

  /* (2) Examine the LSA's LS type. 
     RFC2470 3.5.1. Receiving Link State Update packets  */
  if (IS_AREA_STUB (from->ospf6_if->area) &&
      OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
    {
      if (is_debug)
        zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
      ospf6_lsa_delete (new);
      return;
    }

  /* (3) LSA which have reserved scope is discarded
     RFC2470 3.5.1. Receiving Link State Update packets  */
  /* Flooding scope check. LSAs with unknown scope are discarded here.
     Set appropriate LSDB for the LSA */
  switch (OSPF6_LSA_SCOPE (new->header->type))
    {
    case OSPF6_SCOPE_LINKLOCAL:
      new->lsdb = from->ospf6_if->lsdb;
      break;
    case OSPF6_SCOPE_AREA:
      new->lsdb = from->ospf6_if->area->lsdb;
      break;
    case OSPF6_SCOPE_AS:
      new->lsdb = from->ospf6_if->area->ospf6->lsdb;
      break;
    default:
      if (is_debug)
        zlog_debug ("LSA has reserved scope, discard");
      ospf6_lsa_delete (new);
      return;
    }

  /* (4) if MaxAge LSA and if we have no instance, and no neighbor
         is in states Exchange or Loading */
  if (ospf6_is_maxage_lsa_drop (new, from))
    {
      /* log */
      if (is_debug)
        zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");

      /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
      ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
      if (from->thread_send_lsack == NULL)
        from->thread_send_lsack =
          thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);

      /* b) Discard */
      ospf6_lsa_delete (new);
      return;
    }

  /* (5) */
  /* lookup the same database copy in lsdb */
  old = ospf6_lsdb_lookup (new->header->type, new->header->id,
                           new->header->adv_router, new->lsdb);
  if (old)
    {
      ismore_recent = ospf6_lsa_compare (new, old);
      if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
        {
          if (is_debug)
            zlog_debug ("Received is duplicated LSA");
          SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
        }
    }

  /* if no database copy or received is more recent */
  if (old == NULL || ismore_recent < 0)
    {
      /* in case we have no database copy */
      ismore_recent = -1;

      /* (a) MinLSArrival check */
      if (old)
        {
          struct timeval now, res;
          quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
          timersub (&now, &old->installed, &res);
          if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
            {
              if (is_debug)
                zlog_debug ("LSA can't be updated within MinLSArrival, discard");
              ospf6_lsa_delete (new);
              return;   /* examin next lsa */
            }
        }

      quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);

      if (is_debug)
        zlog_debug ("Flood, Install, Possibly acknowledge the received LSA");

      /* (b) immediately flood and (c) remove from all retrans-list */
      /* Prevent self-originated LSA to be flooded. this is to make
      reoriginated instance of the LSA not to be rejected by other routers
      due to MinLSArrival. */
      if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
        ospf6_flood (from, new);

      /* (c) Remove the current database copy from all neighbors' Link
             state retransmission lists. */
      /* XXX, flood_clear ? */

      /* (d), installing lsdb, which may cause routing
              table calculation (replacing database copy) */
      ospf6_install_lsa (new);

      /* (e) possibly acknowledge */
      ospf6_acknowledge_lsa (new, ismore_recent, from);

      /* (f) Self Originated LSA, section 13.4 */
      if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
        {
          /* Self-originated LSA (newer than ours) is received from
             another router. We have to make a new instance of the LSA
             or have to flush this LSA. */
          if (is_debug)
            {
              zlog_debug ("Newer instance of the self-originated LSA");
              zlog_debug ("Schedule reorigination");
            }
          new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
        }

      return;
    }

  /* (6) if there is instance on sending neighbor's request list */
  if (ospf6_lsdb_lookup (new->header->type, new->header->id,
                         new->header->adv_router, from->request_list))
    {
      /* if no database copy, should go above state (5) */
      assert (old);

      if (is_debug)
        {
          zlog_debug ("Received is not newer, on the neighbor's request-list");
          zlog_debug ("BadLSReq, discard the received LSA");
        }

      /* BadLSReq */
      thread_add_event (master, bad_lsreq, from, 0);

      ospf6_lsa_delete (new);
      return;
    }

  /* (7) if neither one is more recent */
  if (ismore_recent == 0)
    {
      if (is_debug)
        zlog_debug ("The same instance as database copy (neither recent)");

      /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
      rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
                               new->header->adv_router, from->retrans_list);
      if (rem)
        {
          if (is_debug)
            {
              zlog_debug ("It is on the neighbor's retrans-list.");
              zlog_debug ("Treat as an Implied acknowledgement");
            }
          SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
          ospf6_decrement_retrans_count (rem);
          ospf6_lsdb_remove (rem, from->retrans_list);
        }

      if (is_debug)
        zlog_debug ("Possibly acknowledge and then discard");

      /* (b) possibly acknowledge */
      ospf6_acknowledge_lsa (new, ismore_recent, from);

      ospf6_lsa_delete (new);
      return;
    }

  /* (8) previous database copy is more recent */
    {
      assert (old);

      /* If database copy is in 'Seqnumber Wrapping',
         simply discard the received LSA */
      if (OSPF6_LSA_IS_MAXAGE (old) &&
          old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
        {
          if (is_debug)
            {
              zlog_debug ("The LSA is in Seqnumber Wrapping");
              zlog_debug ("MaxAge & MaxSeqNum, discard");
            }
          ospf6_lsa_delete (new);
          return;
        }

      /* Otherwise, Send database copy of this LSA to this neighbor */
        {
          if (is_debug)
            {
              zlog_debug ("Database copy is more recent.");
              zlog_debug ("Send back directly and then discard");
            }

          /* XXX, MinLSArrival check !? RFC 2328 13 (8) */

          ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
          if (from->thread_send_lsupdate == NULL)
            from->thread_send_lsupdate =
              thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
          ospf6_lsa_delete (new);
          return;
        }
      return;
    }
}


DEFUN (debug_ospf6_flooding,
       debug_ospf6_flooding_cmd,
       "debug ospf6 flooding",
       DEBUG_STR
       OSPF6_STR
       "Debug OSPFv3 flooding function\n"
      )
{
  OSPF6_DEBUG_FLOODING_ON ();
  return CMD_SUCCESS;
}

DEFUN (no_debug_ospf6_flooding,
       no_debug_ospf6_flooding_cmd,
       "no debug ospf6 flooding",
       NO_STR
       DEBUG_STR
       OSPF6_STR
       "Debug OSPFv3 flooding function\n"
      )
{
  OSPF6_DEBUG_FLOODING_OFF ();
  return CMD_SUCCESS;
}

int
config_write_ospf6_debug_flood (struct vty *vty)
{
  if (IS_OSPF6_DEBUG_FLOODING)
    vty_out (vty, "debug ospf6 flooding%s", VNL);
  return 0;
}

void
install_element_ospf6_debug_flood (void)
{
  install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
  install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
  install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
  install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
}





