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

📄 ospfd.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* OSPF version 2 daemon program.   Copyright (C) 1999, 2000 Toshiaki TakadaThis file is part of GNU Zebra.GNU Zebra is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.GNU Zebra is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Zebra; see the file COPYING.  If not, write to the FreeSoftware Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.  */#include <zebra.h>#include "thread.h"#include "vty.h"#include "command.h"#include "linklist.h"#include "prefix.h"#include "table.h"#include "if.h"#include "memory.h"#include "stream.h"#include "log.h"#include "sockunion.h"          /* for inet_aton () */#include "zclient.h"#include "plist.h"#include "ospfd/ospfd.h"#include "ospfd/ospf_network.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_spf.h"#include "ospfd/ospf_packet.h"#include "ospfd/ospf_dump.h"#include "ospfd/ospf_zebra.h"#include "ospfd/ospf_abr.h"#include "ospfd/ospf_flood.h"#include "ospfd/ospf_route.h"#include "ospfd/ospf_ase.h"/* OSPF process wide configuration. */static struct ospf_master ospf_master;/* OSPF process wide configuration pointer to export. */struct ospf_master *om;extern struct zclient *zclient;void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);void ospf_network_free (struct ospf *, struct ospf_network *);void ospf_area_free (struct ospf_area *);void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);/* Get Router ID from ospf interface list. */struct in_addrospf_router_id_get (list if_list){  listnode node;  struct in_addr router_id;  memset (&router_id, 0, sizeof (struct in_addr));  for (node = listhead (if_list); node; nextnode (node))    {      struct ospf_interface *oi = getdata (node);      if (!if_is_up (oi->ifp) ||	  OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)	continue;            /* Ignore virtual link interface. */      if (oi->type != OSPF_IFTYPE_VIRTUALLINK &&	  oi->type != OSPF_IFTYPE_LOOPBACK) 	if (IPV4_ADDR_CMP (&router_id, &oi->address->u.prefix4) < 0)	  router_id = oi->address->u.prefix4;    }  return router_id;}#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1voidospf_router_id_update (struct ospf *ospf){  struct in_addr router_id, router_id_old;  listnode node;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));  router_id_old = ospf->router_id;  if (ospf->router_id_static.s_addr != 0)    router_id = ospf->router_id_static;  else    router_id = ospf_router_id_get (ospf->oiflist);  ospf->router_id = router_id;    if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));  if (!IPV4_ADDR_SAME (&router_id_old, &router_id))    {      for (node = listhead (ospf->oiflist); node; nextnode (node))        {	  struct ospf_interface *oi = getdata (node);          /* Update self-neighbor's router_id. */          oi->nbr_self->router_id = router_id;        }      /* If AS-external-LSA is queued, then flush those LSAs. */      if (router_id_old.s_addr == 0 && ospf->external_origin)	{	  int type;	  /* Originate each redistributed external route. */	  for (type = 0; type < ZEBRA_ROUTE_MAX; type++)	    if (ospf->external_origin & (1 << type))	      thread_add_event (master, ospf_external_lsa_originate_timer,				ospf, type);	  /* Originate Deafult. */	  if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))	    thread_add_event (master, ospf_default_originate_timer,			      &ospf->default_originate, 0);	  ospf->external_origin = 0;	}      OSPF_TIMER_ON (ospf->t_router_lsa_update,		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);    }}intospf_router_id_update_timer (struct thread *thread){  struct ospf *ospf = THREAD_ARG (thread);  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Router-ID: Update timer fired!");  ospf->t_router_id_update = NULL;  ospf_router_id_update (ospf);  return 0;}/* For OSPF area sort by area id. */intospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2){  if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))    return 1;  if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))    return -1;  return 0;}/* Allocate new ospf structure. */struct ospf *ospf_new (){  int i;  struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));  new->router_id.s_addr = htonl (0);  new->router_id_static.s_addr = htonl (0);  new->abr_type = OSPF_ABR_STAND;  new->oiflist = list_new ();  new->vlinks = list_new ();  new->areas = list_new ();  new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;  new->networks = route_table_init ();  new->nbr_nbma = route_table_init ();  new->lsdb = ospf_lsdb_new ();  new->default_originate = DEFAULT_ORIGINATE_NONE;  new->new_external_route = route_table_init ();  new->old_external_route = route_table_init ();  new->external_lsas = route_table_init ();  /* Distribute parameter init. */  for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)    {      new->dmetric[i].type = -1;      new->dmetric[i].value = -1;    }  new->default_metric = -1;  new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;  /* SPF timer value init. */  new->spf_delay = OSPF_SPF_DELAY_DEFAULT;  new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;  /* MaxAge init. */  new->maxage_lsa = list_new ();  new->t_maxage_walker =    thread_add_timer (master, ospf_lsa_maxage_walker,                      new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);  /* Distance table init. */  new->distance_table = route_table_init ();  new->lsa_refresh_queue.index = 0;  new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;  new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,					   new, new->lsa_refresh_interval);  new->lsa_refresher_started = time (NULL);  new->fd = ospf_sock_init ();  if (new->fd >= 0)    new->t_read = thread_add_read (master, ospf_read, new, new->fd);  new->oi_write_q = list_new ();    return new;}struct ospf *ospf_lookup (){  if (listcount (om->ospf) == 0)    return NULL;  return getdata (listhead (om->ospf));}voidospf_add (struct ospf *ospf){  listnode_add (om->ospf, ospf);}voidospf_delete (struct ospf *ospf){  listnode_delete (om->ospf, ospf);}struct ospf *ospf_get (){  struct ospf *ospf;  ospf = ospf_lookup ();  if (ospf == NULL)    {      ospf = ospf_new ();      ospf_add (ospf);      if (ospf->router_id_static.s_addr == 0)	ospf_router_id_update (ospf);#ifdef HAVE_OPAQUE_LSA      ospf_opaque_type11_lsa_init (ospf);#endif /* HAVE_OPAQUE_LSA */    }  return ospf;}voidospf_finish (struct ospf *ospf){  struct route_node *rn;  struct ospf_nbr_nbma *nbr_nbma;  struct ospf_lsa *lsa;  listnode node;  int i;#ifdef HAVE_OPAQUE_LSA  ospf_opaque_type11_lsa_term (ospf);#endif /* HAVE_OPAQUE_LSA */  /* Unredister redistribution */  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    ospf_redistribute_unset (ospf, i);  for (node = listhead (ospf->areas); node;)    {      struct ospf_area *area = getdata (node);      nextnode (node);            ospf_remove_vls_through_area (ospf, area);    }    for (node = listhead (ospf->vlinks); node; )    {      struct ospf_vl_data *vl_data = node->data;      nextnode (node);            ospf_vl_delete (ospf, vl_data);    }    list_delete (ospf->vlinks);  /* Reset interface. */  for (node = listhead (ospf->oiflist); node;)    {      struct ospf_interface *oi = getdata (node);      nextnode (node);            if (oi)	ospf_if_free (oi);    }  /* Clear static neighbors */  for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))    if ((nbr_nbma = rn->info))      {	OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);	if (nbr_nbma->nbr)	  {	    nbr_nbma->nbr->nbr_nbma = NULL;	    nbr_nbma->nbr = NULL;	  }	if (nbr_nbma->oi)	  {	    listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);	    nbr_nbma->oi = NULL;	  }	XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);      }  route_table_finish (ospf->nbr_nbma);  /* Clear networks and Areas. */  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))    {      struct ospf_network *network;      if ((network = rn->info) != NULL)	{	  ospf_network_free (ospf, network);	  rn->info = NULL;	  route_unlock_node (rn);	}    }  for (node = listhead (ospf->areas); node;)    {      struct ospf_area *area = getdata (node);      nextnode (node);            listnode_delete (ospf->areas, area);      ospf_area_free (area);    }  /* Cancel all timers. */  OSPF_TIMER_OFF (ospf->t_external_lsa);  OSPF_TIMER_OFF (ospf->t_router_id_update);  OSPF_TIMER_OFF (ospf->t_router_lsa_update);  OSPF_TIMER_OFF (ospf->t_spf_calc);  OSPF_TIMER_OFF (ospf->t_ase_calc);  OSPF_TIMER_OFF (ospf->t_maxage);  OSPF_TIMER_OFF (ospf->t_maxage_walker);  OSPF_TIMER_OFF (ospf->t_abr_task);  OSPF_TIMER_OFF (ospf->t_distribute_update);  OSPF_TIMER_OFF (ospf->t_lsa_refresher);  OSPF_TIMER_OFF (ospf->t_read);  OSPF_TIMER_OFF (ospf->t_write);  close (ospf->fd);   #ifdef HAVE_OPAQUE_LSA  LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)    ospf_discard_from_db (ospf, ospf->lsdb, lsa);#endif /* HAVE_OPAQUE_LSA */  LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)    ospf_discard_from_db (ospf, ospf->lsdb, lsa);  ospf_lsdb_delete_all (ospf->lsdb);  ospf_lsdb_free (ospf->lsdb);  for (node = listhead (ospf->maxage_lsa); node; nextnode (node))    ospf_lsa_unlock (getdata (node));  list_delete (ospf->maxage_lsa);  if (ospf->old_table)    ospf_route_table_free (ospf->old_table);  if (ospf->new_table)    {      ospf_route_delete (ospf->new_table);      ospf_route_table_free (ospf->new_table);    }  if (ospf->old_rtrs)    ospf_rtrs_free (ospf->old_rtrs);  if (ospf->new_rtrs)    ospf_rtrs_free (ospf->new_rtrs);  if (ospf->new_external_route)    {      ospf_route_delete (ospf->new_external_route);      ospf_route_table_free (ospf->new_external_route);    }  if (ospf->old_external_route)    {      ospf_route_delete (ospf->old_external_route);      ospf_route_table_free (ospf->old_external_route);    }  if (ospf->external_lsas)    {      ospf_ase_external_lsas_finish (ospf->external_lsas);    }  list_delete (ospf->areas);    for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)    if (EXTERNAL_INFO (i) != NULL)      for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))	{	  if (rn->info == NULL)	    continue;	  	  XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);	  rn->info = NULL;	  route_unlock_node (rn);	}  ospf_distance_reset (ospf);  route_table_finish (ospf->distance_table);  ospf_delete (ospf);  XFREE (MTYPE_OSPF_TOP, ospf);}/* allocate new OSPF Area object */struct ospf_area *ospf_area_new (struct ospf *ospf, struct in_addr area_id){  struct ospf_area *new;  /* Allocate new config_network. */  new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));  new->ospf = ospf;  new->area_id = area_id;  new->external_routing = OSPF_AREA_DEFAULT;  new->default_cost = 1;  new->auth_type = OSPF_AUTH_NULL;  /* New LSDB init. */  new->lsdb = ospf_lsdb_new ();  /* Self-originated LSAs initialize. */  new->router_lsa_self = NULL;#ifdef HAVE_OPAQUE_LSA  ospf_opaque_type10_lsa_init (new);#endif /* HAVE_OPAQUE_LSA */  new->oiflist = list_new ();  new->ranges = route_table_init ();  if (area_id.s_addr == OSPF_AREA_BACKBONE)    ospf->backbone = new;  return new;}voidospf_area_free (struct ospf_area *area){  struct route_node *rn;  struct ospf_lsa *lsa;  /* Free LSDBs. */  LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);  LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);  LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);  LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);#ifdef HAVE_NSSA  LSDB_LOOP (NSSA_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);#endif /* HAVE_NSSA */#ifdef HAVE_OPAQUE_LSA  LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);  LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)    ospf_discard_from_db (area->ospf, area->lsdb, lsa);#endif /* HAVE_OPAQUE_LSA */  ospf_lsdb_delete_all (area->lsdb);  ospf_lsdb_free (area->lsdb);#ifdef HAVE_OPAQUE_LSA  ospf_opaque_type10_lsa_term (area);#endif /* HAVE_OPAQUE_LSA */  ospf_lsa_unlock (area->router_lsa_self);    route_table_finish (area->ranges);  list_delete (area->oiflist);  if (EXPORT_NAME (area))    free (EXPORT_NAME (area));  if (IMPORT_NAME (area))    free (IMPORT_NAME (area));  /* Cancel timer. */  OSPF_TIMER_OFF (area->t_router_lsa_self);  if (OSPF_IS_AREA_BACKBONE (area))    area->ospf->backbone = NULL;  XFREE (MTYPE_OSPF_AREA, area);}voidospf_area_check_free (struct ospf *ospf, struct in_addr area_id){  struct ospf_area *area;  area = ospf_area_lookup_by_area_id (ospf, area_id);  if (area &&      listcount (area->oiflist) == 0 &&      area->ranges->top == NULL &&      area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&      area->external_routing == OSPF_AREA_DEFAULT &&

⌨️ 快捷键说明

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