/* OSPF version 2 daemon program.
   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 "thread.h"
#include "vty.h"
#include "command.h"
#include "linklist.h"
#include "prefix.h"
#include "table.h"
#include "if.h"
#include "memory.h"
#include "stream.h"
#include "log.h"
#include "sockunion.h"          /* for inet_aton () */
#include "zclient.h"
#include "plist.h"

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



/* OSPF process wide configuration. */
static struct ospf_master ospf_master;

/* OSPF process wide configuration pointer to export. */
struct ospf_master *om;

extern struct zclient *zclient;
extern struct in_addr router_id_zebra;


void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
void ospf_network_free (struct ospf *, struct ospf_network *);
void ospf_area_free (struct ospf_area *);
void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);

#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1

void
ospf_router_id_update (struct ospf *ospf)
{
  struct in_addr router_id, router_id_old;
  struct listnode *node;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));

  router_id_old = ospf->router_id;

  if (ospf->router_id_static.s_addr != 0)
    router_id = ospf->router_id_static;
  else
    router_id = router_id_zebra;

  ospf->router_id = router_id;
  
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));

  if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
    {
      for (node = listhead (ospf->oiflist); node; nextnode (node))
        {
	  struct ospf_interface *oi = getdata (node);

          /* Update self-neighbor's router_id. */
          oi->nbr_self->router_id = router_id;
        }

      /* If AS-external-LSA is queued, then flush those LSAs. */
      if (router_id_old.s_addr == 0 && ospf->external_origin)
	{
	  int type;
	  /* Originate each redistributed external route. */
	  for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
	    if (ospf->external_origin & (1 << type))
	      thread_add_event (master, ospf_external_lsa_originate_timer,
				ospf, type);
	  /* Originate Deafult. */
	  if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
	    thread_add_event (master, ospf_default_originate_timer,
			      &ospf->default_originate, 0);

	  ospf->external_origin = 0;
	}

      OSPF_TIMER_ON (ospf->t_router_lsa_update,
		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
    }
}

int
ospf_router_id_update_timer (struct thread *thread)
{
  struct ospf *ospf = THREAD_ARG (thread);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("Router-ID: Update timer fired!");

  ospf->t_router_id_update = NULL;
  ospf_router_id_update (ospf);

  return 0;
}

/* For OSPF area sort by area id. */
int
ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
{
  if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
    return 1;
  if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
    return -1;
  return 0;
}

/* Allocate new ospf structure. */
struct ospf *
ospf_new ()
{
  int i;

  struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));

  new->router_id.s_addr = htonl (0);
  new->router_id_static.s_addr = htonl (0);

  new->abr_type = OSPF_ABR_STAND;
  new->oiflist = list_new ();
  new->vlinks = list_new ();
  new->areas = list_new ();
  new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
  new->networks = route_table_init ();
  new->nbr_nbma = route_table_init ();

  new->lsdb = ospf_lsdb_new ();

  new->default_originate = DEFAULT_ORIGINATE_NONE;

  new->new_external_route = route_table_init ();
  new->old_external_route = route_table_init ();
  new->external_lsas = route_table_init ();

  /* Distribute parameter init. */
  for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
    {
      new->dmetric[i].type = -1;
      new->dmetric[i].value = -1;
    }
  new->default_metric = -1;
  new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;

  /* SPF timer value init. */
  new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
  new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;

  /* MaxAge init. */
  new->maxage_lsa = list_new ();
  new->t_maxage_walker =
    thread_add_timer (master, ospf_lsa_maxage_walker,
                      new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);

  /* Distance table init. */
  new->distance_table = route_table_init ();

  new->lsa_refresh_queue.index = 0;
  new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
  new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
					   new, new->lsa_refresh_interval);
  new->lsa_refresher_started = time (NULL);

  new->fd = ospf_sock_init ();
  if (new->fd >= 0)
    new->t_read = thread_add_read (master, ospf_read, new, new->fd);
  new->oi_write_q = list_new ();
  
  return new;
}

struct ospf *
ospf_lookup ()
{
  if (listcount (om->ospf) == 0)
    return NULL;

  return getdata (listhead (om->ospf));
}

void
ospf_add (struct ospf *ospf)
{
  listnode_add (om->ospf, ospf);
}

void
ospf_delete (struct ospf *ospf)
{
  listnode_delete (om->ospf, ospf);
}

struct ospf *
ospf_get ()
{
  struct ospf *ospf;

  ospf = ospf_lookup ();
  if (ospf == NULL)
    {
      ospf = ospf_new ();
      ospf_add (ospf);

      if (ospf->router_id_static.s_addr == 0)
	ospf_router_id_update (ospf);

#ifdef HAVE_OPAQUE_LSA
      ospf_opaque_type11_lsa_init (ospf);
#endif /* HAVE_OPAQUE_LSA */
    }

  return ospf;
}

void
ospf_finish (struct ospf *ospf)
{
  struct route_node *rn;
  struct ospf_nbr_nbma *nbr_nbma;
  struct ospf_lsa *lsa;
  struct listnode *node;
  int i;

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_type11_lsa_term (ospf);
#endif /* HAVE_OPAQUE_LSA */

  /* Unredister redistribution */
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    ospf_redistribute_unset (ospf, i);

  for (node = listhead (ospf->areas); node;)
    {
      struct ospf_area *area = getdata (node);
      nextnode (node);
      
      ospf_remove_vls_through_area (ospf, area);
    }
  
  for (node = listhead (ospf->vlinks); node; )
    {
      struct ospf_vl_data *vl_data = node->data;
      nextnode (node);
      
      ospf_vl_delete (ospf, vl_data);
    }
  
  list_delete (ospf->vlinks);

  /* Reset interface. */
  for (node = listhead (ospf->oiflist); node;)
    {
      struct ospf_interface *oi = getdata (node);
      nextnode (node);
      
      if (oi)
	ospf_if_free (oi);
    }

  /* Clear static neighbors */
  for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
    if ((nbr_nbma = rn->info))
      {
	OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);

	if (nbr_nbma->nbr)
	  {
	    nbr_nbma->nbr->nbr_nbma = NULL;
	    nbr_nbma->nbr = NULL;
	  }

	if (nbr_nbma->oi)
	  {
	    listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
	    nbr_nbma->oi = NULL;
	  }

	XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
      }

  route_table_finish (ospf->nbr_nbma);

  /* Clear networks and Areas. */
  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
    {
      struct ospf_network *network;

      if ((network = rn->info) != NULL)
	{
	  ospf_network_free (ospf, network);
	  rn->info = NULL;
	  route_unlock_node (rn);
	}
    }

  for (node = listhead (ospf->areas); node;)
    {
      struct ospf_area *area = getdata (node);
      nextnode (node);
      
      listnode_delete (ospf->areas, area);
      ospf_area_free (area);
    }

  /* Cancel all timers. */
  OSPF_TIMER_OFF (ospf->t_external_lsa);
  OSPF_TIMER_OFF (ospf->t_router_id_update);
  OSPF_TIMER_OFF (ospf->t_router_lsa_update);
  OSPF_TIMER_OFF (ospf->t_spf_calc);
  OSPF_TIMER_OFF (ospf->t_ase_calc);
  OSPF_TIMER_OFF (ospf->t_maxage);
  OSPF_TIMER_OFF (ospf->t_maxage_walker);
  OSPF_TIMER_OFF (ospf->t_abr_task);
  OSPF_TIMER_OFF (ospf->t_distribute_update);
  OSPF_TIMER_OFF (ospf->t_lsa_refresher);
  OSPF_TIMER_OFF (ospf->t_read);
  OSPF_TIMER_OFF (ospf->t_write);

  close (ospf->fd);
   
#ifdef HAVE_OPAQUE_LSA
  LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
    ospf_discard_from_db (ospf, ospf->lsdb, lsa);
#endif /* HAVE_OPAQUE_LSA */
  LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
    ospf_discard_from_db (ospf, ospf->lsdb, lsa);

  ospf_lsdb_delete_all (ospf->lsdb);
  ospf_lsdb_free (ospf->lsdb);

  for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
    ospf_lsa_unlock (getdata (node));

  list_delete (ospf->maxage_lsa);

  if (ospf->old_table)
    ospf_route_table_free (ospf->old_table);
  if (ospf->new_table)
    {
      ospf_route_delete (ospf->new_table);
      ospf_route_table_free (ospf->new_table);
    }
  if (ospf->old_rtrs)
    ospf_rtrs_free (ospf->old_rtrs);
  if (ospf->new_rtrs)
    ospf_rtrs_free (ospf->new_rtrs);
  if (ospf->new_external_route)
    {
      ospf_route_delete (ospf->new_external_route);
      ospf_route_table_free (ospf->new_external_route);
    }
  if (ospf->old_external_route)
    {
      ospf_route_delete (ospf->old_external_route);
      ospf_route_table_free (ospf->old_external_route);
    }
  if (ospf->external_lsas)
    {
      ospf_ase_external_lsas_finish (ospf->external_lsas);
    }

  list_delete (ospf->areas);
  
  for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
    if (EXTERNAL_INFO (i) != NULL)
      for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
	{
	  if (rn->info == NULL)
	    continue;
	  
	  XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
	  rn->info = NULL;
	  route_unlock_node (rn);
	}

  ospf_distance_reset (ospf);
  route_table_finish (ospf->distance_table);

  ospf_delete (ospf);

  XFREE (MTYPE_OSPF_TOP, ospf);
}


/* allocate new OSPF Area object */
struct ospf_area *
ospf_area_new (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *new;

  /* Allocate new config_network. */
  new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));

  new->ospf = ospf;

  new->area_id = area_id;

  new->external_routing = OSPF_AREA_DEFAULT;
  new->default_cost = 1;
  new->auth_type = OSPF_AUTH_NULL;

  /* New LSDB init. */
  new->lsdb = ospf_lsdb_new ();

  /* Self-originated LSAs initialize. */
  new->router_lsa_self = NULL;

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_type10_lsa_init (new);
#endif /* HAVE_OPAQUE_LSA */

  new->oiflist = list_new ();
  new->ranges = route_table_init ();

  if (area_id.s_addr == OSPF_AREA_BACKBONE)
    ospf->backbone = new;

  return new;
}

void
ospf_area_free (struct ospf_area *area)
{
  struct route_node *rn;
  struct ospf_lsa *lsa;

  /* Free LSDBs. */
  LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
  LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
  LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
  LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);

  LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
#ifdef HAVE_OPAQUE_LSA
  LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
  LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
#endif /* HAVE_OPAQUE_LSA */

  ospf_lsdb_delete_all (area->lsdb);
  ospf_lsdb_free (area->lsdb);

  ospf_lsa_unlock (area->router_lsa_self);
  
  route_table_finish (area->ranges);
  list_delete (area->oiflist);

  if (EXPORT_NAME (area))
    free (EXPORT_NAME (area));

  if (IMPORT_NAME (area))
    free (IMPORT_NAME (area));

  /* Cancel timer. */
  OSPF_TIMER_OFF (area->t_router_lsa_self);

  if (OSPF_IS_AREA_BACKBONE (area))
    area->ospf->backbone = NULL;

  XFREE (MTYPE_OSPF_AREA, area);
}

void
ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (area &&
      listcount (area->oiflist) == 0 &&
      area->ranges->top == NULL &&
      area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
      area->external_routing == OSPF_AREA_DEFAULT &&
      area->no_summary == 0 &&
      area->default_cost == 1 &&
      EXPORT_NAME (area) == NULL &&
      IMPORT_NAME (area) == NULL &&
      area->auth_type == OSPF_AUTH_NULL)
    {
      listnode_delete (ospf->areas, area);
      ospf_area_free (area);
    }
}

struct ospf_area *
ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
{
  struct ospf_area *area;
  
  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (!area)
    {
      area = ospf_area_new (ospf, area_id);
      area->format = format;
      listnode_add_sort (ospf->areas, area);
      ospf_check_abr_status (ospf);  
    }

  return area;
}

struct ospf_area *
ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;
  struct listnode *node;

  for (node = listhead (ospf->areas); node; nextnode (node))
    {
      area = getdata (node);

      if (IPV4_ADDR_SAME (&area->area_id, &area_id))
        return area;
    }

  return NULL;
}

void
ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
{
  listnode_add (area->oiflist, oi);
}

void
ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
{
  listnode_delete (area->oiflist, oi);
}


/* Config network statement related functions. */
struct ospf_network *
ospf_network_new (struct in_addr area_id, int format)
{
  struct ospf_network *new;
  new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));

  new->area_id = area_id;
  new->format = format;
  
  return new;
}

void
ospf_network_free (struct ospf *ospf, struct ospf_network *network)
{
  ospf_area_check_free (ospf, network->area_id);
  ospf_schedule_abr_task (ospf);
  XFREE (MTYPE_OSPF_NETWORK, network);
}

int
ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
		  struct in_addr area_id)
{
  struct ospf_network *network;
  struct ospf_area *area;
  struct route_node *rn;
  struct external_info *ei;
  int ret = OSPF_AREA_ID_FORMAT_ADDRESS;

  rn = route_node_get (ospf->networks, (struct prefix *)p);
  if (rn->info)
    {
      /* There is already same network statement. */
      route_unlock_node (rn);
      return 0;
    }

  rn->info = network = ospf_network_new (area_id, ret);
  area = ospf_area_get (ospf, area_id, ret);

  /* Run network config now. */
  ospf_network_run (ospf, (struct prefix *)p, area);

  /* Update connected redistribute. */
  if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
    if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
      for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
	   rn; rn = route_next (rn))
	if ((ei = rn->info) != NULL)
	  if (ospf_external_info_find_lsa (ospf, &ei->p))
	    if (!ospf_distribute_check_connected (ospf, ei))
	      ospf_external_lsa_flush (ospf, ei->type, &ei->p,
				       ei->ifindex, ei->nexthop);

  ospf_area_check_free (ospf, area_id);

  return 1;
}

int
ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
		    struct in_addr area_id)
{
  struct route_node *rn;
  struct ospf_network *network;
  struct external_info *ei;

  rn = route_node_lookup (ospf->networks, (struct prefix *)p);
  if (rn == NULL)
    return 0;

  network = rn->info;
  if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
    return 0;

  ospf_network_free (ospf, rn->info);
  rn->info = NULL;
  route_unlock_node (rn);

  ospf_if_update (ospf);
  
  /* Update connected redistribute. */
  if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
    if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
      for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
	   rn; rn = route_next (rn))
	if ((ei = rn->info) != NULL)
	  if (!ospf_external_info_find_lsa (ospf, &ei->p))
	    if (ospf_distribute_check_connected (ospf, ei))
	      ospf_external_lsa_originate (ospf, ei);

  return 1;
}

/* Check whether interface matches given network
 * returns: 1, true. 0, false
 */
int 
ospf_network_match_iface(struct connected *co, struct prefix *net)
{
  /* Behaviour to match both Cisco where:
   *   iface address lies within network specified -> ospf
   * and zebra 0.9[2ish-3]:
   *   PtP special case: network specified == iface peer addr -> ospf
   */

  /* For PtP, match if peer address matches network address exactly.
   * This can be addr/32 or addr/p for p < 32, but the addr must match
   * exactly; this is not a test for falling within the prefix.  This
   * test is solely for compatibility with zebra.
   */
  if (if_is_pointopoint (co->ifp) && co->destination &&
      IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
    return 1;

#if 0
  /* Decline to accept PtP if dst address does not match the
   * prefix. (ifdefed out because this is a workaround, not the
   * desired behavior.) */
  if (if_is_pointopoint (co->ifp) &&
      ! prefix_match (net, co->destination))
    return 0;
#endif

  /* If the address is within the prefix, accept.  Note that this
   * applies to PtP as well as other types.
   */
  if (prefix_match (net, co->address))
    return 1;

  return 0;			/* no match */
}

void
ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
{
  struct interface *ifp;
  struct listnode *node;

  /* Schedule Router ID Update. */
  if (ospf->router_id_static.s_addr == 0)
    if (ospf->t_router_id_update == NULL)
      {
	OSPF_TIMER_ON (ospf->t_router_id_update, ospf_router_id_update_timer,
		       OSPF_ROUTER_ID_UPDATE_DELAY);
      }

  /* Get target interface. */
  for (node = listhead (om->iflist); node; nextnode (node))
    {
      struct listnode *cn;
      
      if ((ifp = getdata (node)) == NULL)
	continue;

      if (memcmp (ifp->name, "VLINK", 5) == 0)
	continue;
	
      /* if interface prefix is match specified prefix,
	 then create socket and join multicast group. */
      for (cn = listhead (ifp->connected); cn; nextnode (cn))
	{
	  struct connected *co = getdata (cn);
	  struct prefix *addr;
	  
          if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
            continue;

	  if (CONNECTED_POINTOPOINT_HOST(co))
	    addr = co->destination;
	  else 
	    addr = co->address;

	  if (p->family == co->address->family 
	      && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
	      && ospf_network_match_iface(co,p))
	    {
      	struct ospf_interface *oi;
		
		oi = ospf_if_new (ospf, ifp, co->address);
		oi->connected = co;
		
		oi->nbr_self->address = *oi->address;

		oi->area = area;

		oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
		oi->output_cost = ospf_if_get_output_cost (oi);
		
		if (area->external_routing != OSPF_AREA_DEFAULT)
		  UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
		oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
		
		/* Add pseudo neighbor. */
		ospf_nbr_add_self (oi);

		/* Make sure pseudo neighbor's router_id. */
		oi->nbr_self->router_id = ospf->router_id;
		oi->nbr_self->src = oi->address->u.prefix4;
		
		/* Relate ospf interface to ospf instance. */
		oi->ospf = ospf;

		/* update network type as interface flag */
		/* If network type is specified previously,
		   skip network type setting. */
		oi->type = IF_DEF_PARAMS (ifp)->type;
		
		/* Set area flag. */
		switch (area->external_routing)
		  {
		  case OSPF_AREA_DEFAULT:
		    SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
		    break;
		  case OSPF_AREA_STUB:
		    UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
		    break;
		  case OSPF_AREA_NSSA:
		    UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
		    SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
		    break;
		  }

		ospf_area_add_if (oi->area, oi);

		if (if_is_operative (ifp)) 
		  ospf_if_up (oi);

		break;
	      }
	}
    }
}

void
ospf_ls_upd_queue_empty (struct ospf_interface *oi)
{
  struct route_node *rn;
  struct listnode *node;
  struct list *lst;
  struct ospf_lsa *lsa;

  /* empty ls update queue */
  for (rn = route_top (oi->ls_upd_queue); rn;
       rn = route_next (rn))
    if ((lst = (struct list *) rn->info))
      {
	for (node = listhead (lst); node; nextnode (node))
	  if ((lsa = getdata (node)))
	    ospf_lsa_unlock (lsa);
	list_free (lst);
	rn->info = NULL;
      }
  
  /* remove update event */
  if (oi->t_ls_upd_event)
    {
      thread_cancel (oi->t_ls_upd_event);
      oi->t_ls_upd_event = NULL;
    }
}

void
ospf_if_update (struct ospf *ospf)
{
  struct route_node *rn;
  struct listnode *node;
  struct listnode *next;
  struct ospf_network *network;
  struct ospf_area *area;

  if (ospf != NULL)
    {
      /* Update Router ID scheduled. */
      if (ospf->router_id_static.s_addr == 0)
        if (ospf->t_router_id_update == NULL)
          {
	    OSPF_TIMER_ON (ospf->t_router_id_update,
			   ospf_router_id_update_timer,
			   OSPF_ROUTER_ID_UPDATE_DELAY);
          }

      /* Find interfaces that not configured already.  */
      for (node = listhead (ospf->oiflist); node; node = next)
	{
	  int found = 0;
	  struct ospf_interface *oi = getdata (node);
	  struct connected *co = oi->connected;
	  
	  next = nextnode (node);

	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	    continue;
	  
	  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
	    {
	      if (rn->info == NULL)
		continue;
	      
	      if (ospf_network_match_iface(co,&rn->p))
		{
		  found = 1;
		  route_unlock_node (rn);
		  break;
		}
	    }

	  if (found == 0)
	    ospf_if_free (oi);
	}
	
      /* Run each interface. */
      for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
	if (rn->info != NULL)
	  {
	    network = (struct ospf_network *) rn->info;
	    area = ospf_area_get (ospf, network->area_id, network->format);
	    ospf_network_run (ospf, &rn->p, area);
	  }
    }
}

void
ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
{
  struct listnode *node, *next;
  struct ospf_vl_data *vl_data;

  for (node = listhead (ospf->vlinks); node; node = next)
    {
      next = node->next;
      if ((vl_data = getdata (node)) != NULL)
	if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
	  ospf_vl_delete (ospf, vl_data);
    }
}


struct message ospf_area_type_msg[] =
{
  { OSPF_AREA_DEFAULT,	"Default" },
  { OSPF_AREA_STUB,     "Stub" },
  { OSPF_AREA_NSSA,     "NSSA" },
};
int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;

void
ospf_area_type_set (struct ospf_area *area, int type)
{
  struct listnode *node;
  struct ospf_interface *oi;

  if (area->external_routing == type)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("Area[%s]: Types are the same, ignored.",
		   inet_ntoa (area->area_id));
      return;
    }

  area->external_routing = type;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
	       LOOKUP (ospf_area_type_msg, type));

  switch (area->external_routing)
    {
    case OSPF_AREA_DEFAULT:
      for (node = listhead (area->oiflist); node; nextnode (node))
	if ((oi = getdata (node)) != NULL)
	  if (oi->nbr_self != NULL)
	    {
	      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
	      SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
	    }
      break;
    case OSPF_AREA_STUB:
      for (node = listhead (area->oiflist); node; nextnode (node))
	if ((oi = getdata (node)) != NULL)
	  if (oi->nbr_self != NULL)
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("setting options on %s accordingly", IF_NAME (oi));
	      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
	      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("options set on %s: %x",
			   IF_NAME (oi), OPTIONS (oi));
	    }
      break;
    case OSPF_AREA_NSSA:
      for (node = listhead (area->oiflist); node; nextnode (node))
	if ((oi = getdata (node)) != NULL)
	  if (oi->nbr_self != NULL)
	    {
	      zlog_info ("setting nssa options on %s accordingly", IF_NAME (oi));
	      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
	      SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
	      zlog_info ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
	    }
      break;
    default:
      break;
    }

  ospf_router_lsa_timer_add (area);
  ospf_schedule_abr_task (area->ospf);
}

int
ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
{
  if (area->shortcut_configured == mode)
    return 0;

  area->shortcut_configured = mode;
  ospf_router_lsa_timer_add (area);
  ospf_schedule_abr_task (ospf);

  ospf_area_check_free (ospf, area->area_id);

  return 1;
}

int
ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
{
  area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
  ospf_router_lsa_timer_add (area);
  ospf_area_check_free (ospf, area->area_id);
  ospf_schedule_abr_task (ospf);

  return 1;
}

int
ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
{
  struct ospf_vl_data *vl;
  struct listnode *node;
  int count = 0;

  for (node = listhead (ospf->vlinks); node; nextnode (node))
    {
      vl = getdata (node);
      if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
	count++;
    }

  return count;
}

int
ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;
  int format = OSPF_AREA_ID_FORMAT_ADDRESS;

  area = ospf_area_get (ospf, area_id, format);
  if (ospf_area_vlink_count (ospf, area))
    return 0;

  if (area->external_routing != OSPF_AREA_STUB)
    ospf_area_type_set (area, OSPF_AREA_STUB);

  return 1;
}

int
ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (area == NULL)
    return 1;

  if (area->external_routing == OSPF_AREA_STUB)
    ospf_area_type_set (area, OSPF_AREA_DEFAULT);

  ospf_area_check_free (ospf, area_id);

  return 1;
}

int
ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;
  int format = OSPF_AREA_ID_FORMAT_ADDRESS;

  area = ospf_area_get (ospf, area_id, format);
  area->no_summary = 1;

  return 1;
}

int
ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (area == NULL)
    return 0;

  area->no_summary = 0;
  ospf_area_check_free (ospf, area_id);

  return 1;
}

int
ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;
  int format = OSPF_AREA_ID_FORMAT_ADDRESS;

  area = ospf_area_get (ospf, area_id, format);
  if (ospf_area_vlink_count (ospf, area))
    return 0;

  if (area->external_routing != OSPF_AREA_NSSA)
    {
      ospf_area_type_set (area, OSPF_AREA_NSSA);
      ospf->anyNSSA++;
    }

  /* set NSSA area defaults */
  area->no_summary = 0;
  area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
  area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
  area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;

  return 1;
}

int
ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (area == NULL)
    return 0;

  if (area->external_routing == OSPF_AREA_NSSA)
    {
      ospf->anyNSSA--;
      ospf_area_type_set (area, OSPF_AREA_DEFAULT);
    }

  ospf_area_check_free (ospf, area_id);

  return 1;
}

int
ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
				    int role)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (area == NULL)
    return 0;

  area->NSSATranslatorRole = role;

  return 1;
}

int
ospf_area_nssa_translator_role_unset (struct ospf *ospf,
				      struct in_addr area_id)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, area_id);
  if (area == NULL)
    return 0;

  area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;

  ospf_area_check_free (ospf, area_id);

  return 1;
}

int
ospf_area_export_list_set (struct ospf *ospf,
			   struct ospf_area *area, const char *list_name)
{
  struct access_list *list;
  list = access_list_lookup (AFI_IP, list_name);

  EXPORT_LIST (area) = list;

  if (EXPORT_NAME (area))
    free (EXPORT_NAME (area));

  EXPORT_NAME (area) = strdup (list_name);
  ospf_schedule_abr_task (ospf);

  return 1;
}

int
ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
{

  EXPORT_LIST (area) = 0;

  if (EXPORT_NAME (area))
    free (EXPORT_NAME (area));

  EXPORT_NAME (area) = NULL;

  ospf_area_check_free (ospf, area->area_id);
  
  ospf_schedule_abr_task (ospf);

  return 1;
}

int
ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area, 
                           const char *name)
{
  struct access_list *list;
  list = access_list_lookup (AFI_IP, name);

  IMPORT_LIST (area) = list;

  if (IMPORT_NAME (area))
    free (IMPORT_NAME (area));

  IMPORT_NAME (area) = strdup (name);
  ospf_schedule_abr_task (ospf);

  return 1;
}

int
ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
{
  IMPORT_LIST (area) = 0;

  if (IMPORT_NAME (area))
    free (IMPORT_NAME (area));

  IMPORT_NAME (area) = NULL;
  ospf_area_check_free (ospf, area->area_id);

  ospf_schedule_abr_task (ospf);

  return 1;
}

int
ospf_timers_spf_set (struct ospf *ospf, u_int32_t delay, u_int32_t hold)
{
  ospf->spf_delay = delay;
  ospf->spf_holdtime = hold;

  return 1;
}

int
ospf_timers_spf_unset (struct ospf *ospf)
{
  ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT;
  ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;

  return 1;
}

int
ospf_timers_refresh_set (struct ospf *ospf, int interval)
{
  int time_left;

  if (ospf->lsa_refresh_interval == interval)
    return 1;

  time_left = ospf->lsa_refresh_interval -
    (time (NULL) - ospf->lsa_refresher_started);
  
  if (time_left > interval)
    {
      OSPF_TIMER_OFF (ospf->t_lsa_refresher);
      ospf->t_lsa_refresher =
	thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
    }
  ospf->lsa_refresh_interval = interval;

  return 1;
}

int
ospf_timers_refresh_unset (struct ospf *ospf)
{
  int time_left;

  time_left = ospf->lsa_refresh_interval -
    (time (NULL) - ospf->lsa_refresher_started);

  if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
    {
      OSPF_TIMER_OFF (ospf->t_lsa_refresher);
      ospf->t_lsa_refresher =
	thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
			  OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
    }

  ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;

  return 1;
}


struct ospf_nbr_nbma *
ospf_nbr_nbma_new ()
{
  struct ospf_nbr_nbma *nbr_nbma;

  nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
		      sizeof (struct ospf_nbr_nbma));
  memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));

  nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
  nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;

  return nbr_nbma;
}

void
ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
{
  XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
}

void
ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
{
  struct route_node *rn;
  struct prefix_ipv4 p;

  p.family = AF_INET;
  p.prefix = nbr_nbma->addr;
  p.prefixlen = IPV4_MAX_BITLEN;

  rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
  if (rn)
    {
      ospf_nbr_nbma_free (rn->info);
      rn->info = NULL;
      route_unlock_node (rn);
      route_unlock_node (rn);
    }
}

void
ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
{
  OSPF_TIMER_OFF (nbr_nbma->t_poll);

  if (nbr_nbma->nbr)
    {
      nbr_nbma->nbr->nbr_nbma = NULL;
      OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
    }

  if (nbr_nbma->oi)
    listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
}

void
ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
		   struct ospf_interface *oi)
{
  struct ospf_neighbor *nbr;
  struct route_node *rn;
  struct prefix p;

  if (oi->type != OSPF_IFTYPE_NBMA)
    return;

  if (nbr_nbma->nbr != NULL)
    return;

  if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
    return;
      
  nbr_nbma->oi = oi;
  listnode_add (oi->nbr_nbma, nbr_nbma);

  /* Get neighbor information from table. */
  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_BITLEN;
  p.u.prefix4 = nbr_nbma->addr;

  rn = route_node_get (oi->nbrs, (struct prefix *)&p);
  if (rn->info)
    {
      nbr = rn->info;
      nbr->nbr_nbma = nbr_nbma;
      nbr_nbma->nbr = nbr;

      route_unlock_node (rn);
    }
  else
    {
      nbr = rn->info = ospf_nbr_new (oi);
      nbr->state = NSM_Down;
      nbr->src = nbr_nbma->addr;
      nbr->nbr_nbma = nbr_nbma;
      nbr->priority = nbr_nbma->priority;
      nbr->address = p;

      nbr_nbma->nbr = nbr;

      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
    }
}

void
ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
{
  struct ospf_nbr_nbma *nbr_nbma;
  struct route_node *rn;
  struct prefix_ipv4 p;

  if (oi->type != OSPF_IFTYPE_NBMA)
    return;

  for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
    if ((nbr_nbma = rn->info))
      if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
	{
	  p.family = AF_INET;
	  p.prefix = nbr_nbma->addr;
	  p.prefixlen = IPV4_MAX_BITLEN;

	  if (prefix_match (oi->address, (struct prefix *)&p))
	    ospf_nbr_nbma_add (nbr_nbma, oi);
	}
}

struct ospf_nbr_nbma *
ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
{
  struct route_node *rn;
  struct prefix_ipv4 p;

  p.family = AF_INET;
  p.prefix = nbr_addr;
  p.prefixlen = IPV4_MAX_BITLEN;

  rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
  if (rn)
    {
      route_unlock_node (rn);
      return rn->info;
    }
  return NULL;
}

struct ospf_nbr_nbma *
ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
{
#if 0
  struct ospf_nbr_nbma *nbr_nbma;
  struct listnode *node;
#endif

  if (ospf == NULL)
    return NULL;

#if 0
  for (node = listhead (ospf->nbr_nbma); node; nextnode (node))
    {
      nbr_nbma = getdata (node);

      if (first)
	{
	  *addr = nbr_nbma->addr;
	  return nbr_nbma;
	}
      else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
	{
	  *addr = nbr_nbma->addr;
	  return nbr_nbma;
	}
    }
#endif
  return NULL;
}

int
ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
{
  struct ospf_nbr_nbma *nbr_nbma;
  struct ospf_interface *oi;
  struct prefix_ipv4 p;
  struct route_node *rn;
  struct listnode *node;

  nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
  if (nbr_nbma)
    return 0;

  nbr_nbma = ospf_nbr_nbma_new ();
  nbr_nbma->addr = nbr_addr;

  p.family = AF_INET;
  p.prefix = nbr_addr;
  p.prefixlen = IPV4_MAX_BITLEN;

  rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
  rn->info = nbr_nbma;

  for (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      oi = getdata (node);
      if (oi->type == OSPF_IFTYPE_NBMA)
	if (prefix_match (oi->address, (struct prefix *)&p))
	  {
	    ospf_nbr_nbma_add (nbr_nbma, oi);
	    break;
	  }
    }

  return 1;
}

int
ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
{
  struct ospf_nbr_nbma *nbr_nbma;

  nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
  if (nbr_nbma == NULL)
    return 0;

  ospf_nbr_nbma_down (nbr_nbma);
  ospf_nbr_nbma_delete (ospf, nbr_nbma);

  return 1;
}

int
ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
			    u_char priority)
{
  struct ospf_nbr_nbma *nbr_nbma;

  nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
  if (nbr_nbma == NULL)
    return 0;

  if (nbr_nbma->priority != priority)
    nbr_nbma->priority = priority;

  return 1;
}

int
ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
{
  struct ospf_nbr_nbma *nbr_nbma;

  nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
  if (nbr_nbma == NULL)
    return 0;

  if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
    nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;

  return 1;
}

int
ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
				 unsigned int interval)
{
  struct ospf_nbr_nbma *nbr_nbma;

  nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
  if (nbr_nbma == NULL)
    return 0;

  if (nbr_nbma->v_poll != interval)
    {
      nbr_nbma->v_poll = interval;
      if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
	{
	  OSPF_TIMER_OFF (nbr_nbma->t_poll);
	  OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
			      nbr_nbma->v_poll);
	}
    }

  return 1;
}

int
ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
{
  struct ospf_nbr_nbma *nbr_nbma;

  nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
  if (nbr_nbma == NULL)
    return 0;

  if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
    nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;

  return 1;
}

void
ospf_master_init ()
{
  memset (&ospf_master, 0, sizeof (struct ospf_master));

  om = &ospf_master;
  om->ospf = list_new ();
  om->master = thread_master_create ();
  om->start_time = time (NULL);
}
