/*
 * OSPF inter-area routing.
 * 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 "table.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_abr.h"
#include "ospfd/ospf_ia.h"
#include "ospfd/ospf_dump.h"

#define DEBUG

struct ospf_route *
ospf_find_abr_route (struct route_table *rtrs, 
                     struct prefix_ipv4 *abr,
                     struct ospf_area *area)
{
  struct route_node *rn;
  struct ospf_route *or;
  listnode node;

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

  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) && (or->u.std.flags & ROUTER_LSA_BORDER))
	return or;

  return NULL;
}

void
ospf_ia_network_route (struct ospf *ospf, struct route_table *rt,
		       struct prefix_ipv4 *p, struct ospf_route *new_or,
		       struct ospf_route *abr_or)
{
  struct route_node *rn1;
  struct ospf_route *or;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_ia_network_route(): processing summary route to %s/%d", 
	       inet_ntoa (p->prefix), p->prefixlen);

  /* Find a route to the same dest */
  if ((rn1 = route_node_lookup (rt, (struct prefix *) p)))
    {
      int res;

      route_unlock_node (rn1);

      if ((or = rn1->info))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_ia_network_route(): "
		       "Found a route to the same network");
	  /* Check the existing route. */
	  if ((res = ospf_route_cmp (ospf, new_or, or)) < 0)
	    {
	      /* New route is better, so replace old one. */
	      ospf_route_subst (rn1, new_or, abr_or);
	    }
	  else if (res == 0)
	    {
	      /* New and old route are equal, so next hops can be added. */
	      route_lock_node (rn1);
	      ospf_route_copy_nexthops (or, abr_or->paths);
	      route_unlock_node (rn1);

	      /* new route can be deleted, because existing route has been updated. */
	      ospf_route_free (new_or);
	    }
	  else
	    {
	      /* New route is worse, so free it. */
	      ospf_route_free (new_or);
	      return;
	    }
	} /* if (or)*/
    } /*if (rn1)*/
  else
    { /* no route */
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_ia_network_route(): add new route to %s/%d",
		   inet_ntoa (p->prefix), p->prefixlen);
      ospf_route_add (rt, p, new_or, abr_or);
    }
}

void
ospf_ia_router_route (struct ospf *ospf, struct route_table *rtrs,
		      struct prefix_ipv4 *p,
                      struct ospf_route *new_or, struct ospf_route *abr_or)
{
  struct ospf_route *or = NULL;
  struct route_node *rn;
  int ret;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_ia_router_route(): considering %s/%d", 
	       inet_ntoa (p->prefix), p->prefixlen);
  /* Find a route to the same dest */
  rn = route_node_get (rtrs, (struct prefix *) p);
   
  if (rn->info == NULL)
    /* This is a new route */
    rn->info = list_new ();
  else
    {
      struct ospf_area *or_area;
      or_area = ospf_area_lookup_by_area_id (ospf, new_or->u.std.area_id);
      assert (or_area);
      /* This is an additional route */
      route_unlock_node (rn);
      or = ospf_find_asbr_route_through_area (rtrs, p, or_area);
    }

  if (or)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_ia_router_route(): "
		   "a route to the same ABR through the same area exists");
      /* New route is better */
      if ((ret = ospf_route_cmp (ospf, new_or, or)) < 0)
	{
	  listnode_delete (rn->info, or);
	  ospf_route_free (or);
	  /* proceed down */
	}
      /* Routes are the same */
      else if (ret == 0)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_ia_router_route(): merging the new route");

	  ospf_route_copy_nexthops (or, abr_or->paths);
	  ospf_route_free (new_or);
	  return;
	}
      /* New route is worse */
      else
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_ia_router_route(): skipping the new route");
	  ospf_route_free (new_or);
	  return;
	}
    }

  ospf_route_copy_nexthops (new_or, abr_or->paths);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_ia_router_route(): adding the new route"); 

  listnode_add (rn->info, new_or);
}


int
process_summary_lsa (struct ospf_area *area, struct route_table *rt,
		     struct route_table *rtrs, struct ospf_lsa *lsa)
{
  struct ospf *ospf = area->ospf;
  struct ospf_area_range *range;
  struct ospf_route *abr_or, *new_or;
  struct summary_lsa *sl;
  struct prefix_ipv4 p, abr;
  u_int32_t metric;

  if (lsa == NULL)
    return 0;

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

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("process_summary_lsa(): LS ID: %s", inet_ntoa (sl->header.id));

  metric = GET_METRIC (sl->metric);
   
  if (metric == OSPF_LS_INFINITY)
    return 0;

  if (IS_LSA_MAXAGE (lsa))
    return 0;

  if (ospf_lsa_is_self_originated (area->ospf, lsa))
    return 0;

  p.family = AF_INET;
  p.prefix = sl->header.id;
   
  if (sl->header.type == OSPF_SUMMARY_LSA)
    p.prefixlen = ip_masklen (sl->mask);
  else
    p.prefixlen = IPV4_MAX_BITLEN;
      
  apply_mask_ipv4 (&p);

  if (sl->header.type == OSPF_SUMMARY_LSA &&
      (range = ospf_area_range_match_any (ospf, &p)) &&
      ospf_area_range_active (range))
    return 0;

  if (ospf->abr_type != OSPF_ABR_STAND &&
      area->external_routing != OSPF_AREA_DEFAULT &&
      p.prefix.s_addr == OSPF_DEFAULT_DESTINATION &&
      p.prefixlen == 0)
    return 0; /* Ignore summary default from a stub area */

  abr.family = AF_INET;
  abr.prefix = sl->header.adv_router;
  abr.prefixlen = IPV4_MAX_BITLEN;
  apply_mask_ipv4 (&abr);

  abr_or = ospf_find_abr_route (rtrs, &abr, area);

  if (abr_or == NULL)
    return 0;

  new_or = ospf_route_new ();
  new_or->type = OSPF_DESTINATION_NETWORK;
  new_or->id = sl->header.id;
  new_or->mask = sl->mask;
  new_or->u.std.options = sl->header.options;
  new_or->u.std.origin = (struct lsa_header *) sl;
  new_or->cost = abr_or->cost + metric;
  new_or->u.std.area_id = area->area_id;
  new_or->u.std.external_routing = area->external_routing;
  new_or->path_type = OSPF_PATH_INTER_AREA;

  if (sl->header.type == OSPF_SUMMARY_LSA)
    ospf_ia_network_route (ospf, rt, &p, new_or, abr_or);
  else 
    {
      new_or->type = OSPF_DESTINATION_ROUTER;
      new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
      ospf_ia_router_route (ospf, rtrs, &p, new_or, abr_or);
    }

  return 0;
}

void
ospf_examine_summaries (struct ospf_area *area,
			struct route_table *lsdb_rt,
                        struct route_table *rt,
                        struct route_table *rtrs)
{
  struct ospf_lsa *lsa;
  struct route_node *rn;

  LSDB_LOOP (lsdb_rt, rn, lsa)
    process_summary_lsa (area, rt, rtrs, lsa);
}

int
ospf_area_is_transit (struct ospf_area *area)
{
  return (area->transit == OSPF_TRANSIT_TRUE) ||
    ospf_full_virtual_nbrs(area); /* Cisco forgets to set the V-bit :( */
}

void
ospf_update_network_route (struct ospf *ospf,
			   struct route_table *rt, 
                           struct route_table *rtrs,
                           struct summary_lsa *lsa,
                           struct prefix_ipv4 *p,
                           struct ospf_area *area)
{
  struct route_node *rn;
  struct ospf_route *or, *abr_or, *new_or;
  struct prefix_ipv4 abr;
  u_int32_t cost;

  abr.family = AF_INET;
  abr.prefix =lsa->header.adv_router;
  abr.prefixlen = IPV4_MAX_BITLEN;
  apply_mask_ipv4 (&abr);

  abr_or = ospf_find_abr_route (rtrs, &abr, area);

  if (abr_or == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_network_route(): can't find a route to the ABR");
      return;
    }

  cost = abr_or->cost + GET_METRIC (lsa->metric);

  rn = route_node_lookup (rt, (struct prefix *) p);

  if (! rn)
    {
      if (ospf->abr_type != OSPF_ABR_SHORTCUT)
        return; /* Standard ABR can update only already installed
                   backbone paths                                       */
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_network_route(): "
		   "Allowing Shortcut ABR to add new route");
      new_or = ospf_route_new ();
      new_or->type = OSPF_DESTINATION_NETWORK;
      new_or->id = lsa->header.id;
      new_or->mask = lsa->mask;
      new_or->u.std.options = lsa->header.options;
      new_or->u.std.origin = (struct lsa_header *) lsa;
      new_or->cost = cost;
      new_or->u.std.area_id = area->area_id;
      new_or->u.std.external_routing = area->external_routing;
      new_or->path_type = OSPF_PATH_INTER_AREA;
      ospf_route_add (rt, p, new_or, abr_or);

      return;
    }
  else
    {
      route_unlock_node (rn);
      if (rn->info == NULL)
        return;
    }

  or = rn->info;

  if (or->path_type != OSPF_PATH_INTRA_AREA &&
      or->path_type != OSPF_PATH_INTER_AREA)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_network_route(): ERR: path type is wrong");
      return;
    }

  if (ospf->abr_type == OSPF_ABR_SHORTCUT)
    {
      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_update_network_route(): Shortcut: "
		       "this intra-area path is not backbone");
	  return;
	}
    }
  else   /* Not Shortcut ABR */
    {
      if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_update_network_route(): "
		       "route is not BB-associated");
	  return; /* We can update only BB routes */
	}
    }

  if (or->cost < cost)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_network_route(): new route is worse");
      return;
    }

  if (or->cost == cost)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_network_route(): "
		   "new route is same distance, adding nexthops");
      ospf_route_copy_nexthops (or, abr_or->paths);
    }

  if (or->cost > cost)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_network_route(): "
		   "new route is better, overriding nexthops");
      ospf_route_subst_nexthops (or, abr_or->paths);
      or->cost = cost;

      if ((ospf->abr_type == OSPF_ABR_SHORTCUT) &&
	  !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  or->path_type = OSPF_PATH_INTER_AREA;
	  or->u.std.area_id = area->area_id;
	  or->u.std.external_routing = area->external_routing;
          /* Note that we can do this only in Shortcut ABR mode,
             because standard ABR must leave the route type and area
             unchanged
          */
        }
    }
}

void
ospf_update_router_route (struct ospf *ospf,
			  struct route_table *rtrs, 
                          struct summary_lsa *lsa,
                          struct prefix_ipv4 *p,
                          struct ospf_area *area)
{
  struct ospf_route *or, *abr_or, *new_or;
  struct prefix_ipv4 abr;
  u_int32_t cost;

  abr.family = AF_INET;
  abr.prefix = lsa->header.adv_router;
  abr.prefixlen = IPV4_MAX_BITLEN;
  apply_mask_ipv4 (&abr);

  abr_or = ospf_find_abr_route (rtrs, &abr, area);

  if (abr_or == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_update_router_route(): can't find a route to the ABR");
      return;
    }

  cost = abr_or->cost + GET_METRIC (lsa->metric);

  /* First try to find a backbone path,
     because standard ABR can update only BB-associated paths */

  if ((ospf->backbone == NULL) &&
      (ospf->abr_type != OSPF_ABR_SHORTCUT))

     /* no BB area, not Shortcut ABR, exiting */
     return;
 
  or = ospf_find_asbr_route_through_area (rtrs, p, ospf->backbone);

  if (or == NULL)
    {
      if (ospf->abr_type != OSPF_ABR_SHORTCUT)

         /* route to ASBR through the BB not found
            the router is not Shortcut ABR, exiting */

          return;
      else
	/* We're a Shortcut ABR*/
	{
	  /* Let it either add a new router or update the route
	     through the same (non-BB) area. */

	  new_or = ospf_route_new ();
	  new_or->type = OSPF_DESTINATION_ROUTER;
	  new_or->id = lsa->header.id;
	  new_or->mask = lsa->mask;
	  new_or->u.std.options = lsa->header.options;
	  new_or->u.std.origin = (struct lsa_header *)lsa;
	  new_or->cost = cost;
	  new_or->u.std.area_id = area->area_id;
	  new_or->u.std.external_routing = area->external_routing;
	  new_or->path_type = OSPF_PATH_INTER_AREA;
	  new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
	  ospf_ia_router_route (ospf, rtrs, p, new_or, abr_or);

          return;
        }
    }

  /* At this point the "or" is always bb-associated */

  if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_upd_router_route(): the remote router is not an ASBR");
      return;
    }

  if (or->path_type != OSPF_PATH_INTRA_AREA &&
      or->path_type != OSPF_PATH_INTER_AREA)
    return;

  if (or->cost < cost)
    return;

  else if (or->cost == cost)
    ospf_route_copy_nexthops (or, abr_or->paths);

  else if (or->cost > cost)
    {
      ospf_route_subst_nexthops (or, abr_or->paths);
      or->cost = cost;

      /* Even if the ABR runs in Shortcut mode, we can't change
         the path type and area, because the "or" is always bb-associated
         at this point and even Shortcut ABR can't change these attributes */
    }
}

int
process_transit_summary_lsa (struct ospf_area *area, struct route_table *rt,
			     struct route_table *rtrs, struct ospf_lsa *lsa)
{
  struct ospf *ospf = area->ospf;
  struct summary_lsa *sl;
  struct prefix_ipv4 p;
  u_int32_t metric;

  if (lsa == NULL)
    return 0;

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

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("process_transit_summaries(): LS ID: %s",
	       inet_ntoa (lsa->data->id));
  metric = GET_METRIC (sl->metric);
   
  if (metric == OSPF_LS_INFINITY)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("process_transit_summaries(): metric is infinity, skip");
      return 0;
    }

  if (IS_LSA_MAXAGE (lsa))
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("process_transit_summaries(): This LSA is too old");
      return 0;
    }

  if (ospf_lsa_is_self_originated (area->ospf, lsa))
    { 
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("process_transit_summaries(): This LSA is mine, skip");
      return 0;
    }

  p.family = AF_INET;
  p.prefix = sl->header.id;
   
  if (sl->header.type == OSPF_SUMMARY_LSA)
    p.prefixlen = ip_masklen (sl->mask);
  else
    p.prefixlen = IPV4_MAX_BITLEN;
      
  apply_mask_ipv4 (&p);

  if (sl->header.type == OSPF_SUMMARY_LSA)
    ospf_update_network_route (ospf, rt, rtrs, sl, &p, area);
  else
    ospf_update_router_route (ospf, rtrs, sl, &p, area);
 
  return 0;
}

void
ospf_examine_transit_summaries (struct ospf_area *area,
				struct route_table *lsdb_rt,
                                struct route_table *rt,
                                struct route_table *rtrs)
{
  struct ospf_lsa *lsa;
  struct route_node *rn;

  LSDB_LOOP (lsdb_rt, rn, lsa)
    process_transit_summary_lsa (area, rt, rtrs, lsa);
}

void
ospf_ia_routing (struct ospf *ospf,
		 struct route_table *rt,
                 struct route_table *rtrs)
{
  struct ospf_area * area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_ia_routing():start");

  if (IS_OSPF_ABR (ospf))
    {
      listnode node; 
      struct ospf_area *area;

      switch (ospf->abr_type)
        {
        case OSPF_ABR_STAND:
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_ia_routing():Standard ABR");

          if ((area = ospf->backbone))
            {
              listnode node;

	      if (IS_DEBUG_OSPF_EVENT)
		{
		  zlog_info ("ospf_ia_routing():backbone area found");
		  zlog_info ("ospf_ia_routing():examining summaries");
		}

              OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);

	      for (node = listhead (ospf->areas); node; nextnode (node))
                if ((area = getdata (node)) != NULL)
                  if (area != ospf->backbone)
		    if (ospf_area_is_transit (area))
		      OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs);
            }
          else
	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_info ("ospf_ia_routing():backbone area NOT found");
          break;
        case OSPF_ABR_IBM:
        case OSPF_ABR_CISCO:
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_ia_routing():Alternative Cisco/IBM ABR");
          area = ospf->backbone; /* Find the BB */

          /* If we have an active BB connection */
          if (area && ospf_act_bb_connection (ospf))
            {
	      if (IS_DEBUG_OSPF_EVENT)
		{
		  zlog_info ("ospf_ia_routing(): backbone area found");
		  zlog_info ("ospf_ia_routing(): examining BB summaries");
		}

              OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);

	      for (node = listhead (ospf->areas); node; nextnode (node))
                if ((area = getdata (node)) != NULL)
                  if (area != ospf->backbone)
		    if (ospf_area_is_transit (area))
		      OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs);
            }
          else
            { /* No active BB connection--consider all areas */
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_ia_routing(): "
			   "Active BB connection not found");
	      for (node = listhead (ospf->areas); node; nextnode (node))
                if ((area = getdata (node)) != NULL)
                  OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
            }
          break;
        case OSPF_ABR_SHORTCUT:
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_ia_routing():Alternative Shortcut");
          area = ospf->backbone; /* Find the BB */

          /* If we have an active BB connection */
          if (area && ospf_act_bb_connection (ospf))
            {
	      if (IS_DEBUG_OSPF_EVENT)
		{
		  zlog_info ("ospf_ia_routing(): backbone area found");
		  zlog_info ("ospf_ia_routing(): examining BB summaries");
		}
              OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
            }

	  for (node = listhead (ospf->areas); node; nextnode (node))
            if ((area = getdata (node)) != NULL)
              if (area != ospf->backbone)
		if (ospf_area_is_transit (area) ||
		    ((area->shortcut_configured != OSPF_SHORTCUT_DISABLE) &&
		     ((ospf->backbone == NULL) ||
                      ((area->shortcut_configured == OSPF_SHORTCUT_ENABLE) &&
		       area->shortcut_capability))))
		  OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs);
          break;
        default:
          break;
        }
    }
  else 
    {
      listnode node;

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_ia_routing():not ABR, considering all areas");

      for (node = listhead (ospf->areas); node; nextnode (node))
        if ((area = getdata (node)) != NULL)
          OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
    }
}
