/* 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 "sockopt.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;


static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
static void ospf_network_free (struct ospf *, struct ospf_network *);
static void ospf_area_free (struct ospf_area *);
static void ospf_network_run (struct prefix *, struct ospf_area *);
static void ospf_network_run_interface (struct ospf *, struct interface *, 
                                        struct prefix *, struct ospf_area *);
static void ospf_network_run_subnet (struct ospf *, struct connected *, 
                                     struct prefix *, struct ospf_area *);
static int ospf_network_match_iface (const struct connected *,
				     const struct prefix *);
static void ospf_finish_final (struct ospf *);

#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1

void
ospf_router_id_update (struct ospf *ospf)
{
  struct in_addr router_id, router_id_old;
  struct ospf_interface *oi;
  struct interface *ifp;
  struct listnode *node;

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

  router_id_old = ospf->router_id;

  /* Select the router ID based on these priorities:
       1. Statically assigned router ID is always the first choice.
       2. If there is no statically assigned router ID, then try to stick
          with the most recent value, since changing router ID's is very
	  disruptive.
       3. Last choice: just go with whatever the zebra daemon recommends.
  */
  if (ospf->router_id_static.s_addr != 0)
    router_id = ospf->router_id_static;
  else if (ospf->router_id.s_addr != 0)
    router_id = ospf->router_id;
  else
    router_id = router_id_zebra;

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

  if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
    {
      for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
	{
	  /* Some nbrs are identified by router_id, these needs
	   * to be rebuilt. Possible optimization would be to do
	   * oi->nbr_self->router_id = router_id for
	   * !(virtual | ptop) links
	   */
	  ospf_nbr_self_reset (oi);
	}

      /* 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, 0);

	  ospf->external_origin = 0;
	}

      /* update router-lsa's for each area */
      ospf_router_lsa_update (ospf);
      
      /* update ospf_interface's */
      for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
        ospf_if_update (ospf, ifp);
    }
}

/* For OSPF area sort by area id. */
static 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. */
static struct ospf *
ospf_new (void)
{
  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_DEFAULT;
  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->passive_interface_default = OSPF_IF_ACTIVE;
  
  new->new_external_route = route_table_init ();
  new->old_external_route = route_table_init ();
  new->external_lsas = route_table_init ();
  
  new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
  new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
  new->stub_router_admin_set     = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;

  /* 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;

  /* LSA timers */
  new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
  new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;

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

  /* MaxAge init. */
  new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
  new->maxage_lsa = route_table_init();
  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 = quagga_time (NULL);

  if ((new->fd = ospf_sock_init()) < 0)
    {
      zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
	       "a socket");
      exit(1);
    }
  new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
    zlog_debug ("%s: starting with OSPF send buffer size %u",
      __func__, new->maxsndbuflen);
  if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
    {
      zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
	       OSPF_MAX_PACKET_SIZE+1);
      exit(1);
    }
  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 listgetdata (listhead (om->ospf));
}

static int
ospf_is_ready (struct ospf *ospf)
{
  /* OSPF must be on and Router-ID must be configured. */
  if (!ospf || ospf->router_id.s_addr == 0)
    return 0;
  
  return 1;
}

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

static 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);

      ospf_opaque_type11_lsa_init (ospf);
    }

  return ospf;
}

/* Handle the second half of deferred shutdown. This is called either
 * from the deferred-shutdown timer thread, or directly through
 * ospf_deferred_shutdown_check.
 *
 * Function is to cleanup G-R state, if required then call ospf_finish_final
 * to complete shutdown of this ospf instance. Possibly exit if the
 * whole process is being shutdown and this was the last OSPF instance.
 */
static void
ospf_deferred_shutdown_finish (struct ospf *ospf)
{
  ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;  
  OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
  
  ospf_finish_final (ospf);
  
  /* *ospf is now invalid */
  
  /* ospfd being shut-down? If so, was this the last ospf instance? */
  if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
      && (listcount (om->ospf) == 0))
    exit (0);

  return;
}

/* Timer thread for G-R */
static int
ospf_deferred_shutdown_timer (struct thread *t)
{
  struct ospf *ospf = THREAD_ARG(t);
  
  ospf_deferred_shutdown_finish (ospf);
  
  return 0;
}

/* Check whether deferred-shutdown must be scheduled, otherwise call
 * down directly into second-half of instance shutdown.
 */
static void
ospf_deferred_shutdown_check (struct ospf *ospf)
{
  unsigned long timeout;
  struct listnode *ln;
  struct ospf_area *area;
  
  /* deferred shutdown already running? */
  if (ospf->t_deferred_shutdown)
    return;
  
  /* Should we try push out max-metric LSAs? */
  if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
    {
      for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
        {
          SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
          
          if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
            ospf_router_lsa_update_area (area);
        }
      timeout = ospf->stub_router_shutdown_time;
    }
  else
    {
      /* No timer needed */
      ospf_deferred_shutdown_finish (ospf);
      return;
    }
  
  OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
                 timeout);
  return;
}

/* Shut down the entire process */
void
ospf_terminate (void)
{
  struct ospf *ospf;
  struct listnode *node, *nnode;
  
  /* shutdown already in progress */
  if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
    return;
  
  SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);

  /* exit immediately if OSPF not actually running */
  if (listcount(om->ospf) == 0)
    exit(0);

  for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
    ospf_finish (ospf);

  /* Deliberately go back up, hopefully to thread scheduler, as
   * One or more ospf_finish()'s may have deferred shutdown to a timer
   * thread
   */
}

void
ospf_finish (struct ospf *ospf)
{
  /* let deferred shutdown decide */
  ospf_deferred_shutdown_check (ospf);
      
  /* if ospf_deferred_shutdown returns, then ospf_finish_final is
   * deferred to expiry of G-S timer thread. Return back up, hopefully
   * to thread scheduler.
   */
  return;
}

/* Final cleanup of ospf instance */
static void
ospf_finish_final (struct ospf *ospf)
{
  struct route_node *rn;
  struct ospf_nbr_nbma *nbr_nbma;
  struct ospf_lsa *lsa;
  struct ospf_interface *oi;
  struct ospf_area *area;
  struct ospf_vl_data *vl_data;
  struct listnode *node, *nnode;
  int i;

  ospf_opaque_type11_lsa_term (ospf);
  
  /* be nice if this worked, but it doesn't */
  /*ospf_flush_self_originated_lsas_now (ospf);*/
  
  /* Unregister redistribution */
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    ospf_redistribute_unset (ospf, i);
  ospf_redistribute_default_unset (ospf);

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    ospf_remove_vls_through_area (ospf, area);
  
  for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
    ospf_vl_delete (ospf, vl_data);
  
  list_delete (ospf->vlinks);

  /* Reset interface. */
  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, 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 (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    {
      listnode_delete (ospf->areas, area);
      ospf_area_free (area);
    }

  /* Cancel all timers. */
  OSPF_TIMER_OFF (ospf->t_external_lsa);
  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_asbr_check);
  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);
  OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);

  close (ospf->fd);
  stream_free(ospf->ibuf);
   
  LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
    ospf_discard_from_db (ospf, ospf->lsdb, 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 (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
    {
      struct ospf_lsa *lsa;

      if ((lsa = rn->info) != NULL)
	{
	  ospf_lsa_unlock (&lsa);
	  rn->info = NULL;
	}
      route_unlock_node (rn);
    }
  route_table_finish (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 */
static 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;

  ospf_opaque_type10_lsa_init (new);

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

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

  return new;
}

static 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);
  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);

  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_stub_router);
  OSPF_TIMER_OFF (area->t_opaque_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);  
      if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
        {
          SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
        }
    }

  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 (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    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. */
static 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;
}

static void 
add_ospf_interface (struct connected *co, struct ospf_area *area)
{
  struct ospf_interface *oi;

  oi = ospf_if_new (area->ospf, co->ifp, co->address);
  oi->connected = co;

  oi->area = area;

  oi->params = ospf_lookup_if_params (co->ifp, oi->address->u.prefix4);
  oi->output_cost = ospf_if_get_output_cost (oi);

  /* Relate ospf interface to ospf instance. */
  oi->ospf = area->ospf;

  /* update network type as interface flag */
  /* If network type is specified previously,
     skip network type setting. */
  oi->type = IF_DEF_PARAMS (co->ifp)->type;

  /* Add pseudo neighbor. */
  ospf_nbr_self_reset (oi);

  ospf_area_add_if (oi->area, oi);

  /* if router_id is not configured, dont bring up
   * interfaces.
   * ospf_router_id_update() will call ospf_if_update
   * whenever r-id is configured instead.
   */
  if ((area->ospf->router_id.s_addr != 0)
      && if_is_operative (co->ifp)) 
    ospf_if_up (oi);
}

static void
update_redistributed (struct ospf *ospf, int add_to_ospf)
{
  struct route_node *rn;
  struct external_info *ei;

  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 (add_to_ospf)
              {
                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 */);
              }
            else
              {
                if (!ospf_external_info_find_lsa (ospf, &ei->p))
                  if (ospf_distribute_check_connected (ospf, ei))
                    ospf_external_lsa_originate (ospf, ei);
              }
          }
}

static 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;
  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 ((struct prefix *)p, area);

  /* Update connected redistribute. */
  update_redistributed(ospf, 1);
  
  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 listnode *node, *nnode;
  struct ospf_interface *oi;

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

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

  ospf_network_free (ospf, rn->info);
  rn->info = NULL;
  route_unlock_node (rn);	/* initial reference */

  /* Find interfaces that not configured already.  */
  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
    {
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
        continue;
      
      ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);
    }
  
  /* Update connected redistribute. */
  update_redistributed(ospf, 0);
  
  ospf_area_check_free (ospf, area_id);
  
  return 1;
}

/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means
 * there might not be any 'router ospf' config.
 *
 * Otherwise, doesn't do anything different to ospf_if_update for now
 */
void
ospf_interface_area_set (struct interface *ifp)
{
  struct ospf *ospf = ospf_get();
  
  ospf_if_update (ospf, ifp);
  /* if_update does a update_redistributed */
  
  return;
}

void
ospf_interface_area_unset (struct interface *ifp)
{
  struct route_node *rn_oi;
  struct ospf *ospf;

  if ((ospf = ospf_lookup ()) == NULL)
    return; /* Ospf not ready yet */
  
  /* Find interfaces that may need to be removed. */
  for (rn_oi = route_top (IF_OIFS (ifp)); rn_oi; rn_oi = route_next (rn_oi))
    {
      struct ospf_interface *oi;

      if ( (oi = rn_oi->info) == NULL)
	continue;
      
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	continue;
      
      ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);
    }

  /* Update connected redistribute. */
  update_redistributed (ospf, 0); /* interfaces possibly removed */
  
  return;
}


/* Check whether interface matches given network
 * returns: 1, true. 0, false
 */
static int
ospf_network_match_iface(const struct connected *co, const struct prefix *net)
{
  /* new approach: more elegant and conceptually clean */
  return prefix_match(net, CONNECTED_PREFIX(co));
}

static void
ospf_update_interface_area (struct connected *co, struct ospf_area *area)
{
  struct ospf_interface *oi = ospf_if_table_lookup (co->ifp, co->address);
  
  /* nothing to be done case */
  if (oi && oi->area == area)
    return;
  
  if (oi) 
    ospf_if_free (oi);
  
  add_ospf_interface (co, area);
}

/* Run OSPF for the given subnet, taking into account the following
 * possible sources of area configuration, in the given order of preference:
 *
 * - Whether there is interface+address specific area configuration
 * - Whether there is a default area for the interface
 * - Whether there is an area given as a parameter.
 * - If no specific network prefix/area is supplied, whether there's
 *   a matching network configured.
 */
static void
ospf_network_run_subnet (struct ospf *ospf, struct connected *co,
                         struct prefix *p, struct ospf_area *given_area)
{
  struct ospf_interface *oi;
  struct ospf_if_params *params;
  struct ospf_area *area = NULL;
  struct route_node *rn;
  int configed = 0;
  
  if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
    return;
  
  if (co->address->family != AF_INET)
    return;
  
  /* Try determine the appropriate area for this interface + address
   * Start by checking interface config 
   */   
  if (!(params = ospf_lookup_if_params (co->ifp, co->address->u.prefix4)))
    params = IF_DEF_PARAMS (co->ifp);
  
  if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
    area = (ospf_area_get (ospf, params->if_area,
                           OSPF_AREA_ID_FORMAT_ADDRESS));
  
  /* If we've found an interface and/or addr specific area, then we're
   * done
   */
  if (area)
    {
      ospf_update_interface_area (co, area);
      return;
    }
  
  /* Otherwise, only remaining possibility is a matching network statement */
  if (p)
    {
      assert (given_area != NULL);
      
      /* Which either was supplied as a parameter.. (e.g. cause a new
       * network/area was just added)..
       */
      if (p->family == co->address->family 
          && ospf_network_match_iface (co, p))
        ospf_update_interface_area (co, given_area);
      
      return;
    }
  
  /* Else we have to search the existing network/area config to see
   * if any match..
   */
  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
    if (rn->info != NULL
        && ospf_network_match_iface (co, &rn->p))
      {
        struct ospf_network *network = (struct ospf_network *) rn->info;
        area = ospf_area_get (ospf, network->area_id, network->format);
        ospf_update_interface_area (co, area);
        configed = 1;
      }
  
  /* If the subnet isn't in any area, deconfigure */
  if (!configed && (oi = ospf_if_table_lookup (co->ifp, co->address)))
    ospf_if_free (oi);
}

static void
ospf_network_run_interface (struct ospf *ospf, struct interface *ifp,
                            struct prefix *p,
                            struct ospf_area *given_area)
{
  struct listnode *cnode;
  struct connected *co;
  
  if (memcmp (ifp->name, "VLINK", 5) == 0)
    return;
  
  /* Network prefix without area is nonsensical */
  if (p)
    assert (given_area != NULL);
  
  /* if interface prefix is match specified prefix,
     then create socket and join multicast group. */
  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
    ospf_network_run_subnet (ospf, co, p, given_area);  
}

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

  /* Schedule Router ID Update. */
  if (area->ospf->router_id.s_addr == 0)
    ospf_router_id_update (area->ospf);
  
  /* Get target interface. */
  for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
    ospf_network_run_interface (area->ospf, ifp, p, area);
}

void
ospf_ls_upd_queue_empty (struct ospf_interface *oi)
{
  struct route_node *rn;
  struct listnode *node, *nnode;
  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 (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
          ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
	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 interface *ifp)
{
  if (!ospf)
    ospf = ospf_lookup ();

  /* OSPF must be ready. */
  if (!ospf_is_ready (ospf))
    return;
  
  ospf_network_run_interface (ospf, ifp, NULL, NULL);
  
  /* Update connected redistribute. */
  update_redistributed(ospf, 1);
}

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

  for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
    if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
      ospf_vl_delete (ospf, vl_data);
}


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

static 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_debug ("Area[%s]: Types are the same, ignored.",
		   inet_ntoa (area->area_id));
      return;
    }

  area->external_routing = type;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("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 (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
        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 (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
        if (oi->nbr_self != NULL)
          {
            if (IS_DEBUG_OSPF_EVENT)
              zlog_debug ("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_debug ("options set on %s: %x",
                         IF_NAME (oi), OPTIONS (oi));
          }
      break;
    case OSPF_AREA_NSSA:
      for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
        if (oi->nbr_self != NULL)
          {
            zlog_debug ("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_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
          }
      break;
    default:
      break;
    }

  ospf_router_lsa_update_area (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_update_area (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_update_area (area);
  ospf_area_check_free (ospf, area->area_id);
  ospf_schedule_abr_task (ospf);

  return 1;
}

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

  for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
    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;
}

#if 0
/* XXX: unused? Leave for symmetry? */
static 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;
}
#endif

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_refresh_set (struct ospf *ospf, int interval)
{
  int time_left;

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

  time_left = ospf->lsa_refresh_interval -
    (quagga_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 -
    (quagga_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;
}


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

  nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
		      sizeof (struct ospf_nbr_nbma));

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

  return nbr_nbma;
}

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

static 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);
    }
}

static 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);
}

static 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 (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
    {
      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);
  if (rn->info)
    route_unlock_node (rn);
  rn->info = nbr_nbma;

  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    {
      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 = quagga_time (NULL);
}
