/*
 * IS-IS Rout(e)ing protocol               - isis_route.c
 * Copyright (C) 2001,2002   Sampo Saaristo
 *                           Tampere University of Technology      
 *                           Institute of Communications Engineering
 *
 *                                         based on ../ospf6d/ospf6_route.[ch]
 *                                         by Yasuhiro Ohara
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public Licenseas published by the Free 
 * Software Foundation; either version 2 of the License, or (at your option) 
 * any later version.
 *
 * This program 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 this program; 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 "linklist.h"
#include "vty.h"
#include "log.h"
#include "memory.h"
#include "prefix.h"
#include "hash.h"
#include "if.h"
#include "table.h"

#include "isis_constants.h"
#include "isis_common.h"
#include "isis_flags.h"
#include "dict.h"
#include "isisd.h"
#include "isis_misc.h"
#include "isis_adjacency.h"
#include "isis_circuit.h"
#include "isis_tlv.h"
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_spf.h"
#include "isis_route.h"
#include "isis_zebra.h"

static struct isis_nexthop *
isis_nexthop_create (struct in_addr *ip, ifindex_t ifindex)
{
  struct listnode *node;
  struct isis_nexthop *nexthop;

  for (ALL_LIST_ELEMENTS_RO (isis->nexthops, node, nexthop))
    {
      if (nexthop->ifindex != ifindex)
	continue;
      if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0)
	continue;

      nexthop->lock++;
      return nexthop;
    }

  nexthop = XCALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop));

  nexthop->ifindex = ifindex;
  memcpy (&nexthop->ip, ip, sizeof (struct in_addr));
  listnode_add (isis->nexthops, nexthop);
  nexthop->lock++;

  return nexthop;
}

static void
isis_nexthop_delete (struct isis_nexthop *nexthop)
{
  nexthop->lock--;
  if (nexthop->lock == 0)
    {
      listnode_delete (isis->nexthops, nexthop);
      XFREE (MTYPE_ISIS_NEXTHOP, nexthop);
    }

  return;
}

static int
nexthoplookup (struct list *nexthops, struct in_addr *ip,
	       ifindex_t ifindex)
{
  struct listnode *node;
  struct isis_nexthop *nh;

  for (ALL_LIST_ELEMENTS_RO (nexthops, node, nh))
    {
      if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) &&
	  ifindex == nh->ifindex)
	return 1;
    }

  return 0;
}

#ifdef EXTREME_DEBUG
static void
nexthop_print (struct isis_nexthop *nh)
{
  u_char buf[BUFSIZ];

  inet_ntop (AF_INET, &nh->ip, (char *) buf, BUFSIZ);

  zlog_debug ("      %s %u", buf, nh->ifindex);
}

static void
nexthops_print (struct list *nhs)
{
  struct listnode *node;
  struct isis_nexthop *nh;

  for (ALL_LIST_ELEMENTS_RO (nhs, node, nh))
    nexthop_print (nh);
}
#endif /* EXTREME_DEBUG */

#ifdef HAVE_IPV6
static struct isis_nexthop6 *
isis_nexthop6_new (struct in6_addr *ip6, ifindex_t ifindex)
{
  struct isis_nexthop6 *nexthop6;

  nexthop6 = XCALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6));

  nexthop6->ifindex = ifindex;
  memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr));
  nexthop6->lock++;

  return nexthop6;
}

static struct isis_nexthop6 *
isis_nexthop6_create (struct in6_addr *ip6, ifindex_t ifindex)
{
  struct listnode *node;
  struct isis_nexthop6 *nexthop6;

  for (ALL_LIST_ELEMENTS_RO (isis->nexthops6, node, nexthop6))
    {
      if (nexthop6->ifindex != ifindex)
	continue;
      if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0)
	continue;

      nexthop6->lock++;
      return nexthop6;
    }

  nexthop6 = isis_nexthop6_new (ip6, ifindex);

  return nexthop6;
}

static void
isis_nexthop6_delete (struct isis_nexthop6 *nexthop6)
{

  nexthop6->lock--;
  if (nexthop6->lock == 0)
    {
      listnode_delete (isis->nexthops6, nexthop6);
      XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6);
    }

  return;
}

static int
nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
		ifindex_t ifindex)
{
  struct listnode *node;
  struct isis_nexthop6 *nh6;

  for (ALL_LIST_ELEMENTS_RO (nexthops6, node, nh6))
    {
      if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) &&
	  ifindex == nh6->ifindex)
	return 1;
    }

  return 0;
}

#ifdef EXTREME_DEBUG
static void
nexthop6_print (struct isis_nexthop6 *nh6)
{
  u_char buf[BUFSIZ];

  inet_ntop (AF_INET6, &nh6->ip6, (char *) buf, BUFSIZ);

  zlog_debug ("      %s %u", buf, nh6->ifindex);
}

static void
nexthops6_print (struct list *nhs6)
{
  struct listnode *node;
  struct isis_nexthop6 *nh6;

  for (ALL_LIST_ELEMENTS_RO (nhs6, node, nh6))
    nexthop6_print (nh6);
}
#endif /* EXTREME_DEBUG */
#endif /* HAVE_IPV6 */

static void
adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
{
  struct isis_nexthop *nh;
  struct listnode *node;
  struct in_addr *ipv4_addr;

  if (adj->ipv4_addrs == NULL)
    return;

  for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
    {
      if (!nexthoplookup (nexthops, ipv4_addr,
			  adj->circuit->interface->ifindex))
	{
	  nh = isis_nexthop_create (ipv4_addr,
				    adj->circuit->interface->ifindex);
          nh->router_address = adj->router_address;
	  listnode_add (nexthops, nh);
	}
    }
}

#ifdef HAVE_IPV6
static void
adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
{
  struct listnode *node;
  struct in6_addr *ipv6_addr;
  struct isis_nexthop6 *nh6;

  if (!adj->ipv6_addrs)
    return;

  for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
    {
      if (!nexthop6lookup (nexthops6, ipv6_addr,
			   adj->circuit->interface->ifindex))
	{
	  nh6 = isis_nexthop6_create (ipv6_addr,
				      adj->circuit->interface->ifindex);
          nh6->router_address6 = adj->router_address6;
	  listnode_add (nexthops6, nh6);
	}
    }
}
#endif /* HAVE_IPV6 */

static struct isis_route_info *
isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth,
                     struct list *adjacencies)
{
  struct isis_route_info *rinfo;
  struct isis_adjacency *adj;
  struct listnode *node;

  rinfo = XCALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info));

  if (prefix->family == AF_INET)
    {
      rinfo->nexthops = list_new ();
      for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj))
        {
          /* check for force resync this route */
          if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
            SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
          /* update neighbor router address */
          if (depth == 2 && prefix->prefixlen == 32)
            adj->router_address = prefix->u.prefix4;
          adjinfo2nexthop (rinfo->nexthops, adj);
        }
    }
#ifdef HAVE_IPV6
  if (prefix->family == AF_INET6)
    {
      rinfo->nexthops6 = list_new ();
      for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj))
        {
          /* check for force resync this route */
          if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
            SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
          /* update neighbor router address */
          if (depth == 2 && prefix->prefixlen == 128)
            adj->router_address6 = prefix->u.prefix6;
          adjinfo2nexthop6 (rinfo->nexthops6, adj);
        }
    }

#endif /* HAVE_IPV6 */

  rinfo->cost = cost;
  rinfo->depth = depth;

  return rinfo;
}

static void
isis_route_info_delete (struct isis_route_info *route_info)
{
  if (route_info->nexthops)
    {
      route_info->nexthops->del = (void (*)(void *)) isis_nexthop_delete;
      list_delete (route_info->nexthops);
    }

#ifdef HAVE_IPV6
  if (route_info->nexthops6)
    {
      route_info->nexthops6->del = (void (*)(void *)) isis_nexthop6_delete;
      list_delete (route_info->nexthops6);
    }
#endif /* HAVE_IPV6 */

  XFREE (MTYPE_ISIS_ROUTE_INFO, route_info);
}

static int
isis_route_info_same_attrib (struct isis_route_info *new,
			     struct isis_route_info *old)
{
  if (new->cost != old->cost)
    return 0;
  if (new->depth != old->depth)
    return 0;

  return 1;
}

static int
isis_route_info_same (struct isis_route_info *new,
		      struct isis_route_info *old, u_char family)
{
  struct listnode *node;
  struct isis_nexthop *nexthop;
#ifdef HAVE_IPV6
  struct isis_nexthop6 *nexthop6;
#endif /* HAVE_IPV6 */

  if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
    return 0;

  if (CHECK_FLAG (new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC))
    return 0;

  if (!isis_route_info_same_attrib (new, old))
    return 0;

  if (family == AF_INET)
    {
      for (ALL_LIST_ELEMENTS_RO (new->nexthops, node, nexthop))
        if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex)
              == 0)
          return 0;

      for (ALL_LIST_ELEMENTS_RO (old->nexthops, node, nexthop))
        if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex)
             == 0)
          return 0;
    }
#ifdef HAVE_IPV6
  else if (family == AF_INET6)
    {
      for (ALL_LIST_ELEMENTS_RO (new->nexthops6, node, nexthop6))
        if (nexthop6lookup (old->nexthops6, &nexthop6->ip6,
                            nexthop6->ifindex) == 0)
          return 0;

      for (ALL_LIST_ELEMENTS_RO (old->nexthops6, node, nexthop6))
        if (nexthop6lookup (new->nexthops6, &nexthop6->ip6,
                            nexthop6->ifindex) == 0)
          return 0;
    }
#endif /* HAVE_IPV6 */

  return 1;
}

struct isis_route_info *
isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
		   struct list *adjacencies, struct isis_area *area,
		   int level)
{
  struct route_node *route_node;
  struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
  u_char buff[BUFSIZ];
  u_char family;

  family = prefix->family;
  /* for debugs */
  prefix2str (prefix, (char *) buff, BUFSIZ);

  rinfo_new = isis_route_info_new (prefix, cost, depth, adjacencies);

  if (family == AF_INET)
    route_node = route_node_get (area->route_table[level - 1], prefix);
#ifdef HAVE_IPV6
  else if (family == AF_INET6)
    route_node = route_node_get (area->route_table6[level - 1], prefix);
#endif /* HAVE_IPV6 */
  else
    {
      isis_route_info_delete (rinfo_new);
      return NULL;
    }

  rinfo_old = route_node->info;
  if (!rinfo_old)
    {
      if (isis->debugs & DEBUG_RTE_EVENTS)
        zlog_debug ("ISIS-Rte (%s) route created: %s", area->area_tag, buff);
      route_info = rinfo_new;
      UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
    }
  else
    {
      if (isis->debugs & DEBUG_RTE_EVENTS)
        zlog_debug ("ISIS-Rte (%s) route already exists: %s", area->area_tag,
                   buff);
      if (isis_route_info_same (rinfo_new, rinfo_old, family))
        {
          if (isis->debugs & DEBUG_RTE_EVENTS)
            zlog_debug ("ISIS-Rte (%s) route unchanged: %s", area->area_tag,
                        buff);
          isis_route_info_delete (rinfo_new);
          route_info = rinfo_old;
        }
      else
        {
          if (isis->debugs & DEBUG_RTE_EVENTS)
            zlog_debug ("ISIS-Rte (%s) route changed: %s", area->area_tag,
                        buff);
          isis_route_info_delete (rinfo_old);
          route_info = rinfo_new;
          UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
        }
    }

  SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE);
  route_node->info = route_info;

  return route_info;
}

static void
isis_route_delete (struct prefix *prefix, struct route_table *table)
{
  struct route_node *rode;
  struct isis_route_info *rinfo;
  char buff[BUFSIZ];

  /* for log */
  prefix2str (prefix, buff, BUFSIZ);


  rode = route_node_get (table, prefix);
  rinfo = rode->info;

  if (rinfo == NULL)
    {
      if (isis->debugs & DEBUG_RTE_EVENTS)
	zlog_debug ("ISIS-Rte: tried to delete non-existant route %s", buff);
      return;
    }

  if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
    {
      UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
      if (isis->debugs & DEBUG_RTE_EVENTS)
	zlog_debug ("ISIS-Rte: route delete  %s", buff);
      isis_zebra_route_update (prefix, rinfo);
    }
  isis_route_info_delete (rinfo);
  rode->info = NULL;

  return;
}

/* Validating routes in particular table. */
static void
isis_route_validate_table (struct isis_area *area, struct route_table *table)
{
  struct route_node *rnode, *drnode;
  struct isis_route_info *rinfo;
  u_char buff[BUFSIZ];

  for (rnode = route_top (table); rnode; rnode = route_next (rnode))
    {
      if (rnode->info == NULL)
	continue;
      rinfo = rnode->info;

      if (isis->debugs & DEBUG_RTE_EVENTS)
	{
	  prefix2str (&rnode->p, (char *) buff, BUFSIZ);
	  zlog_debug ("ISIS-Rte (%s): route validate: %s %s %s %s",
		      area->area_tag,
		      (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED) ?
		      "synced" : "not-synced"),
		      (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC) ?
		      "resync" : "not-resync"),
		      (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ?
		      "active" : "inactive"), buff);
	}

      isis_zebra_route_update (&rnode->p, rinfo);
      if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
	{
	  /* Area is either L1 or L2 => we use level route tables directly for
	   * validating => no problems with deleting routes. */
	  if (area->is_type != IS_LEVEL_1_AND_2)
	    {
	      isis_route_delete (&rnode->p, table);
	      continue;
	    }
	  /* If area is L1L2, we work with merge table and therefore must
	   * delete node from level tables as well before deleting route info.
	   * FIXME: Is it performance problem? There has to be the better way.
	   * Like not to deal with it here at all (see the next comment)? */
	  if (rnode->p.family == AF_INET)
	    {
	      drnode = route_node_get (area->route_table[0], &rnode->p);
	      if (drnode->info == rnode->info)
		drnode->info = NULL;
	      drnode = route_node_get (area->route_table[1], &rnode->p);
	      if (drnode->info == rnode->info)
		drnode->info = NULL;
	    }

#ifdef HAVE_IPV6
	  if (rnode->p.family == AF_INET6)
	    {
	      drnode = route_node_get (area->route_table6[0], &rnode->p);
	      if (drnode->info == rnode->info)
		drnode->info = NULL;
	      drnode = route_node_get (area->route_table6[1], &rnode->p);
	      if (drnode->info == rnode->info)
		drnode->info = NULL;
	    }
#endif
	      
	  isis_route_delete (&rnode->p, table);
	}
    }
}

/* Function to validate route tables for L1L2 areas. In this case we can't use
 * level route tables directly, we have to merge them at first. L1 routes are
 * preferred over the L2 ones.
 *
 * Merge algorithm is trivial (at least for now). All L1 paths are copied into
 * merge table at first, then L2 paths are added if L1 path for same prefix
 * doesn't already exists there.
 *
 * FIXME: Is it right place to do it at all? Maybe we should push both levels
 * to the RIB with different zebra route types and let RIB handle this? */
static void
isis_route_validate_merge (struct isis_area *area, int family)
{
  struct route_table *table = NULL;
  struct route_table *merge;
  struct route_node *rnode, *mrnode;

  merge = route_table_init ();

  if (family == AF_INET)
    table = area->route_table[0];
#ifdef HAVE_IPV6
  else if (family == AF_INET6)
    table = area->route_table6[0];
#endif

  for (rnode = route_top (table); rnode; rnode = route_next (rnode))
    {
      if (rnode->info == NULL)
        continue;
      mrnode = route_node_get (merge, &rnode->p);
      mrnode->info = rnode->info;
    }

  if (family == AF_INET)
    table = area->route_table[1];
#ifdef HAVE_IPV6
  else if (family == AF_INET6)
    table = area->route_table6[1];
#endif

  for (rnode = route_top (table); rnode; rnode = route_next (rnode))
    {
      if (rnode->info == NULL)
        continue;
      mrnode = route_node_get (merge, &rnode->p);
      if (mrnode->info != NULL)
        continue;
      mrnode->info = rnode->info;
    }

  isis_route_validate_table (area, merge);
  route_table_finish (merge);
}

/* Walk through route tables and propagate necessary changes into RIB. In case
 * of L1L2 area, level tables have to be merged at first. */
void
isis_route_validate (struct isis_area *area)
{
  struct listnode *node;
  struct isis_circuit *circuit;

  if (area->is_type == IS_LEVEL_1)
    isis_route_validate_table (area, area->route_table[0]);
  else if (area->is_type == IS_LEVEL_2)
    isis_route_validate_table (area, area->route_table[1]);
  else
    isis_route_validate_merge (area, AF_INET);

#ifdef HAVE_IPV6
  if (area->is_type == IS_LEVEL_1)
    isis_route_validate_table (area, area->route_table6[0]);
  else if (area->is_type == IS_LEVEL_2)
    isis_route_validate_table (area, area->route_table6[1]);
  else
    isis_route_validate_merge (area, AF_INET6);
#endif

  if (!area->circuit_list) {
    return;
  }
  /* walk all circuits and reset any spf specific flags */
  for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
    UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);

  return;
}

void
isis_route_invalidate_table (struct isis_area *area, struct route_table *table)
{
  struct route_node *rode;
  struct isis_route_info *rinfo;
  for (rode = route_top (table); rode; rode = route_next (rode))
    {
      if (rode->info == NULL)
        continue;
      rinfo = rode->info;

      UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
    }
}

void
isis_route_invalidate (struct isis_area *area)
{
  if (area->is_type & IS_LEVEL_1)
    isis_route_invalidate_table (area, area->route_table[0]);
  if (area->is_type & IS_LEVEL_2)
    isis_route_invalidate_table (area, area->route_table[1]);
}
