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

#ifdef HAVE_NSSA
  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;
    }
#endif /* HAVE_NSSA */

  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;
#ifdef HAVE_NSSA
  listnode node;
  struct ospf_area *area;
#endif /* HAVE_NSSA */

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

#ifdef HAVE_NSSA
      /*  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);

#endif /* HAVE_NSSA */

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