ospf_neighbor.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:7k
源码类别:

网络

开发平台:

Unix_Linux

  1. /*
  2.  * OSPF Neighbor functions.
  3.  * Copyright (C) 1999, 2000 Toshiaki Takada
  4.  *
  5.  * This file is part of GNU Zebra.
  6.  * 
  7.  * GNU Zebra is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published
  9.  * by the Free Software Foundation; either version 2, or (at your
  10.  * option) any later version.
  11.  *
  12.  * GNU Zebra is distributed in the hope that it will be useful, but
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with GNU Zebra; see the file COPYING.  If not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22. #include <zebra.h>
  23. #include "linklist.h"
  24. #include "prefix.h"
  25. #include "memory.h"
  26. #include "command.h"
  27. #include "thread.h"
  28. #include "stream.h"
  29. #include "table.h"
  30. #include "log.h"
  31. #include "ospfd/ospfd.h"
  32. #include "ospfd/ospf_interface.h"
  33. #include "ospfd/ospf_asbr.h"
  34. #include "ospfd/ospf_lsa.h"
  35. #include "ospfd/ospf_lsdb.h"
  36. #include "ospfd/ospf_neighbor.h"
  37. #include "ospfd/ospf_nsm.h"
  38. #include "ospfd/ospf_packet.h"
  39. #include "ospfd/ospf_network.h"
  40. #include "ospfd/ospf_flood.h"
  41. #include "ospfd/ospf_dump.h"
  42. struct ospf_neighbor *
  43. ospf_nbr_new (struct ospf_interface *oi)
  44. {
  45.   struct ospf_neighbor *nbr;
  46.   /* Allcate new neighbor. */
  47.   nbr = XMALLOC (MTYPE_OSPF_NEIGHBOR, sizeof (struct ospf_neighbor));
  48.   memset (nbr, 0, sizeof (struct ospf_neighbor));
  49.   /* Relate neighbor to the interface. */
  50.   nbr->oi = oi;
  51.   /* Set default values. */
  52.   nbr->state = NSM_Down;
  53.   /* Set inheritance values. */
  54.   nbr->v_inactivity = OSPF_IF_PARAM (oi, v_wait);
  55.   nbr->v_db_desc = OSPF_IF_PARAM (oi, retransmit_interval);
  56.   nbr->v_ls_req = OSPF_IF_PARAM (oi, retransmit_interval);
  57.   nbr->v_ls_upd = OSPF_IF_PARAM (oi, retransmit_interval);
  58.   nbr->priority = -1;
  59.   /* DD flags. */
  60.   nbr->dd_flags = OSPF_DD_FLAG_MS|OSPF_DD_FLAG_M|OSPF_DD_FLAG_I;
  61.   /* Last received and sent DD. */
  62.   nbr->last_send = NULL;
  63.   nbr->nbr_nbma = NULL;
  64.   ospf_lsdb_init (&nbr->db_sum);
  65.   ospf_lsdb_init (&nbr->ls_rxmt);
  66.   ospf_lsdb_init (&nbr->ls_req);
  67.   nbr->crypt_seqnum = 0;
  68.   return nbr;
  69. }
  70. void
  71. ospf_nbr_free (struct ospf_neighbor *nbr)
  72. {
  73.   /* Free DB summary list. */
  74.   if (ospf_db_summary_count (nbr))
  75.     ospf_db_summary_clear (nbr);
  76.     /* ospf_db_summary_delete_all (nbr); */
  77.   /* Free ls request list. */
  78.   if (ospf_ls_request_count (nbr))
  79.     ospf_ls_request_delete_all (nbr);
  80.   /* Free retransmit list. */
  81.   if (ospf_ls_retransmit_count (nbr))
  82.     ospf_ls_retransmit_clear (nbr);
  83.   /* Cleanup LSDBs. */
  84.   ospf_lsdb_cleanup (&nbr->db_sum);
  85.   ospf_lsdb_cleanup (&nbr->ls_req);
  86.   ospf_lsdb_cleanup (&nbr->ls_rxmt);
  87.   
  88.   /* Clear last send packet. */
  89.   if (nbr->last_send)
  90.     ospf_packet_free (nbr->last_send);
  91.   if (nbr->nbr_nbma)
  92.     {
  93.       nbr->nbr_nbma->nbr = NULL;
  94.       nbr->nbr_nbma = NULL;
  95.     }
  96.   /* Cancel all timers. */
  97.   OSPF_NSM_TIMER_OFF (nbr->t_inactivity);
  98.   OSPF_NSM_TIMER_OFF (nbr->t_db_desc);
  99.   OSPF_NSM_TIMER_OFF (nbr->t_ls_req);
  100.   OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);
  101.   /* Cancel all events. *//* Thread lookup cost would be negligible. */
  102.   thread_cancel_event (master, nbr);
  103.   XFREE (MTYPE_OSPF_NEIGHBOR, nbr);
  104. }
  105. /* Delete specified OSPF neighbor from interface. */
  106. void
  107. ospf_nbr_delete (struct ospf_neighbor *nbr)
  108. {
  109.   struct ospf_interface *oi;
  110.   struct route_node *rn;
  111.   struct prefix p;
  112.   oi = nbr->oi;
  113.   /* Unlink ospf neighbor from the interface. */
  114.   p.family = AF_INET;
  115.   p.prefixlen = IPV4_MAX_BITLEN;
  116.   p.u.prefix4 = nbr->src;
  117.   rn = route_node_lookup (oi->nbrs, &p);
  118.   if (rn)
  119.     {
  120.       if (rn->info)
  121. {
  122.   rn->info = NULL;
  123.   route_unlock_node (rn);
  124. }
  125.       else
  126. zlog_info ("Can't find neighbor %s in the interface %s",
  127.    inet_ntoa (nbr->src), IF_NAME (oi));
  128.       route_unlock_node (rn);
  129.     }
  130.   /* Free ospf_neighbor structure. */
  131.   ospf_nbr_free (nbr);
  132. }
  133. /* Check myself is in the neighbor list. */
  134. int
  135. ospf_nbr_bidirectional (struct in_addr *router_id,
  136. struct in_addr *neighbors, int size)
  137. {
  138.   int i;
  139.   int max;
  140.   max = size / sizeof (struct in_addr);
  141.   for (i = 0; i < max; i ++)
  142.     if (IPV4_ADDR_SAME (router_id, &neighbors[i]))
  143.       return 1;
  144.   return 0;
  145. }
  146. /* Add self to nbr list. */
  147. void
  148. ospf_nbr_add_self (struct ospf_interface *oi)
  149. {
  150.   struct ospf_neighbor *nbr;
  151.   struct prefix p;
  152.   struct route_node *rn;
  153.   p.family = AF_INET;
  154.   p.prefixlen = 32;
  155.   p.u.prefix4 = oi->address->u.prefix4;
  156.   rn = route_node_get (oi->nbrs, &p);
  157.   if (rn->info)
  158.     {
  159.       /* There is already pseudo neighbor. */
  160.       nbr = rn->info;
  161.       route_unlock_node (rn);
  162.     }
  163.   else
  164.     rn->info = oi->nbr_self;
  165. }
  166. /* Get neighbor count by status.
  167.    Specify status = 0, get all neighbor other than myself. */
  168. int
  169. ospf_nbr_count (struct ospf_interface *oi, int state)
  170. {
  171.   struct ospf_neighbor *nbr;
  172.   struct route_node *rn;
  173.   int count = 0;
  174.   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
  175.     if ((nbr = rn->info))
  176.       if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
  177. if (state == 0 || nbr->state == state)
  178.   count++;
  179.   return count;
  180. }
  181. #ifdef HAVE_OPAQUE_LSA
  182. int
  183. ospf_nbr_count_opaque_capable (struct ospf_interface *oi)
  184. {
  185.   struct ospf_neighbor *nbr;
  186.   struct route_node *rn;
  187.   int count = 0;
  188.   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
  189.     if ((nbr = rn->info))
  190.       if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
  191. if (nbr->state == NSM_Full)
  192.   if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
  193.     count++;
  194.   return count;
  195. }
  196. #endif /* HAVE_OPAQUE_LSA */
  197. struct ospf_neighbor *
  198. ospf_nbr_lookup_by_addr (struct route_table *nbrs,
  199.  struct in_addr *addr)
  200. {
  201.   struct prefix p;
  202.   struct route_node *rn;
  203.   struct ospf_neighbor *nbr;
  204.   p.family = AF_INET;
  205.   p.prefixlen = IPV4_MAX_BITLEN;
  206.   p.u.prefix4 = *addr;
  207.   rn = route_node_lookup (nbrs, &p);
  208.   if (! rn)
  209.     return NULL;
  210.   if (rn->info == NULL)
  211.     {
  212.       route_unlock_node (rn);
  213.       return NULL;
  214.     }
  215.   nbr = (struct ospf_neighbor *) rn->info;
  216.   route_unlock_node (rn);
  217.   return nbr;
  218. }
  219. struct ospf_neighbor *
  220. ospf_nbr_lookup_by_routerid (struct route_table *nbrs,
  221.      struct in_addr *id)
  222. {
  223.   struct route_node *rn;
  224.   struct ospf_neighbor *nbr;
  225.   for (rn = route_top (nbrs); rn; rn = route_next (rn))
  226.     if ((nbr = rn->info) != NULL)
  227.       if (IPV4_ADDR_SAME (&nbr->router_id, id))
  228. {
  229.   route_unlock_node(rn);
  230.   return nbr;
  231. }
  232.   return NULL;
  233. }
  234. void
  235. ospf_renegotiate_optional_capabilities (struct ospf *top)
  236. {
  237.   listnode node;
  238.   struct ospf_interface *oi;
  239.   struct route_table *nbrs;
  240.   struct route_node *rn;
  241.   struct ospf_neighbor *nbr;
  242.   /* At first, flush self-originated LSAs from routing domain. */
  243.   ospf_flush_self_originated_lsas_now (top);
  244.   /* Revert all neighbor status to ExStart. */
  245.   for (node = listhead (top->oiflist); node; nextnode (node))
  246.     {
  247.       if ((oi = getdata (node)) == NULL || (nbrs = oi->nbrs) == NULL)
  248.         continue;
  249.       for (rn = route_top (nbrs); rn; rn = route_next (rn))
  250.         {
  251.           if ((nbr = rn->info) == NULL || nbr == oi->nbr_self)
  252.             continue;
  253.           if (nbr->state < NSM_ExStart)
  254.             continue;
  255.           if (IS_DEBUG_OSPF_EVENT)
  256.             zlog_info ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr->router_id));
  257.           OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
  258.         }
  259.     }
  260.   return;
  261. }