/*
 * OSPF AS Boundary Router functions.
 * Copyright (C) 1999, 2000 Kunihiro Ishiguro, 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 "log.h"

#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"


/* Remove external route. */
void
ospf_external_route_remove (struct ospf *ospf, struct prefix_ipv4 *p)
{
  struct route_node *rn;
  struct ospf_route *or;

  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p);
  if (rn)
    if ((or = rn->info))
      {
	zlog_info ("Route[%s/%d]: external path deleted",
		   inet_ntoa (p->prefix), p->prefixlen);

	/* Remove route from zebra. */
        if (or->type == OSPF_DESTINATION_NETWORK)
	  ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or);

	ospf_route_free (or);
	rn->info = NULL;

	route_unlock_node (rn);
	route_unlock_node (rn);
	return;
      }

  zlog_info ("Route[%s/%d]: no such external path",
	     inet_ntoa (p->prefix), p->prefixlen);
}

/* Lookup external route. */
struct ospf_route *
ospf_external_route_lookup (struct ospf *ospf,
			    struct prefix_ipv4 *p)
{
  struct route_node *rn;

  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p);
  if (rn)
    {
      route_unlock_node (rn);
      if (rn->info)
	return rn->info;
    }

  zlog_warn ("Route[%s/%d]: lookup, no such prefix",
	     inet_ntoa (p->prefix), p->prefixlen);

  return NULL;
}


/* Add an External info for AS-external-LSA. */
struct external_info *
ospf_external_info_new (u_char type)
{
  struct external_info *new;

  new = (struct external_info *)
    XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info));
  new->type = type;

  ospf_reset_route_map_set_values (&new->route_map_set);
  return new;
}

static void
ospf_external_info_free (struct external_info *ei)
{
  XFREE (MTYPE_OSPF_EXTERNAL_INFO, ei);
}

void
ospf_reset_route_map_set_values (struct route_map_set_values *values)
{
  values->metric = -1;
  values->metric_type = -1;
}

int
ospf_route_map_set_compare (struct route_map_set_values *values1,
			    struct route_map_set_values *values2)
{
  return values1->metric == values2->metric &&
    values1->metric_type == values2->metric_type;
}

/* Add an External info for AS-external-LSA. */
struct external_info *
ospf_external_info_add (u_char type, struct prefix_ipv4 p,
			unsigned int ifindex, struct in_addr nexthop)
{
  struct external_info *new;
  struct route_node *rn;

  /* Initialize route table. */
  if (EXTERNAL_INFO (type) == NULL)
    EXTERNAL_INFO (type) = route_table_init ();

  rn = route_node_get (EXTERNAL_INFO (type), (struct prefix *) &p);
  /* If old info exists, -- discard new one or overwrite with new one? */
  if (rn)
    if (rn->info)
      {
	route_unlock_node (rn);
	zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
		   ospf_redist_string(type),
		   inet_ntoa (p.prefix), p.prefixlen);
	/* XFREE (MTYPE_OSPF_TMP, rn->info); */
	return rn->info;
      }

  /* Create new External info instance. */
  new = ospf_external_info_new (type);
  new->p = p;
  new->ifindex = ifindex;
  new->nexthop = nexthop;
  new->tag = 0;

  if (rn)
    rn->info = new;

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    zlog_debug ("Redistribute[%s]: %s/%d external info created.",
	       ospf_redist_string(type),
	       inet_ntoa (p.prefix), p.prefixlen);
  return new;
}

void
ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
{
  struct route_node *rn;

  rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
  if (rn)
    {
      ospf_external_info_free (rn->info);
      rn->info = NULL;
      route_unlock_node (rn);
      route_unlock_node (rn);
    }
}

struct external_info *
ospf_external_info_lookup (u_char type, struct prefix_ipv4 *p)
{
  struct route_node *rn;
  rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) p);
  if (rn)
    {
      route_unlock_node (rn);
      if (rn->info)
	return rn->info;
    }

  return NULL;
}

struct ospf_lsa *
ospf_external_info_find_lsa (struct ospf *ospf,
			     struct prefix_ipv4 *p)
{
  struct ospf_lsa *lsa;
  struct as_external_lsa *al;
  struct in_addr mask, id;

  lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
				p->prefix, ospf->router_id);

  if (!lsa)
    return NULL;

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

  masklen2ip (p->prefixlen, &mask);

  if (mask.s_addr != al->mask.s_addr)
    {
      id.s_addr = p->prefix.s_addr | (~mask.s_addr);
      lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
				   id, ospf->router_id);
      if (!lsa)
	return NULL;
    }

  return lsa;
}


/* Update ASBR status. */
void
ospf_asbr_status_update (struct ospf *ospf, u_char status)
{
  zlog_info ("ASBR[Status:%d]: Update", status);

  /* ASBR on. */
  if (status)
    {
      /* Already ASBR. */
      if (IS_OSPF_ASBR (ospf))
	{
	  zlog_info ("ASBR[Status:%d]: Already ASBR", status);
	  return;
	}
      SET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
    }
  else
    {
      /* Already non ASBR. */
      if (! IS_OSPF_ASBR (ospf))
	{
	  zlog_info ("ASBR[Status:%d]: Already non ASBR", status);
	  return;
	}
      UNSET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
    }

  /* Transition from/to status ASBR, schedule timer. */
  ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_STATUS_CHANGE);
  ospf_router_lsa_update (ospf);
}

void
ospf_redistribute_withdraw (struct ospf *ospf, u_char type)
{
  struct route_node *rn;
  struct external_info *ei;

  /* Delete external info for specified type. */
  if (EXTERNAL_INFO (type))
    for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
      if ((ei = rn->info))
	if (ospf_external_info_find_lsa (ospf, &ei->p))
	  {
	    if (is_prefix_default (&ei->p) &&
		ospf->default_originate != DEFAULT_ORIGINATE_NONE)
	      continue;
	    ospf_external_lsa_flush (ospf, type, &ei->p,
				     ei->ifindex /*, ei->nexthop */);

	    ospf_external_info_free (ei);
	    route_unlock_node (rn);
	    rn->info = NULL;
	  }
}
