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

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

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

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;

  oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface));
  memset (oi, 0, sizeof (struct ospf_interface));

  /* 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->nbr_self->state = NSM_TwoWay;
  oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
  oi->nbr_self->options = OSPF_OPTION_E;

  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;
  listnode node;
  struct ospf_neighbor *nbr;

  /* oi->nbrs and oi->nbr_nbma should be deletete on InterafceDown event */
  /* delete all static neighbors attached to this interface */
  for (node = listhead (oi->nbr_nbma); node; )
    {
      struct ospf_nbr_nbma *nbr_nbma = getdata (node);
      nextnode (node);

      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 (node = listhead (oi->ls_ack); node; nextnode (node))
    ospf_lsa_unlock (node->data);
  list_delete_all_node (oi->ls_ack);

  oi->crypt_seqnum = 0;
  
  /* Empty link state update queue */
  ospf_ls_upd_queue_empty (oi);
  
 /* Handle pseudo neighbor. */
  ospf_nbr_delete (oi->nbr_self);
  oi->nbr_self = ospf_nbr_new (oi);
  oi->nbr_self->state = NSM_TwoWay;
  oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);

  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;
#ifdef HAVE_NSSA
    case OSPF_AREA_NSSA:
      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
      SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
      break;
#endif /* HAVE_NSSA */
    }

  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.
*/
struct ospf_interface *
ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
{
  listnode node;
  struct ospf_interface *oi;
  struct prefix *addr;
  
  for (node = listhead (ospf->oiflist); node; nextnode (node))
    if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
      {
	if (oi->type == OSPF_IFTYPE_POINTOPOINT)
	  addr = oi->connected->destination;
	else
	  addr = oi->address;
	
	if (IPV4_ADDR_SAME (address, &addr->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_lookup_by_local_addr (struct ospf *ospf,
			      struct interface *ifp, struct in_addr address)
{
  listnode node;
  struct ospf_interface *oi;
  
  for (node = listhead (ospf->oiflist); node; nextnode (node))
    if ((oi = getdata (node)) != NULL && 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)
{
  listnode node;
  struct ospf_interface *oi;
  struct prefix ptmp;
  
  /* Check each Interface. */
  for (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
	{
	  if (oi->type == OSPF_IFTYPE_POINTOPOINT)
	    {
	      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)
{
  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 (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      oi = getdata (node);
      
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	continue;
      
      if (oi->type == OSPF_IFTYPE_POINTOPOINT)
	{
	  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;
       }
    }
}


struct ospf_if_params *
ospf_new_if_params ()
{
  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, 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.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, 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.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;

  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), 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;
}

int
ospf_if_delete_hook (struct interface *ifp)
{
  int rc = 0;
#ifdef HAVE_OPAQUE_LSA
  rc = ospf_opaque_del_if (ifp);
#endif /* HAVE_OPAQUE_LSA */
  route_table_finish (IF_OIFS (ifp));
  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;
}

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
    {
      if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
	ospf_if_add_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);
      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);
  if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
    ospf_if_drop_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);


  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_info ("ospf_vl_new(): Start");
  if (vlink_count == OSPF_VL_MAX_COUNT)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_vl_new(): Alarm: "
		   "cannot create more than OSPF_MAX_VL_COUNT virtual links");
      return NULL;
    }

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

  vi = if_create ();
  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_info ("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;

  sprintf (ifname, "VLINK%d", vlink_count++);
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_vl_new(): Created name: %s", ifname);
  strncpy (vi->name, ifname, IFNAMSIZ);
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("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_info ("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_info ("ospf_vl_new(): Stop");
  return voi;
}

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;
  listnode node;

  for (node = listhead (area->ospf->vlinks); node; nextnode (node))
    if ((vl_data = getdata (node)) != NULL)
      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;
}

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);
}

int
ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
{
  int changed = 0;
  struct ospf_interface *voi;
  listnode node;
  struct vertex_nexthop *nh;
  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 (node = listhead (v->nexthop); node; nextnode (node))
    if ((nh = getdata (node)) != NULL)
      {
	vl_data->out_oi = (struct ospf_interface *) nh->oi;

	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;
  
  for (i = 0; i < ntohs (rl->links); i++)
    {
      switch (rl->link[i].type)
        {
          case LSA_LINK_TYPE_VIRTUALLINK:
            if (IS_DEBUG_OSPF_EVENT)
              zlog_info ("found back link through VL");
          case LSA_LINK_TYPE_TRANSIT:
          case LSA_LINK_TYPE_POINTOPOINT:
            vl_data->peer_addr = rl->link[i].link_data;
          if (IS_DEBUG_OSPF_EVENT)
            zlog_info ("%s peer address is %s\n",
        	           vl_data->vl_oi->ifp->name, 
        	           inet_ntoa(vl_data->peer_addr));
          return changed;
        }
    }
  return changed;
}


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

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

  for (node = listhead (ospf->vlinks); node; nextnode (node))
    {
      if ((vl_data = getdata (node)) == NULL)
        continue;
  
      if (IS_DEBUG_OSPF_EVENT)
	{
	  zlog_info ("ospf_vl_up_check(): considering VL, name: %s", 
		     vl_data->vl_oi->ifp->name);
	  zlog_info ("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_info ("ospf_vl_up_check(): this VL matched");

          if (oi->state == ISM_Down)
            {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("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_info ("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_info ("ospf_vl_up_check: VL cost change, no backbone!");
           }
        }
    }
}

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

  for (node = listhead (ospf->vlinks); node; nextnode (node))
    if ((vl_data = getdata (node)) != NULL)
      UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
}

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

  for (node = listhead (ospf->vlinks); node; nextnode (node))
    if ((vl_data = getdata (node)) != NULL)
      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_info ("counting fully adjacent virtual neighbors in area %s",
		 inet_ntoa (area->area_id));
      zlog_info ("there are %d of them", area->full_vls);
    }

  return area->full_vls;
}

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

  for (node = listhead (area->ospf->vlinks); node; nextnode (node))
    if ((vl_data = getdata (node)) != NULL)
      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 (list crypt, struct crypt_key *ck)
{
  listnode_add (crypt, ck);
}

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

  for (node = listhead (auth_crypt); node; nextnode (node))
    {
      ck = getdata (node);
      if (ck->key_id == key_id)
        return ck;
    }

  return NULL;
}

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

  for (node = listhead (auth_crypt); node; nextnode (node))
    {
      ck = getdata (node);
      if (ck->key_id == key_id)
        {
          listnode_delete (auth_crypt, ck);
          return 1;
        }
    }

  return 0;
}

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);
}
