/* 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->dtag[i] = 0;
    }
  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 ((struct listnode *)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);
}
