⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ospf_interface.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 */intospf_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;}voidospf_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);	}    }}voidospf_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;  }voidospf_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);  assert (! rn->info);  rn->info = oi;}voidospf_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 */voidospf_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);}voidospf_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;}intospf_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))	    match = oi;	}    }  return match;}voidospf_if_stream_set (struct ospf_interface *oi){  /* set output fifo queue. */  if (oi->obuf == NULL)     oi->obuf = ospf_fifo_new ();}voidospf_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));  memset (oip, 0, 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;}voidospf_del_if_params (struct ospf_if_params *oip){  list_delete (oip->auth_crypt);  XFREE (MTYPE_OSPF_IF_PARAMS, oip);}voidospf_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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -