/*
 * 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"

static 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;
}

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

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

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

static 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;
  struct ospf_area *area;
  struct listnode *node;

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    if ((range = ospf_area_range_match (area, p)))
      return range;

  return NULL;
}

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

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

  area = ospf_area_get (ospf, 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 (ospf);
    }
  else
    {
      range = ospf_area_range_new (p);
      ospf_area_range_add (area, range);
      ospf_schedule_abr_task (ospf);
    }

  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_ADDRESS;

  area = ospf_area_get (ospf, 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 (ospf);
    }

  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 (ospf, 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);

  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_ADDRESS;

  area = ospf_area_get (ospf, 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 (ospf);
    }
  else
    {
      range = ospf_area_range_new (p);
      ospf_area_range_add (area, range);
      ospf_schedule_abr_task (ospf);
    }

  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 (ospf, 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 (ospf);

  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 (struct ospf *ospf)
{
  if (ospf->backbone == NULL)
    return 0;

  return ospf->backbone->full_nbrs;
}

/* Determine whether this router is elected translator or not for area */
static int
ospf_abr_nssa_am_elected (struct ospf_area *area)
{
  struct route_node *rn;
  struct ospf_lsa *lsa;
  struct router_lsa *rlsa;
  struct in_addr *best = NULL;
  
  LSDB_LOOP ( ROUTER_LSDB (area), rn, lsa)
    {
      /* sanity checks */
      if (!lsa 
          || (lsa->data->type != OSPF_ROUTER_LSA) 
          || IS_LSA_SELF (lsa))
        continue;
      
      rlsa = (struct router_lsa *) lsa->data;
      
      /* ignore non-ABR routers */
      if (!IS_ROUTER_LSA_BORDER (rlsa))
        continue;
      
      /* Router has Nt flag - always translate */
      if (IS_ROUTER_LSA_NT (rlsa))
        {
          if (IS_DEBUG_OSPF_NSSA)
            zlog_debug ("ospf_abr_nssa_am_elected: "
                       "router %s asserts Nt",
                       inet_ntoa (lsa->data->id) );
          return 0;
        }
      
      if (best == NULL)
      	best = &lsa->data->id;
      else
        if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0)
          best = &lsa->data->id;
    }
    
    if (IS_DEBUG_OSPF_NSSA)
      zlog_debug ("ospf_abr_nssa_am_elected: best electable ABR is: %s",
                  (best) ? inet_ntoa (*best) : "<none>" );
                  
    if (best == NULL)
      return 1;
    
    if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0)
      return 1;
    else
      return 0;
}

/* Check NSSA ABR status
 * assumes there are nssa areas
 */
static void 
ospf_abr_nssa_check_status (struct ospf *ospf)
{
  struct ospf_area *area;
  struct listnode *lnode, *nnode;
    
  for (ALL_LIST_ELEMENTS (ospf->areas, lnode, nnode, area))
    {
    
      if (area->external_routing != OSPF_AREA_NSSA)
        continue;
        
      if (IS_DEBUG_OSPF (nssa, NSSA))
        zlog_debug ("ospf_abr_nssa_check_status: "
                    "checking area %s",
                    inet_ntoa (area->area_id));
      
      if (!IS_OSPF_ABR (area->ospf))
        {
          if (IS_DEBUG_OSPF (nssa, NSSA))
            zlog_debug ("ospf_abr_nssa_check_status: "
	    		"not ABR");
          area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
          continue;
        }
      
      switch (area->NSSATranslatorRole)
        {      
          case OSPF_NSSA_ROLE_NEVER:
            /* We never Translate Type-7 LSA. */
            /* TODO: check previous state and flush? */
            if (IS_DEBUG_OSPF (nssa, NSSA))
              zlog_debug ("ospf_abr_nssa_check_status: "
	      		  "never translate");
            area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
            continue;
             
          case OSPF_NSSA_ROLE_ALWAYS:
            /* We always translate if we are an ABR
             * TODO: originate new LSAs if state change?
             * or let the nssa abr task take care of it?
             */
            if (IS_DEBUG_OSPF (nssa, NSSA))
              zlog_debug ("ospf_abr_nssa_check_status: "
			  "translate always");
            area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
            continue;
      
          case OSPF_NSSA_ROLE_CANDIDATE:
            /* We are a candidate for Translation */
            if (ospf_abr_nssa_am_elected (area) > 0 )
              {
                area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
                if (IS_DEBUG_OSPF (nssa, NSSA))
                  zlog_debug ("ospf_abr_nssa_check_status: "
                              "elected translator");
               }
            else
               {
                 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
                 if (IS_DEBUG_OSPF (nssa, NSSA))
                   zlog_debug ("ospf_abr_nssa_check_status: "
			       "not elected");
               }
            continue;
         }
    }
}

/* Check area border router status. */
void
ospf_check_abr_status (struct ospf *ospf)
{
  struct ospf_area *area;
  struct listnode *node, *nnode;
  int bb_configured = 0;
  int bb_act_attached = 0;
  int areas_configured = 0;
  int areas_act_attached = 0;
  u_char new_flags = ospf->flags;

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

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    {
      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_debug ("ospf_check_abr_status(): looked through areas");
      zlog_debug ("ospf_check_abr_status(): bb_configured: %d", bb_configured);
      zlog_debug ("ospf_check_abr_status(): bb_act_attached: %d",
		 bb_act_attached);
      zlog_debug ("ospf_check_abr_status(): areas_configured: %d",
		 areas_configured);
      zlog_debug ("ospf_check_abr_status(): areas_act_attached: %d",
		 areas_act_attached);
    }

  switch (ospf->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->flags)
    {
      ospf_spf_calculate_schedule (ospf);
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags);
      ospf->flags = new_flags;
      OSPF_TIMER_ON (ospf->t_router_lsa_update,
		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
    }
}

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

  if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
    {
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("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_debug ("ospf_abr_update_aggregate(): largest 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 = (u_char *) &metric;
  mp++;
  header = (struct summary_lsa *) lsa->data;
  memcpy(header->metric, mp, 3);
}

static 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 */
static int
ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
{
  /* 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 *old = NULL,
                  *new = NULL;
  struct as_external_lsa *ext7;
  struct prefix_ipv4 p;

  if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation",
                   inet_ntoa (lsa->data->id));
      return 1; 
    }
  
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5",
               inet_ntoa (lsa->data->id));

  ext7 = (struct as_external_lsa *)(lsa->data);
  p.prefix = lsa->data->id;
  p.prefixlen = ip_masklen (ext7->mask);
  
  if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION)
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, "
                   "Forward address is 0, NO Translation",
                   inet_ntoa (lsa->data->id));
      return 1;
    }
  
  /* try find existing AS-External LSA for this prefix */

  old = ospf_external_info_find_lsa (area->ospf, &p);

  if (old)
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_abr_translate_nssa(): " 
                   "found old translated LSA Id %s, refreshing",
                   inet_ntoa (old->data->id));
            
      /* refresh */
      new = ospf_translated_nssa_refresh (area->ospf, lsa, old);
      if (!new)
        {
          if (IS_DEBUG_OSPF_NSSA)
            zlog_debug ("ospf_abr_translate_nssa(): "
              "could not refresh translated LSA Id %s",
              inet_ntoa (old->data->id));
        }
    }
  else
    {
      /* no existing external route for this LSA Id
       * originate translated LSA 
       */
      
	  if ((new = ospf_translated_nssa_originate (area->ospf, lsa)) 
	       == NULL)
	    {
	      if (IS_DEBUG_OSPF_NSSA)
	        zlog_debug ("ospf_abr_translate_nssa(): Could not translate "
	                   "Type-7 for %s to Type-5", 
	                   inet_ntoa (lsa->data->id));
	        return 1;
	    }
    }

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

  return 0;
}

static 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... */
}

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_debug ("ospf_abr_announce_network_to_area(): Start");

  old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, 
                                   (struct prefix_ipv4 *) p,
                                   area->ospf->router_id);
  if (old)
    {
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_network_to_area(): old summary found");

      sl = (struct summary_lsa *) old->data;

      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_network_to_area(): "
        	   "old metric: %d, new metric: %d",
               GET_METRIC (sl->metric), cost);
               
      if (GET_METRIC (sl->metric) == cost)
        {
          /* unchanged. simply reapprove it */
          if (IS_DEBUG_OSPF_EVENT)
            zlog_debug ("ospf_abr_announce_network_to_area(): "
                       "old summary approved"); 
          SET_FLAG (old->flags, OSPF_LSA_APPROVED);
        }
      else
        {
          /* LSA is changed, refresh it */
          if (IS_DEBUG_OSPF_EVENT)
            zlog_debug ("ospf_abr_announce_network_to_area(): "
                       "refreshing summary");
          set_metric (old, cost);
          lsa = ospf_summary_lsa_refresh (area->ospf, old);
          
          if (!lsa)
            {
	      char buf[INET_ADDRSTRLEN + 3]; /* ipv4 and /XX */
	      
	      prefix2str ((struct prefix *) p, buf, sizeof(buf));
	      zlog_warn ("%s: Could not refresh %s to %s",
	                 __func__,
	                 buf,
	                 inet_ntoa (area->area_id));
	      return;
	    }
	  
          SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
          /* This will flood through area. */
        }
    }
  else
    {
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_network_to_area(): "
        	   "creating new summary");
      lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area);
          /* This will flood through area. */
      
      if (!lsa)
      	{
      	  char buf[INET_ADDRSTRLEN + 3]; /* ipv4 and /XX */
      	  
      	  prefix2str ((struct prefix *)p, buf, sizeof(buf));
	  zlog_warn ("%s: Could not originate %s to %s",
	             __func__,
	             buf,
		     inet_ntoa (area->area_id));
	  return;
	}
      
      SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_network_to_area(): "
        	   "flooding new version of summary");
    }

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

static int
ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
				  struct ospf_area *area)
{
  struct listnode *node, *nnode;
  struct ospf_path *path;

  for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
    {
      struct ospf_interface *oi = path->oi;

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

  return 0;
}

static int
ospf_abr_should_accept (struct prefix_ipv4 *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;
}

static int
ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
			 struct prefix_ipv4 *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;
}

static int
ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
			  struct prefix_ipv4 *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;
}

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

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_abr_announce_network(): Start");

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("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 (p, area))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("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, p))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("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_debug ("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_debug ("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_debug ("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);
        }
    }
}

static int
ospf_abr_should_announce (struct ospf *ospf,
			  struct prefix_ipv4 *p, struct ospf_route *or)
{
  struct ospf_area *area;

  area = ospf_area_lookup_by_area_id (ospf, 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;
}

static void
ospf_abr_process_nssa_translates (struct ospf *ospf)
{
  /* 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 ) */
  struct listnode *node;
  struct ospf_area *area;
  struct route_node *rn;
  struct ospf_lsa *lsa;

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (! area->NSSATranslatorState)
        continue; /* skip if not translator */
      
      if (area->external_routing != OSPF_AREA_NSSA)
        continue;  /* skip if not Nssa Area */

      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("ospf_abr_process_nssa_translates(): "
                   "looking at area %s", inet_ntoa (area->area_id));
      
      LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
        ospf_abr_translate_nssa (area, lsa);
    }
 
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_process_nssa_translates(): Stop");

}

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

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("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 (ospf, or->u.std.area_id)))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("ospf_abr_process_network_rt(): area %s no longer exists",
		       inet_ntoa (or->u.std.area_id));
	  continue;
	}

      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("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_debug ("ospf_abr_process_network_rt(): "
		       "this is an External router, skipping");
	  continue;
	}

      if (or->cost >= OSPF_LS_INFINITY)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("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_debug ("ospf_abr_process_network_rt():"
		       " this is a discard entry, skipping");
	  continue;
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug("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, (struct prefix_ipv4 *) &rn->p))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug("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_debug ("ospf_abr_process_network_rt():"
		       " this is route is not backbone one, skipping");
	  continue;
	}


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

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

      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_process_network_rt(): announcing");
      ospf_abr_announce_network (ospf, (struct prefix_ipv4 *)&rn->p, or);
    }

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

static 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_debug ("ospf_abr_announce_rtr_to_area(): Start");

  old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA,
				   p, area->ospf->router_id);
  if (old)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary found");
      slsa = (struct summary_lsa *) old->data;

      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("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_debug ("ospf_abr_announce_rtr_to_area(): old summary approved");
      SET_FLAG (old->flags, OSPF_LSA_APPROVED);
    }
  else
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_announce_rtr_to_area(): 2.2");
       
      if (old) 
	{ 
	  set_metric (old, cost);
	  lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
	}
      else
	lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
      if (!lsa)
        {
          char buf[INET_ADDRSTRLEN + 3]; /* ipv4 and /XX */
          
          prefix2str ((struct prefix *)p, buf, sizeof(buf));
          zlog_warn ("%s: Could not refresh/originate %s to %s",
                     __func__,
                     buf,
                     inet_ntoa (area->area_id));
          return;
        }
      
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("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_debug ("ospf_abr_announce_rtr_to_area(): Stop");
}


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

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("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_debug ("ospf_abr_announce_rtr(): "
		       "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_debug ("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_debug ("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_debug ("ospf_abr_announce_rtr(): Stop");
}

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

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

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

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

      l = rn->info;

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

      for (ALL_LIST_ELEMENTS (l, node, nnode, or))
	{
	  if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_debug ("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_debug ("ospf_abr_process_router_rt(): "
			   "This is not an ASBR, skipping");
	      continue;
	    }

	  if (!flag)
	    {
	      best = ospf_find_asbr_route (ospf, rt,
					   (struct prefix_ipv4 *) &rn->p);
	      flag = 1;
	    }
	  
        if (best == NULL)
	  continue;
	
        if (or != best)
	  {
	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_debug ("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_debug ("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_debug ("ospf_abr_process_router_rt(): "
			 "This route has LS_INFINITY metric, skipping");
	    continue;
	  }

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

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

	}

    }

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

static void
ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
{
  struct ospf_lsa *lsa;
  struct route_node *rn;

  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("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 */

  LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
    if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
      {
        UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
        if (IS_DEBUG_OSPF_NSSA)
          zlog_debug ("ospf_abr_unapprove_translates(): "
                     "approved unset on link id %s",
                     inet_ntoa (lsa->data->id));
      }

  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_unapprove_translates(): Stop");
}

static void
ospf_abr_unapprove_summaries (struct ospf *ospf)
{
  struct listnode *node;
  struct ospf_area *area;
  struct route_node *rn;
  struct ospf_lsa *lsa;

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_unapprove_summaries(): "
                   "considering area %s",
                   inet_ntoa (area->area_id)); 
      LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
      if (ospf_lsa_is_self_originated (ospf, lsa))
        {
          if (IS_DEBUG_OSPF_EVENT)
            zlog_debug ("ospf_abr_unapprove_summaries(): "
                       "approved unset on summary link id %s",
                       inet_ntoa (lsa->data->id)); 
          UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
        }

      LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
      if (ospf_lsa_is_self_originated (ospf, lsa))
        {
          if (IS_DEBUG_OSPF_EVENT)
            zlog_debug ("ospf_abr_unapprove_summaries(): "
                       "approved unset on asbr-summary link id %s",
                       inet_ntoa (lsa->data->id));
          UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
        }
    }

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

static void
ospf_abr_prepare_aggregates (struct ospf *ospf)
{
  struct listnode *node;
  struct route_node *rn;
  struct ospf_area_range *range;
  struct ospf_area *area;

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      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_debug ("ospf_abr_prepare_aggregates(): Stop");
}

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

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("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_debug ("ospf_abr_announce_aggregates():"
			     " discarding suppress-ranges");
		continue;
	      }

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

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

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

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

		for (ALL_LIST_ELEMENTS_RO (ospf->areas, n, ar))
		  {
		    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_debug ("ospf_abr_announce_aggregates(): Skipping "
				     "announcement of BB aggregate into"
				     " a transit area");
			continue; 
		      }
		    ospf_abr_announce_network_to_area ((struct prefix_ipv4 *)&p, range->cost, ar);
		  }
	      }
	  }
    }

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

static void
ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
{
  struct 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_debug ("ospf_abr_send_nssa_aggregates(): Start");

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (! area->NSSATranslatorState)
	continue;

      if (IS_DEBUG_OSPF_NSSA)
	zlog_debug ("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_debug ("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_debug ("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_debug ("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);
            }
        } /* all area ranges*/
    } /* all areas */

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

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

  if (! IS_OSPF_ABR (ospf))
    return;

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_NSSA)
        zlog_debug ("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->NSSATranslatorState)
        {
          if (IS_DEBUG_OSPF_NSSA)
            zlog_debug ("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); */
          /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/
        }
    }
}

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

  if (! IS_OSPF_ABR (ospf))
    return;

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

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_stub_defaults(): looking at area %s",
		    inet_ntoa (area->area_id));

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

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

      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_stub_defaults(): "
		    "announcing 0.0.0.0/0 to area %s",
                 inet_ntoa (area->area_id));
      ospf_abr_announce_network_to_area (&p, area->default_cost, area);
    }

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

static int
ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
					     struct ospf_lsa *lsa)
{
  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 (ospf, lsa);

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

static void
ospf_abr_remove_unapproved_translates (struct ospf *ospf)
{
  struct route_node *rn;
  struct ospf_lsa *lsa;

  /* All AREA PROCESS should have APPROVED necessary LSAs */
  /* Remove any left over and not APPROVED */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_remove_unapproved_translates(): Start");

  LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
    ospf_abr_remove_unapproved_translates_apply (ospf, lsa);
 
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_remove_unapproved_translates(): Stop");
}

static void
ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
{
  struct listnode *node;
  struct ospf_area *area;
  struct route_node *rn;
  struct ospf_lsa *lsa;

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

  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_remove_unapproved_summaries(): "
		   "looking at area %s", inet_ntoa (area->area_id));

      LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
	if (ospf_lsa_is_self_originated (ospf, lsa))
	  if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
	    ospf_lsa_flush_area (lsa, area);

      LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
	if (ospf_lsa_is_self_originated (ospf, lsa))
	  if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED))
	    ospf_lsa_flush_area (lsa, area);
    }
 
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_abr_remove_unapproved_summaries(): Stop");
}

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

  for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
    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->new_table, area,
				      (struct prefix_ipv4 *) &rn->p);
	    else
	      ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
	  }
}

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

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

  if (! IS_OSPF_ABR (ospf))
    return;

  if (! ospf->anyNSSA)
    return;

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

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

  ospf_abr_unapprove_translates (ospf);

  /* RESET all Ranges in every Area, same as summaries */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_nssa_task(): NSSA initialize aggregates");
  ospf_abr_prepare_aggregates (ospf);  /*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_debug ("ospf_abr_nssa_task(): process translates");
  ospf_abr_process_nssa_translates (ospf);

  /* 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_debug("ospf_abr_nssa_task(): send NSSA aggregates");
  ospf_abr_send_nssa_aggregates (ospf);  /*TURNED OFF FOR NOW */

  /* Send any NSSA defaults as Type-5 
   *if (IS_DEBUG_OSPF_NSSA)
   * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults");
   *ospf_abr_announce_nssa_defaults (ospf);
   * havnt a clue what above is supposed to do.
   */
   
  /* Flush any unapproved previous translates from Global Data Base */
  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_nssa_task(): remove unapproved translates");
  ospf_abr_remove_unapproved_translates (ospf);

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

  if (IS_DEBUG_OSPF_NSSA)
    zlog_debug ("ospf_abr_nssa_task(): Stop");
}

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

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

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_abr_task(): unapprove summaries");
  ospf_abr_unapprove_summaries (ospf);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_abr_task(): prepare aggregates");
  ospf_abr_prepare_aggregates (ospf);

  if (IS_OSPF_ABR (ospf))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_task(): process network RT");
      ospf_abr_process_network_rt (ospf, ospf->new_table);

      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_task(): process router RT");
      ospf_abr_process_router_rt (ospf, ospf->new_rtrs);

      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_abr_task(): announce aggregates");
      ospf_abr_announce_aggregates (ospf);

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

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

  ospf_abr_manage_discard_routes (ospf);

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

static int
ospf_abr_task_timer (struct thread *thread)
{
  struct ospf *ospf = THREAD_ARG (thread);

  ospf->t_abr_task = 0;

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

  ospf_check_abr_status (ospf);
  ospf_abr_nssa_check_status (ospf);

  ospf_abr_task (ospf);
  ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */

  return 0;
}

void
ospf_schedule_abr_task (struct ospf *ospf)
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("Scheduling ABR task");

  if (ospf->t_abr_task == NULL)
    ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
					 ospf, OSPF_ABR_TASK_DELAY);
}
