/*
 * 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;

  ospf = ospf_lookup ();

  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 ((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_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--;
}

struct ospf_vl_data *
ospf_vl_lookup (struct ospf_area *area, struct in_addr vl_peer)
{
  struct ospf_vl_data *vl_data;
  struct listnode *node;

  for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
    if (vl_data->vl_peer.s_addr == vl_peer.s_addr &&
        IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
      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->out_oi = vp->nexthop->oi;
      
      if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
                          &vl_data->out_oi->address->u.prefix4))
        changed = 1;
        
      voi->address->u.prefix4 = vl_data->out_oi->address->u.prefix4;
      voi->address->prefixlen = vl_data->out_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 ("ospf_vl_set_params: %s peer address is %s\n",
                               vl_data->vl_oi->ifp->name, 
                               inet_ntoa(vl_data->peer_addr));
              return changed;
            }
        }
    }
    
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_set_params: %s peer address is %s\n",
               vl_data->vl_oi->ifp->name,
               inet_ntoa(vl_data->peer_addr));
               
  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 ("ospf_vl_up_check(): considering VL, name: %s", 
		     vl_data->vl_oi->ifp->name);
	  zlog_debug ("ospf_vl_up_check(): VL area: %s, peer ID: %s", 
		     inet_ntoa (vl_data->vl_area_id),
		     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);
}
