/*
 * OSPF AS external route calculation.
 * 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 "hash.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "vty.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_ase.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"

#define DEBUG

struct ospf_route *
ospf_find_asbr_route (struct ospf *ospf,
		      struct route_table *rtrs, struct prefix_ipv4 *asbr)
{
  struct route_node *rn;
  struct ospf_route *or, *best = NULL;
  listnode node;
  list chosen;

  /* Sanity check. */
  if (rtrs == NULL)
    return NULL;

  rn = route_node_lookup (rtrs, (struct prefix *) asbr);
  if (! rn)
    return NULL;

  route_unlock_node (rn);

  chosen = list_new ();

  /* First try to find intra-area non-bb paths. */
  if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
    for (node = listhead ((list) rn->info); node; nextnode (node))
      if ((or = getdata (node)) != NULL)
	if (or->cost < OSPF_LS_INFINITY)
	  if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id) &&
	      or->path_type == OSPF_PATH_INTRA_AREA)
	    listnode_add (chosen, or);

  /* If none is found -- look through all. */
  if (listcount (chosen) == 0)
    {
      list_free (chosen);
      chosen = rn->info;
    }

  /* Now find the route with least cost. */
  for (node = listhead (chosen); node; nextnode (node))
    if ((or = getdata (node)) != NULL)
      if (or->cost < OSPF_LS_INFINITY)
	{
	  if (best == NULL)
	    best = or;
	  else if (best->cost > or->cost)
	    best = or;
	  else if (best->cost == or->cost &&
		   IPV4_ADDR_CMP (&best->u.std.area_id,
				  &or->u.std.area_id) < 0)
	    best = or;
	}

  if (chosen != rn->info)
    list_delete (chosen);

  return best;
}

struct ospf_route * 
ospf_find_asbr_route_through_area (struct route_table *rtrs, 
				   struct prefix_ipv4 *asbr, 
				   struct ospf_area *area)
{
  struct route_node *rn;

  /* Sanity check. */
  if (rtrs == NULL)
    return NULL;

  rn = route_node_lookup (rtrs, (struct prefix *) asbr);
 
  if (rn)
    {
      listnode node;
      struct ospf_route *or;

      route_unlock_node (rn);

      for (node = listhead ((list) rn->info); node; nextnode (node))
	if ((or = getdata (node)) != NULL)
	  if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id))
	    return or;
    }

  return NULL;
}

void
ospf_ase_complete_direct_routes (struct ospf_route *ro, struct in_addr nexthop)
{
  listnode node;
  struct ospf_path *op;

  for (node = listhead (ro->paths); node; nextnode (node))
    if ((op = getdata (node)) != NULL)
      if (op->nexthop.s_addr == 0)
	op->nexthop.s_addr = nexthop.s_addr;
}

int
ospf_ase_forward_address_check (struct ospf *ospf, struct in_addr fwd_addr)
{
  listnode ifn;
  struct ospf_interface *oi;

  for (ifn = listhead (ospf->oiflist); ifn; nextnode (ifn))
    if ((oi = getdata (ifn)) != NULL)
      if (if_is_operative (oi->ifp))
	if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
	  if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &fwd_addr))
	    return 0;
  
  return 1;
}

/* Calculate ASBR route. */
struct ospf_route *
ospf_ase_calculate_asbr_route (struct ospf *ospf,
			       struct route_table *rt_network,
			       struct route_table *rt_router,
			       struct as_external_lsa *al)
{
  struct prefix_ipv4 asbr;
  struct ospf_route *asbr_route;
  struct route_node *rn;

  /* Find ASBR route from Router routing table. */
  asbr.family = AF_INET;
  asbr.prefix = al->header.adv_router;
  asbr.prefixlen = IPV4_MAX_BITLEN;
  apply_mask_ipv4 (&asbr);

  asbr_route = ospf_find_asbr_route (ospf, rt_router, &asbr);

  if (asbr_route == NULL)
    {
      zlog_info ("ospf_ase_calculate(): Route to ASBR %s not found",
		 inet_ntoa (asbr.prefix));
      return NULL;
    }

  if (!(asbr_route->u.std.flags & ROUTER_LSA_EXTERNAL))
    {
      zlog_info ("ospf_ase_calculate(): Originating router is not an ASBR");
      return NULL;
    }
   
  if (al->e[0].fwd_addr.s_addr != 0)
    {
      zlog_info ("ospf_ase_calculate(): "
		 "Forwarding address is not 0.0.0.0.");

      if (! ospf_ase_forward_address_check (ospf, al->e[0].fwd_addr))
	{
	  zlog_info ("ospf_ase_calculate(): "
		     "Forwarding address is one of our addresses, Ignore.");
	  return NULL;
        }

      zlog_info ("ospf_ase_calculate(): "
		 "Looking up in the Network Routing Table.");

      /* Looking up the path to the fwd_addr from Network route. */
      asbr.family = AF_INET;
      asbr.prefix = al->e[0].fwd_addr;
      asbr.prefixlen = IPV4_MAX_BITLEN;

      rn = route_node_match (rt_network, (struct prefix *) &asbr);
   
      if (rn == NULL)
	{
	  zlog_info ("ospf_ase_calculate(): "
		     "Couldn't find a route to the forwarding address.");
	  return NULL;
	}

      route_unlock_node (rn);

      if ((asbr_route = rn->info) == NULL)
	{
	  zlog_info ("ospf_ase_calculate(): "
		     "Somehow OSPF route to ASBR is lost");
	  return NULL;
	}
    }

  return asbr_route;
}

struct ospf_route *
ospf_ase_calculate_new_route (struct ospf_lsa *lsa,
			      struct ospf_route *asbr_route, u_int32_t metric)
{
  struct as_external_lsa *al;
  struct ospf_route *new;

  al = (struct as_external_lsa *) lsa->data;

  new = ospf_route_new ();

  /* Set redistributed type -- does make sense? */
  /* new->type = type; */
  new->id = al->header.id;
  new->mask = al->mask;

  if (!IS_EXTERNAL_METRIC (al->e[0].tos))
    {
      zlog_info ("Route[External]: type-1 created.");
      new->path_type = OSPF_PATH_TYPE1_EXTERNAL;
      new->cost = asbr_route->cost + metric;		/* X + Y */
    }
  else
    {
      zlog_info ("Route[External]: type-2 created.");
      new->path_type = OSPF_PATH_TYPE2_EXTERNAL;
      new->cost = asbr_route->cost;			/* X */
      new->u.ext.type2_cost = metric;			/* Y */
    }

  new->type = OSPF_DESTINATION_NETWORK;
  new->u.ext.origin = lsa;
  new->u.ext.tag = ntohl (al->e[0].route_tag);
  new->u.ext.asbr = asbr_route;

  assert (new != asbr_route);

  return new;
}

#define OSPF_ASE_CALC_INTERVAL 1

int
ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa)
{
  u_int32_t metric;
  struct as_external_lsa *al;
  struct ospf_route *asbr_route;
  struct prefix_ipv4 asbr, p;
  struct route_node *rn;
  struct ospf_route *new, *or;
  int ret;
  
  assert (lsa);
  al = (struct as_external_lsa *) lsa->data;

  if (lsa->data->type == OSPF_AS_NSSA_LSA)
    if (IS_DEBUG_OSPF_NSSA)
      zlog_info ("ospf_ase_calc(): Processing Type-7");

  /* Stay away from any Local Translated Type-7 LSAs */
  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
    {
      if (IS_DEBUG_OSPF_NSSA)
	zlog_info ("ospf_ase_calc(): Rejecting Local Xlt'd");
      return 0;
    }

  zlog_info ("Route[External]: Calculate AS-external-LSA to %s/%d",
	     inet_ntoa (al->header.id), ip_masklen (al->mask));
  /* (1) If the cost specified by the LSA is LSInfinity, or if the
         LSA's LS age is equal to MaxAge, then examine the next LSA. */
  if ((metric = GET_METRIC (al->e[0].metric)) >= OSPF_LS_INFINITY)
    {
      zlog_info ("Route[External]: Metric is OSPF_LS_INFINITY");
      return 0;
    }
  if (IS_LSA_MAXAGE (lsa))
    {
      zlog_info ("Route[External]: AS-external-LSA is MAXAGE");
      return 0;
    }
  
  /* (2) If the LSA was originated by the calculating router itself,
     examine the next LSA. */
  if (IS_LSA_SELF (lsa))
    {
      zlog_info ("Route[External]: AS-external-LSA is self originated");
      return 0;
    }

  /* (3) Call the destination described by the LSA N.  N's address is
         obtained by masking the LSA's Link State ID with the
	 network/subnet mask contained in the body of the LSA.  Look
	 up the routing table entries (potentially one per attached
	 area) for the AS boundary router (ASBR) that originated the
	 LSA. If no entries exist for router ASBR (i.e., ASBR is
	 unreachable), do nothing with this LSA and consider the next
	 in the list. */
  
  asbr.family = AF_INET;
  asbr.prefix = al->header.adv_router;
  asbr.prefixlen = IPV4_MAX_BITLEN;
  apply_mask_ipv4 (&asbr);
  
  asbr_route = ospf_find_asbr_route (ospf, ospf->new_rtrs, &asbr);
  if (asbr_route == NULL)
    {
      zlog_info ("Route[External]: Can't find originating ASBR route");
      return 0;
    }
  if (!(asbr_route->u.std.flags & ROUTER_LSA_EXTERNAL))
    {
      zlog_info ("Route[External]: Originating router is not an ASBR");
      return 0;
    }
  
  /*     Else, this LSA describes an AS external path to destination
	 N.  Examine the forwarding address specified in the AS-
	 external-LSA.  This indicates the IP address to which
	 packets for the destination should be forwarded. */
  
  if (al->e[0].fwd_addr.s_addr == 0)
    {
      /* If the forwarding address is set to 0.0.0.0, packets should
	 be sent to the ASBR itself. Among the multiple routing table
	 entries for the ASBR, select the preferred entry as follows.
	 If RFC1583Compatibility is set to "disabled", prune the set
	 of routing table entries for the ASBR as described in
	 Section 16.4.1. In any case, among the remaining routing
	 table entries, select the routing table entry with the least
	 cost; when there are multiple least cost routing table
	 entries the entry whose associated area has the largest OSPF
	 Area ID (when considered as an unsigned 32-bit integer) is
	 chosen. */

      /* asbr_route already contains the requested route */
    }
  else
    {
      /* If the forwarding address is non-zero, look up the
	 forwarding address in the routing table.[24] The matching
	 routing table entry must specify an intra-area or inter-area
	 path; if no such path exists, do nothing with the LSA and
	 consider the next in the list. */
      if (! ospf_ase_forward_address_check (ospf, al->e[0].fwd_addr))
	{
	  zlog_info ("Route[External]: Forwarding address is our router address");
	  return 0;
	}
      
      asbr.family = AF_INET;
      asbr.prefix = al->e[0].fwd_addr;
      asbr.prefixlen = IPV4_MAX_BITLEN;

      rn = route_node_match (ospf->new_table, (struct prefix *) &asbr);
      
      if (rn == NULL || (asbr_route = rn->info) == NULL)
	{
	  zlog_info ("Route[External]: Can't find route to forwarding address");
	  if (rn)
	    route_unlock_node (rn);
	  return 0;
	}

      route_unlock_node (rn);
    }

  /* (4) Let X be the cost specified by the preferred routing table
         entry for the ASBR/forwarding address, and Y the cost
	 specified in the LSA.  X is in terms of the link state
	 metric, and Y is a type 1 or 2 external metric. */
			 

  /* (5) Look up the routing table entry for the destination N.  If
         no entry exists for N, install the AS external path to N,
	 with next hop equal to the list of next hops to the
	 forwarding address, and advertising router equal to ASBR.
	 If the external metric type is 1, then the path-type is set
	 to type 1 external and the cost is equal to X+Y.  If the
	 external metric type is 2, the path-type is set to type 2
	 external, the link state component of the route's cost is X,
	 and the type 2 cost is Y. */
  new = ospf_ase_calculate_new_route (lsa, asbr_route, metric);

  /* (6) Compare the AS external path described by the LSA with the
         existing paths in N's routing table entry, as follows. If
	 the new path is preferred, it replaces the present paths in
	 N's routing table entry.  If the new path is of equal
	 preference, it is added to N's routing table entry's list of
	 paths. */

  /* Set prefix. */
  p.family = AF_INET;
  p.prefix = al->header.id;
  p.prefixlen = ip_masklen (al->mask);

  /* if there is a Intra/Inter area route to the N
     do not install external route */
  if ((rn = route_node_lookup (ospf->new_table,
			       (struct prefix *) &p)) != NULL
      && (rn->info != NULL))
    {
      if (new)
	ospf_route_free (new);
      return 0;
    }
  
  /* Find a route to the same dest */
  /* If there is no route, create new one. */
  if ((rn = route_node_lookup (ospf->new_external_route,
			       (struct prefix *) &p)) == NULL 
      || (or = rn->info) == NULL)
    {
      zlog_info ("Route[External]: Adding a new route %s/%d",
		 inet_ntoa (p.prefix), p.prefixlen);

      ospf_route_add (ospf->new_external_route, &p, new, asbr_route);

      if (al->e[0].fwd_addr.s_addr)
	ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr);
      return 0;
    }
  else
    {
      /* (a) Intra-area and inter-area paths are always preferred
             over AS external paths.

         (b) Type 1 external paths are always preferred over type 2
             external paths. When all paths are type 2 external
	     paths, the paths with the smallest advertised type 2
	     metric are always preferred. */
      ret = ospf_route_cmp (ospf, new, or);
  
  /*     (c) If the new AS external path is still indistinguishable
             from the current paths in the N's routing table entry,
	     and RFC1583Compatibility is set to "disabled", select
	     the preferred paths based on the intra-AS paths to the
	     ASBR/forwarding addresses, as specified in Section
	     16.4.1.

         (d) If the new AS external path is still indistinguishable
             from the current paths in the N's routing table entry,
	     select the preferred path based on a least cost
	     comparison.  Type 1 external paths are compared by
	     looking at the sum of the distance to the forwarding
	     address and the advertised type 1 metric (X+Y).  Type 2
	     external paths advertising equal type 2 metrics are
	     compared by looking at the distance to the forwarding
	     addresses.
  */
      /* New route is better */
      if (ret < 0)
	{
	  zlog_info ("Route[External]: New route is better");
	  ospf_route_subst (rn, new, asbr_route);
	  if (al->e[0].fwd_addr.s_addr)
	    ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr);
	  or = new;
	  new = NULL;
	}
      /* Old route is better */
      else if (ret > 0)
	{
	  zlog_info ("Route[External]: Old route is better");
	  /* do nothing */
	}
      /* Routes are equal */
      else
	{
	  zlog_info ("Route[External]: Routes are equal");
	  ospf_route_copy_nexthops (or, asbr_route->paths);
	  if (al->e[0].fwd_addr.s_addr)
	    ospf_ase_complete_direct_routes (or, al->e[0].fwd_addr);
	}
    }
  /* Make sure setting newly calculated ASBR route.*/
  or->u.ext.asbr = asbr_route;
  if (new)
    ospf_route_free (new);

  lsa->route = or;
  return 0;
}

int
ospf_ase_route_match_same (struct route_table *rt, struct prefix *prefix,
			   struct ospf_route *newor)
{
  struct route_node *rn;
  struct ospf_route *or;
  struct ospf_path *op;
  struct ospf_path *newop;
  listnode n1;
  listnode n2;

  if (! rt || ! prefix)
    return 0;

   rn = route_node_lookup (rt, prefix);
   if (! rn)
     return 0;
 
   route_unlock_node (rn);

   or = rn->info;
   if (or->path_type != newor->path_type)
     return 0;

   switch (or->path_type)
     {
     case OSPF_PATH_TYPE1_EXTERNAL:
       if (or->cost != newor->cost)
	 return 0;
       break;
     case OSPF_PATH_TYPE2_EXTERNAL:
       if ((or->cost != newor->cost) ||
	   (or->u.ext.type2_cost != newor->u.ext.type2_cost))
	 return 0;
       break;
     default:
       assert (0);
       return 0;
     }
   
   if (or->paths->count != newor->paths->count)
     return 0;
       
   /* Check each path. */
   for (n1 = listhead (or->paths), n2 = listhead (newor->paths);
	n1 && n2; nextnode (n1), nextnode (n2))
     { 
       op = getdata (n1);
       newop = getdata (n2);
       
       if (! IPV4_ADDR_SAME (&op->nexthop, &newop->nexthop))
	 return 0;
     }
   return 1;
}

int
ospf_ase_compare_tables (struct route_table *new_external_route,
			 struct route_table *old_external_route)
{
  struct route_node *rn, *new_rn;
  struct ospf_route *or;
  
  /* Remove deleted routes */
  for (rn = route_top (old_external_route); rn; rn = route_next (rn))
    if ((or = rn->info))
      {
	if (! (new_rn = route_node_lookup (new_external_route, &rn->p)))
	  ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or);
	else
	  route_unlock_node (new_rn);
      }
  
	
  /* Install new routes */
  for (rn = route_top (new_external_route); rn; rn = route_next (rn))
    if ((or = rn->info) != NULL)
      if (! ospf_ase_route_match_same (old_external_route, &rn->p, or))
	ospf_zebra_add ((struct prefix_ipv4 *) &rn->p, or);
				       
  return 0;
}

int
ospf_ase_calculate_timer (struct thread *t)
{
  struct ospf *ospf;
  struct ospf_lsa *lsa;
  struct route_node *rn;
  listnode node;
  struct ospf_area *area;

  ospf = THREAD_ARG (t);
  ospf->t_ase_calc = NULL;

  if (ospf->ase_calc)
    {
      ospf->ase_calc = 0;

      /* Calculate external route for each AS-external-LSA */
      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
	ospf_ase_calculate_route (ospf, lsa);

      /*  This version simple adds to the table all NSSA areas  */
      if (ospf->anyNSSA)
	for (node = listhead (ospf->areas); node; nextnode (node))
	  {
	    area = getdata (node);
	    if (IS_DEBUG_OSPF_NSSA)
	      zlog_info ("ospf_ase_calculate_timer(): looking at area %s",
			 inet_ntoa (area->area_id));

	    if (area->external_routing == OSPF_AREA_NSSA)
	      LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
		ospf_ase_calculate_route (ospf, lsa);
	  }
      /* kevinm: And add the NSSA routes in ospf_top */
      LSDB_LOOP (NSSA_LSDB (ospf),rn,lsa)
      		ospf_ase_calculate_route(ospf,lsa);

      /* Compare old and new external routing table and install the
	 difference info zebra/kernel */
      ospf_ase_compare_tables (ospf->new_external_route,
			       ospf->old_external_route);

      /* Delete old external routing table */
      ospf_route_table_free (ospf->old_external_route);
      ospf->old_external_route = ospf->new_external_route;
      ospf->new_external_route = route_table_init ();
    }
  return 0;
}

void
ospf_ase_calculate_schedule (struct ospf *ospf)
{
  if (ospf == NULL)
    return;

  ospf->ase_calc = 1;
}

void
ospf_ase_calculate_timer_add (struct ospf *ospf)
{
  if (ospf == NULL)
    return;

  if (! ospf->t_ase_calc)
    ospf->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer,
					 ospf, OSPF_ASE_CALC_INTERVAL);
}

void
ospf_ase_register_external_lsa (struct ospf_lsa *lsa, struct ospf *top)
{
  struct route_node *rn;
  struct prefix_ipv4 p;
  list lst;
  struct as_external_lsa *al;

  al = (struct as_external_lsa *) lsa->data;
  p.family = AF_INET;
  p.prefix = lsa->data->id;
  p.prefixlen = ip_masklen (al->mask);
  apply_mask_ipv4 (&p);

  rn = route_node_get (top->external_lsas, (struct prefix *) &p);
  if ((lst = rn->info) == NULL)
    rn->info = lst = list_new();

  /* We assume that if LSA is deleted from DB
     is is also deleted from this RT */

  listnode_add (lst, ospf_lsa_lock (lsa));
}

void
ospf_ase_unregister_external_lsa (struct ospf_lsa *lsa, struct ospf *top)
{
  struct route_node *rn;
  struct prefix_ipv4 p;
  list lst;
  struct as_external_lsa *al;

  al = (struct as_external_lsa *) lsa->data;
  p.family = AF_INET;
  p.prefix = lsa->data->id;
  p.prefixlen = ip_masklen (al->mask);
  apply_mask_ipv4 (&p);

  rn = route_node_get (top->external_lsas, (struct prefix *) &p);
  lst = rn->info;
#ifdef ORIGINAL_CODING
  assert (lst);

  listnode_delete (lst, lsa);
  ospf_lsa_unlock (lsa);
#else /* ORIGINAL_CODING */
  /* XXX lst can be NULL */
  if (lst) {
    listnode_delete (lst, lsa);
    ospf_lsa_unlock (lsa);
  }
#endif /* ORIGINAL_CODING */
}

void
ospf_ase_external_lsas_finish (struct route_table *rt)
{
  struct route_node *rn;
  struct ospf_lsa *lsa;
  list lst;
  listnode node;
  
  for (rn = route_top (rt); rn; rn = route_next (rn))
    if ((lst = rn->info) != NULL)
      {
	for (node = listhead (lst); node; node = nextnode (node))
	  if ((lsa = getdata (node)) != NULL)
	    ospf_lsa_unlock (lsa);
	list_delete (lst);
      }
  
  route_table_finish (rt);
}

void
ospf_ase_incremental_update (struct ospf *ospf, struct ospf_lsa *lsa)
{
  list lsas;
  listnode node;
  struct route_node *rn, *rn2;
  struct prefix_ipv4 p;
  struct route_table *tmp_old;
  struct as_external_lsa *al;

  al = (struct as_external_lsa *) lsa->data;
  p.family = AF_INET;
  p.prefix = lsa->data->id;
  p.prefixlen = ip_masklen (al->mask);
  apply_mask_ipv4 (&p);

  /* if new_table is NULL, there was no spf calculation, thus
     incremental update is unneeded */
  if (!ospf->new_table)
    return;
  
  /* If there is already an intra-area or inter-area route
     to the destination, no recalculation is necessary
     (internal routes take precedence). */
  
  rn = route_node_lookup (ospf->new_table, (struct prefix *) &p);
  if (rn && rn->info)
    {
      route_unlock_node (rn);
      return;
    }

  rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p);
  assert (rn && rn->info);
  lsas = rn->info;
  
  for (node = listhead (lsas); node; nextnode (node))
    if ((lsa = getdata (node)) != NULL)
      ospf_ase_calculate_route (ospf, lsa);

  /* prepare temporary old routing table for compare */
  tmp_old = route_table_init ();
  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) &p);
  if (rn && rn->info)
    {
      rn2 = route_node_get (tmp_old, (struct prefix *) &p);
      rn2->info = rn->info;
    }

  /* install changes to zebra */
  ospf_ase_compare_tables (ospf->new_external_route, tmp_old);

  /* update ospf->old_external_route table */
  if (rn && rn->info)
    ospf_route_free ((struct ospf_route *) rn->info);

  rn2 = route_node_lookup (ospf->new_external_route, (struct prefix *) &p);
  /* if new route exists, install it to ospf->old_external_route */
  if (rn2 && rn2->info)
    {
      if (!rn)
	rn = route_node_get (ospf->old_external_route, (struct prefix *) &p);
      rn->info = rn2->info;
    }
  else
    {
      /* remove route node from ospf->old_external_route */
      if (rn)
	{
	  rn->info = NULL;
	  route_unlock_node (rn);
	  route_unlock_node (rn);
	}
    }

  if (rn2)
    {
      /* rn2->info is stored in route node of ospf->old_external_route */
      rn2->info = NULL;
      route_unlock_node (rn2);
      route_unlock_node (rn2);
    }

  route_table_finish (tmp_old);
}
