/*
 * OSPF Interface 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 "thread.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "memory.h"
#include "command.h"
#include "stream.h"
#include "log.h"

#include "ospfd/ospfd.h"
#include "ospfd/ospf_spf.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_packet.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_dump.h"
#ifdef HAVE_SNMP
#include "ospfd/ospf_snmp.h"
#endif /* HAVE_SNMP */


int
ospf_if_get_output_cost (struct ospf_interface *oi)
{
  /* If all else fails, use default OSPF cost */
  u_int32_t cost;
  u_int32_t bw, refbw;

  bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH;
  refbw = oi->ospf->ref_bandwidth;

  /* A specifed ip ospf cost overrides a calculated one. */
  if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) ||
      OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd))
    cost = OSPF_IF_PARAM (oi, output_cost_cmd);
  /* See if a cost can be calculated from the zebra processes
     interface bandwidth field. */
  else
    {
      cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
      if (cost < 1)
	cost = 1;
      else if (cost > 65535)
	cost = 65535;
    }

  return cost;
}

void
ospf_if_recalculate_output_cost (struct interface *ifp)
{
  u_int32_t newcost;
  struct route_node *rn;
  
  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
    {
      struct ospf_interface *oi;
      
      if ( (oi = rn->info) == NULL)
	continue;

      newcost = ospf_if_get_output_cost (oi);

      /* Is actual output cost changed? */
      if (oi->output_cost != newcost)
	{
	  oi->output_cost = newcost;
	  ospf_router_lsa_timer_add (oi->area);
	}
    }
}

/* Simulate down/up on the interface.  This is needed, for example, when 
   the MTU changes. */
void
ospf_if_reset(struct interface *ifp)
{
  struct route_node *rn;
  
  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
    {
      struct ospf_interface *oi;
      
      if ( (oi = rn->info) == NULL)
	continue;

      ospf_if_down(oi);
      ospf_if_up(oi);
    }
}

void
ospf_if_reset_variables (struct ospf_interface *oi)
{
  /* Set default values. */
  /* don't clear this flag.  oi->flag = OSPF_IF_DISABLE; */

  if (oi->vl_data)
    oi->type = OSPF_IFTYPE_VIRTUALLINK;
  else 
  /* preserve network-type */
  if (oi->type != OSPF_IFTYPE_NBMA)
    oi->type = OSPF_IFTYPE_BROADCAST;

  oi->state = ISM_Down;

  oi->crypt_seqnum = 0;

  /* This must be short, (less than RxmtInterval) 
     - RFC 2328 Section 13.5 para 3.  Set to 1 second to avoid Acks being
       held back for too long - MAG */
  oi->v_ls_ack = 1;  
}

/* lookup oi for specified prefix/ifp */
static struct ospf_interface *
ospf_if_table_lookup (struct interface *ifp, struct prefix *prefix)
{
  struct prefix p;
  struct route_node *rn;
  struct ospf_interface *rninfo = NULL;
  
  p = *prefix;
  p.prefixlen = IPV4_MAX_PREFIXLEN;
  
  /* route_node_get implicitely locks */
  if ((rn = route_node_lookup (IF_OIFS (ifp), &p)))
    {
      rninfo = (struct ospf_interface *) rn->info;
      route_unlock_node (rn);
    }
  
  return rninfo;
}

static void
ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi)
{
  struct route_node *rn;
  struct prefix p;

  p = *oi->address;
  p.prefixlen = IPV4_MAX_PREFIXLEN;

  rn = route_node_get (IF_OIFS (ifp), &p);
  /* rn->info should either be NULL or equal to this oi
   * as route_node_get may return an existing node
   */
  assert (!rn->info || rn->info == oi);
  rn->info = oi;
}

static void
ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi)
{
  struct route_node *rn;
  struct prefix p;

  p = *oi->address;
  p.prefixlen = IPV4_MAX_PREFIXLEN;

  rn = route_node_lookup (IF_OIFS (oi->ifp), &p);
  assert (rn);
  assert (rn->info);
  rn->info = NULL;
  route_unlock_node (rn);
  route_unlock_node (rn);
}

struct ospf_interface *
ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
{
  struct ospf_interface *oi;

  if ((oi = ospf_if_table_lookup (ifp, p)) == NULL)
    {
      oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface));
      memset (oi, 0, sizeof (struct ospf_interface));
    }
  else
    return oi;
    
  /* Set zebra interface pointer. */
  oi->ifp = ifp;
  oi->address = p;
  
  ospf_add_to_if (ifp, oi);
  listnode_add (ospf->oiflist, oi);
  
  /* Clear self-originated network-LSA. */
  oi->network_lsa_self = NULL;

  /* Initialize neighbor list. */
  oi->nbrs = route_table_init ();

  /* Initialize static neighbor list. */
  oi->nbr_nbma = list_new ();

  /* Initialize Link State Acknowledgment list. */
  oi->ls_ack = list_new ();
  oi->ls_ack_direct.ls_ack = list_new ();

  /* Set default values. */
  ospf_if_reset_variables (oi);

  /* Add pseudo neighbor. */
  oi->nbr_self = ospf_nbr_new (oi);

  oi->ls_upd_queue = route_table_init ();
  oi->t_ls_upd_event = NULL;
  oi->t_ls_ack_direct = NULL;

  oi->crypt_seqnum = time (NULL);

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_type9_lsa_init (oi);
#endif /* HAVE_OPAQUE_LSA */

  oi->ospf = ospf;
  
  return oi;
}

/* Restore an interface to its pre UP state
   Used from ism_interface_down only */
void
ospf_if_cleanup (struct ospf_interface *oi)
{
  struct route_node *rn;
  struct listnode *node, *nnode;
  struct ospf_neighbor *nbr;
  struct ospf_nbr_nbma *nbr_nbma;
  struct ospf_lsa *lsa;

  /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
  /* delete all static neighbors attached to this interface */
  for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma))
    {
      OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);

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

      nbr_nbma->oi = NULL;
      
      listnode_delete (oi->nbr_nbma, nbr_nbma);
    }

  /* send Neighbor event KillNbr to all associated neighbors. */
  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info) != NULL)
      if (nbr != oi->nbr_self)
	OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr);

  /* Cleanup Link State Acknowlegdment list. */
  for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa))
    ospf_lsa_unlock (lsa);
  list_delete_all_node (oi->ls_ack);

  oi->crypt_seqnum = 0;
  
  /* Empty link state update queue */
  ospf_ls_upd_queue_empty (oi);
  
  /* Reset pseudo neighbor. */
  ospf_nbr_delete (oi->nbr_self);
  oi->nbr_self = ospf_nbr_new (oi);
  ospf_nbr_add_self (oi);
  
  ospf_lsa_unlock (oi->network_lsa_self);
  oi->network_lsa_self = NULL;
  OSPF_TIMER_OFF (oi->t_network_lsa_self);
}

void
ospf_if_free (struct ospf_interface *oi)
{
  ospf_if_down (oi);

  assert (oi->state == ISM_Down);

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_type9_lsa_term (oi);
#endif /* HAVE_OPAQUE_LSA */

  /* Free Pseudo Neighbour */
  ospf_nbr_delete (oi->nbr_self);
  
  route_table_finish (oi->nbrs);
  route_table_finish (oi->ls_upd_queue);
  
  /* Free any lists that should be freed */
  list_free (oi->nbr_nbma);
  
  list_free (oi->ls_ack);
  list_free (oi->ls_ack_direct.ls_ack);
  
  ospf_delete_from_if (oi->ifp, oi);

  listnode_delete (oi->ospf->oiflist, oi);
  listnode_delete (oi->area->oiflist, oi);

  memset (oi, 0, sizeof (*oi));
  XFREE (MTYPE_OSPF_IF, oi);
}


/*
*  check if interface with given address is configured and
*  return it if yes.  special treatment for PtP networks.
*/
struct ospf_interface *
ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
{
  struct listnode *node, *nnode;
  struct ospf_interface *oi;
  struct prefix_ipv4 addr;

  addr.family = AF_INET;
  addr.prefix = *address;
  addr.prefixlen = IPV4_MAX_PREFIXLEN;
  
  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
    if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
      {
	if (oi->type == OSPF_IFTYPE_POINTOPOINT)
	  {
	    if (CONNECTED_DEST_HOST(oi->connected))
	      {
		/* match only destination addr, since local addr is most likely
		 * not unique (borrowed from another interface) */
		if (IPV4_ADDR_SAME (address,
				    &oi->connected->destination->u.prefix4))
		return oi;
	      }
	    else
	      {
		/* special leniency: match if addr is anywhere on PtP subnet */
		if (prefix_match(oi->address,(struct prefix *)&addr))
		  return oi;
	      }
	  }
	else
	  {
	    if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4))
	      return oi;
	  }
      }
  return NULL;
}

int
ospf_if_is_up (struct ospf_interface *oi)
{
  return if_is_up (oi->ifp);
}

struct ospf_interface *
ospf_if_exists (struct ospf_interface *oic)
{ 
  struct listnode *node;
  struct ospf *ospf;
  struct ospf_interface *oi;

  if ((ospf = ospf_lookup ()) == NULL)
    return NULL;

  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    if (oi == oic)
      return oi;

  return NULL;
}

struct ospf_interface *
ospf_if_lookup_by_local_addr (struct ospf *ospf,
			      struct interface *ifp, struct in_addr address)
{
  struct listnode *node;
  struct ospf_interface *oi;
  
  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
      {
	if (ifp && oi->ifp != ifp)
	  continue;
	
	if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
	  return oi;
      }

  return NULL;
}

struct ospf_interface *
ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
{
  struct listnode *node;
  struct ospf_interface *oi;
  struct prefix ptmp;
  
  /* Check each Interface. */
  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    {
      if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
	{
	  if ((oi->type == OSPF_IFTYPE_POINTOPOINT) &&
	      CONNECTED_DEST_HOST(oi->connected))
	    {
	      prefix_copy (&ptmp, oi->connected->destination);
	      ptmp.prefixlen = IPV4_MAX_BITLEN;
	    }
	  else
	    prefix_copy (&ptmp, oi->address);
	
	  apply_mask (&ptmp);
	  if (prefix_same (&ptmp, (struct prefix *) p))
	    return oi;
	}
    }
  return NULL;
}

/* determine receiving interface by source of packet */
struct ospf_interface *
ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src)
{
  struct listnode *node;
  struct prefix_ipv4 addr;
  struct ospf_interface *oi, *match;

  addr.family = AF_INET;
  addr.prefix = src;
  addr.prefixlen = IPV4_MAX_BITLEN;

  match = NULL;

  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    {
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	continue;
      
      if (if_is_loopback (oi->ifp))
        continue;
      
      if ((oi->type == OSPF_IFTYPE_POINTOPOINT) &&
	  CONNECTED_DEST_HOST(oi->connected))
	{
	  if (IPV4_ADDR_SAME (&oi->connected->destination->u.prefix4, &src))
	    return oi;
	}
      else
	{
	  if (prefix_match (oi->address, (struct prefix *) &addr))
	    {
	      if ( (match == NULL) || 
	           (match->address->prefixlen < oi->address->prefixlen)
	         )
	        match = oi;
	    }
	}
    }

  return match;
}

void
ospf_if_stream_set (struct ospf_interface *oi)
{
  /* set output fifo queue. */
  if (oi->obuf == NULL) 
    oi->obuf = ospf_fifo_new ();
}

void
ospf_if_stream_unset (struct ospf_interface *oi)
{
  struct ospf *ospf = oi->ospf;

  if (oi->obuf)
    {
     ospf_fifo_free (oi->obuf);
     oi->obuf = NULL;

     if (oi->on_write_q)
       {
	 listnode_delete (ospf->oi_write_q, oi);
         if (list_isempty(ospf->oi_write_q))
           OSPF_TIMER_OFF (ospf->t_write);
	 oi->on_write_q = 0;
       }
    }
}


static struct ospf_if_params *
ospf_new_if_params (void)
{
  struct ospf_if_params *oip;

  oip = XMALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));

  if (!oip)
    return NULL;

  memset (oip, 0, sizeof (struct ospf_if_params));

  UNSET_IF_PARAM (oip, output_cost_cmd);
  UNSET_IF_PARAM (oip, transmit_delay);
  UNSET_IF_PARAM (oip, retransmit_interval);
  UNSET_IF_PARAM (oip, passive_interface);
  UNSET_IF_PARAM (oip, v_hello);
  UNSET_IF_PARAM (oip, fast_hello);
  UNSET_IF_PARAM (oip, v_wait);
  UNSET_IF_PARAM (oip, priority);
  UNSET_IF_PARAM (oip, type);
  UNSET_IF_PARAM (oip, auth_simple);
  UNSET_IF_PARAM (oip, auth_crypt);
  UNSET_IF_PARAM (oip, auth_type);

  oip->auth_crypt = list_new ();
  
  return oip;
}

void
ospf_del_if_params (struct ospf_if_params *oip)
{
  list_delete (oip->auth_crypt);
  XFREE (MTYPE_OSPF_IF_PARAMS, oip);
}

void
ospf_free_if_params (struct interface *ifp, struct in_addr addr)
{
  struct ospf_if_params *oip;
  struct prefix_ipv4 p;
  struct route_node *rn;

  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_PREFIXLEN;
  p.prefix = addr;
  rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  if (!rn || !rn->info)
    return;

  oip = rn->info;
  route_unlock_node (rn);
  
  if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
      !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
      listcount (oip->auth_crypt) == 0)
    {
      ospf_del_if_params (oip);
      rn->info = NULL;
      route_unlock_node (rn);
    }
}

struct ospf_if_params *
ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
{
  struct prefix_ipv4 p;
  struct route_node *rn;

  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_PREFIXLEN;
  p.prefix = addr;

  rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  
  if (rn)
    {
      route_unlock_node (rn);
      return rn->info;
    }

  return NULL;
}

struct ospf_if_params *
ospf_get_if_params (struct interface *ifp, struct in_addr addr)
{
  struct prefix_ipv4 p;
  struct route_node *rn;

  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_PREFIXLEN;
  p.prefix = addr;

  rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  
  if (rn->info == NULL)
    rn->info = ospf_new_if_params ();
  else
    route_unlock_node (rn);
  
  return rn->info;
}

void
ospf_if_update_params (struct interface *ifp, struct in_addr addr)
{
  struct route_node *rn;
  struct ospf_interface *oi;
  
  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
    {
      if ((oi = rn->info) == NULL)
	continue;

      if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
	oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
    }
}

int
ospf_if_new_hook (struct interface *ifp)
{
  int rc = 0;

  ifp->info = XMALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
  memset (ifp->info, 0, sizeof (struct ospf_if_info));
  
  IF_OIFS (ifp) = route_table_init ();
  IF_OIFS_PARAMS (ifp) = route_table_init ();
  
  IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
  
  SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
  IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
  
  SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
  IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;

  SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
  IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;

  IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;

  SET_IF_PARAM (IF_DEF_PARAMS (ifp), passive_interface);
  IF_DEF_PARAMS (ifp)->passive_interface = OSPF_IF_ACTIVE;

  SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
  IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;

  SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello);
  IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;

  SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
  IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;

  SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
  memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
  
  SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
  IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
  
#ifdef HAVE_OPAQUE_LSA
  rc = ospf_opaque_new_if (ifp);
#endif /* HAVE_OPAQUE_LSA */
  return rc;
}

static int
ospf_if_delete_hook (struct interface *ifp)
{
  int rc = 0;
  struct route_node *rn;
#ifdef HAVE_OPAQUE_LSA
  rc = ospf_opaque_del_if (ifp);
#endif /* HAVE_OPAQUE_LSA */

  route_table_finish (IF_OIFS (ifp));

  for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
    if (rn->info)
      ospf_del_if_params (rn->info);
  route_table_finish (IF_OIFS_PARAMS (ifp));

  ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp));
  XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
  ifp->info = NULL;

  return rc;
}

int
ospf_if_is_enable (struct ospf_interface *oi)
{
  if (!if_is_loopback (oi->ifp))
    if (if_is_up (oi->ifp))
	return 1;

  return 0;
}

void
ospf_if_set_multicast(struct ospf_interface *oi)
{
  if ((oi->state > ISM_Loopback) &&
      (oi->type != OSPF_IFTYPE_LOOPBACK) &&
      (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
      (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE))
    {
      /* The interface should belong to the OSPF-all-routers group. */
      if (!CHECK_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS) &&
	  (ospf_if_add_allspfrouters(oi->ospf, oi->address,
				     oi->ifp->ifindex) >= 0))
	/* Set the flag only if the system call to join succeeded. */
        SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
    }
  else
    {
      /* The interface should NOT belong to the OSPF-all-routers group. */
      if (CHECK_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS))
        {
	  ospf_if_drop_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);
	  /* Unset the flag regardless of whether the system call to leave
	     the group succeeded, since it's much safer to assume that
	     we are not a member. */
	  UNSET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
        }
    }

  if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
       (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
      ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
      (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE))
    {
      /* The interface should belong to the OSPF-designated-routers group. */
      if (!CHECK_FLAG(oi->multicast_memberships, MEMBER_DROUTERS) &&
	  (ospf_if_add_alldrouters(oi->ospf, oi->address,
	  			   oi->ifp->ifindex) >= 0))
	/* Set the flag only if the system call to join succeeded. */
        SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
    }
  else
    {
      /* The interface should NOT belong to the OSPF-designated-routers group */
      if (CHECK_FLAG(oi->multicast_memberships, MEMBER_DROUTERS))
        {
	  ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
	  /* Unset the flag regardless of whether the system call to leave
	     the group succeeded, since it's much safer to assume that
	     we are not a member. */
          UNSET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
        }
    }
}

int
ospf_if_up (struct ospf_interface *oi)
{
  if (oi == NULL)
    return 0;

  if (oi->type == OSPF_IFTYPE_LOOPBACK)
    OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
  else
    {
      ospf_if_stream_set (oi);
      OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
    }

  return 1;
}

int
ospf_if_down (struct ospf_interface *oi)
{
  if (oi == NULL)
    return 0;

  OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  /* Shutdown packet reception and sending */
  ospf_if_stream_unset (oi);

  return 1;
}


/* Virtual Link related functions. */

struct ospf_vl_data *
ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
{
  struct ospf_vl_data *vl_data;

  vl_data = XMALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
  memset (vl_data, 0, sizeof (struct ospf_vl_data));

  vl_data->vl_peer.s_addr = vl_peer.s_addr;
  vl_data->vl_area_id = area->area_id;
  vl_data->format = area->format;

  return vl_data;
}

void
ospf_vl_data_free (struct ospf_vl_data *vl_data)
{
  XFREE (MTYPE_OSPF_VL_DATA, vl_data);
}

u_int vlink_count = 0;

struct ospf_interface * 
ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
{
  struct ospf_interface * voi;
  struct interface * vi;
  char   ifname[INTERFACE_NAMSIZ + 1];
  struct ospf_area *area;
  struct in_addr area_id;
  struct connected *co;
  struct prefix_ipv4 *p;
  
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): Start");
  if (vlink_count == OSPF_VL_MAX_COUNT)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_vl_new(): Alarm: "
		   "cannot create more than OSPF_MAX_VL_COUNT virtual links");
      return NULL;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");

  snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
  vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
  co = connected_new ();
  co->ifp = vi;
  listnode_add (vi->connected, co);

  p = prefix_ipv4_new ();
  p->family = AF_INET;
  p->prefix.s_addr = 0;
  p->prefixlen = 0;
 
  co->address = (struct prefix *)p;
  
  voi = ospf_if_new (ospf, vi, co->address);
  if (voi == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
      return NULL;
    }
  voi->connected = co;
  voi->vl_data = vl_data;
  voi->ifp->mtu = OSPF_VL_MTU;
  voi->type = OSPF_IFTYPE_VIRTUALLINK;

  vlink_count++;
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);

  area_id.s_addr = 0;
  area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
  voi->area = area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): set associated area to the backbone");

  ospf_nbr_add_self (voi);
  ospf_area_add_if (voi->area, voi);

  ospf_if_stream_set (voi);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): Stop");
  return voi;
}

static void
ospf_vl_if_delete (struct ospf_vl_data *vl_data)
{
  struct interface *ifp = vl_data->vl_oi->ifp;
  vl_data->vl_oi->address->u.prefix4.s_addr = 0;
  vl_data->vl_oi->address->prefixlen = 0;
  ospf_if_free (vl_data->vl_oi);
  if_delete (ifp);
  vlink_count--;
}

/* Look up vl_data for given peer, optionally qualified to be in the
 * specified area. NULL area returns first found..
 */
struct ospf_vl_data *
ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area,
                struct in_addr vl_peer)
{
  struct ospf_vl_data *vl_data;
  struct listnode *node;
  
  if (IS_DEBUG_OSPF_EVENT)
    {
      zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer));
      if (area)
        zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id));
    }
  
  for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
    {
      if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("%s: VL %s, peer %s", __func__,
                    vl_data->vl_oi->ifp->name,
                    inet_ntoa (vl_data->vl_peer));
      
      if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
        continue;
      
      if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer))
        return vl_data;
    }

  return NULL;
}

static void 
ospf_vl_shutdown (struct ospf_vl_data *vl_data)
{
  struct ospf_interface *oi;

  if ((oi = vl_data->vl_oi) == NULL)
    return;

  oi->address->u.prefix4.s_addr = 0;
  oi->address->prefixlen = 0;

  UNSET_FLAG (oi->ifp->flags, IFF_UP);
  /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
  OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
}

void
ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
{
  listnode_add (ospf->vlinks, vl_data);
#ifdef HAVE_SNMP
  ospf_snmp_vl_add (vl_data);
#endif /* HAVE_SNMP */
}

void
ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
{
  ospf_vl_shutdown (vl_data);
  ospf_vl_if_delete (vl_data);

#ifdef HAVE_SNMP
  ospf_snmp_vl_delete (vl_data);
#endif /* HAVE_SNMP */
  listnode_delete (ospf->vlinks, vl_data);

  ospf_vl_data_free (vl_data);
}

static int
ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
{
  int changed = 0;
  struct ospf_interface *voi;
  struct listnode *node;
  struct vertex_parent *vp = NULL;
  int i;
  struct router_lsa *rl;

  voi = vl_data->vl_oi;

  if (voi->output_cost != v->distance)
    {
     
      voi->output_cost = v->distance;
      changed = 1;
    }

  for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
    {
      vl_data->nexthop.oi = vp->nexthop->oi;
      vl_data->nexthop.router = vp->nexthop->router;
      
      if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
                          &vl_data->nexthop.oi->address->u.prefix4))
        changed = 1;
        
      voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4;
      voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen;

      break; /* We take the first interface. */
    }

  rl = (struct router_lsa *)v->lsa;

  /* use SPF determined backlink index in struct vertex
   * for virtual link destination address
   */
  if (vp && vp->backlink >= 0)
    {
      if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
                           &rl->link[vp->backlink].link_data))
        changed = 1;
      vl_data->peer_addr = rl->link[vp->backlink].link_data;
    }
  else
    {
      /* This is highly odd, there is no backlink index
       * there should be due to the ospf_spf_has_link() check
       * in SPF. Lets warn and try pick a link anyway.
       */
      zlog_warn ("ospf_vl_set_params: No backlink for %s!",
                 vl_data->vl_oi->ifp->name);
      for (i = 0; i < ntohs (rl->links); i++)
        {
          switch (rl->link[i].type)
            {
              case LSA_LINK_TYPE_VIRTUALLINK:
                if (IS_DEBUG_OSPF_EVENT)
                  zlog_debug ("found back link through VL");
              case LSA_LINK_TYPE_TRANSIT:
              case LSA_LINK_TYPE_POINTOPOINT:
                if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
                                     &rl->link[i].link_data))
                  changed = 1;
                vl_data->peer_addr = rl->link[i].link_data;
            }
        }
    }
    
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__,
               vl_data->vl_oi->ifp->name,
               inet_ntoa(vl_data->peer_addr),
               voi->output_cost,
               (changed ? " " : " un"));
               
  return changed;
}


void
ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
                  struct vertex *v)
{
  struct ospf *ospf = area->ospf;
  struct listnode *node;
  struct ospf_vl_data *vl_data;
  struct ospf_interface *oi;

  if (IS_DEBUG_OSPF_EVENT)
    {
      zlog_debug ("ospf_vl_up_check(): Start");
      zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
      zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
    }

  for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
    {
      if (IS_DEBUG_OSPF_EVENT)
	{
	  zlog_debug ("%s: considering VL, %s in area %s", __func__,
		     vl_data->vl_oi->ifp->name,
		     inet_ntoa (vl_data->vl_area_id));
	  zlog_debug ("%s: peer ID: %s", __func__,
		     inet_ntoa (vl_data->vl_peer));
	}

      if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
          IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
        {
          oi = vl_data->vl_oi;
          SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);

	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("ospf_vl_up_check(): this VL matched");

          if (oi->state == ISM_Down)
            {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_debug ("ospf_vl_up_check(): VL is down, waking it up");
              SET_FLAG (oi->ifp->flags, IFF_UP);
              OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp);
            }

         if (ospf_vl_set_params (vl_data, v))
           {
             if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
               zlog_debug ("ospf_vl_up_check: VL cost change,"
                          " scheduling router lsa refresh");
             if(ospf->backbone)
               ospf_router_lsa_timer_add (ospf->backbone);
             else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
               zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
           }
        }
    }
}

void
ospf_vl_unapprove (struct ospf *ospf)
{
  struct listnode *node;
  struct ospf_vl_data *vl_data;

  for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
    UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
}

void
ospf_vl_shut_unapproved (struct ospf *ospf)
{
  struct listnode *node, *nnode;
  struct ospf_vl_data *vl_data;

  for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
    if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
      ospf_vl_shutdown (vl_data);
}

int
ospf_full_virtual_nbrs (struct ospf_area *area)
{
  if (IS_DEBUG_OSPF_EVENT)
    {
      zlog_debug ("counting fully adjacent virtual neighbors in area %s",
		 inet_ntoa (area->area_id));
      zlog_debug ("there are %d of them", area->full_vls);
    }

  return area->full_vls;
}

int
ospf_vls_in_area (struct ospf_area *area)
{
  struct listnode *node;
  struct ospf_vl_data *vl_data;
  int c = 0;

  for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
    if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
      c++;

  return c;
}


struct crypt_key *
ospf_crypt_key_new ()
{
  struct crypt_key *ck;

  ck = XMALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
  memset (ck, 0, sizeof (struct crypt_key));

  return ck;
}

void
ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
{
  listnode_add (crypt, ck);
}

struct crypt_key *
ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id)
{
  struct listnode *node;
  struct crypt_key *ck;

  for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck))
    if (ck->key_id == key_id)
      return ck;

  return NULL;
}

int
ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id)
{
  struct listnode *node, *nnode;
  struct crypt_key *ck;

  for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck))
    {
      if (ck->key_id == key_id)
        {
          listnode_delete (auth_crypt, ck);
          XFREE (MTYPE_OSPF_CRYPT_KEY, ck);
          return 1;
        }
    }

  return 0;
}

u_char
ospf_default_iftype(struct interface *ifp)
{
  if (if_is_pointopoint (ifp))
    return OSPF_IFTYPE_POINTOPOINT;
  else if (if_is_loopback (ifp))
    return OSPF_IFTYPE_LOOPBACK;
  else
    return OSPF_IFTYPE_BROADCAST;
}

void
ospf_if_init ()
{
  /* Initialize Zebra interface data structure. */
  if_init ();
  om->iflist = iflist;
  if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
  if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
}
