/*
 * OSPF ABR functions.
 * Copyright (C) 1999, 2000 Alex Zinin, 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 "memory.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "vty.h"
#include "filter.h"
#include "plist.h"
#include "log.h"

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


struct ospf_area_range *
ospf_area_range_new (struct prefix_ipv4 *p)
{
  struct ospf_area_range *range;

  range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range));
  range->addr = p->prefix;
  range->masklen = p->prefixlen;
  range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;

  return range;
}

void
ospf_area_range_free (struct ospf_area_range *range)
{
  XFREE (MTYPE_OSPF_AREA_RANGE, range);
}

void
ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)
{
  struct route_node *rn;
  struct prefix_ipv4 p;

  p.family = AF_INET;
  p.prefixlen = range->masklen;
  p.prefix = range->addr;

  rn = route_node_get (area->ranges, (struct prefix *)&p);
  if (rn->info)
    route_unlock_node (rn);
  else
    rn->info = range;
}

void
ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range)
{
  struct route_node *rn;
  struct prefix_ipv4 p;

  p.family = AF_INET;
  p.prefixlen = range->masklen;
  p.prefix = range->addr;

  rn = route_node_lookup (area->ranges, (struct prefix *)&p);
  if (rn)
    {
      ospf_area_range_free (rn->info);
      rn->info = NULL;
      route_unlock_node (rn);
      route_unlock_node (rn);
    }
}

struct ospf_area_range *
ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p)
{
  struct route_node *rn;

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

struct ospf_area_range *
ospf_area_range_lookup_next (struct ospf_area *area, struct in_addr *range_net,
			     int first)
{
  struct route_node *rn;
  struct prefix_ipv4 p;
  struct ospf_area_range *find;

  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_BITLEN;
  p.prefix = *range_net;

  if (first)
    rn = route_top (area->ranges);
  else
    {
      rn = route_node_get (area->ranges, (struct prefix *) &p);
      rn = route_next (rn);
    }

  for (; rn; rn = route_next (rn))
    if (rn->info)
      break;

  if (rn && rn->info)
    {
      find = rn->info;
      *range_net = rn->p.u.prefix4;
      route_unlock_node (rn);
      return find;
    }
  return NULL;
}

struct ospf_area_range *
ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p)
{
  struct route_node *node;

  node = route_node_match (area->ranges, (struct prefix *) p);
  if (node)
    {
      route_unlock_node (node);
      return node->info;
    }
  return NULL;
}

struct ospf_area_range *
ospf_area_range_match_any (struct ospf *ospf, struct prefix_ipv4 *p)
{
  struct ospf_area_range *range;
  listnode node;

  for (node = listhead (ospf->areas); node; nextnode (node))
    if ((range = ospf_area_range_match (node->data, p)))
      return range;

  return NULL;
}

int
ospf_area_range_active (struct ospf_area_range *range)
{
  return range->specifics;
}

int
ospf_area_actively_attached (struct ospf_area *area)
{
  return area->act_ints;
}

int
ospf_area_range_set (struct ospf *ospf, struct in_addr area_id,
		     struct prefix_ipv4 *p, int advertise)
{
  struct ospf_area *area;
  struct ospf_area_range *range;
  int ret = OSPF_AREA_ID_FORMAT_DECIMAL;

  area = ospf_area_get (area_id, ret);
  if (area == NULL)
    return 0;

  range = ospf_area_range_lookup (area, p);
  if (range != NULL)
    {
      if ((CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)
	   && !CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))
	  || (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)
	      && CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)))
	ospf_schedule_abr_task ();
    }
  else
    {
      range = ospf_area_range_new (p);
      ospf_area_range_add (area, range);
      ospf_schedule_abr_task ();
    }

  if (CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))
    SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE);
  else
    UNSET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE);

  return 1;
}

int
ospf_area_range_cost_set (struct ospf *ospf, struct in_addr area_id,
			  struct prefix_ipv4 *p, u_int32_t cost)
{
  struct ospf_area *area;
  struct ospf_area_range *range;
  int ret = OSPF_AREA_ID_FORMAT_DECIMAL;

  area = ospf_area_get (area_id, ret);
  if (area == NULL)
    return 0;

  range = ospf_area_range_new (p);
  if (range == NULL)
    return 0;

  if (range->cost_config != cost)
    {
      range->cost_config = cost;
      if (ospf_area_range_active (range))
	ospf_schedule_abr_task ();
    }

  return 1;
}

int
ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id,
		       struct prefix_ipv4 *p)
{
  struct ospf_area *area;
  struct ospf_area_range *range;

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

  range = ospf_area_range_lookup (area, p);
  if (range == NULL)
    return 0;

  if (ospf_area_range_active (range))
    ospf_schedule_abr_task ();

  ospf_area_range_delete (area, range);

  return 1;
}

int
ospf_area_range_substitute_set (struct ospf *ospf, struct in_addr area_id,
				struct prefix_ipv4 *p, struct prefix_ipv4 *s)
{
  struct ospf_area *area;
  struct ospf_area_range *range;
  int ret = OSPF_AREA_ID_FORMAT_DECIMAL;

  area = ospf_area_get (area_id, ret);
  range = ospf_area_range_lookup (area, p);

  if (range != NULL)
    {
      if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) ||
	  !CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
	ospf_schedule_abr_task ();
    }
  else
    {
      range = ospf_area_range_new (p);
      ospf_area_range_add (area, range);
      ospf_schedule_abr_task ();
    }

  SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE);
  SET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
  range->subst_addr = s->prefix;
  range->subst_masklen = s->prefixlen;

  return 1;
}

int
ospf_area_range_substitute_unset (struct ospf *ospf, struct in_addr area_id,
				  struct prefix_ipv4 *p)
{
  struct ospf_area *area;
  struct ospf_area_range *range;

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

  range = ospf_area_range_lookup (area, p);
  if (range == NULL)
    return 0;

  if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
    if (ospf_area_range_active (range))
      ospf_schedule_abr_task ();

  UNSET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
  range->subst_addr.s_addr = 0;
  range->subst_masklen = 0;

  return 1;
}

int
ospf_act_bb_connection ()
{
  if (ospf_top->backbone == NULL)
    return 0;

  return ospf_top->backbone->full_nbrs;
}

/* Check area border router status. */
void
ospf_check_abr_status ()
{
  struct ospf_area *area;
  listnode node;
  int bb_configured = 0;
  int bb_act_attached = 0;
  int areas_configured = 0;
  int areas_act_attached = 0;

  u_char new_flags = ospf_top->flags;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_check_abr_status(): Start");

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

      if (listcount (area->oiflist)) 
	{
	  areas_configured++;
	  
	  if (OSPF_IS_AREA_BACKBONE (area))
 	    bb_configured = 1;
	}

      if (ospf_area_actively_attached (area))
	{
	  areas_act_attached++;
	  
	  if (OSPF_IS_AREA_BACKBONE (area))
            bb_act_attached = 1;
	}
    }

  if (IS_DEBUG_OSPF_EVENT)
    {
      zlog_info ("ospf_check_abr_status(): looked through areas");
      zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured);
      zlog_info ("ospf_check_abr_status(): bb_act_attached: %d",
		 bb_act_attached);
      zlog_info ("ospf_check_abr_status(): areas_configured: %d",
		 areas_configured);
      zlog_info ("ospf_check_abr_status(): areas_act_attached: %d",
		 areas_act_attached);
    }

  switch (ospf_top->abr_type)
    {
    case OSPF_ABR_SHORTCUT:
    case OSPF_ABR_STAND:
      if (areas_act_attached > 1)
	SET_FLAG (new_flags, OSPF_FLAG_ABR);
      else
	UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
      break;

    case OSPF_ABR_IBM:
      if ((areas_act_attached > 1) && bb_configured)
	SET_FLAG (new_flags, OSPF_FLAG_ABR);
      else
	UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
      break;

    case OSPF_ABR_CISCO:
      if ((areas_configured > 1) && bb_act_attached)
	SET_FLAG (new_flags, OSPF_FLAG_ABR);
      else
	UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
      break;
    default:
      break;
    }

  if (new_flags != ospf_top->flags)
    {
      ospf_spf_calculate_schedule ();
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags);
      ospf_top->flags = new_flags;
      OSPF_TIMER_ON (ospf_top->t_router_lsa_update,
		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
    }
}

void
ospf_abr_update_aggregate (struct ospf_area_range *range,
			   struct ospf_route *or)
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_update_aggregate(): Start");

  if (range->cost_config != -1)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_update_aggregate(): use configured cost %d",
		   range->cost_config);

      range->cost = range->cost_config;
    }
  else
    {
      if (range->specifics == 0)
	range->cost = or->cost; /* 1st time get 1st cost */

      if (or->cost < range->cost)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_update_aggregate(): lowest cost, update");

	  range->cost = or->cost;
	}
    }

  range->specifics++;
}

static void
set_metric (struct ospf_lsa *lsa, u_int32_t metric)
{
  struct summary_lsa *header;
  u_char *mp;
  metric = htonl (metric);
  mp = (char *) &metric;
  mp++;
  header = (struct summary_lsa *) lsa->data;
  memcpy(header->metric, mp, 3);
}

#ifdef HAVE_NSSA
int
ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost,
				   struct ospf_area *area)
{
  /* The Type-7 is tested against the aggregated prefix and forwarded
       for lsa installation and flooding */
  return 0;
}

/* ospf_abr_translate_nssa */
int
ospf_abr_translate_nssa (struct ospf_lsa *lsa, void *p_arg, int int_arg)
{
  /* Incoming Type-7 or later aggregated Type-7 

     LSA is skipped if P-bit is off.
     LSA is aggregated if within range.

     The Type-7 is translated, Installed/Approved as a Type-5 into
     global LSDB, then Flooded through AS

     Later, any Unapproved Translated Type-5's are flushed/discarded */

  struct ospf_lsa *dup;

  if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
    {
      if (IS_DEBUG_OSPF_NSSA)
	zlog_info ("ospf_abr_nssa(): P-bit off, NO Translation");
      return 0; 
    }

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa(): TRANSLATING 7 to 5");

  /* No more P-bit. */
  /* UNSET_FLAG (lsa->data->options, OSPF_OPTION_NP); */

  /* Area where Aggregate testing will be inserted, just like summary
     advertisements */
  /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */

  /* Follow thru here means no aggregation */
  dup = ospf_lsa_dup (lsa);	/* keep LSDB intact, lock = 1 */

  SET_FLAG (dup->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7  */
  SET_FLAG (dup->flags, OSPF_LSA_APPROVED); /* So, do not remove it */

  dup->data->type = OSPF_AS_EXTERNAL_LSA;  /* make Type-5 */

  ospf_lsa_checksum (dup->data);

  ospf_lsa_install (NULL, dup); /* Install this Type-5 into LSDB, Lock = 2. */

  ospf_flood_through_as (NULL, dup); /* flood non-NSSA/STUB areas */
  
  /* This translated Type-5 will go to all non-NSSA areas connected to
     this ABR; The Type-5 could come from any of the NSSA's connected
     to this ABR.  */

  return 0;
}

void
ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost)
{
  /* The Type-7 is created from the aggregated prefix and forwarded
     for lsa installation and flooding... to be added... */
}
#endif /* HAVE_NSSA */

void
ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
				   struct ospf_area *area)
{
  struct ospf_lsa *lsa, *old = NULL;
  struct summary_lsa *sl = NULL;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_network_to_area(): Start");

  old = OSPF_SUMMARY_LSA_SELF_FIND_BY_PREFIX (area, p);

  if (old)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network_to_area(): old summary found");
      sl = (struct summary_lsa *) old->data;

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network_to_area(): "
		   "old metric: %d, new metric: %d",
		   GET_METRIC (sl->metric), cost);
    }

  if (old && (GET_METRIC (sl->metric) == cost))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network_to_area(): "
		   "old summary approved"); 
      SET_FLAG (old->flags, OSPF_LSA_APPROVED);
    }
  else
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network_to_area(): "
		   "creating new summary");
      if (old)
	{

	  set_metric (old, cost);
	  lsa = ospf_summary_lsa_refresh (old);
	  /* This will flood through area. */
	}
      else
	{
	  lsa = ospf_summary_lsa_originate (p, cost, area);
	  /* This will flood through area. */
	}
      

      SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network_to_area(): "
		   "flooding new version of summary");

#ifndef HAVE_NSSA      
      ospf_flood_through_area (area, NULL, lsa);
#endif /* ! HAVE_NSSA */
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_network_to_area(): Stop");
}

int
ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
				  struct ospf_area *area)
{
  listnode node;

  for (node = listhead (or->path); node; nextnode (node))
    {
      struct ospf_path *path = node->data;
      struct ospf_interface *oi = path->oi;

      if (oi != NULL)
	if (oi->area == area)
	  return 1;
    }

  return 0;
}

int
ospf_abr_should_accept (struct prefix *p, struct ospf_area *area)
{
  if (IMPORT_NAME (area))
    {
      if (IMPORT_LIST (area) == NULL)
	IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area));

      if (IMPORT_LIST (area))
        if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY)
           return 0;
    }

 return 1;
}

int
ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
			 struct prefix *p)
{
  if (PREFIX_NAME_IN (area))
    {
      if (PREFIX_LIST_IN (area) == NULL)
	PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP,
						    PREFIX_NAME_IN (area));
      if (PREFIX_LIST_IN (area))
	if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT)
	  return 0;
    }
  return 1;
}

int
ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
			  struct prefix *p)
{
  if (PREFIX_NAME_OUT (area))
    {
      if (PREFIX_LIST_OUT (area) == NULL)
	PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP,
						     PREFIX_NAME_OUT (area));
      if (PREFIX_LIST_OUT (area))
	if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT)
	  return 0;
    }
  return 1;
}

void
ospf_abr_announce_network (struct route_node *n, struct ospf_route *or)
{
  listnode node;
  struct ospf_area_range *range;
  struct prefix_ipv4 *p;
  struct ospf_area *area, *or_area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_network(): Start");
  p = (struct prefix_ipv4 *) &n->p;

  or_area = ospf_area_lookup_by_area_id (or->u.std.area_id); 
  assert (or_area);

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

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network(): looking at area %s",
		   inet_ntoa (area->area_id));

      if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
	continue;

      if (ospf_abr_nexthops_belong_to_area (or, area))
	continue;

      if (!ospf_abr_should_accept (&n->p, area))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_network(): "
		       "prefix %s/%d was denied by import-list",
		       inet_ntoa (p->prefix), p->prefixlen);
	  continue; 
	}

      if (!ospf_abr_plist_in_check (area, or, &n->p))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_network(): "
		       "prefix %s/%d was denied by prefix-list",
		       inet_ntoa (p->prefix), p->prefixlen);
	  continue; 
	}

      if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_network(): "
		       "area %s is stub and no_summary",
		       inet_ntoa (area->area_id));
          continue;
	}

      if (or->path_type == OSPF_PATH_INTER_AREA)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_network(): this is "
		       "inter-area route to %s/%d",
		       inet_ntoa (p->prefix), p->prefixlen);

          if (!OSPF_IS_AREA_BACKBONE (area))
	    ospf_abr_announce_network_to_area (p, or->cost, area);
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_network(): "
		       "this is intra-area route to %s/%d",
		       inet_ntoa (p->prefix), p->prefixlen);
	  if ((range = ospf_area_range_match (or_area, p)) &&
              !ospf_area_is_transit (area))
	    ospf_abr_update_aggregate (range, or);
	  else
	    ospf_abr_announce_network_to_area (p, or->cost, area);
	}
    }
}

int
ospf_abr_should_announce (struct prefix *p, struct ospf_route *or)
{
  struct ospf_area *area = ospf_area_lookup_by_area_id (or->u.std.area_id);

  assert (area);
  
  if (EXPORT_NAME (area))
    {
      if (EXPORT_LIST (area) == NULL)
	EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area));

      if (EXPORT_LIST (area))
        if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY)
           return 0;
    }

  return 1;
}

#ifdef HAVE_NSSA
void
ospf_abr_process_nssa_translates ()
{
  /* Scan through all NSSA_LSDB records for all areas;

     If P-bit is on, translate all Type-7's to 5's and aggregate or
     flood install as approved in Type-5 LSDB with XLATE Flag on
     later, do same for all aggregates...  At end, DISCARD all
     remaining UNAPPROVED Type-5's (Aggregate is for future ) */
  listnode node;
  struct ospf_area *area;

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_process_nssa_translates(): Start");

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

      if (! area->NSSATranslator)
	continue; /* skip if not translator */
      
      if (area->external_routing != OSPF_AREA_NSSA)
	continue;  /* skip if not Nssa Area */

      if (IS_DEBUG_OSPF_NSSA)
	zlog_info ("ospf_abr_process_nssa_translates(): "
		   "looking at area %s", inet_ntoa (area->area_id));
      
      foreach_lsa (NSSA_LSDB (area), area, 0, ospf_abr_translate_nssa);
    }
 
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_process_nssa_translates(): Stop");

}
#endif /* HAVE_NSSA */

void
ospf_abr_process_network_rt (struct route_table *rt)
{
  struct route_node *rn;
  struct ospf_route *or;
  struct ospf_area *area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_network_rt(): Start");

  for (rn = route_top (rt); rn; rn = route_next (rn))
    {
      if ((or = rn->info) == NULL)
	continue;

      if (!(area = ospf_area_lookup_by_area_id (or->u.std.area_id)))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists",
		       inet_ntoa (or->u.std.area_id));
	  continue;
	}

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d",
		   inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
      if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt(): "
		       "this is an External router, skipping");
	  continue;
	}

      if (or->cost >= OSPF_LS_INFINITY)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt():"
		       " this route's cost is infinity, skipping");
	  continue;
	}

      if (or->type == OSPF_DESTINATION_DISCARD)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt():"
		       " this is a discard entry, skipping");
	  continue;
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !ospf_abr_should_announce (&rn->p, or))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info("ospf_abr_process_network_rt(): denied by export-list");
	  continue;
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !ospf_abr_plist_out_check (area, or, &rn->p))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info("ospf_abr_process_network_rt(): denied by prefix-list");
	  continue;
	}

      if ((or->path_type == OSPF_PATH_INTER_AREA) &&
          !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt():"
		       " this is route is not backbone one, skipping");
	  continue;
	}


      if ((ospf_top->abr_type == OSPF_ABR_CISCO) ||
          (ospf_top->abr_type == OSPF_ABR_IBM))

          if (!ospf_act_bb_connection () &&
              or->path_type != OSPF_PATH_INTRA_AREA)
	     {
	       if (IS_DEBUG_OSPF_EVENT)
		 zlog_info ("ospf_abr_process_network_rt(): ALT ABR: "
			    "No BB connection, skip not intra-area routes");
	       continue;
	     }

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_process_network_rt(): announcing");
      ospf_abr_announce_network (rn, or);
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_network_rt(): Stop");
}

void
ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
			       struct ospf_area *area)
{
  struct ospf_lsa *lsa, *old = NULL;
  struct summary_lsa *slsa = NULL;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_rtr_to_area(): Start");

  old = OSPF_SUMMARY_ASBR_LSA_SELF_FIND_BY_PREFIX (area, p);
  /* old = ospf_find_self_summary_asbr_lsa_by_prefix (area, p); */

  if (old)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_rtr_to_area(): old summary found");
      slsa = (struct summary_lsa *) old->data;

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_network_to_area(): "
		   "old metric: %d, new metric: %d",
		   GET_METRIC (slsa->metric), cost);
    }

  if (old && (GET_METRIC (slsa->metric) == cost))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_rtr_to_area(): old summary approved");
      SET_FLAG (old->flags, OSPF_LSA_APPROVED);
    }
  else
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_rtr_to_area(): 2.2");
       
      if (old) 
	{ 
	  set_metric (old, cost);
	  lsa = ospf_summary_asbr_lsa_refresh (old);
	}
      else
	lsa = ospf_summary_asbr_lsa_originate (p, cost, area);

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_rtr_to_area(): "
		   "flooding new version of summary");
      /*
      zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary");
      lsa = ospf_summary_asbr_lsa (p, cost, area, old); */

      SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
      /* ospf_flood_through_area (area, NULL, lsa);*/
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_rtr_to_area(): Stop");
}


void
ospf_abr_announce_rtr (struct prefix_ipv4 *p, struct ospf_route *or)
{
  listnode node;
  struct ospf_area *area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_rtr(): Start");

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

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_rtr(): looking at area %s",
		   inet_ntoa (area->area_id));

      if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
	continue;

      if (ospf_abr_nexthops_belong_to_area (or, area))
	continue;

      if (area->external_routing != OSPF_AREA_DEFAULT)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_network(): "
		       "area %s doesn't support external routing",
		       inet_ntoa(area->area_id));
          continue;
	}

      if (or->path_type == OSPF_PATH_INTER_AREA)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_rtr(): "
		       "this is inter-area route to %s", inet_ntoa (p->prefix));
          if (!OSPF_IS_AREA_BACKBONE (area))
	    ospf_abr_announce_rtr_to_area (p, or->cost, area);
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_announce_rtr(): "
		       "this is intra-area route to %s", inet_ntoa (p->prefix));
          ospf_abr_announce_rtr_to_area (p, or->cost, area);
	}
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_rtr(): Stop");
}

void
ospf_abr_process_router_rt (struct route_table *rt)
{
  struct route_node *rn;
  struct ospf_route *or;
  struct list *l;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_router_rt(): Start");

  for (rn = route_top (rt); rn; rn = route_next (rn))
    {
      listnode node;
      char flag = 0;
      struct ospf_route *best = NULL;

      if (rn->info == NULL)
	continue;

      l = rn->info;

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_process_router_rt(): this is a route to %s",
		   inet_ntoa (rn->p.u.prefix4));

      for (node = listhead (l); node; nextnode (node))
	{
	  or = getdata (node);
	  if (or == NULL)
	    continue;

	  if (!ospf_area_lookup_by_area_id (or->u.std.area_id))
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists",
			 inet_ntoa (or->u.std.area_id));
	      continue;
	    }


	  if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL))
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): "
			   "This is not an ASBR, skipping");
	      continue;
	    }

	  if (!flag)
	    {
	      best = ospf_find_asbr_route (rt, (struct prefix_ipv4 *) &rn->p);
	      flag = 1;
	    }
	  
        if (best == NULL)
	  continue;
	
        if (or != best)
	  {
	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_info ("ospf_abr_process_router_rt(): "
			 "This route is not the best among possible, skipping");
	    continue;
	  }
	
        if (or->path_type == OSPF_PATH_INTER_AREA &&
            !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	  {
	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_info ("ospf_abr_process_router_rt(): "
			 "This route is not a backbone one, skipping");
	    continue;
	  }

        if (or->cost >= OSPF_LS_INFINITY)
	  {
	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_info ("ospf_abr_process_router_rt(): "
			 "This route has LS_INFINITY metric, skipping");
	    continue;
	  }

        if (ospf_top->abr_type == OSPF_ABR_CISCO ||
            ospf_top->abr_type == OSPF_ABR_IBM)
	  if (!ospf_act_bb_connection () &&
	      or->path_type != OSPF_PATH_INTRA_AREA)
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info("ospf_abr_process_network_rt(): ALT ABR: "
			  "No BB connection, skip not intra-area routes");
	      continue;
	    }

        ospf_abr_announce_rtr ((struct prefix_ipv4 *) &rn->p, or);

	}

    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_router_rt(): Stop");
}

#ifdef HAVE_NSSA
int
ospf_abr_unapprove_translates_apply (struct ospf_lsa *lsa, void *p_arg,
				    int int_arg)
{
  /* Could be a mix of Normal Type-5's, self-originated, or Type-7s
      that are Locally ABR Translated */

  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
    UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
  
  return 0;
}

void
ospf_abr_unapprove_translates () /* For NSSA Translations */
{
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_unapprove_translates(): Start");

  /* NSSA Translator is not checked, because it may have gone away,
    and we would want to flush any residuals anyway */

  foreach_lsa (EXTERNAL_LSDB (ospf_top), NULL, 0,
	       ospf_abr_unapprove_translates_apply);

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_unapprove_translates(): Stop");
}
#endif /* HAVE_NSSA */

int
ospf_abr_unapprove_summaries_apply (struct ospf_lsa *lsa, void *p_arg,
				    int int_arg)
{
  if (ospf_lsa_is_self_originated (lsa))
    UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);

  return 0;
}

void
ospf_abr_unapprove_summaries ()
{
  listnode node;
  struct ospf_area *area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_unapprove_summaries(): Start");

  for (node = listhead (ospf_top->areas); node; nextnode (node))
    {
      area = getdata (node);
      foreach_lsa (SUMMARY_LSDB (area), NULL, 0,
		   ospf_abr_unapprove_summaries_apply);
      foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0,
		   ospf_abr_unapprove_summaries_apply);
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_unapprove_summaries(): Stop");
}

void
ospf_abr_prepare_aggregates ()
{
  listnode node;
  struct route_node *rn;
  struct ospf_area_range *range;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_prepare_aggregates(): Start");

  for (node = listhead (ospf_top->areas); node; nextnode (node))
    {
      struct ospf_area *area = getdata (node);

      for (rn = route_top (area->ranges); rn; rn = route_next (rn))
	if ((range = rn->info) != NULL)
	  {
	    range->cost = 0;
	    range->specifics = 0;
	  }
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_prepare_aggregates(): Stop");
}

void
ospf_abr_announce_aggregates ()
{
  struct ospf_area *area, *ar;
  struct ospf_area_range *range;
  struct route_node *rn;
  struct prefix_ipv4 p;
  listnode node, n;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_aggregates(): Start");

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

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_aggregates(): looking at area %s",
		   inet_ntoa (area->area_id));

      for (rn = route_top (area->ranges); rn; rn = route_next (rn))
	if ((range =  rn->info))
	  {
	    if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
	      {
		if (IS_DEBUG_OSPF_EVENT)
		  zlog_info ("ospf_abr_announce_aggregates():"
			     " discarding suppress-ranges");
		continue;
	      }

	    p.family = AF_INET;
	    p.prefix = range->addr;
	    p.prefixlen = range->masklen;

	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_info ("ospf_abr_announce_aggregates():"
			 " this is range: %s/%d",
			 inet_ntoa (p.prefix), p.prefixlen);

	    if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
	      {
		p.family = AF_INET;
		p.prefix = range->subst_addr;
		p.prefixlen = range->subst_masklen;
	      }

	    if (range->specifics)
	      {
		if (IS_DEBUG_OSPF_EVENT)
		  zlog_info ("ospf_abr_announce_aggregates(): active range");

		for (n = listhead (ospf_top->areas); n; nextnode (n))
		  {
		    ar = getdata (n);
		    if (ar == area)
		      continue;

		    /* We do not check nexthops here, because
		       intra-area routes can be associated with
		       one area only */

		    /* backbone routes are not summarized
		       when announced into transit areas */

		    if (ospf_area_is_transit (ar) &&
			OSPF_IS_AREA_BACKBONE (area))
		      {
			if (IS_DEBUG_OSPF_EVENT)
			  zlog_info ("ospf_abr_announce_aggregates(): Skipping "
				     "announcement of BB aggregate into"
				     " a transit area");
			continue; 
		      }
		    ospf_abr_announce_network_to_area (&p, range->cost, ar);
		  }
	      }
	  }
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_aggregates(): Stop");
}

#ifdef HAVE_NSSA
void
ospf_abr_send_nssa_aggregates () /* temporarily turned off */
{
  listnode node; /*, n; */
  struct ospf_area *area; /*, *ar; */
  struct route_node *rn;
  struct ospf_area_range *range;
  struct prefix_ipv4 p;

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_send_nssa_aggregates(): Start");

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

      if (! area->NSSATranslator)
	continue;

      if (IS_DEBUG_OSPF_NSSA)
	zlog_info ("ospf_abr_send_nssa_aggregates(): looking at area %s",
		   inet_ntoa (area->area_id));

      for (rn = route_top (area->ranges); rn; rn = route_next (rn))
	{
          if (rn->info == NULL)
	    continue;

	  range = rn->info;

          if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
	    {
	      if (IS_DEBUG_OSPF_NSSA)
		zlog_info ("ospf_abr_send_nssa_aggregates():"
			   " discarding suppress-ranges");
	      continue;
	    }

          p.family = AF_INET;
          p.prefix = range->addr;
          p.prefixlen = range->masklen;

	  if (IS_DEBUG_OSPF_NSSA)
	    zlog_info ("ospf_abr_send_nssa_aggregates():"
		       " this is range: %s/%d",
		       inet_ntoa (p.prefix), p.prefixlen);

          if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
	    {
	      p.family = AF_INET;
	      p.prefix = range->subst_addr;
	      p.prefixlen = range->subst_masklen;
	    }

          if (range->specifics)
	    {
	      if (IS_DEBUG_OSPF_NSSA)
		zlog_info ("ospf_abr_send_nssa_aggregates(): active range");

	      /* Fetch LSA-Type-7 from aggregate prefix, and then
                 translate, Install (as Type-5), Approve, and Flood */
		ospf_abr_translate_nssa_range (&p, range->cost);
	    } /* if (range->specifics)*/
	} /* all area ranges*/
    } /* all areas */

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_send_nssa_aggregates(): Stop");
}

void
ospf_abr_announce_nssa_defaults () /* By ABR-Translator */
{
  listnode node;
  struct ospf_area *area;
  struct prefix_ipv4 p;

  if (! OSPF_IS_ABR)
    return;

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_announce_stub_defaults(): Start");

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

  for (node = listhead (ospf_top->areas); node; nextnode (node))
    {
      area = getdata (node);
      if (IS_DEBUG_OSPF_NSSA)
	zlog_info ("ospf_abr_announce_nssa_defaults(): looking at area %s",
		   inet_ntoa (area->area_id));

      if (area->external_routing != OSPF_AREA_NSSA)
	continue;

      if (OSPF_IS_AREA_BACKBONE (area))
	continue; /* Sanity Check */

      /* if (!TranslatorRole continue V 1.0 look for "always" conf */
      if (area->NSSATranslator)
	{
	  if (IS_DEBUG_OSPF_NSSA)
	    zlog_info ("ospf_abr_announce_nssa_defaults(): "
		       "announcing 0.0.0.0/0 to this nssa");
	  /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
	}
    }
}
#endif /* HAVE_NSSA */

void
ospf_abr_announce_stub_defaults ()
{
  listnode node;
  struct ospf_area *area;
  struct prefix_ipv4 p;

  if (! OSPF_IS_ABR)
    return;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_stub_defaults(): Start");

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

  for (node = listhead (ospf_top->areas); node; nextnode (node))
    {
      area = getdata (node);
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s",
		   inet_ntoa (area->area_id));

#ifdef HAVE_NSSA
      if (area->external_routing != OSPF_AREA_STUB)
#else /* ! HAVE_NSSA */
      if (area->external_routing == OSPF_AREA_DEFAULT)
#endif /* HAVE_NSSA */
	continue;

      if (OSPF_IS_AREA_BACKBONE (area))
	continue; /* Sanity Check */

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_announce_stub_defaults(): "
		   "announcing 0.0.0.0/0 to this area");
      ospf_abr_announce_network_to_area (&p, area->default_cost, area);
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_announce_stub_defaults(): Stop");
}

#ifdef HAVE_NSSA
int
ospf_abr_remove_unapproved_translates_apply (struct ospf_lsa *lsa, void *p_arg,
					     int int_arg)
{
  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)
      && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
    {
      zlog_info ("ospf_abr_remove_unapproved_translates(): "
		 "removing unapproved translates, ID: %s",
		 inet_ntoa (lsa->data->id));

      /* FLUSH THROUGHOUT AS */
      ospf_lsa_flush_as (lsa);

      /* DISCARD from LSDB  */
    }
  return 0;
}

void
ospf_abr_remove_unapproved_translates () /* For NSSA Translations */
{
  /* All AREA PROCESS should have APPROVED necessary LSAs */
  /* Remove any left over and not APPROVED */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_remove_unapproved_translates(): Start");

  foreach_lsa (EXTERNAL_LSDB (ospf_top), NULL, 0,
	       ospf_abr_remove_unapproved_translates_apply);
 
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_remove_unapproved_translates(): Stop");
}
#endif /* HAVE_NSSA */

int
ospf_abr_remove_unapproved_summaries_apply (struct ospf_lsa *lsa, void *p_arg,
					    int int_arg)
{
  struct ospf_area *area;

  area = (struct ospf_area *) p_arg;

  if (ospf_lsa_is_self_originated (lsa) &&
      !CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_remove_unapproved_summaries(): "
		   "removing unapproved summary, ID: %s",
		   inet_ntoa (lsa->data->id));
      ospf_lsa_flush_area (lsa, area);
    }
  return 0;
}

void
ospf_abr_remove_unapproved_summaries ()
{
  listnode node;
  struct ospf_area *area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_remove_unapproved_summaries(): Start");

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

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_remove_unapproved_summaries(): "
		   "looking at area %s", inet_ntoa (area->area_id));

      foreach_lsa (SUMMARY_LSDB (area), area, 0,
		   ospf_abr_remove_unapproved_summaries_apply);
      foreach_lsa (ASBR_SUMMARY_LSDB (area), area, 0,
		   ospf_abr_remove_unapproved_summaries_apply);
    }
 
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_remove_unapproved_summaries(): Stop");
}

void
ospf_abr_manage_discard_routes ()
{
  listnode node;
  struct route_node *rn;
  struct ospf_area *area;
  struct ospf_area_range *range;

  for (node = listhead (ospf_top->areas); node; nextnode (node))
    if ((area = node->data) != NULL)
      for (rn = route_top (area->ranges); rn; rn = route_next (rn))
	if ((range = rn->info) != NULL)
	  if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE))
	    {
	      if (range->specifics)
		ospf_add_discard_route (ospf_top->new_table, area,
					(struct prefix_ipv4 *) &rn->p);
	      else
		ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
	    }
}

#ifdef HAVE_NSSA
/* This is the function taking care about ABR NSSA, i.e.  NSSA
   Translator, -LSA aggregation and flooding. For all NSSAs

   Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB.  These LSA's
   are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
   with the P-bit set.

   Any received Type-5s are legal for an ABR, else illegal for IR.
   Received Type-7s are installed, by area, with incoming P-bit.  They
   are flooded; if the Elected NSSA Translator, then P-bit off.

   Additionally, this ABR will place "translated type-7's" into the
   Type-5 LSDB in order to keep track of APPROVAL or not.

   It will scan through every area, looking for Type-7 LSAs with P-Bit
   SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
   AGGREGATED.  Later, the AGGREGATED LSAs are AS-FLOODED &
   5-INSTALLED.

   5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
   left over are FLUSHED and DISCARDED.

   For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
   any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */

void
ospf_abr_nssa_task () /* called only if any_nssa */
{
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("Check for NSSA-ABR Tasks():");

  if (! OSPF_IS_ABR)
    return;

  if (! ospf_top->anyNSSA)
    return;

  /* Each area must confirm TranslatorRole */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): Start");

  /* For all Global Entries flagged "local-translate", unset APPROVED */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): unapprove translates");

  ospf_abr_unapprove_translates ();

  /* RESET all Ranges in every Area, same as summaries */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): NSSA initialize aggregates");

  /*    ospf_abr_prepare_aggregates ();  TURNED OFF just for now */

  /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
     Aggregate as Type-7 */
  /* Install or Approve in Type-5 Global LSDB */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): process translates");

  ospf_abr_process_nssa_translates (ospf_top->new_table);

  /* Translate/Send any "ranged" aggregates, and also 5-Install and
     Approve */
  /* Scan Type-7's for aggregates, translate to Type-5's,
     Install/Flood/Approve */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info("ospf_abr_nssa_task(): send NSSA aggregates");
  /*       ospf_abr_send_nssa_aggregates ();  TURNED OFF FOR NOW */

  /* Send any NSSA defaults as Type-5 */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): announce nssa defaults");
  ospf_abr_announce_nssa_defaults ();
   
  /* Flush any unapproved previous translates from Global Data Base */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): remove unapproved translates");
  ospf_abr_remove_unapproved_translates ();

  ospf_abr_manage_discard_routes (); /* same as normal...discard */

  if (IS_DEBUG_OSPF_NSSA)
    zlog_info ("ospf_abr_nssa_task(): Stop");
}
#endif /* HAVE_NSSA */

/* This is the function taking care about ABR stuff, i.e.
   summary-LSA origination and flooding. */
void
ospf_abr_task ()
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_task(): Start");

  if (ospf_top->new_table == NULL || ospf_top->new_rtrs == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_task(): Routing tables are not yet ready");
      return;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_task(): unapprove summaries");
  ospf_abr_unapprove_summaries ();

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_task(): prepare aggregates");
  ospf_abr_prepare_aggregates ();

  if (OSPF_IS_ABR)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_task(): process network RT");
      ospf_abr_process_network_rt (ospf_top->new_table);

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_task(): process router RT");
      ospf_abr_process_router_rt (ospf_top->new_rtrs);

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_task(): announce aggregates");
      ospf_abr_announce_aggregates ();

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_task(): announce stub defaults");
      ospf_abr_announce_stub_defaults ();
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_task(): remove unapproved summaries");
  ospf_abr_remove_unapproved_summaries ();

  ospf_abr_manage_discard_routes ();

#ifdef HAVE_NSSA
  ospf_abr_nssa_task(); /* if nssa-abr, then scan Type-7 LSDB */
#endif /* HAVE_NSSA */

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_task(): Stop");
}


int
ospf_abr_task_timer (struct thread *t)
{
  ospf_top->t_abr_task = 0;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("Running ABR task on timer");

  ospf_check_abr_status ();

  ospf_abr_task ();

 return 0;
}

void
ospf_schedule_abr_task ()
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("Scheduling ABR task");
  if (! ospf_top->t_abr_task)
    ospf_top->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
					     0, OSPF_ABR_TASK_DELAY);
}
