/*
 * OSPF Neighbor functions.
 * Copyright (C) 1999, 2000 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 "linklist.h"
#include "prefix.h"
#include "memory.h"
#include "command.h"
#include "thread.h"
#include "stream.h"
#include "table.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_nsm.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_dump.h"

/* Fill in the the 'key' as appropriate to retrieve the entry for nbr
 * from the ospf_interface's nbrs table. Indexed by interface address
 * for all cases except Virtual-link and PointToPoint interfaces, where
 * neighbours are indexed by router-ID instead.
 */
static void
ospf_nbr_key (struct ospf_interface *oi, struct ospf_neighbor *nbr,
              struct prefix *key)
{
  key->family = AF_INET;
  key->prefixlen = IPV4_MAX_BITLEN;

  /* vlinks are indexed by router-id */
  if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
      oi->type == OSPF_IFTYPE_POINTOPOINT)
    key->u.prefix4 = nbr->router_id;
  else
    key->u.prefix4 = nbr->src;
  return;
}

struct ospf_neighbor *
ospf_nbr_new (struct ospf_interface *oi)
{
  struct ospf_neighbor *nbr;

  /* Allcate new neighbor. */
  nbr = XCALLOC (MTYPE_OSPF_NEIGHBOR, sizeof (struct ospf_neighbor));

  /* Relate neighbor to the interface. */
  nbr->oi = oi;

  /* Set default values. */
  nbr->state = NSM_Down;

  /* Set inheritance values. */
  nbr->v_inactivity = OSPF_IF_PARAM (oi, v_wait);
  nbr->v_db_desc = OSPF_IF_PARAM (oi, retransmit_interval);
  nbr->v_ls_req = OSPF_IF_PARAM (oi, retransmit_interval);
  nbr->v_ls_upd = OSPF_IF_PARAM (oi, retransmit_interval);
  nbr->priority = -1;

  /* DD flags. */
  nbr->dd_flags = OSPF_DD_FLAG_MS|OSPF_DD_FLAG_M|OSPF_DD_FLAG_I;

  /* Last received and sent DD. */
  nbr->last_send = NULL;

  nbr->nbr_nbma = NULL;

  ospf_lsdb_init (&nbr->db_sum);
  ospf_lsdb_init (&nbr->ls_rxmt);
  ospf_lsdb_init (&nbr->ls_req);

  nbr->crypt_seqnum = 0;

  return nbr;
}

void
ospf_nbr_free (struct ospf_neighbor *nbr)
{
  /* Free DB summary list. */
  if (ospf_db_summary_count (nbr))
    ospf_db_summary_clear (nbr);
    /* ospf_db_summary_delete_all (nbr); */

  /* Free ls request list. */
  if (ospf_ls_request_count (nbr))
    ospf_ls_request_delete_all (nbr);

  /* Free retransmit list. */
  if (ospf_ls_retransmit_count (nbr))
    ospf_ls_retransmit_clear (nbr);

  /* Cleanup LSDBs. */
  ospf_lsdb_cleanup (&nbr->db_sum);
  ospf_lsdb_cleanup (&nbr->ls_req);
  ospf_lsdb_cleanup (&nbr->ls_rxmt);
  
  /* Clear last send packet. */
  if (nbr->last_send)
    ospf_packet_free (nbr->last_send);

  if (nbr->nbr_nbma)
    {
      nbr->nbr_nbma->nbr = NULL;
      nbr->nbr_nbma = NULL;
    }

  /* Cancel all timers. */
  OSPF_NSM_TIMER_OFF (nbr->t_inactivity);
  OSPF_NSM_TIMER_OFF (nbr->t_db_desc);
  OSPF_NSM_TIMER_OFF (nbr->t_ls_req);
  OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);

  /* Cancel all events. *//* Thread lookup cost would be negligible. */
  thread_cancel_event (master, nbr);

  XFREE (MTYPE_OSPF_NEIGHBOR, nbr);
}

/* Delete specified OSPF neighbor from interface. */
void
ospf_nbr_delete (struct ospf_neighbor *nbr)
{
  struct ospf_interface *oi;
  struct route_node *rn;
  struct prefix p;

  oi = nbr->oi;
  
  /* get appropriate prefix 'key' */
  ospf_nbr_key (oi, nbr, &p);

  rn = route_node_lookup (oi->nbrs, &p);
  if (rn)
    {
      /* If lookup for a NBR succeeds, the leaf route_node could
       * only exist because there is (or was) a nbr there.
       * If the nbr was deleted, the leaf route_node should have
       * lost its last refcount too, and be deleted.
       * Therefore a looked-up leaf route_node in nbrs table
       * should never have NULL info.
       */
      assert (rn->info);
      
      if (rn->info)
	{
	  rn->info = NULL;
	  route_unlock_node (rn);
	}
      else
	zlog_info ("Can't find neighbor %s in the interface %s",
		   inet_ntoa (nbr->src), IF_NAME (oi));

      route_unlock_node (rn);
    }

  /* Free ospf_neighbor structure. */
  ospf_nbr_free (nbr);
}

/* Check myself is in the neighbor list. */
int
ospf_nbr_bidirectional (struct in_addr *router_id,
			struct in_addr *neighbors, int size)
{
  int i;
  int max;

  max = size / sizeof (struct in_addr);

  for (i = 0; i < max; i ++)
    if (IPV4_ADDR_SAME (router_id, &neighbors[i]))
      return 1;

  return 0;
}

/* reset nbr_self */
void
ospf_nbr_self_reset (struct ospf_interface *oi)
{
  ospf_nbr_delete (oi->nbr_self);
  oi->nbr_self = ospf_nbr_new (oi);
  ospf_nbr_add_self (oi);
}

/* Add self to nbr list. */
void
ospf_nbr_add_self (struct ospf_interface *oi)
{
  struct prefix p;
  struct route_node *rn;

  /* Initial state */
  oi->nbr_self->address = *oi->address;
  oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
  oi->nbr_self->router_id = oi->ospf->router_id;
  oi->nbr_self->src = oi->address->u.prefix4;
  oi->nbr_self->state = NSM_TwoWay;
  
  switch (oi->area->external_routing)
    {
      case OSPF_AREA_DEFAULT:
        SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
        break;
      case OSPF_AREA_STUB:
        UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
        break;
      case OSPF_AREA_NSSA:
        UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
        SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
        break;
    }
  
  /* Add nbr_self to nbrs table */
  ospf_nbr_key (oi, oi->nbr_self, &p);
  
  rn = route_node_get (oi->nbrs, &p);
  if (rn->info)
    {
      /* There is already pseudo neighbor. */
      assert (oi->nbr_self == rn->info);
      route_unlock_node (rn);
    }
  else
    rn->info = oi->nbr_self;
}

/* Get neighbor count by status.
   Specify status = 0, get all neighbor other than myself. */
int
ospf_nbr_count (struct ospf_interface *oi, int state)
{
  struct ospf_neighbor *nbr;
  struct route_node *rn;
  int count = 0;

  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info))
      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
	if (state == 0 || nbr->state == state)
	  count++;

  return count;
}

#ifdef HAVE_OPAQUE_LSA
int
ospf_nbr_count_opaque_capable (struct ospf_interface *oi)
{
  struct ospf_neighbor *nbr;
  struct route_node *rn;
  int count = 0;

  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info))
      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
	if (nbr->state == NSM_Full)
	  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
	    count++;

  return count;
}
#endif /* HAVE_OPAQUE_LSA */

/* lookup nbr by address - use this only if you know you must
 * otherwise use the ospf_nbr_lookup() wrapper, which deals
 * with virtual link and PointToPoint neighbours
 */
struct ospf_neighbor *
ospf_nbr_lookup_by_addr (struct route_table *nbrs,
			 struct in_addr *addr)
{
  struct prefix p;
  struct route_node *rn;
  struct ospf_neighbor *nbr;

  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_BITLEN;
  p.u.prefix4 = *addr;

  rn = route_node_lookup (nbrs, &p);
  if (! rn)
    return NULL;
  
  /* See comment in ospf_nbr_delete */
  assert (rn->info);

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

  nbr = (struct ospf_neighbor *) rn->info;
  route_unlock_node (rn);

  return nbr;
}

struct ospf_neighbor *
ospf_nbr_lookup_by_routerid (struct route_table *nbrs,
			     struct in_addr *id)
{
  struct route_node *rn;
  struct ospf_neighbor *nbr;

  for (rn = route_top (nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info) != NULL)
      if (IPV4_ADDR_SAME (&nbr->router_id, id))
	{
	  route_unlock_node(rn);
	  return nbr;
	}

  return NULL;
}

void
ospf_renegotiate_optional_capabilities (struct ospf *top)
{
  struct listnode *node;
  struct ospf_interface *oi;
  struct route_table *nbrs;
  struct route_node *rn;
  struct ospf_neighbor *nbr;

  /* At first, flush self-originated LSAs from routing domain. */
  ospf_flush_self_originated_lsas_now (top);

  /* Revert all neighbor status to ExStart. */
  for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi))
    {
      if ((nbrs = oi->nbrs) == NULL)
        continue;

      for (rn = route_top (nbrs); rn; rn = route_next (rn))
        {
          if ((nbr = rn->info) == NULL || nbr == oi->nbr_self)
            continue;

          if (nbr->state < NSM_ExStart)
            continue;

          if (IS_DEBUG_OSPF_EVENT)
            zlog_debug ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr->router_id));

          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
        }
    }

  return;
}


struct ospf_neighbor *
ospf_nbr_lookup (struct ospf_interface *oi, struct ip *iph,
                 struct ospf_header *ospfh)
{
  if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
      oi->type == OSPF_IFTYPE_POINTOPOINT)
    return (ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id));
  else
    return (ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src));
}

static struct ospf_neighbor *
ospf_nbr_add (struct ospf_interface *oi, struct ospf_header *ospfh,
              struct prefix *p)
{
  struct ospf_neighbor *nbr;
  
  nbr = ospf_nbr_new (oi);
  nbr->state = NSM_Down;
  nbr->src = p->u.prefix4;
  memcpy (&nbr->address, p, sizeof (struct prefix));

  nbr->nbr_nbma = NULL;
  if (oi->type == OSPF_IFTYPE_NBMA)
    {
      struct ospf_nbr_nbma *nbr_nbma;
      struct listnode *node;

      for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, node, nbr_nbma))
        {
          if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src))
            {
              nbr_nbma->nbr = nbr;
              nbr->nbr_nbma = nbr_nbma;

              if (nbr_nbma->t_poll)
                OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);

              nbr->state_change = nbr_nbma->state_change + 1;
            }
        }
    }
      
  /* New nbr, save the crypto sequence number if necessary */
  if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
    nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
  
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
               inet_ntoa (nbr->router_id));
  
  return nbr;
}

struct ospf_neighbor *
ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh,
              struct ip *iph, struct prefix *p)
{
  struct route_node *rn;
  struct prefix key;
  struct ospf_neighbor *nbr;
  
  key.family = AF_INET;
  key.prefixlen = IPV4_MAX_BITLEN;

  if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
      oi->type == OSPF_IFTYPE_POINTOPOINT)
    key.u.prefix4 = ospfh->router_id;/* index vlink and ptp nbrs by router-id */
  else
    key.u.prefix4 = iph->ip_src;

  rn = route_node_get (oi->nbrs, &key);
  if (rn->info)
    {
      route_unlock_node (rn);
      nbr = rn->info;
      
      if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt)
        {
          nbr->src = iph->ip_src;
          memcpy (&nbr->address, p, sizeof (struct prefix));
        }
    }
  else
    {
      rn->info = nbr = ospf_nbr_add (oi, ospfh, p);
    }
  
  nbr->router_id = ospfh->router_id;

  return nbr;
}
