/*
 * OSPF Link State Advertisement
 * 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 "table.h"
#include "memory.h"
#include "stream.h"
#include "log.h"
#include "thread.h"
#include "hash.h"
#include "sockunion.h"		/* for inet_aton() */
#include "checksum.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_flood.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"


u_int32_t
get_metric (u_char *metric)
{
  u_int32_t m;
  m = metric[0];
  m = (m << 8) + metric[1];
  m = (m << 8) + metric[2];
  return m;
}


struct timeval
tv_adjust (struct timeval a)
{
  while (a.tv_usec >= 1000000)
    {
      a.tv_usec -= 1000000;
      a.tv_sec++;
    }

  while (a.tv_usec < 0)
    {
      a.tv_usec += 1000000;
      a.tv_sec--;
    }

  return a;
}

int
tv_ceil (struct timeval a)
{
  a = tv_adjust (a);

  return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
}

int
tv_floor (struct timeval a)
{
  a = tv_adjust (a);

  return a.tv_sec;
}

struct timeval
int2tv (int a)
{
  struct timeval ret;

  ret.tv_sec = a;
  ret.tv_usec = 0;

  return ret;
}

struct timeval
msec2tv (int a)
{
  struct timeval ret;

  ret.tv_sec = 0;
  ret.tv_usec = a * 1000;

  return tv_adjust (ret);
}

struct timeval
tv_add (struct timeval a, struct timeval b)
{
  struct timeval ret;

  ret.tv_sec = a.tv_sec + b.tv_sec;
  ret.tv_usec = a.tv_usec + b.tv_usec;

  return tv_adjust (ret);
}

struct timeval
tv_sub (struct timeval a, struct timeval b)
{
  struct timeval ret;

  ret.tv_sec = a.tv_sec - b.tv_sec;
  ret.tv_usec = a.tv_usec - b.tv_usec;

  return tv_adjust (ret);
}

int
tv_cmp (struct timeval a, struct timeval b)
{
  return (a.tv_sec == b.tv_sec ?
	  a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
}

int
ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
{
  struct timeval delta, now;
  int delay = 0;

  quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  delta = tv_sub (now, lsa->tv_orig);

  if (tv_cmp (delta, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0)
    {
      delay = tv_ceil (tv_sub (msec2tv (OSPF_MIN_LS_INTERVAL), delta));

      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
	           lsa->data->type, inet_ntoa (lsa->data->id), delay);

      assert (delay > 0);
    }

  return delay;
}


int
get_age (struct ospf_lsa *lsa)
{
  int age;

  age = ntohs (lsa->data->ls_age) 
        + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));

  return age;
}


/* Fletcher Checksum -- Refer to RFC1008. */

/* All the offsets are zero-based. The offsets in the RFC1008 are 
   one-based. */
u_int16_t
ospf_lsa_checksum (struct lsa_header *lsa)
{
  u_char *buffer = (u_char *) &lsa->options;
  int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */

  /* Skip the AGE field */
  u_int16_t len = ntohs(lsa->length) - options_offset; 

  /* Checksum offset starts from "options" field, not the beginning of the
     lsa_header struct. The offset is 14, rather than 16. */
  int checksum_offset = (u_char *) &lsa->checksum - buffer;

  return fletcher_checksum(buffer, len, checksum_offset);
}

int
ospf_lsa_checksum_valid (struct lsa_header *lsa)
{
  u_char *buffer = (u_char *) &lsa->options;
  int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */

  /* Skip the AGE field */
  u_int16_t len = ntohs(lsa->length) - options_offset;

  return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
}



/* Create OSPF LSA. */
struct ospf_lsa *
ospf_lsa_new ()
{
  struct ospf_lsa *new;

  new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));

  new->flags = 0;
  new->lock = 1;
  new->retransmit_counter = 0;
  new->tv_recv = recent_relative_time ();
  new->tv_orig = new->tv_recv;
  new->refresh_list = -1;
  
  return new;
}

/* Duplicate OSPF LSA. */
struct ospf_lsa *
ospf_lsa_dup (struct ospf_lsa *lsa)
{
  struct ospf_lsa *new;

  if (lsa == NULL)
    return NULL;

  new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));

  memcpy (new, lsa, sizeof (struct ospf_lsa));
  UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
  new->lock = 1;
  new->retransmit_counter = 0;
  new->data = ospf_lsa_data_dup (lsa->data);

  /* kevinm: Clear the refresh_list, otherwise there are going
     to be problems when we try to remove the LSA from the
     queue (which it's not a member of.)
     XXX: Should we add the LSA to the refresh_list queue? */
  new->refresh_list = -1;

  if (IS_DEBUG_OSPF (lsa, LSA))
    zlog_debug ("LSA: duplicated %p (new: %p)", (void *)lsa, (void *)new);

  return new;
}

/* Free OSPF LSA. */
void
ospf_lsa_free (struct ospf_lsa *lsa)
{
  assert (lsa->lock == 0);
  
  if (IS_DEBUG_OSPF (lsa, LSA))
    zlog_debug ("LSA: freed %p", (void *)lsa);

  /* Delete LSA data. */
  if (lsa->data != NULL)
    ospf_lsa_data_free (lsa->data);

  assert (lsa->refresh_list < 0);

  memset (lsa, 0, sizeof (struct ospf_lsa)); 
  XFREE (MTYPE_OSPF_LSA, lsa);
}

/* Lock LSA. */
struct ospf_lsa *
ospf_lsa_lock (struct ospf_lsa *lsa)
{
  lsa->lock++;
  return lsa;
}

/* Unlock LSA. */
void
ospf_lsa_unlock (struct ospf_lsa **lsa)
{
  /* This is sanity check. */
  if (!lsa || !*lsa)
    return;
  
  (*lsa)->lock--;

  assert ((*lsa)->lock >= 0);

  if ((*lsa)->lock == 0)
    {
      assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
      ospf_lsa_free (*lsa);
      *lsa = NULL;
    }
}

/* Check discard flag. */
void
ospf_lsa_discard (struct ospf_lsa *lsa)
{
  if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
    {
      SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
      ospf_lsa_unlock (&lsa);
    }
}

/* Create LSA data. */
struct lsa_header *
ospf_lsa_data_new (size_t size)
{
  return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
}

/* Duplicate LSA data. */
struct lsa_header *
ospf_lsa_data_dup (struct lsa_header *lsah)
{
  struct lsa_header *new;

  new = ospf_lsa_data_new (ntohs (lsah->length));
  memcpy (new, lsah, ntohs (lsah->length));

  return new;
}

/* Free LSA data. */
void
ospf_lsa_data_free (struct lsa_header *lsah)
{
  if (IS_DEBUG_OSPF (lsa, LSA))
    zlog_debug ("LSA[Type%d:%s]: data freed %p",
	       lsah->type, inet_ntoa (lsah->id), (void *)lsah);

  XFREE (MTYPE_OSPF_LSA_DATA, lsah);
}


/* LSA general functions. */

const char *
dump_lsa_key (struct ospf_lsa *lsa)
{
  static char buf[] = {
    "Type255,id(255.255.255.255),ar(255.255.255.255)"
  };
  struct lsa_header *lsah;

  if (lsa != NULL && (lsah = lsa->data) != NULL)
    {
      char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
      strcpy (id, inet_ntoa (lsah->id));
      strcpy (ar, inet_ntoa (lsah->adv_router));

      sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
    }
  else
    strcpy (buf, "NULL");

  return buf;
}

u_int32_t
lsa_seqnum_increment (struct ospf_lsa *lsa)
{
  u_int32_t seqnum;

  seqnum = ntohl (lsa->data->ls_seqnum) + 1;

  return htonl (seqnum);
}

void
lsa_header_set (struct stream *s, u_char options,
		u_char type, struct in_addr id, struct in_addr router_id)
{
  struct lsa_header *lsah;

  lsah = (struct lsa_header *) STREAM_DATA (s);

  lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
  lsah->options = options;
  lsah->type = type;
  lsah->id = id;
  lsah->adv_router = router_id;
  lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);

  stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
}


/* router-LSA related functions. */
/* Get router-LSA flags. */
static u_char
router_lsa_flags (struct ospf_area *area)
{
  u_char flags;

  flags = area->ospf->flags;

  /* Set virtual link flag. */
  if (ospf_full_virtual_nbrs (area))
    SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
  else
    /* Just sanity check */
    UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);

  /* Set Shortcut ABR behabiour flag. */
  UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
  if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
    if (!OSPF_IS_AREA_BACKBONE (area))
      if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
	   area->ospf->backbone == NULL) ||
	  area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
	SET_FLAG (flags, ROUTER_LSA_SHORTCUT);

  /* ASBR can't exit in stub area. */
  if (area->external_routing == OSPF_AREA_STUB)
    UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
  /* If ASBR set External flag */
  else if (IS_OSPF_ASBR (area->ospf))
    SET_FLAG (flags, ROUTER_LSA_EXTERNAL);

  /* Set ABR dependent flags */
  if (IS_OSPF_ABR (area->ospf))
    {
      SET_FLAG (flags,  ROUTER_LSA_BORDER);
      /* If Area is NSSA and we are both ABR and unconditional translator, 
       * set Nt bit to inform other routers.
       */
      if ( (area->external_routing == OSPF_AREA_NSSA)
           && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
        SET_FLAG (flags, ROUTER_LSA_NT);
    }
  return flags;
}

/* Lookup neighbor other than myself.
   And check neighbor count,
   Point-to-Point link must have only 1 neighbor. */
struct ospf_neighbor *
ospf_nbr_lookup_ptop (struct ospf_interface *oi)
{
  struct ospf_neighbor *nbr = NULL;
  struct route_node *rn;

  /* Search neighbor, there must be one of two nbrs. */
  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info))
      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
	if (nbr->state == NSM_Full)
	  {
	    route_unlock_node (rn);
	    break;
	  }

  /* PtoP link must have only 1 neighbor. */
  if (ospf_nbr_count (oi, 0) > 1)
    zlog_warn ("Point-to-Point link has more than 1 neighobrs.");

  return nbr;
}

/* Determine cost of link, taking RFC3137 stub-router support into
 * consideration
 */
static u_int16_t
ospf_link_cost (struct ospf_interface *oi)
{
  /* RFC3137 stub router support */
  if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
    return oi->output_cost;
  else
    return OSPF_OUTPUT_COST_INFINITE;
}

/* Set a link information. */
static char
link_info_set (struct stream *s, struct in_addr id,
	       struct in_addr data, u_char type, u_char tos, u_int16_t cost)
{
  /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
   * vast majority of cases. Some rare routers with lots of links need more.
   * we try accomodate those here.
   */
  if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
    {
      size_t ret = OSPF_MAX_LSA_SIZE;
      
      /* Can we enlarge the stream still? */
      if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
        {
          /* we futz the size here for simplicity, really we need to account
           * for just:
           * IP Header - (sizeof (struct ip))
           * OSPF Header - OSPF_HEADER_SIZE
           * LSA Header - OSPF_LSA_HEADER_SIZE
           * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
           *
           * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
           */
          ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
        }
      
      if (ret == OSPF_MAX_LSA_SIZE)
        {
          zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
                     __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
          return 0;
        }
    }
  
  /* TOS based routing is not supported. */
  stream_put_ipv4 (s, id.s_addr);		/* Link ID. */
  stream_put_ipv4 (s, data.s_addr);		/* Link Data. */
  stream_putc (s, type);			/* Link Type. */
  stream_putc (s, tos);				/* TOS = 0. */
  stream_putw (s, cost);			/* Link Cost. */
  
  return 1;
}

/* Describe Point-to-Point link (Section 12.4.1.1). */
static int
lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
{
  int links = 0;
  struct ospf_neighbor *nbr;
  struct in_addr id, mask;
  u_int16_t cost = ospf_link_cost (oi);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type1]: Set link Point-to-Point");

  if ((nbr = ospf_nbr_lookup_ptop (oi)))
    if (nbr->state == NSM_Full)
      {
	/* For unnumbered point-to-point networks, the Link Data field
	   should specify the interface's MIB-II ifIndex value. */
	links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
		                LSA_LINK_TYPE_POINTOPOINT, 0, cost);
      }

  /* Regardless of the state of the neighboring router, we must
     add a Type 3 link (stub network).
     N.B. Options 1 & 2 share basically the same logic. */
  masklen2ip (oi->address->prefixlen, &mask);
  id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
  links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
			  oi->output_cost);
  return links;
}

/* Describe Broadcast Link. */
static int
lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
{
  struct ospf_neighbor *dr;
  struct in_addr id, mask;
  u_int16_t cost = ospf_link_cost (oi);
  
  /* Describe Type 3 Link. */
  if (oi->state == ISM_Waiting)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type1]: Interface %s is in state Waiting. "
                    "Adding stub interface", oi->ifp->name);
      masklen2ip (oi->address->prefixlen, &mask);
      id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
      return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
                            oi->output_cost);
    }

  dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
  /* Describe Type 2 link. */
  if (dr && (dr->state == NSM_Full ||
	     IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
      ospf_nbr_count (oi, NSM_Full) > 0)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type1]: Interface %s has a DR. "
                    "Adding transit interface", oi->ifp->name);
      return link_info_set (s, DR (oi), oi->address->u.prefix4,
                            LSA_LINK_TYPE_TRANSIT, 0, cost);
    }
  /* Describe type 3 link. */
  else
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type1]: Interface %s has no DR. "
                    "Adding stub interface", oi->ifp->name);
      masklen2ip (oi->address->prefixlen, &mask);
      id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
      return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
                            oi->output_cost);
    }
}

static int
lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
{
  struct in_addr id, mask;
  
  /* Describe Type 3 Link. */
  if (oi->state != ISM_Loopback)
    return 0;

  mask.s_addr = 0xffffffff;
  id.s_addr = oi->address->u.prefix4.s_addr;
  return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
}

/* Describe Virtual Link. */
static int
lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
{
  struct ospf_neighbor *nbr;
  u_int16_t cost = ospf_link_cost (oi);

  if (oi->state == ISM_PointToPoint)
    if ((nbr = ospf_nbr_lookup_ptop (oi)))
      if (nbr->state == NSM_Full)
	{
	  return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
			        LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
	}

  return 0;
}

#define lsa_link_nbma_set(S,O)  lsa_link_broadcast_set (S, O)

/* this function add for support point-to-multipoint ,see rfc2328 
12.4.1.4.*/
/* from "edward rrr" <edward_rrr@hotmail.com>
   http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
static int
lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
{
  int links = 0;
  struct route_node *rn;
  struct ospf_neighbor *nbr = NULL;
  struct in_addr id, mask;
  u_int16_t cost = ospf_link_cost (oi);

  mask.s_addr = 0xffffffff;
  id.s_addr = oi->address->u.prefix4.s_addr;
  links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("PointToMultipoint: running ptomultip_set");

  /* Search neighbor, */
  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info) != NULL)
      /* Ignore myself. */
      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
	if (nbr->state == NSM_Full)

	  {
	    links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
			            LSA_LINK_TYPE_POINTOPOINT, 0, cost);
            if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
 	      zlog_debug ("PointToMultipoint: set link to %s",
		         inet_ntoa(oi->address->u.prefix4));
	  }
  
  return links;
}

/* Set router-LSA link information. */
static int
router_lsa_link_set (struct stream *s, struct ospf_area *area)
{
  struct listnode *node;
  struct ospf_interface *oi;
  int links = 0;

  for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
    {
      struct interface *ifp = oi->ifp;

      /* Check interface is up, OSPF is enable. */
      if (if_is_operative (ifp))
	{
	  if (oi->state != ISM_Down)
	    {
	      oi->lsa_pos_beg = links;
	      /* Describe each link. */
	      switch (oi->type)
		{
		case OSPF_IFTYPE_POINTOPOINT:
		  links += lsa_link_ptop_set (s, oi);
		  break;
		case OSPF_IFTYPE_BROADCAST:
		  links += lsa_link_broadcast_set (s, oi);
		  break;
		case OSPF_IFTYPE_NBMA:
		  links += lsa_link_nbma_set (s, oi);
		  break;
		case OSPF_IFTYPE_POINTOMULTIPOINT:
		  links += lsa_link_ptomp_set (s, oi);
		  break;
		case OSPF_IFTYPE_VIRTUALLINK:
		  links += lsa_link_virtuallink_set (s, oi);
		  break;
		case OSPF_IFTYPE_LOOPBACK:
		  links += lsa_link_loopback_set (s, oi); 
		}
	      oi->lsa_pos_end = links;
	    }
	}
    }

  return links;
}

/* Set router-LSA body. */
static void
ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
{
  unsigned long putp;
  u_int16_t cnt;

  /* Set flags. */
  stream_putc (s, router_lsa_flags (area));

  /* Set Zero fields. */
  stream_putc (s, 0);

  /* Keep pointer to # links. */
  putp = stream_get_endp(s);

  /* Forward word */
  stream_putw(s, 0);

  /* Set all link information. */
  cnt = router_lsa_link_set (s, area);

  /* Set # of links here. */
  stream_putw_at (s, putp, cnt);
}

static int
ospf_stub_router_timer (struct thread *t)
{
  struct ospf_area *area = THREAD_ARG (t);
  
  area->t_stub_router = NULL;
  
  SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
  
  /* clear stub route state and generate router-lsa refresh, don't
   * clobber an administratively set stub-router state though.
   */
  if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
    return 0;
  
  UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
  
  ospf_router_lsa_update_area (area);
  
  return 0;
}

static void
ospf_stub_router_check (struct ospf_area *area)
{
  /* area must either be administratively configured to be stub
   * or startup-time stub-router must be configured and we must in a pre-stub
   * state.
   */
  if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
    {
      SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
      return;
    }
  
  /* not admin-stubbed, check whether startup stubbing is configured and
   * whether it's not been done yet
   */
  if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
    return;
  
  if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
    {
      /* stub-router is hence done forever for this area, even if someone
       * tries configure it (take effect next restart).
       */
      SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
      return;
    }
  
  /* startup stub-router configured and not yet done */
  SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
  
  OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
                      area->ospf->stub_router_startup_time);
}
 
/* Create new router-LSA. */
static struct ospf_lsa *
ospf_router_lsa_new (struct ospf_area *area)
{
  struct ospf *ospf = area->ospf;
  struct stream *s;
  struct lsa_header *lsah;
  struct ospf_lsa *new;
  int length;

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type1]: Create router-LSA instance");

  /* check whether stub-router is desired, and if this is the first 
   * router LSA.
   */
  ospf_stub_router_check (area);
  
  /* Create a stream for LSA. */
  s = stream_new (OSPF_MAX_LSA_SIZE);
  /* Set LSA common header fields. */
  lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
		  OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);

  /* Set router-LSA body fields. */
  ospf_router_lsa_body_set (s, area);

  /* Set length. */
  length = stream_get_endp (s);
  lsah = (struct lsa_header *) STREAM_DATA (s);
  lsah->length = htons (length);

  /* Now, create OSPF LSA instance. */
  if ( (new = ospf_lsa_new ()) == NULL)
    {
      zlog_err ("%s: Unable to create new lsa", __func__);
      return NULL;
    }
  
  new->area = area;
  SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);

  /* Copy LSA data to store, discard stream. */
  new->data = ospf_lsa_data_new (length);
  memcpy (new->data, lsah, length);
  stream_free (s);

  return new;
}

/* Originate Router-LSA. */
static struct ospf_lsa *
ospf_router_lsa_originate (struct ospf_area *area)
{
  struct ospf_lsa *new;
  
  /* Create new router-LSA instance. */
  if ( (new = ospf_router_lsa_new (area)) == NULL)
    {
      zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
      return NULL;
    }

  /* Sanity check. */
  if (new->data->adv_router.s_addr == 0)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
      ospf_lsa_discard (new);
      return NULL;
    }

  /* Install LSA to LSDB. */
  new = ospf_lsa_install (area->ospf, NULL, new);

  /* Update LSA origination count. */
  area->ospf->lsa_originate_count++;

  /* Flooding new LSA through area. */
  ospf_flood_through_area (area, NULL, new);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
		 new->data->type, inet_ntoa (new->data->id), (void *)new);
      ospf_lsa_header_dump (new->data);
    }

  return new;
}

/* Refresh router-LSA. */
static struct ospf_lsa *
ospf_router_lsa_refresh (struct ospf_lsa *lsa)
{
  struct ospf_area *area = lsa->area;
  struct ospf_lsa *new;

  /* Sanity check. */
  assert (lsa->data);

  /* Delete LSA from neighbor retransmit-list. */
  ospf_ls_retransmit_delete_nbr_area (area, lsa);

  /* Unregister LSA from refresh-list */
  ospf_refresher_unregister_lsa (area->ospf, lsa);
  
  /* Create new router-LSA instance. */
  if ( (new = ospf_router_lsa_new (area)) == NULL)
    {
      zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
      return NULL;
    }
  
  new->data->ls_seqnum = lsa_seqnum_increment (lsa);

  ospf_lsa_install (area->ospf, NULL, new);

  /* Flood LSA through area. */
  ospf_flood_through_area (area, NULL, new);

  /* Debug logging. */
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
		 new->data->type, inet_ntoa (new->data->id));
      ospf_lsa_header_dump (new->data);
    }

  return NULL;
}

int
ospf_router_lsa_update_area (struct ospf_area *area)
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("[router-LSA]: (router-LSA area update)");

  /* Now refresh router-LSA. */
  if (area->router_lsa_self)
    ospf_lsa_refresh (area->ospf, area->router_lsa_self);
  /* Newly originate router-LSA. */
  else
    ospf_router_lsa_originate (area);

  return 0;
}

int
ospf_router_lsa_update (struct ospf *ospf)
{
  struct listnode *node, *nnode;
  struct ospf_area *area;

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("Timer[router-LSA Update]: (timer expire)");

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    {
      struct ospf_lsa *lsa = area->router_lsa_self;
      struct router_lsa *rl;
      const char *area_str;

      /* Keep Area ID string. */
      area_str = AREA_NAME (area);

      /* If LSA not exist in this Area, originate new. */
      if (lsa == NULL)
        {
	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
	    zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);

	  ospf_router_lsa_originate (area);
        }
      /* If router-ID is changed, Link ID must change.
	 First flush old LSA, then originate new. */
      else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
	{
	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
	    zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
		      lsa->data->type, inet_ntoa (lsa->data->id), area_str);
          ospf_refresher_unregister_lsa (ospf, lsa);
	  ospf_lsa_flush_area (lsa, area);
	  ospf_lsa_unlock (&area->router_lsa_self);
	  area->router_lsa_self = NULL;

	  /* Refresh router-LSA, (not install) and flood through area. */
	  ospf_router_lsa_update_area (area);
	}
      else
	{
	  rl = (struct router_lsa *) lsa->data;
	  /* Refresh router-LSA, (not install) and flood through area. */
	  if (rl->flags != ospf->flags)
	    ospf_router_lsa_update_area (area);
	}
    }

  return 0;
}


/* network-LSA related functions. */
/* Originate Network-LSA. */
static void
ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
{
  struct in_addr mask;
  struct route_node *rn;
  struct ospf_neighbor *nbr;

  masklen2ip (oi->address->prefixlen, &mask);
  stream_put_ipv4 (s, mask.s_addr);

  /* The network-LSA lists those routers that are fully adjacent to
    the Designated Router; each fully adjacent router is identified by
    its OSPF Router ID.  The Designated Router includes itself in this
    list. RFC2328, Section 12.4.2 */

  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info) != NULL)
      if (nbr->state == NSM_Full || nbr == oi->nbr_self)
	stream_put_ipv4 (s, nbr->router_id.s_addr);
}

static struct ospf_lsa *
ospf_network_lsa_new (struct ospf_interface *oi)
{
  struct stream *s;
  struct ospf_lsa *new;
  struct lsa_header *lsah;
  struct ospf_if_params *oip;
  int length;

  /* If there are no neighbours on this network (the net is stub),
     the router does not originate network-LSA (see RFC 12.4.2) */
  if (oi->full_nbrs == 0)
    return NULL;
  
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type2]: Create network-LSA instance");

  /* Create new stream for LSA. */
  s = stream_new (OSPF_MAX_LSA_SIZE);
  lsah = (struct lsa_header *) STREAM_DATA (s);

  lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
		  OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);

  /* Set network-LSA body fields. */
  ospf_network_lsa_body_set (s, oi);

  /* Set length. */
  length = stream_get_endp (s);
  lsah->length = htons (length);

  /* Create OSPF LSA instance. */
  if ( (new = ospf_lsa_new ()) == NULL)
    {
      zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
      return NULL;
    }
  
  new->area = oi->area;
  SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);

  /* Copy LSA to store. */
  new->data = ospf_lsa_data_new (length);
  memcpy (new->data, lsah, length);
  stream_free (s);
  
  /* Remember prior network LSA sequence numbers, even if we stop
   * originating one for this oi, to try avoid re-originating LSAs with a
   * prior sequence number, and thus speed up adjency forming & convergence.
   */
  if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
    {
      new->data->ls_seqnum = oip->network_lsa_seqnum;
      new->data->ls_seqnum = lsa_seqnum_increment (new);
    }
  else
    {
      oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
      ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
    }
  oip->network_lsa_seqnum = new->data->ls_seqnum;
  
  return new;
}

/* Originate network-LSA. */
void
ospf_network_lsa_update (struct ospf_interface *oi)
{
  struct ospf_lsa *new;
  
  if (oi->network_lsa_self != NULL)
    {
      ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
      return;
    }
  
  /* Create new network-LSA instance. */
  new = ospf_network_lsa_new (oi);
  if (new == NULL)
    return;

  /* Install LSA to LSDB. */
  new = ospf_lsa_install (oi->ospf, oi, new);

  /* Update LSA origination count. */
  oi->ospf->lsa_originate_count++;

  /* Flooding new LSA through area. */
  ospf_flood_through_area (oi->area, NULL, new);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
		 new->data->type, inet_ntoa (new->data->id), (void *)new);
      ospf_lsa_header_dump (new->data);
    }

  return;
}

static struct ospf_lsa *
ospf_network_lsa_refresh (struct ospf_lsa *lsa)
{
  struct ospf_area *area = lsa->area;
  struct ospf_lsa *new, *new2;
  struct ospf_if_params *oip;
  struct ospf_interface *oi;
  
  assert (lsa->data);
  
  /* Retrieve the oi for the network LSA */
  oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
  if (oi == NULL)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        {
          zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
                      "no oi found, ick, ignoring.",
		      lsa->data->type, inet_ntoa (lsa->data->id));
          ospf_lsa_header_dump (lsa->data);
        }
      return NULL;
    }
  /* Delete LSA from neighbor retransmit-list. */
  ospf_ls_retransmit_delete_nbr_area (area, lsa);

  /* Unregister LSA from refresh-list */
  ospf_refresher_unregister_lsa (area->ospf, lsa);
  
  /* Create new network-LSA instance. */
  new = ospf_network_lsa_new (oi);
  if (new == NULL)
    return NULL;
  
  oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
  assert (oip != NULL);
  oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);

  new2 = ospf_lsa_install (area->ospf, oi, new);
  
  assert (new2 == new);
  
  /* Flood LSA through aera. */
  ospf_flood_through_area (area, NULL, new);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
		 new->data->type, inet_ntoa (new->data->id));
      ospf_lsa_header_dump (new->data);
    }

  return new;
}

static void
stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
{
  u_int32_t metric;
  char *mp;

  /* Put 0 metric. TOS metric is not supported. */
  metric = htonl (metric_value);
  mp = (char *) &metric;
  mp++;
  stream_put (s, mp, 3);
}

/* summary-LSA related functions. */
static void
ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
			   u_int32_t metric)
{
  struct in_addr mask;

  masklen2ip (p->prefixlen, &mask);

  /* Put Network Mask. */
  stream_put_ipv4 (s, mask.s_addr);

  /* Set # TOS. */
  stream_putc (s, (u_char) 0);

  /* Set metric. */
  stream_put_ospf_metric (s, metric);
}

static struct ospf_lsa *
ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
		      u_int32_t metric, struct in_addr id)
{
  struct stream *s;
  struct ospf_lsa *new;
  struct lsa_header *lsah;
  int length;

  if (id.s_addr == 0xffffffff)
    {
      /* Maybe Link State ID not available. */
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
                    OSPF_SUMMARY_LSA);
      return NULL;
    }

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type3]: Create summary-LSA instance");

  /* Create new stream for LSA. */
  s = stream_new (OSPF_MAX_LSA_SIZE);
  lsah = (struct lsa_header *) STREAM_DATA (s);

  lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
		  id, area->ospf->router_id);

  /* Set summary-LSA body fields. */
  ospf_summary_lsa_body_set (s, p, metric);

  /* Set length. */
  length = stream_get_endp (s);
  lsah->length = htons (length);

  /* Create OSPF LSA instance. */
  new = ospf_lsa_new ();
  new->area = area;
  SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);

  /* Copy LSA to store. */
  new->data = ospf_lsa_data_new (length);
  memcpy (new->data, lsah, length);
  stream_free (s);

  return new;
}

/* Originate Summary-LSA. */
struct ospf_lsa *
ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric, 
			    struct ospf_area *area)
{
  struct ospf_lsa *new;
  struct in_addr id;
  
  id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);

  if (id.s_addr == 0xffffffff)
    {
      /* Maybe Link State ID not available. */
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
                    OSPF_SUMMARY_LSA);
      return NULL;
    }
  
  /* Create new summary-LSA instance. */
  if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
    return NULL;

  /* Instlal LSA to LSDB. */
  new = ospf_lsa_install (area->ospf, NULL, new);

  /* Update LSA origination count. */
  area->ospf->lsa_originate_count++;

  /* Flooding new LSA through area. */
  ospf_flood_through_area (area, NULL, new);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
		 new->data->type, inet_ntoa (new->data->id), (void *)new);
      ospf_lsa_header_dump (new->data);
    }

  return new;
}

static struct ospf_lsa*
ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct ospf_lsa *new;
  struct summary_lsa *sl;
  struct prefix p;
  
  /* Sanity check. */
  assert (lsa->data);

  sl = (struct summary_lsa *)lsa->data;
  p.prefixlen = ip_masklen (sl->mask);
  new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
			      sl->header.id);
  
  if (!new)
    return NULL;
  
  new->data->ls_seqnum = lsa_seqnum_increment (lsa);

  ospf_lsa_install (ospf, NULL, new);
  
  /* Flood LSA through AS. */
  ospf_flood_through_area (new->area, NULL, new);

  /* Debug logging. */
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
		 new->data->type, inet_ntoa (new->data->id));
      ospf_lsa_header_dump (new->data);
    }
  
  return new;
}


/* summary-ASBR-LSA related functions. */
static void
ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
				u_int32_t metric)
{
  /* Put Network Mask. */
  stream_put_ipv4 (s, (u_int32_t) 0);

  /* Set # TOS. */
  stream_putc (s, (u_char) 0);

  /* Set metric. */
  stream_put_ospf_metric (s, metric);
}

static struct ospf_lsa *
ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
			   u_int32_t metric, struct in_addr id)
{
  struct stream *s;
  struct ospf_lsa *new;
  struct lsa_header *lsah;
  int length;

  if (id.s_addr == 0xffffffff)
    {
      /* Maybe Link State ID not available. */
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
                    OSPF_ASBR_SUMMARY_LSA);
      return NULL;
    }

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type3]: Create summary-LSA instance");

  /* Create new stream for LSA. */
  s = stream_new (OSPF_MAX_LSA_SIZE);
  lsah = (struct lsa_header *) STREAM_DATA (s);

  lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
		  id, area->ospf->router_id);

  /* Set summary-LSA body fields. */
  ospf_summary_asbr_lsa_body_set (s, p, metric);

  /* Set length. */
  length = stream_get_endp (s);
  lsah->length = htons (length);

  /* Create OSPF LSA instance. */
  new = ospf_lsa_new ();
  new->area = area;
  SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);

  /* Copy LSA to store. */
  new->data = ospf_lsa_data_new (length);
  memcpy (new->data, lsah, length);
  stream_free (s);

  return new;
}

/* Originate summary-ASBR-LSA. */
struct ospf_lsa *
ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric, 
				 struct ospf_area *area)
{
  struct ospf_lsa *new;
  struct in_addr id;
  
  id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);

  if (id.s_addr == 0xffffffff)
    {
      /* Maybe Link State ID not available. */
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
                    OSPF_ASBR_SUMMARY_LSA);
      return NULL;
    }
  
  /* Create new summary-LSA instance. */
  new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
  if (!new)
    return NULL;

  /* Install LSA to LSDB. */
  new = ospf_lsa_install (area->ospf, NULL, new);
  
  /* Update LSA origination count. */
  area->ospf->lsa_originate_count++;

  /* Flooding new LSA through area. */
  ospf_flood_through_area (area, NULL, new);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
		 new->data->type, inet_ntoa (new->data->id), (void *)new);
      ospf_lsa_header_dump (new->data);
    }

  return new;
}

static struct ospf_lsa*
ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct ospf_lsa *new;
  struct summary_lsa *sl;
  struct prefix p;

  /* Sanity check. */
  assert (lsa->data);

  sl = (struct summary_lsa *)lsa->data;
  p.prefixlen = ip_masklen (sl->mask);
  new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
				   sl->header.id);
  if (!new)
    return NULL;
  
  new->data->ls_seqnum = lsa_seqnum_increment (lsa);

  ospf_lsa_install (ospf, NULL, new);
  
  /* Flood LSA through area. */
  ospf_flood_through_area (new->area, NULL, new);

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
		 new->data->type, inet_ntoa (new->data->id));
      ospf_lsa_header_dump (new->data);
    }

  return new;
}

/* AS-external-LSA related functions. */

/* Get nexthop for AS-external-LSAs.  Return nexthop if its interface
   is connected, else 0*/
static struct in_addr
ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
{
  struct in_addr fwd;
  struct prefix nh;
  struct listnode *node;
  struct ospf_interface *oi;

  fwd.s_addr = 0;

  if (!nexthop.s_addr)
    return fwd;

  /* Check whether nexthop is covered by OSPF network. */
  nh.family = AF_INET;
  nh.u.prefix4 = nexthop;
  nh.prefixlen = IPV4_MAX_BITLEN;
  
  /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
   * better to make use of the per-ifp table of ois.
   */
  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    if (if_is_operative (oi->ifp))
      if (oi->address->family == AF_INET)
        if (prefix_match (oi->address, &nh))
          return nexthop;

  return fwd;
}

/* NSSA-external-LSA related functions. */

/* Get 1st IP connection for Forward Addr */

struct in_addr
ospf_get_ip_from_ifp (struct ospf_interface *oi)
{
  struct in_addr fwd;

  fwd.s_addr = 0;

  if (if_is_operative (oi->ifp))
    return oi->address->u.prefix4;
  
  return fwd;
}

/* Get 1st IP connection for Forward Addr */
struct in_addr
ospf_get_nssa_ip (struct ospf_area *area)
{
  struct in_addr fwd;
  struct in_addr best_default;
  struct listnode *node;
  struct ospf_interface *oi;

  fwd.s_addr = 0;
  best_default.s_addr = 0;

  for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
    {
      if (if_is_operative (oi->ifp))
	if (oi->area->external_routing == OSPF_AREA_NSSA)
	  if (oi->address && oi->address->family == AF_INET)
	    {
	      if (best_default.s_addr == 0)
		best_default = oi->address->u.prefix4;
	      if (oi->area == area)
		return oi->address->u.prefix4;
	    }
    }
  if (best_default.s_addr != 0)
    return best_default;

  if (best_default.s_addr != 0)
    return best_default;

  return fwd;
}

#define DEFAULT_DEFAULT_METRIC	             20
#define DEFAULT_DEFAULT_ORIGINATE_METRIC     10
#define DEFAULT_DEFAULT_ALWAYS_METRIC	      1

#define DEFAULT_METRIC_TYPE		     EXTERNAL_METRIC_TYPE_2

int
metric_type (struct ospf *ospf, u_char src)
{
  return (ospf->dmetric[src].type < 0 ?
	  DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
}

int
metric_value (struct ospf *ospf, u_char src)
{
  if (ospf->dmetric[src].value < 0)
    {
      if (src == DEFAULT_ROUTE)
	{
	  if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
	    return DEFAULT_DEFAULT_ORIGINATE_METRIC;
	  else
	    return DEFAULT_DEFAULT_ALWAYS_METRIC;
	}
      else if (ospf->default_metric < 0)
	return DEFAULT_DEFAULT_METRIC;
      else
	return ospf->default_metric;
    }

  return ospf->dmetric[src].value;
}

/* Set AS-external-LSA body. */
static void
ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
			    struct ospf *ospf)
{
  struct prefix_ipv4 *p = &ei->p;
  struct in_addr mask, fwd_addr;
  u_int32_t mvalue;
  int mtype;
  int type;

  /* Put Network Mask. */
  masklen2ip (p->prefixlen, &mask);
  stream_put_ipv4 (s, mask.s_addr);

  /* If prefix is default, specify DEFAULT_ROUTE. */
  type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
  
  mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
    ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);

  mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
    ROUTEMAP_METRIC (ei) : metric_value (ospf, type);

  /* Put type of external metric. */
  stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));

  /* Put 0 metric. TOS metric is not supported. */
  stream_put_ospf_metric (s, mvalue);
  
  /* Get forwarding address to nexthop if on the Connection List, else 0. */
  fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);

  /* Put forwarding address. */
  stream_put_ipv4 (s, fwd_addr.s_addr);
  
  /* Put route tag */
  stream_putl (s, ei->tag);
}

/* Create new external-LSA. */
static struct ospf_lsa *
ospf_external_lsa_new (struct ospf *ospf,
		       struct external_info *ei, struct in_addr *old_id)
{
  struct stream *s;
  struct lsa_header *lsah;
  struct ospf_lsa *new;
  struct in_addr id;
  int length;

  if (ei == NULL)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
	zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
      return NULL;
    }

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");

  /* If old Link State ID is specified, refresh LSA with same ID. */
  if (old_id)
    id = *old_id;
  /* Get Link State with unique ID. */
  else
    {
      id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
      if (id.s_addr == 0xffffffff)
	{
	  /* Maybe Link State ID not available. */
	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
	    zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
	  return NULL;
	}
    }

  /* Create new stream for LSA. */
  s = stream_new (OSPF_MAX_LSA_SIZE);
  lsah = (struct lsa_header *) STREAM_DATA (s);

  /* Set LSA common header fields. */
  lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
		  id, ospf->router_id);

  /* Set AS-external-LSA body fields. */
  ospf_external_lsa_body_set (s, ei, ospf);

  /* Set length. */
  length = stream_get_endp (s);
  lsah->length = htons (length);

  /* Now, create OSPF LSA instance. */
  new = ospf_lsa_new ();
  new->area = NULL;
  SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);

  /* Copy LSA data to store, discard stream. */
  new->data = ospf_lsa_data_new (length);
  memcpy (new->data, lsah, length);
  stream_free (s);

  return new;
}

/* As Type-7 */
static void
ospf_install_flood_nssa (struct ospf *ospf, 
			 struct ospf_lsa *lsa, struct external_info *ei)
{
  struct ospf_lsa *new;
  struct as_external_lsa *extlsa;
  struct ospf_area *area;
  struct listnode *node, *nnode;

  /* LSA may be a Type-5 originated via translation of a Type-7 LSA
   * which originated from an NSSA area. In which case it should not be 
   * flooded back to NSSA areas.
   */
  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
    return;
    
  /* NSSA Originate or Refresh (If anyNSSA)

  LSA is self-originated. And just installed as Type-5.
  Additionally, install as Type-7 LSDB for every attached NSSA.

  P-Bit controls which ABR performs translation to outside world; If
  we are an ABR....do not set the P-bit, because we send the Type-5,
  not as the ABR Translator, but as the ASBR owner within the AS!

  If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set.  The
  elected ABR Translator will see the P-bit, Translate, and re-flood.

  Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
  Type-5's to non-NSSA Areas.  (it will also attempt a re-install) */

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    {
      /* Don't install Type-7 LSA's into nonNSSA area */
      if (area->external_routing != OSPF_AREA_NSSA)
        continue;

      /* make lsa duplicate, lock=1 */
      new = ospf_lsa_dup (lsa);
      new->area = area;
      new->data->type = OSPF_AS_NSSA_LSA;

      /* set P-bit if not ABR */
      if (! IS_OSPF_ABR (ospf))
        {
	  SET_FLAG(new->data->options, OSPF_OPTION_NP);
       
	  /* set non-zero FWD ADDR
       
	  draft-ietf-ospf-nssa-update-09.txt
       
	  if the network between the NSSA AS boundary router and the
	  adjacent AS is advertised into OSPF as an internal OSPF route,
	  the forwarding address should be the next op address as is cu
	  currently done with type-5 LSAs.  If the intervening network is
	  not adversited into OSPF as an internal OSPF route and the
	  type-7 LSA's P-bit is set a forwarding address should be
	  selected from one of the router's active OSPF inteface addresses
	  which belong to the NSSA.  If no such addresses exist, then
	  no type-7 LSA's with the P-bit set should originate from this
	  router.   */
       
	  /* kevinm: not updating lsa anymore, just new */
	  extlsa = (struct as_external_lsa *)(new->data);
       
	  if (extlsa->e[0].fwd_addr.s_addr == 0)
	    extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */

	  if (extlsa->e[0].fwd_addr.s_addr == 0) 
	  {
	    if (IS_DEBUG_OSPF_NSSA)
	      zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
	    ospf_lsa_discard (new);
	    return;
	  }
	}

      /* install also as Type-7 */
      ospf_lsa_install (ospf, NULL, new);   /* Remove Old, Lock New = 2 */

      /* will send each copy, lock=2+n */
      ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
    }
}

static struct ospf_lsa *
ospf_lsa_translated_nssa_new (struct ospf *ospf, 
                             struct ospf_lsa *type7)
{

  struct ospf_lsa *new;
  struct as_external_lsa *ext, *extnew;
  struct external_info ei;
  
  ext = (struct as_external_lsa *)(type7->data);

  /* need external_info struct, fill in bare minimum */  
  ei.p.family = AF_INET;
  ei.p.prefix = type7->data->id;
  ei.p.prefixlen = ip_masklen (ext->mask);
  ei.type = ZEBRA_ROUTE_OSPF;
  ei.nexthop = ext->header.adv_router;
  ei.route_map_set.metric = -1;
  ei.route_map_set.metric_type = -1;
  ei.tag = 0;
  
  if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
  {
    if (IS_DEBUG_OSPF_NSSA)
      zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
                 "Translated Type-5 for %s", 
                 inet_ntoa (ei.p.prefix));
    return NULL;
  }

  extnew = (struct as_external_lsa *)(new->data);
   
  /* copy over Type-7 data to new */
  extnew->e[0].tos = ext->e[0].tos;
  extnew->e[0].route_tag = ext->e[0].route_tag;
  extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
  new->data->ls_seqnum = type7->data->ls_seqnum;

  /* add translated flag, checksum and lock new lsa */
  SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7  */   
  new = ospf_lsa_lock (new);
  
  return new; 
}

/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
struct ospf_lsa *
ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
{
  struct ospf_lsa *new;
  struct as_external_lsa *extnew;
  
  /* we cant use ospf_external_lsa_originate() as we need to set
   * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
   */
  
  if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
                 "Type-7, Id %s, to Type-5",
                 inet_ntoa (type7->data->id));
      return NULL;
    }
    
  extnew = (struct as_external_lsa *)new;
  
  if (IS_DEBUG_OSPF_NSSA)
    {
      zlog_debug ("ospf_translated_nssa_originate(): "
                 "translated Type 7, installed:");
      ospf_lsa_header_dump (new->data);
      zlog_debug ("   Network mask: %d",ip_masklen (extnew->mask));
      zlog_debug ("   Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
    }
  
  if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_lsa_translated_nssa_originate(): "
                   "Could not install LSA "
                   "id %s", inet_ntoa (type7->data->id));
      return NULL;
    }
    
  ospf->lsa_originate_count++;
  ospf_flood_through_as (ospf, NULL, new);

  return new;
}

/* Refresh Translated from NSSA AS-external-LSA. */
struct ospf_lsa *
ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7, 
                              struct ospf_lsa *type5)
{
  struct ospf_lsa *new = NULL;
  
  /* Sanity checks. */
  assert (type7 || type5);
  if (!(type7 || type5))
    return NULL;
  if (type7)
    assert (type7->data);
  if (type5)
    assert (type5->data);
  assert (ospf->anyNSSA);

  /* get required data according to what has been given */
  if (type7 && type5 == NULL)
    {
      /* find the translated Type-5 for this Type-7 */
      struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
      struct prefix_ipv4 p = 
        { 
          .prefix = type7->data->id,
          .prefixlen = ip_masklen (ext->mask),
          .family = AF_INET,
        };

      type5 = ospf_external_info_find_lsa (ospf, &p);
    }
  else if (type5 && type7 == NULL)
    {
      /* find the type-7 from which supplied type-5 was translated,
       * ie find first type-7 with same LSA Id.
       */
      struct listnode *ln, *lnn;
      struct route_node *rn;
      struct ospf_lsa *lsa;
      struct ospf_area *area;
          
      for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
        {
          if (area->external_routing != OSPF_AREA_NSSA 
              && !type7)
            continue;
            
          LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
            {
              if (lsa->data->id.s_addr == type5->data->id.s_addr)
                {
                  type7 = lsa;
                  break;
                }
            }
        }
    }

  /* do we have type7? */
  if (!type7)
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
                   "Type-5 LSA Id %s",
                   inet_ntoa (type5->data->id));
      return NULL;
    }

  /* do we have valid translated type5? */
  if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
                   "found for Type-7 with Id %s",
                   inet_ntoa (type7->data->id));
      return NULL;
    }

  /* Delete LSA from neighbor retransmit-list. */
  ospf_ls_retransmit_delete_nbr_as (ospf, type5);
  
  /* create new translated LSA */
  if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
                   "Type-7 for %s to Type-5",
                   inet_ntoa (type7->data->id));
      return NULL;
    }

  if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
                   "translated LSA, Id %s",
                   inet_ntoa (type7->data->id));
      return NULL;
    }
  
  /* Flood LSA through area. */
  ospf_flood_through_as (ospf, NULL, new);

  return new;
}

int
is_prefix_default (struct prefix_ipv4 *p)
{
  struct prefix_ipv4 q;

  q.family = AF_INET;
  q.prefix.s_addr = 0;
  q.prefixlen = 0;

  return prefix_same ((struct prefix *) p, (struct prefix *) &q);
}

/* Originate an AS-external-LSA, install and flood. */
struct ospf_lsa *
ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
{
  struct ospf_lsa *new;

  /* Added for NSSA project....

       External LSAs are originated in ASBRs as usual, but for NSSA systems.
     there is the global Type-5 LSDB and a Type-7 LSDB installed for
     every area.  The Type-7's are flooded to every IR and every ABR; We
     install the Type-5 LSDB so that the normal "refresh" code operates
     as usual, and flag them as not used during ASE calculations.  The
     Type-7 LSDB is used for calculations.  Each Type-7 has a Forwarding
     Address of non-zero.

     If an ABR is the elected NSSA translator, following SPF and during
     the ABR task it will translate all the scanned Type-7's, with P-bit
     ON and not-self generated, and translate to Type-5's throughout the
     non-NSSA/STUB AS.

     A difference in operation depends whether this ASBR is an ABR
     or not.  If not an ABR, the P-bit is ON, to indicate that any
     elected NSSA-ABR can perform its translation.

     If an ABR, the P-bit is OFF;  No ABR will perform translation and
     this ASBR will flood the Type-5 LSA as usual.

     For the case where this ASBR is not an ABR, the ASE calculations
     are based on the Type-5 LSDB;  The Type-7 LSDB exists just to
     demonstrate to the user that there are LSA's that belong to any
     attached NSSA.

     Finally, it just so happens that when the ABR is translating every
     Type-7 into Type-5, it installs it into the Type-5 LSDB as an
     approved Type-5 (translated from Type-7);  at the end of translation
     if any Translated Type-5's remain unapproved, then they must be
     flushed from the AS.

     */
  
  /* Check the AS-external-LSA should be originated. */
  if (!ospf_redistribute_check (ospf, ei, NULL))
    return NULL;
  
  /* Create new AS-external-LSA instance. */
  if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
		   inet_ntoa (ei->p.prefix));
      return NULL;
    }

  /* Install newly created LSA into Type-5 LSDB, lock = 1. */
  ospf_lsa_install (ospf, NULL, new);

  /* Update LSA origination count. */
  ospf->lsa_originate_count++;

  /* Flooding new LSA. only to AS (non-NSSA/STUB) */
  ospf_flood_through_as (ospf, NULL, new);

  /* If there is any attached NSSA, do special handling */
  if (ospf->anyNSSA &&
      /* stay away from translated LSAs! */
      !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
    ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */

  /* Debug logging. */
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
		 new->data->type, inet_ntoa (new->data->id), (void *)new);
      ospf_lsa_header_dump (new->data);
    }

  return new;
}

/* Originate AS-external-LSA from external info with initial flag. */
int
ospf_external_lsa_originate_timer (struct thread *thread)
{
  struct ospf *ospf = THREAD_ARG (thread);
  struct route_node *rn;
  struct external_info *ei;
  struct route_table *rt;
  int type = THREAD_VAL (thread);

  ospf->t_external_lsa = NULL;

  /* Originate As-external-LSA from all type of distribute source. */
  if ((rt = EXTERNAL_INFO (type)))
    for (rn = route_top (rt); rn; rn = route_next (rn))
      if ((ei = rn->info) != NULL)
	if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
	  if (!ospf_external_lsa_originate (ospf, ei))
	    zlog_warn ("LSA: AS-external-LSA was not originated.");
  
  return 0;
}

static struct external_info *
ospf_default_external_info (struct ospf *ospf)
{
  int type;
  struct route_node *rn;
  struct prefix_ipv4 p;
  
  p.family = AF_INET;
  p.prefix.s_addr = 0;
  p.prefixlen = 0;

  /* First, lookup redistributed default route. */
  for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
    if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
      {
	rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
	if (rn != NULL)
	  {
	    route_unlock_node (rn);
	    assert (rn->info);
	    if (ospf_redistribute_check (ospf, rn->info, NULL))
	      return rn->info;
	  }
      }

  return NULL;
}

int
ospf_default_originate_timer (struct thread *thread)
{
  struct prefix_ipv4 p;
  struct in_addr nexthop;
  struct external_info *ei;
  struct ospf *ospf;
  
  ospf = THREAD_ARG (thread);

  p.family = AF_INET;
  p.prefix.s_addr = 0;
  p.prefixlen = 0;

  if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
    {
      /* If there is no default route via redistribute,
	 then originate AS-external-LSA with nexthop 0 (self). */
      nexthop.s_addr = 0;
      ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop, 0);
    }

  if ((ei = ospf_default_external_info (ospf)))
    ospf_external_lsa_originate (ospf, ei);
  
  return 0;
}

/* Flush any NSSA LSAs for given prefix */
void
ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
{
  struct listnode *node, *nnode;
  struct ospf_lsa *lsa;
  struct ospf_area *area;

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
  {
    if (area->external_routing == OSPF_AREA_NSSA)
    {
      if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
                                ospf->router_id))) 
      {
        if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) 
          zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
                    inet_ntoa (p->prefix), p->prefixlen);
        continue;
      }
      ospf_ls_retransmit_delete_nbr_area (area, lsa);
      if (!IS_LSA_MAXAGE (lsa)) 
      {
        ospf_refresher_unregister_lsa (ospf, lsa);
        ospf_lsa_flush_area (lsa, area);
      }
    }
  }
}

/* Flush an AS-external-LSA from LSDB and routing domain. */
void
ospf_external_lsa_flush (struct ospf *ospf,
			 u_char type, struct prefix_ipv4 *p,
			 ifindex_t ifindex /*, struct in_addr nexthop */)
{
  struct ospf_lsa *lsa;

  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
    zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
	       inet_ntoa (p->prefix), p->prefixlen);

  /* First lookup LSA from LSDB. */
  if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
    {
      if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
	zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
		   inet_ntoa (p->prefix), p->prefixlen);
      return;
    }

  /* If LSA is selforiginated, not a translated LSA, and there is 
   * NSSA area, flush Type-7 LSA's at first. 
   */
  if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
      && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
    ospf_nssa_lsa_flush (ospf, p);

  /* Sweep LSA from Link State Retransmit List. */
  ospf_ls_retransmit_delete_nbr_as (ospf, lsa);

  /* There must be no self-originated LSA in rtrs_external. */
#if 0
  /* Remove External route from Zebra. */
  ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
#endif

  if (!IS_LSA_MAXAGE (lsa))
    {
      /* Unregister LSA from Refresh queue. */
      ospf_refresher_unregister_lsa (ospf, lsa);

      /* Flush AS-external-LSA through AS. */
      ospf_lsa_flush_as (ospf, lsa);
    }

  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
    zlog_debug ("ospf_external_lsa_flush(): stop");
}

void
ospf_external_lsa_refresh_default (struct ospf *ospf)
{
  struct prefix_ipv4 p;
  struct external_info *ei;
  struct ospf_lsa *lsa;

  p.family = AF_INET;
  p.prefixlen = 0;
  p.prefix.s_addr = 0;

  ei = ospf_default_external_info (ospf);
  lsa = ospf_external_info_find_lsa (ospf, &p);

  if (ei)
    {
      if (lsa)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
		       (void *)lsa);
	  ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
	}
      else
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
	  ospf_external_lsa_originate (ospf, ei);
	}
    }
  else
    {
      if (lsa)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
          ospf_refresher_unregister_lsa (ospf, lsa);
	  ospf_lsa_flush_as (ospf, lsa);
	}
    }
}

void
ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
{
  struct route_node *rn;
  struct external_info *ei;

  if (type != DEFAULT_ROUTE)
    if (EXTERNAL_INFO(type))
      /* Refresh each redistributed AS-external-LSAs. */
      for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
	if ((ei = rn->info))
	  if (!is_prefix_default (&ei->p))
	    {
	      struct ospf_lsa *lsa;

	      if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
		ospf_external_lsa_refresh (ospf, lsa, ei, force);
	      else
		ospf_external_lsa_originate (ospf, ei);
	    }
}

/* Refresh AS-external-LSA. */
struct ospf_lsa *
ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
			   struct external_info *ei, int force)
{
  struct ospf_lsa *new;
  int changed;
  
  /* Check the AS-external-LSA should be originated. */
  if (!ospf_redistribute_check (ospf, ei, &changed))
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
                   "redist check fail", 
                   lsa->data->type, inet_ntoa (lsa->data->id));
      ospf_external_lsa_flush (ospf, ei->type, &ei->p,
			       ei->ifindex /*, ei->nexthop */);
      return NULL;
    }

  if (!changed && !force)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
        zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
                   lsa->data->type, inet_ntoa (lsa->data->id));
      return NULL;
    }

  /* Delete LSA from neighbor retransmit-list. */
  ospf_ls_retransmit_delete_nbr_as (ospf, lsa);

  /* Unregister AS-external-LSA from refresh-list. */
  ospf_refresher_unregister_lsa (ospf, lsa);

  new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
  
  if (new == NULL)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
	zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
		   inet_ntoa (lsa->data->id));
      return NULL;
    }
  
  new->data->ls_seqnum = lsa_seqnum_increment (lsa);

  ospf_lsa_install (ospf, NULL, new);	/* As type-5. */

  /* Flood LSA through AS. */
  ospf_flood_through_as (ospf, NULL, new);

  /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
  if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
    ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */

  /* Register self-originated LSA to refresh queue. 
   * Translated LSAs should not be registered, but refreshed upon 
   * refresh of the Type-7
   */
  if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
    ospf_refresher_register_lsa (ospf, new);

  /* Debug logging. */
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
                 new->data->type, inet_ntoa (new->data->id));
      ospf_lsa_header_dump (new->data);
    }

  return new;
}


/* LSA installation functions. */

/* Install router-LSA to an area. */
static struct ospf_lsa *
ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
                         int rt_recalc)
{
  struct ospf_area *area = new->area;

  /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
     The entire routing table must be recalculated, starting with
     the shortest path calculations for each area (not just the
     area whose link-state database has changed). 
  */

  if (IS_LSA_SELF (new))
    {

      /* Only install LSA if it is originated/refreshed by us.
       * If LSA was received by flooding, the RECEIVED flag is set so do
       * not link the LSA */
      if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
	return new; /* ignore stale LSA */

      /* Set self-originated router-LSA. */
      ospf_lsa_unlock (&area->router_lsa_self);
      area->router_lsa_self = ospf_lsa_lock (new);

      ospf_refresher_register_lsa (ospf, new);
    }
  if (rt_recalc)
    ospf_spf_calculate_schedule (ospf, SPF_FLAG_ROUTER_LSA_INSTALL);
  return new;
}

#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
	if (!(T)) \
	  (T) = thread_add_timer (master, (F), oi, (V))

/* Install network-LSA to an area. */
static struct ospf_lsa *
ospf_network_lsa_install (struct ospf *ospf,
			  struct ospf_interface *oi, 
			  struct ospf_lsa *new,
			  int rt_recalc)
{

  /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
     The entire routing table must be recalculated, starting with
     the shortest path calculations for each area (not just the
     area whose link-state database has changed). 
  */
  if (IS_LSA_SELF (new))
    {
      /* We supposed that when LSA is originated by us, we pass the int
	 for which it was originated. If LSA was received by flooding,
	 the RECEIVED flag is set, so we do not link the LSA to the int. */
      if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
	return new; /* ignore stale LSA */

      ospf_lsa_unlock (&oi->network_lsa_self);
      oi->network_lsa_self = ospf_lsa_lock (new);
      ospf_refresher_register_lsa (ospf, new);
    }
  if (rt_recalc)
    ospf_spf_calculate_schedule (ospf, SPF_FLAG_NETWORK_LSA_INSTALL);

  return new;
}

/* Install summary-LSA to an area. */
static struct ospf_lsa *
ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
			  int rt_recalc)
{
  if (rt_recalc && !IS_LSA_SELF (new))
    {
      /* RFC 2328 Section 13.2 Summary-LSAs
	 The best route to the destination described by the summary-
	 LSA must be recalculated (see Section 16.5).  If this
	 destination is an AS boundary router, it may also be
	 necessary to re-examine all the AS-external-LSAs.
      */

#if 0
      /* This doesn't exist yet... */
      ospf_summary_incremental_update(new); */
#else /* #if 0 */
      ospf_spf_calculate_schedule (ospf, SPF_FLAG_SUMMARY_LSA_INSTALL);
#endif /* #if 0 */
 
    }

  if (IS_LSA_SELF (new))
    ospf_refresher_register_lsa (ospf, new);

  return new;
}

/* Install ASBR-summary-LSA to an area. */
static struct ospf_lsa *
ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
			       int rt_recalc)
{
  if (rt_recalc && !IS_LSA_SELF (new))
    {
      /* RFC 2328 Section 13.2 Summary-LSAs
	 The best route to the destination described by the summary-
	 LSA must be recalculated (see Section 16.5).  If this
	 destination is an AS boundary router, it may also be
	 necessary to re-examine all the AS-external-LSAs.
      */
#if 0
      /* These don't exist yet... */
      ospf_summary_incremental_update(new);
      /* Isn't this done by the above call? 
	 - RFC 2328 Section 16.5 implies it should be */
      /* ospf_ase_calculate_schedule(); */
#else  /* #if 0 */
      ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL);
#endif /* #if 0 */
    }

  /* register LSA to refresh-list. */
  if (IS_LSA_SELF (new))
    ospf_refresher_register_lsa (ospf, new);

  return new;
}

/* Install AS-external-LSA. */
static struct ospf_lsa *
ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
			   int rt_recalc)
{
  ospf_ase_register_external_lsa (new, ospf);
  /* If LSA is not self-originated, calculate an external route. */
  if (rt_recalc)
    {
      /* RFC 2328 Section 13.2 AS-external-LSAs
            The best route to the destination described by the AS-
            external-LSA must be recalculated (see Section 16.6).
      */

      if (!IS_LSA_SELF (new))
        ospf_ase_incremental_update (ospf, new);
    }

  if (new->data->type == OSPF_AS_NSSA_LSA)
    {
      /* There is no point to register selforiginate Type-7 LSA for
       * refreshing. We rely on refreshing Type-5 LSA's 
       */
      if (IS_LSA_SELF (new))
        return new;
      else
        {
          /* Try refresh type-5 translated LSA for this LSA, if one exists.
           * New translations will be taken care of by the abr_task.
           */ 
          ospf_translated_nssa_refresh (ospf, new, NULL);
          ospf_schedule_abr_task(ospf);
        }
    }

  /* Register self-originated LSA to refresh queue. 
   * Leave Translated LSAs alone if NSSA is enabled
   */
  if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
    ospf_refresher_register_lsa (ospf, new);

  return new;
}

void
ospf_discard_from_db (struct ospf *ospf,
		      struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
{
  struct ospf_lsa *old;
  
  if (!lsdb)
    {
      zlog_warn ("%s: Called with NULL lsdb!", __func__);
      if (!lsa)
        zlog_warn ("%s: and NULL LSA!", __func__);
      else
        zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
                   lsa->data->type, inet_ntoa (lsa->data->id));
      return;
    }
  
  old = ospf_lsdb_lookup (lsdb, lsa);

  if (!old)
    return;

  if (old->refresh_list >= 0)
    ospf_refresher_unregister_lsa (ospf, old);

  switch (old->data->type)
    {
    case OSPF_AS_EXTERNAL_LSA:
      ospf_ase_unregister_external_lsa (old, ospf);
      ospf_ls_retransmit_delete_nbr_as (ospf, old);
      break;
    case OSPF_OPAQUE_AS_LSA:
      ospf_ls_retransmit_delete_nbr_as (ospf, old);
      break;
    case OSPF_AS_NSSA_LSA:
      ospf_ls_retransmit_delete_nbr_area (old->area, old);
      ospf_ase_unregister_external_lsa (old, ospf);
      break;
    default:
      ospf_ls_retransmit_delete_nbr_area (old->area, old);
      break;
    }

  ospf_lsa_maxage_delete (ospf, old);
  ospf_lsa_discard (old);
}

struct ospf_lsa *
ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
		  struct ospf_lsa *lsa)
{
  struct ospf_lsa *new = NULL;
  struct ospf_lsa *old = NULL;
  struct ospf_lsdb *lsdb = NULL;
  int rt_recalc;

  /* Set LSDB. */
  switch (lsa->data->type)
    {
      /* kevinm */
    case OSPF_AS_NSSA_LSA:
      if (lsa->area)
	lsdb = lsa->area->lsdb;
      else
	lsdb = ospf->lsdb;
      break;
    case OSPF_AS_EXTERNAL_LSA:
    case OSPF_OPAQUE_AS_LSA:
      lsdb = ospf->lsdb;
      break;
    default:
      lsdb = lsa->area->lsdb;
      break;
    }

  assert (lsdb);

  /*  RFC 2328 13.2.  Installing LSAs in the database

        Installing a new LSA in the database, either as the result of
        flooding or a newly self-originated LSA, may cause the OSPF
        routing table structure to be recalculated.  The contents of the
        new LSA should be compared to the old instance, if present.  If
        there is no difference, there is no need to recalculate the
        routing table. When comparing an LSA to its previous instance,
        the following are all considered to be differences in contents:

            o   The LSA's Options field has changed.

            o   One of the LSA instances has LS age set to MaxAge, and
                the other does not.

            o   The length field in the LSA header has changed.

            o   The body of the LSA (i.e., anything outside the 20-byte
                LSA header) has changed. Note that this excludes changes
                in LS Sequence Number and LS Checksum.

  */
  /* Look up old LSA and determine if any SPF calculation or incremental
     update is needed */
  old = ospf_lsdb_lookup (lsdb, lsa);

  /* Do comparision and record if recalc needed. */
  rt_recalc = 0;
  if (  old == NULL || ospf_lsa_different(old, lsa))
    rt_recalc = 1;

  /*
     Sequence number check (Section 14.1 of rfc 2328)
     "Premature aging is used when it is time for a self-originated
      LSA's sequence number field to wrap.  At this point, the current
      LSA instance (having LS sequence number MaxSequenceNumber) must
      be prematurely aged and flushed from the routing domain before a
      new instance with sequence number equal to InitialSequenceNumber
      can be originated. "
   */

  if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
    {
      if (ospf_lsa_is_self_originated(ospf, lsa))
        {
          lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
          
          if (!IS_LSA_MAXAGE(lsa))
            lsa->flags |= OSPF_LSA_PREMATURE_AGE;
          lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
      	
          if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
            {
      	      zlog_debug ("ospf_lsa_install() Premature Aging "
		         "lsa 0x%p, seqnum 0x%x",
		         (void *)lsa, ntohl(lsa->data->ls_seqnum));
      	      ospf_lsa_header_dump (lsa->data);
            }
        }
      else
        {
          if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
            {
      	      zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
		         "that was not self originated. Ignoring\n");
      	      ospf_lsa_header_dump (lsa->data);
            }
	  return old;
        }
    }

  /* discard old LSA from LSDB */
  if (old != NULL)
    ospf_discard_from_db (ospf, lsdb, lsa);

  /* Calculate Checksum if self-originated?. */
  if (IS_LSA_SELF (lsa))
    ospf_lsa_checksum (lsa->data);

  /* Insert LSA to LSDB. */
  ospf_lsdb_add (lsdb, lsa);
  lsa->lsdb = lsdb;

  /* Do LSA specific installation process. */
  switch (lsa->data->type)
    {
    case OSPF_ROUTER_LSA:
      new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
      break;
    case OSPF_NETWORK_LSA:
      assert (oi);
      new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
      break;
    case OSPF_SUMMARY_LSA:
      new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
      break;
    case OSPF_ASBR_SUMMARY_LSA:
      new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
      break;
    case OSPF_AS_EXTERNAL_LSA:
      new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
      break;
    case OSPF_OPAQUE_LINK_LSA:
      if (IS_LSA_SELF (lsa))
	lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
      else
        {
          /* Incoming "oi" for this LSA has set at LSUpd reception. */
        }
      /* Fallthrough */
    case OSPF_OPAQUE_AREA_LSA:
    case OSPF_OPAQUE_AS_LSA:
      new = ospf_opaque_lsa_install (lsa, rt_recalc);
      break;
    case OSPF_AS_NSSA_LSA:
      new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
    default: /* type-6,8,9....nothing special */
      break;
    }

  if (new == NULL)
    return new;  /* Installation failed, cannot proceed further -- endo. */

  /* Debug logs. */
  if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
    {
      char area_str[INET_ADDRSTRLEN];

      switch (lsa->data->type)
        {
        case OSPF_AS_EXTERNAL_LSA:
        case OSPF_OPAQUE_AS_LSA:
        case OSPF_AS_NSSA_LSA:
          zlog_debug ("LSA[%s]: Install %s",
                 dump_lsa_key (new),
                 LOOKUP (ospf_lsa_type_msg, new->data->type));
          break;
        default:
	  strcpy (area_str, inet_ntoa (new->area->area_id));
          zlog_debug ("LSA[%s]: Install %s to Area %s",
                 dump_lsa_key (new),
                 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
          break;
        }
    }

  /* 
     If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
     (it's getting flushed out of the area), set LSA on MaxAge LSA list. 
   */
  if (IS_LSA_MAXAGE (new))
    {
      if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
        zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
                   new->data->type,
                   inet_ntoa (new->data->id),
                   (void *)lsa);
      ospf_lsa_maxage (ospf, lsa);
    }

  return new;
}


int
ospf_check_nbr_status (struct ospf *ospf)
{
  struct listnode *node, *nnode;
  struct ospf_interface *oi;
  
  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
    {
      struct route_node *rn;
      struct ospf_neighbor *nbr;

      if (ospf_if_is_enable (oi))
	for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
          if ((nbr = rn->info) != NULL)
	    if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
	      {
		route_unlock_node (rn);
		return 0;
	      }
    }

  return 1;
}



static int
ospf_maxage_lsa_remover (struct thread *thread)
{
  struct ospf *ospf = THREAD_ARG (thread);
  struct ospf_lsa *lsa;
  struct route_node *rn;
  int reschedule = 0;

  ospf->t_maxage = NULL;

  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
    zlog_debug ("LSA[MaxAge]: remover Start");

  reschedule = !ospf_check_nbr_status (ospf);

  if (!reschedule)
    for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
      {
	if ((lsa = rn->info) == NULL)
	  {
	    continue;
	  }

        /* There is at least one neighbor from which we still await an ack
         * for that LSA, so we are not allowed to remove it from our lsdb yet
         * as per RFC 2328 section 14 para 4 a) */
        if (lsa->retransmit_counter > 0)
          {
            reschedule = 1;
            continue;
          }
        
        /* TODO: maybe convert this function to a work-queue */
        if (thread_should_yield (thread))
          {
            OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
            route_unlock_node(rn); /* route_top/route_next */
            return 0;
          }
          
        /* Remove LSA from the LSDB */
        if (IS_LSA_SELF (lsa))
          if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
            zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
                       lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);

        if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
          zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
                     lsa->data->type, inet_ntoa (lsa->data->id));

	if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
          {
            if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
              zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa);
            ospf_lsa_refresh (ospf, lsa);
          }

	/* Remove from lsdb. */
	if (lsa->lsdb)
	  {
	    ospf_discard_from_db (ospf, lsa->lsdb, lsa);
	    ospf_lsdb_delete (lsa->lsdb, lsa);
          }
        else
          zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
                     lsa->data->type, inet_ntoa (lsa->data->id));
      }

  /*    A MaxAge LSA must be removed immediately from the router's link
        state database as soon as both a) it is no longer contained on any
        neighbor Link state retransmission lists and b) none of the router's
        neighbors are in states Exchange or Loading. */
  if (reschedule)
    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
                   ospf->maxage_delay);

  return 0;
}

void
ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct route_node *rn;
  struct prefix_ptr lsa_prefix;

  lsa_prefix.family = 0;
  lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
  lsa_prefix.prefix = (uintptr_t) lsa;

  if ((rn = route_node_lookup(ospf->maxage_lsa,
			      (struct prefix *)&lsa_prefix)))
    {
      if (rn->info == lsa)
	{
	  UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
	  ospf_lsa_unlock (&lsa); /* maxage_lsa */
	  rn->info = NULL;
	  route_unlock_node (rn); /* unlock node because lsa is deleted */
	}
      route_unlock_node (rn); /* route_node_lookup */
    }
}

/* Add LSA onto the MaxAge list, and schedule for removal.
 * This does *not* lead to the LSA being flooded, that must be taken
 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
 * function).
 */
void
ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct prefix_ptr lsa_prefix;
  struct route_node *rn;

  /* When we saw a MaxAge LSA flooded to us, we put it on the list
     and schedule the MaxAge LSA remover. */
  if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
    {
      if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
	zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
		   lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
      return;
    }

  lsa_prefix.family = 0;
  lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
  lsa_prefix.prefix = (uintptr_t) lsa;

  if ((rn = route_node_get (ospf->maxage_lsa,
			    (struct prefix *)&lsa_prefix)) != NULL)
    {
      if (rn->info != NULL)
	{
	  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
	    zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
			dump_lsa_key (lsa), rn->info, (void *)lsa,
			lsa_prefix.prefixlen);
	  route_unlock_node (rn);
	}
      else
	{
	  rn->info = ospf_lsa_lock(lsa);
	  SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
	}
    }
  else
    {
      zlog_err("Unable to allocate memory for maxage lsa\n");
      assert(0);
    }

  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
    zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));

  OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
                 ospf->maxage_delay);
}

static int
ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
{
  /* Stay away from any Local Translated Type-7 LSAs */
  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
    return 0;

  if (IS_LSA_MAXAGE (lsa))
    /* Self-originated LSAs should NOT time-out instead,
       they're flushed and submitted to the max_age list explicitly. */
    if (!ospf_lsa_is_self_originated (ospf, lsa))
      {
	if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
	  zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));

        switch (lsa->data->type)
          {
          case OSPF_OPAQUE_LINK_LSA:
          case OSPF_OPAQUE_AREA_LSA:
          case OSPF_OPAQUE_AS_LSA:
            /*
             * As a general rule, whenever network topology has changed
             * (due to an LSA removal in this case), routing recalculation
             * should be triggered. However, this is not true for opaque
             * LSAs. Even if an opaque LSA instance is going to be removed
             * from the routing domain, it does not mean a change in network
             * topology, and thus, routing recalculation is not needed here.
             */
            break;
          case OSPF_AS_EXTERNAL_LSA:
          case OSPF_AS_NSSA_LSA:
	    ospf_ase_incremental_update (ospf, lsa);
            break;
          default:
	    ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE);
            break;
          }
	ospf_lsa_maxage (ospf, lsa);
      }

  if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
    if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
      printf ("Eek! Shouldn't happen!\n");

  return 0;
}

/* Periodical check of MaxAge LSA. */
int
ospf_lsa_maxage_walker (struct thread *thread)
{
  struct ospf *ospf = THREAD_ARG (thread);
  struct route_node *rn;
  struct ospf_lsa *lsa;
  struct ospf_area *area;
  struct listnode *node, *nnode;

  ospf->t_maxage_walker = NULL;

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    {
      LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
        ospf_lsa_maxage_walker_remover (ospf, lsa);
    }

  /* for AS-external-LSAs. */
  if (ospf->lsdb)
    {
      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
      LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
	ospf_lsa_maxage_walker_remover (ospf, lsa);
    }

  OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
		 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
  return 0;
}

struct ospf_lsa *
ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
			   struct prefix_ipv4 *p, struct in_addr router_id)
{
  struct ospf_lsa *lsa;
  struct in_addr mask, id;
  struct lsa_header_mask
  {
    struct lsa_header header;
    struct in_addr mask;
  } *hmask;

  lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
  if (lsa == NULL)
    return NULL;

  masklen2ip (p->prefixlen, &mask);

  hmask = (struct lsa_header_mask *) lsa->data;

  if (mask.s_addr != hmask->mask.s_addr)
    {
      id.s_addr = p->prefix.s_addr | (~mask.s_addr);
      lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
      if (!lsa)
        return NULL;
    }

  return lsa;
}

struct ospf_lsa *
ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
                 struct in_addr id, struct in_addr adv_router)
{
  struct ospf *ospf = ospf_lookup();
  assert(ospf);

  switch (type)
    {
    case OSPF_ROUTER_LSA:
    case OSPF_NETWORK_LSA:
    case OSPF_SUMMARY_LSA:
    case OSPF_ASBR_SUMMARY_LSA:
    case OSPF_AS_NSSA_LSA:
    case OSPF_OPAQUE_LINK_LSA:
    case OSPF_OPAQUE_AREA_LSA:
      return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
    case OSPF_AS_EXTERNAL_LSA:
    case OSPF_OPAQUE_AS_LSA:
      return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
    default:
      break;
    }

  return NULL;
}

struct ospf_lsa *
ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type, 
                       struct in_addr id)
{
  struct ospf_lsa *lsa;
  struct route_node *rn;

  switch (type)
    {
    case OSPF_ROUTER_LSA:
      return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
    case OSPF_NETWORK_LSA:
      for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
	if ((lsa = rn->info))
	  if (IPV4_ADDR_SAME (&lsa->data->id, &id))
	    {
	      route_unlock_node (rn);
	      return lsa;
	    }
      break;
    case OSPF_SUMMARY_LSA:
    case OSPF_ASBR_SUMMARY_LSA:
      /* Currently not used. */
      assert (1);
      return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
    case OSPF_AS_EXTERNAL_LSA:
    case OSPF_AS_NSSA_LSA:
    case OSPF_OPAQUE_LINK_LSA:
    case OSPF_OPAQUE_AREA_LSA:
    case OSPF_OPAQUE_AS_LSA:
      /* Currently not used. */
      break;
    default:
      break;
    }

  return NULL;
}

struct ospf_lsa *
ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
{
  struct ospf_lsa *match;

  /*
   * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
   * is redefined to have two subfields; opaque-type and opaque-id.
   * However, it is harmless to treat the two sub fields together, as if
   * they two were forming a unique LSA-ID.
   */

  match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);

  if (match == NULL)
    if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
      zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
		 lsah->type, inet_ntoa (lsah->id));

  return match;
}

/* return +n, l1 is more recent.
   return -n, l2 is more recent.
   return 0, l1 and l2 is identical. */
int
ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
{
  int r;
  int x, y;

  if (l1 == NULL && l2 == NULL)
    return 0;
  if (l1 == NULL)
    return -1;
  if (l2 == NULL)
    return 1;

  /* compare LS sequence number. */
  x = (int) ntohl (l1->data->ls_seqnum);
  y = (int) ntohl (l2->data->ls_seqnum);
  if (x > y)
    return 1;
  if (x < y)
    return -1;

  /* compare LS checksum. */
  r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
  if (r)
    return r;

  /* compare LS age. */
  if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
    return 1;
  else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
    return -1;

  /* compare LS age with MaxAgeDiff. */
  if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
    return -1;
  else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
    return 1;

  /* LSAs are identical. */
  return 0;
}

/* If two LSAs are different, return 1, otherwise return 0. */
int
ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
{
  char *p1, *p2;
  assert (l1);
  assert (l2);
  assert (l1->data);
  assert (l2->data);

  if (l1->data->options != l2->data->options)
    return 1;

  if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
    return 1;

  if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
    return 1;

  if (l1->data->length != l2->data->length)
    return 1;

  if (l1->data->length ==  0)
    return 1;

  if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
    return 1; /* May be a stale LSA in the LSBD */

  assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);

  p1 = (char *) l1->data;
  p2 = (char *) l2->data;

  if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
              ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
    return 1;

  return 0;
}

#ifdef ORIGINAL_CODING
void
ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
                                struct ospf_lsa *self,
                                struct ospf_lsa *new)
{
  u_int32_t seqnum;

  /* Adjust LS Sequence Number. */
  seqnum = ntohl (new->data->ls_seqnum) + 1;
  self->data->ls_seqnum = htonl (seqnum);

  /* Recalculate LSA checksum. */
  ospf_lsa_checksum (self->data);

  /* Reflooding LSA. */
  /*  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 (nbr->oi->type == OSPF_IFTYPE_NBMA)
    {
      struct route_node *rn;
      struct ospf_neighbor *onbr;

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

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
	       self->data->type, inet_ntoa (self->data->id));
}
#else /* ORIGINAL_CODING */
static int
ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
{
  if (lsa == NULL || !IS_LSA_SELF (lsa))
    return 0;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));

  /* Force given lsa's age to MaxAge. */
  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);

  switch (lsa->data->type)
    {
    /* Opaque wants to be notified of flushes */
    case OSPF_OPAQUE_LINK_LSA:
    case OSPF_OPAQUE_AREA_LSA:
    case OSPF_OPAQUE_AS_LSA:
      ospf_opaque_lsa_refresh (lsa);
      break;
    default:
      ospf_refresher_unregister_lsa (ospf, lsa);
      ospf_lsa_flush (ospf, lsa);
      break;
    }

  return 0;
}

void
ospf_flush_self_originated_lsas_now (struct ospf *ospf)
{
  struct listnode *node, *nnode;
  struct listnode *node2, *nnode2;
  struct ospf_area *area;
  struct ospf_interface *oi;
  struct ospf_lsa *lsa;
  struct route_node *rn;
  int need_to_flush_ase = 0;

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    {
      if ((lsa = area->router_lsa_self) != NULL)
        {
          if (IS_DEBUG_OSPF_EVENT)
            zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
                        lsa->data->type, inet_ntoa (lsa->data->id));
          
          ospf_refresher_unregister_lsa (ospf, lsa);
          ospf_lsa_flush_area (lsa, area);
          ospf_lsa_unlock (&area->router_lsa_self);
          area->router_lsa_self = NULL;
        }

      for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
        {
          if ((lsa = oi->network_lsa_self) != NULL
               &&   oi->state == ISM_DR
               &&   oi->full_nbrs > 0)
            {
              if (IS_DEBUG_OSPF_EVENT)
                zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
                            lsa->data->type, inet_ntoa (lsa->data->id));
              
              ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
              ospf_lsa_flush_area (oi->network_lsa_self, area);
              ospf_lsa_unlock (&oi->network_lsa_self);
              oi->network_lsa_self = NULL;
            }

          if (oi->type != OSPF_IFTYPE_VIRTUALLINK
          &&  area->external_routing == OSPF_AREA_DEFAULT)
            need_to_flush_ase = 1;
        }

      LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
	ospf_lsa_flush_schedule (ospf, lsa);
      LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
	ospf_lsa_flush_schedule (ospf, lsa);
      LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
	ospf_lsa_flush_schedule (ospf, lsa);
      LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
	ospf_lsa_flush_schedule (ospf, lsa);
    }

  if (need_to_flush_ase)
    {
      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
	ospf_lsa_flush_schedule (ospf, lsa);
      LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
	ospf_lsa_flush_schedule (ospf, lsa);
    }

  /*
   * Make sure that the MaxAge LSA remover is executed immediately,
   * without conflicting to other threads.
   */
  if (ospf->t_maxage != NULL)
    {
      OSPF_TIMER_OFF (ospf->t_maxage);
      thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
    }

  return;
}
#endif /* ORIGINAL_CODING */

/* If there is self-originated LSA, then return 1, otherwise return 0. */
/* An interface-independent version of ospf_lsa_is_self_originated */
int 
ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct listnode *node;
  struct ospf_interface *oi;

  /* This LSA is already checked. */
  if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
    return IS_LSA_SELF (lsa);

  /* Make sure LSA is self-checked. */
  SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);

  /* AdvRouter and Router ID is the same. */
  if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
    SET_FLAG (lsa->flags, OSPF_LSA_SELF);

  /* LSA is router-LSA. */
  else if (lsa->data->type == OSPF_ROUTER_LSA &&
      IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
    SET_FLAG (lsa->flags, OSPF_LSA_SELF);

  /* LSA is network-LSA.  Compare Link ID with all interfaces. */
  else if (lsa->data->type == OSPF_NETWORK_LSA)
    for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
      {
	/* Ignore virtual link. */
        if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
	  if (oi->address->family == AF_INET)
	    if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
	      {
		/* to make it easier later */
		SET_FLAG (lsa->flags, OSPF_LSA_SELF);
		return IS_LSA_SELF (lsa);
	      }
      }

  return IS_LSA_SELF (lsa);
}

/* Get unique Link State ID. */
struct in_addr
ospf_lsa_unique_id (struct ospf *ospf,
		    struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
{
  struct ospf_lsa *lsa;
  struct in_addr mask, id;

  id = p->prefix;

  /* Check existence of LSA instance. */
  lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
  if (lsa)
    {
      struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
      if (ip_masklen (al->mask) == p->prefixlen)
	{
	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
	    zlog_debug ("ospf_lsa_unique_id(): "
		       "Can't get Link State ID for %s/%d",
		       inet_ntoa (p->prefix), p->prefixlen);
	  /*	  id.s_addr = 0; */
	  id.s_addr = 0xffffffff;
	  return id;
	}
      /* Masklen differs, then apply wildcard mask to Link State ID. */
      else
	{
	  masklen2ip (p->prefixlen, &mask);

	  id.s_addr = p->prefix.s_addr | (~mask.s_addr);
	  lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
				       id, ospf->router_id);
	  if (lsa)
	    {
	      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
		zlog_debug ("ospf_lsa_unique_id(): "
			   "Can't get Link State ID for %s/%d",
			   inet_ntoa (p->prefix), p->prefixlen);
	      /* 	      id.s_addr = 0; */
	      id.s_addr = 0xffffffff;
	      return id;
	    }
	}
    }

  return id;
}


#define LSA_ACTION_FLOOD_AREA 1
#define LSA_ACTION_FLUSH_AREA 2

struct lsa_action
{
  u_char action;
  struct ospf_area *area;
  struct ospf_lsa *lsa;
};

static int
ospf_lsa_action (struct thread *t)
{
  struct lsa_action *data;

  data = THREAD_ARG (t);

  if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
    zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
	       data->action);

  switch (data->action)
    {
    case LSA_ACTION_FLOOD_AREA:
      ospf_flood_through_area (data->area, NULL, data->lsa);
      break;
    case LSA_ACTION_FLUSH_AREA:
      ospf_lsa_flush_area (data->lsa, data->area);
      break;
    }

  ospf_lsa_unlock (&data->lsa); /* Message */
  XFREE (MTYPE_OSPF_MESSAGE, data);
  return 0;
}

void
ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
{
  struct lsa_action *data;

  data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
  data->action = LSA_ACTION_FLOOD_AREA;
  data->area = area;
  data->lsa  = ospf_lsa_lock (lsa); /* Message / Flood area */

  thread_add_event (master, ospf_lsa_action, data, 0);
}

void
ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
{
  struct lsa_action *data;

  data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
  data->action = LSA_ACTION_FLUSH_AREA;
  data->area = area;
  data->lsa  = ospf_lsa_lock (lsa); /* Message / Flush area */

  thread_add_event (master, ospf_lsa_action, data, 0);
}


/* LSA Refreshment functions. */
struct ospf_lsa *
ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
{
  struct external_info *ei;
  struct ospf_lsa *new = NULL;
  assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
  assert (IS_LSA_SELF (lsa));
  assert (lsa->lock > 0);

  switch (lsa->data->type)
    {
      /* Router and Network LSAs are processed differently. */
    case OSPF_ROUTER_LSA:
      new = ospf_router_lsa_refresh (lsa);
      break;
    case OSPF_NETWORK_LSA: 
      new = ospf_network_lsa_refresh (lsa);
      break;
    case OSPF_SUMMARY_LSA:
      new = ospf_summary_lsa_refresh (ospf, lsa);
      break;
    case OSPF_ASBR_SUMMARY_LSA:
      new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
      break;
    case OSPF_AS_EXTERNAL_LSA:
      /* Translated from NSSA Type-5s are refreshed when 
       * from refresh of Type-7 - do not refresh these directly.
       */
      if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
        break;
      ei = ospf_external_info_check (lsa);
      if (ei)
        new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
      else
        ospf_lsa_flush_as (ospf, lsa);
      break;
    case OSPF_OPAQUE_LINK_LSA:
    case OSPF_OPAQUE_AREA_LSA:
    case OSPF_OPAQUE_AS_LSA:
      new = ospf_opaque_lsa_refresh (lsa);
      break;
    default:
      break;
    }
  return new;
}

void
ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
{
  u_int16_t index, current_index;
  
  assert (lsa->lock > 0);
  assert (IS_LSA_SELF (lsa));

  if (lsa->refresh_list < 0)
    {
      int delay;

      if (LS_AGE (lsa) == 0 &&
	  ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
	/* Randomize first update by  OSPF_LS_REFRESH_SHIFT factor */ 
	delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
      else
	/* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
	delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
	  + (random () % (2*OSPF_LS_REFRESH_JITTER)); 

      if (delay < 0)
	delay = 0;

      current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
                - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
      
      index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
	      % (OSPF_LSA_REFRESHER_SLOTS);

      if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
	zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
		   inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
      if (!ospf->lsa_refresh_queue.qs[index])
	ospf->lsa_refresh_queue.qs[index] = list_new ();
      listnode_add (ospf->lsa_refresh_queue.qs[index],
                    ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
      lsa->refresh_list = index;
      if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
        zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
                   "setting refresh_list on lsa %p (slod %d)", 
                   inet_ntoa (lsa->data->id), (void *)lsa, index);
    }
}

void
ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
{
  assert (lsa->lock > 0);
  assert (IS_LSA_SELF (lsa));
  if (lsa->refresh_list >= 0)
    {
      struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
      listnode_delete (refresh_list, lsa);
      if (!listcount (refresh_list))
	{
	  list_free (refresh_list);
	  ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
	}
      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
      lsa->refresh_list = -1;
    }
}

int
ospf_lsa_refresh_walker (struct thread *t)
{
  struct list *refresh_list;
  struct listnode *node, *nnode;
  struct ospf *ospf = THREAD_ARG (t);
  struct ospf_lsa *lsa;
  int i;
  struct list *lsa_to_refresh = list_new ();

  if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
    zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");

  
  i = ospf->lsa_refresh_queue.index;
  
  /* Note: if clock has jumped backwards, then time change could be negative,
     so we are careful to cast the expression to unsigned before taking
     modulus. */
  ospf->lsa_refresh_queue.index =
   ((unsigned long)(ospf->lsa_refresh_queue.index +
		    (quagga_time (NULL) - ospf->lsa_refresher_started)
		    / OSPF_LSA_REFRESHER_GRANULARITY))
		    % OSPF_LSA_REFRESHER_SLOTS;

  if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
    zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
	       ospf->lsa_refresh_queue.index);

  for (;i != ospf->lsa_refresh_queue.index;
       i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
    {
      if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
	zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
	           "refresh index %d", i);

      refresh_list = ospf->lsa_refresh_queue.qs [i];
      
      assert (i >= 0);

      ospf->lsa_refresh_queue.qs [i] = NULL;

      if (refresh_list)
	{
	  for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
	    {
	      if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
		zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
		           "refresh lsa %p (slot %d)",
		           inet_ntoa (lsa->data->id), (void *)lsa, i);

	      assert (lsa->lock > 0);
	      list_delete_node (refresh_list, node);
	      lsa->refresh_list = -1;
	      listnode_add (lsa_to_refresh, lsa);
	    }
	  list_free (refresh_list);
	}
    }

  ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
					   ospf, ospf->lsa_refresh_interval);
  ospf->lsa_refresher_started = quagga_time (NULL);

  for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
    {
      ospf_lsa_refresh (ospf, lsa);
      assert (lsa->lock > 0);
      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
    }
  
  list_delete (lsa_to_refresh);
  
  if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
    zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
  
  return 0;
}

