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

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 2003 Yasuhiro Ohara
  3.  *
  4.  * This file is part of GNU Zebra.
  5.  *
  6.  * GNU Zebra is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  *
  11.  * GNU Zebra is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with GNU Zebra; see the file COPYING.  If not, write to the 
  18.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
  19.  * Boston, MA 02111-1307, USA.  
  20.  */
  21. #include <zebra.h>
  22. #include "log.h"
  23. #include "memory.h"
  24. #include "thread.h"
  25. #include "linklist.h"
  26. #include "vty.h"
  27. #include "command.h"
  28. #include "ospf6_proto.h"
  29. #include "ospf6_lsa.h"
  30. #include "ospf6_lsdb.h"
  31. #include "ospf6_message.h"
  32. #include "ospf6_top.h"
  33. #include "ospf6_area.h"
  34. #include "ospf6_interface.h"
  35. #include "ospf6_neighbor.h"
  36. #include "ospf6_intra.h"
  37. #include "ospf6_flood.h"
  38. #include "ospf6d.h"
  39. unsigned char conf_debug_ospf6_neighbor = 0;
  40. char *ospf6_neighbor_state_str[] =
  41. { "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
  42.   "Loading", "Full", NULL };
  43. int
  44. ospf6_neighbor_cmp (void *va, void *vb)
  45. {
  46.   struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
  47.   struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
  48.   return (ntohl (ona->router_id) < ntohl (onb->router_id) ? -1 : 1);
  49. }
  50. struct ospf6_neighbor *
  51. ospf6_neighbor_lookup (u_int32_t router_id,
  52.                        struct ospf6_interface *oi)
  53. {
  54.   listnode n;
  55.   struct ospf6_neighbor *on;
  56.   for (n = listhead (oi->neighbor_list); n; nextnode (n))
  57.     {
  58.       on = (struct ospf6_neighbor *) getdata (n);
  59.       if (on->router_id == router_id)
  60.         return on;
  61.     }
  62.   return (struct ospf6_neighbor *) NULL;
  63. }
  64. /* create ospf6_neighbor */
  65. struct ospf6_neighbor *
  66. ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
  67. {
  68.   struct ospf6_neighbor *on;
  69.   char buf[16];
  70.   on = (struct ospf6_neighbor *)
  71.     XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
  72.   if (on == NULL)
  73.     {
  74.       zlog_warn ("neighbor: malloc failed");
  75.       return NULL;
  76.     }
  77.   memset (on, 0, sizeof (struct ospf6_neighbor));
  78.   inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
  79.   snprintf (on->name, sizeof (on->name), "%s%%%s",
  80.             buf, oi->interface->name);
  81.   on->ospf6_if = oi;
  82.   on->state = OSPF6_NEIGHBOR_DOWN;
  83.   gettimeofday (&on->last_changed, (struct timezone *) NULL);
  84.   on->router_id = router_id;
  85.   on->summary_list = ospf6_lsdb_create (on);
  86.   on->request_list = ospf6_lsdb_create (on);
  87.   on->retrans_list = ospf6_lsdb_create (on);
  88.   on->dbdesc_list = ospf6_lsdb_create (on);
  89.   on->lsreq_list = ospf6_lsdb_create (on);
  90.   on->lsupdate_list = ospf6_lsdb_create (on);
  91.   on->lsack_list = ospf6_lsdb_create (on);
  92.   listnode_add_sort (oi->neighbor_list, on);
  93.   return on;
  94. }
  95. void
  96. ospf6_neighbor_delete (struct ospf6_neighbor *on)
  97. {
  98.   struct ospf6_lsa *lsa;
  99.   ospf6_lsdb_remove_all (on->summary_list);
  100.   ospf6_lsdb_remove_all (on->request_list);
  101.   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  102.        lsa = ospf6_lsdb_next (lsa))
  103.     {
  104.       ospf6_decrement_retrans_count (lsa);
  105.       ospf6_lsdb_remove (lsa, on->retrans_list);
  106.     }
  107.   ospf6_lsdb_remove_all (on->dbdesc_list);
  108.   ospf6_lsdb_remove_all (on->lsreq_list);
  109.   ospf6_lsdb_remove_all (on->lsupdate_list);
  110.   ospf6_lsdb_remove_all (on->lsack_list);
  111.   ospf6_lsdb_delete (on->summary_list);
  112.   ospf6_lsdb_delete (on->request_list);
  113.   ospf6_lsdb_delete (on->retrans_list);
  114.   ospf6_lsdb_delete (on->dbdesc_list);
  115.   ospf6_lsdb_delete (on->lsreq_list);
  116.   ospf6_lsdb_delete (on->lsupdate_list);
  117.   ospf6_lsdb_delete (on->lsack_list);
  118.   THREAD_OFF (on->inactivity_timer);
  119.   THREAD_OFF (on->thread_send_dbdesc);
  120.   THREAD_OFF (on->thread_send_lsreq);
  121.   THREAD_OFF (on->thread_send_lsupdate);
  122.   THREAD_OFF (on->thread_send_lsack);
  123.   XFREE (MTYPE_OSPF6_NEIGHBOR, on);
  124. }
  125. static void
  126. ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
  127. {
  128.   u_char prev_state;
  129.   prev_state = on->state;
  130.   on->state = next_state;
  131.   if (prev_state == next_state)
  132.     return;
  133.   gettimeofday (&on->last_changed, (struct timezone *) NULL);
  134.   /* log */
  135.   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
  136.     {
  137.       zlog_info ("Neighbor state change %s: [%s]->[%s]", on->name,
  138.                  ospf6_neighbor_state_str[prev_state],
  139.                  ospf6_neighbor_state_str[next_state]);
  140.     }
  141.   if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
  142.     {
  143.       OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
  144.       if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
  145.         {
  146.           OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
  147.           OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
  148.         }
  149.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
  150.     }
  151. #ifdef XXX
  152.   if (prev_state == NBS_FULL || next_state == NBS_FULL)
  153.     nbs_full_change (on->ospf6_interface);
  154.   /* check for LSAs that already reached MaxAge */
  155.   if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
  156.        prev_state == OSPF6_NEIGHBOR_LOADING) &&
  157.       (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
  158.        next_state != OSPF6_NEIGHBOR_LOADING))
  159.     {
  160.       ospf6_maxage_remover ();
  161.     }
  162. #endif /*XXX*/
  163. }
  164. /* RFC2328 section 10.4 */
  165. int
  166. need_adjacency (struct ospf6_neighbor *on)
  167. {
  168.   if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
  169.       on->ospf6_if->state == OSPF6_INTERFACE_DR ||
  170.       on->ospf6_if->state == OSPF6_INTERFACE_BDR)
  171.     return 1;
  172.   if (on->ospf6_if->drouter == on->router_id ||
  173.       on->ospf6_if->bdrouter == on->router_id)
  174.     return 1;
  175.   return 0;
  176. }
  177. int
  178. hello_received (struct thread *thread)
  179. {
  180.   struct ospf6_neighbor *on;
  181.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  182.   assert (on);
  183.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  184.     zlog_info ("Neighbor Event %s: *HelloReceived*", on->name);
  185.   /* reset Inactivity Timer */
  186.   THREAD_OFF (on->inactivity_timer);
  187.   on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
  188.                                            on->ospf6_if->dead_interval);
  189.   if (on->state <= OSPF6_NEIGHBOR_DOWN)
  190.     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
  191.   return 0;
  192. }
  193. int
  194. twoway_received (struct thread *thread)
  195. {
  196.   struct ospf6_neighbor *on;
  197.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  198.   assert (on);
  199.   if (on->state > OSPF6_NEIGHBOR_INIT)
  200.     return 0;
  201.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  202.     zlog_info ("Neighbor Event %s: *2Way-Received*", on->name);
  203.   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  204.   if (! need_adjacency (on))
  205.     {
  206.       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
  207.       return 0;
  208.     }
  209.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  210.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  211.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  212.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  213.   THREAD_OFF (on->thread_send_dbdesc);
  214.   on->thread_send_dbdesc =
  215.     thread_add_event (master, ospf6_dbdesc_send, on, 0);
  216.   return 0;
  217. }
  218. int
  219. negotiation_done (struct thread *thread)
  220. {
  221.   struct ospf6_neighbor *on;
  222.   struct ospf6_lsa *lsa;
  223.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  224.   assert (on);
  225.   if (on->state != OSPF6_NEIGHBOR_EXSTART)
  226.     return 0;
  227.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  228.     zlog_info ("Neighbor Event %s: *NegotiationDone*", on->name);
  229.   /* clear ls-list */
  230.   ospf6_lsdb_remove_all (on->summary_list);
  231.   ospf6_lsdb_remove_all (on->request_list);
  232.   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  233.        lsa = ospf6_lsdb_next (lsa))
  234.     {
  235.       ospf6_decrement_retrans_count (lsa);
  236.       ospf6_lsdb_remove (lsa, on->retrans_list);
  237.     }
  238.   /* Interface scoped LSAs */
  239.   for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
  240.        lsa = ospf6_lsdb_next (lsa))
  241.     {
  242.       if (OSPF6_LSA_IS_MAXAGE (lsa))
  243.         {
  244.           ospf6_increment_retrans_count (lsa);
  245.           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  246.         }
  247.       else
  248.         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  249.     }
  250.   /* Area scoped LSAs */
  251.   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
  252.        lsa = ospf6_lsdb_next (lsa))
  253.     {
  254.       if (OSPF6_LSA_IS_MAXAGE (lsa))
  255.         {
  256.           ospf6_increment_retrans_count (lsa);
  257.           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  258.         }
  259.       else
  260.         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  261.     }
  262.   /* AS scoped LSAs */
  263.   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
  264.        lsa = ospf6_lsdb_next (lsa))
  265.     {
  266.       if (OSPF6_LSA_IS_MAXAGE (lsa))
  267.         {
  268.           ospf6_increment_retrans_count (lsa);
  269.           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  270.         }
  271.       else
  272.         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  273.     }
  274.   UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  275.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on);
  276.   return 0;
  277. }
  278. int
  279. exchange_done (struct thread *thread)
  280. {
  281.   struct ospf6_neighbor *on;
  282.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  283.   assert (on);
  284.   if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
  285.     return 0;
  286.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  287.     zlog_info ("Neighbor Event %s: *ExchangeDone*", on->name);
  288.   THREAD_OFF (on->thread_send_dbdesc);
  289.   ospf6_lsdb_remove_all (on->dbdesc_list);
  290. /* XXX
  291.   thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
  292.                     on->ospf6_if->dead_interval);
  293. */
  294.   if (on->request_list->count == 0)
  295.     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
  296.   else
  297.     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on);
  298.   return 0;
  299. }
  300. int
  301. loading_done (struct thread *thread)
  302. {
  303.   struct ospf6_neighbor *on;
  304.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  305.   assert (on);
  306.   if (on->state != OSPF6_NEIGHBOR_LOADING)
  307.     return 0;
  308.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  309.     zlog_info ("Neighbor Event %s: *LoadingDone*", on->name);
  310.   assert (on->request_list->count == 0);
  311.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
  312.   return 0;
  313. }
  314. int
  315. adj_ok (struct thread *thread)
  316. {
  317.   struct ospf6_neighbor *on;
  318.   struct ospf6_lsa *lsa;
  319.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  320.   assert (on);
  321.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  322.     zlog_info ("Neighbor Event %s: *AdjOK?*", on->name);
  323.   if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
  324.     {
  325.       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  326.       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  327.       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  328.       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  329.       THREAD_OFF (on->thread_send_dbdesc);
  330.       on->thread_send_dbdesc =
  331.         thread_add_event (master, ospf6_dbdesc_send, on, 0);
  332.     }
  333.   else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
  334.            ! need_adjacency (on))
  335.     {
  336.       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
  337.       ospf6_lsdb_remove_all (on->summary_list);
  338.       ospf6_lsdb_remove_all (on->request_list);
  339.       for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  340.            lsa = ospf6_lsdb_next (lsa))
  341.         {
  342.           ospf6_decrement_retrans_count (lsa);
  343.           ospf6_lsdb_remove (lsa, on->retrans_list);
  344.         }
  345.     }
  346.   return 0;
  347. }
  348. int
  349. seqnumber_mismatch (struct thread *thread)
  350. {
  351.   struct ospf6_neighbor *on;
  352.   struct ospf6_lsa *lsa;
  353.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  354.   assert (on);
  355.   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
  356.     return 0;
  357.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  358.     zlog_info ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
  359.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  360.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  361.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  362.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  363.   ospf6_lsdb_remove_all (on->summary_list);
  364.   ospf6_lsdb_remove_all (on->request_list);
  365.   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  366.        lsa = ospf6_lsdb_next (lsa))
  367.     {
  368.       ospf6_decrement_retrans_count (lsa);
  369.       ospf6_lsdb_remove (lsa, on->retrans_list);
  370.     }
  371.   THREAD_OFF (on->thread_send_dbdesc);
  372.   on->thread_send_dbdesc =
  373.     thread_add_event (master, ospf6_dbdesc_send, on, 0);
  374.   return 0;
  375. }
  376. int
  377. bad_lsreq (struct thread *thread)
  378. {
  379.   struct ospf6_neighbor *on;
  380.   struct ospf6_lsa *lsa;
  381.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  382.   assert (on);
  383.   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
  384.     return 0;
  385.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  386.     zlog_info ("Neighbor Event %s: *BadLSReq*", on->name);
  387.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  388.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  389.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  390.   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  391.   ospf6_lsdb_remove_all (on->summary_list);
  392.   ospf6_lsdb_remove_all (on->request_list);
  393.   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  394.        lsa = ospf6_lsdb_next (lsa))
  395.     {
  396.       ospf6_decrement_retrans_count (lsa);
  397.       ospf6_lsdb_remove (lsa, on->retrans_list);
  398.     }
  399.   THREAD_OFF (on->thread_send_dbdesc);
  400.   on->thread_send_dbdesc =
  401.     thread_add_event (master, ospf6_dbdesc_send, on, 0);
  402.   return 0;
  403. }
  404. int
  405. oneway_received (struct thread *thread)
  406. {
  407.   struct ospf6_neighbor *on;
  408.   struct ospf6_lsa *lsa;
  409.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  410.   assert (on);
  411.   if (on->state < OSPF6_NEIGHBOR_TWOWAY)
  412.     return 0;
  413.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  414.     zlog_info ("Neighbor Event %s: *1Way-Received*", on->name);
  415.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
  416.   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  417.   ospf6_lsdb_remove_all (on->summary_list);
  418.   ospf6_lsdb_remove_all (on->request_list);
  419.   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  420.        lsa = ospf6_lsdb_next (lsa))
  421.     {
  422.       ospf6_decrement_retrans_count (lsa);
  423.       ospf6_lsdb_remove (lsa, on->retrans_list);
  424.     }
  425.   THREAD_OFF (on->thread_send_dbdesc);
  426.   THREAD_OFF (on->thread_send_lsreq);
  427.   THREAD_OFF (on->thread_send_lsupdate);
  428.   THREAD_OFF (on->thread_send_lsack);
  429.   return 0;
  430. }
  431. int
  432. inactivity_timer (struct thread *thread)
  433. {
  434.   struct ospf6_neighbor *on;
  435.   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  436.   assert (on);
  437.   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  438.     zlog_info ("Neighbor Event %s: *InactivityTimer*", on->name);
  439.   on->inactivity_timer = NULL;
  440.   on->drouter = on->prev_drouter = 0;
  441.   on->bdrouter = on->prev_bdrouter = 0;
  442.   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on);
  443.   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  444.   listnode_delete (on->ospf6_if->neighbor_list, on);
  445.   ospf6_neighbor_delete (on);
  446.   return 0;
  447. }
  448. /* vty functions */
  449. /* show neighbor structure */
  450. void
  451. ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
  452. {
  453.   char router_id[16];
  454.   char duration[16];
  455.   struct timeval now, res;
  456.   char nstate[16];
  457.   char deadtime[16];
  458.   long h, m, s;
  459.   /* Router-ID (Name) */
  460.   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  461. #ifdef HAVE_GETNAMEINFO
  462.   {
  463.   }
  464. #endif /*HAVE_GETNAMEINFO*/
  465.   gettimeofday (&now, NULL);
  466.   /* Dead time */
  467.   h = m = s = 0;
  468.   if (on->inactivity_timer)
  469.     {
  470.       s = on->inactivity_timer->u.sands.tv_sec - now.tv_sec;
  471.       h = s / 3600;
  472.       s -= h * 3600;
  473.       m = s / 60;
  474.       s -= m * 60;
  475.     }
  476.   snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
  477.   /* Neighbor State */
  478.   if (if_is_pointopoint (on->ospf6_if->interface))
  479.     snprintf (nstate, sizeof (nstate), "PointToPoint");
  480.   else
  481.     {
  482.       if (on->router_id == on->drouter)
  483.         snprintf (nstate, sizeof (nstate), "DR");
  484.       else if (on->router_id == on->bdrouter)
  485.         snprintf (nstate, sizeof (nstate), "BDR");
  486.       else
  487.         snprintf (nstate, sizeof (nstate), "DROther");
  488.     }
  489.   /* Duration */
  490.   timersub (&now, &on->last_changed, &res);
  491.   timerstring (&res, duration, sizeof (duration));
  492.   /*
  493.   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
  494.            "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
  495.            "I/F", "State", VNL);
  496.   */
  497.   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
  498.            router_id, on->priority, deadtime,
  499.            ospf6_neighbor_state_str[on->state], nstate, duration,
  500.            on->ospf6_if->interface->name,
  501.            ospf6_interface_state_str[on->ospf6_if->state], VNL);
  502. }
  503. void
  504. ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
  505. {
  506.   char router_id[16];
  507.   char drouter[16], bdrouter[16];
  508.   char duration[16];
  509.   struct timeval now, res;
  510. /*
  511.     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  512.              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
  513.              "State", VNL);
  514. */
  515.   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  516.   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  517.   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
  518.   gettimeofday (&now, NULL);
  519.   timersub (&now, &on->last_changed, &res);
  520.   timerstring (&res, duration, sizeof (duration));
  521.   vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  522.            router_id, ospf6_neighbor_state_str[on->state],
  523.            duration, drouter, bdrouter, on->ospf6_if->interface->name,
  524.            ospf6_interface_state_str[on->ospf6_if->state],
  525.            VNL);
  526. }
  527. void
  528. ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
  529. {
  530.   char drouter[16], bdrouter[16];
  531.   char linklocal_addr[64], duration[32];
  532.   struct timeval now, res;
  533.   struct ospf6_lsa *lsa;
  534.   inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
  535.              sizeof (linklocal_addr));
  536.   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  537.   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
  538.   gettimeofday (&now, NULL);
  539.   timersub (&now, &on->last_changed, &res);
  540.   timerstring (&res, duration, sizeof (duration));
  541.   vty_out (vty, " Neighbor %s%s", on->name,
  542.            VNL);
  543.   vty_out (vty, "    Area %s via interface %s (ifindex %d)%s",
  544.            on->ospf6_if->area->name,
  545.            on->ospf6_if->interface->name,
  546.            on->ospf6_if->interface->ifindex,
  547.            VNL);
  548.   vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
  549.            on->ifindex, linklocal_addr,
  550.            VNL);
  551.   vty_out (vty, "    State %s for a duration of %s%s",
  552.            ospf6_neighbor_state_str[on->state], duration,
  553.            VNL);
  554.   vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
  555.            drouter, bdrouter, on->priority,
  556.            VNL);
  557.   vty_out (vty, "    DbDesc status: %s%s%s SeqNum: %#lx%s",
  558.            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
  559.            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
  560.            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
  561.             "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
  562.            VNL);
  563.   vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
  564.            VNL);
  565.   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
  566.        lsa = ospf6_lsdb_next (lsa))
  567.     vty_out (vty, "      %s%s", lsa->name, VNL);
  568.   vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
  569.            VNL);
  570.   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
  571.        lsa = ospf6_lsdb_next (lsa))
  572.     vty_out (vty, "      %s%s", lsa->name, VNL);
  573.   vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
  574.            VNL);
  575.   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  576.        lsa = ospf6_lsdb_next (lsa))
  577.     vty_out (vty, "      %s%s", lsa->name, VNL);
  578.   timerclear (&res);
  579.   if (on->thread_send_dbdesc)
  580.     timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
  581.   timerstring (&res, duration, sizeof (duration));
  582.   vty_out (vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
  583.            on->dbdesc_list->count, duration,
  584.            (on->thread_send_dbdesc ? "on" : "off"),
  585.            VNL);
  586.   for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
  587.        lsa = ospf6_lsdb_next (lsa))
  588.     vty_out (vty, "      %s%s", lsa->name, VNL);
  589.   timerclear (&res);
  590.   if (on->thread_send_lsreq)
  591.     timersub (&on->thread_send_lsreq->u.sands, &now, &res);
  592.   timerstring (&res, duration, sizeof (duration));
  593.   vty_out (vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]%s",
  594.            on->lsreq_list->count, duration,
  595.            (on->thread_send_lsreq ? "on" : "off"),
  596.            VNL);
  597.   for (lsa = ospf6_lsdb_head (on->lsreq_list); lsa;
  598.        lsa = ospf6_lsdb_next (lsa))
  599.     vty_out (vty, "      %s%s", lsa->name, VNL);
  600.   timerclear (&res);
  601.   if (on->thread_send_lsupdate)
  602.     timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
  603.   timerstring (&res, duration, sizeof (duration));
  604.   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
  605.            on->lsupdate_list->count, duration,
  606.            (on->thread_send_lsupdate ? "on" : "off"),
  607.            VNL);
  608.   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
  609.        lsa = ospf6_lsdb_next (lsa))
  610.     vty_out (vty, "      %s%s", lsa->name, VNL);
  611.   timerclear (&res);
  612.   if (on->thread_send_lsack)
  613.     timersub (&on->thread_send_lsack->u.sands, &now, &res);
  614.   timerstring (&res, duration, sizeof (duration));
  615.   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
  616.            on->lsack_list->count, duration,
  617.            (on->thread_send_lsack ? "on" : "off"),
  618.            VNL);
  619.   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
  620.        lsa = ospf6_lsdb_next (lsa))
  621.     vty_out (vty, "      %s%s", lsa->name, VNL);
  622. }
  623. DEFUN (show_ipv6_ospf6_neighbor,
  624.        show_ipv6_ospf6_neighbor_cmd,
  625.        "show ipv6 ospf6 neighbor",
  626.        SHOW_STR
  627.        IP6_STR
  628.        OSPF6_STR
  629.        "Neighbor listn"
  630.       )
  631. {
  632.   struct ospf6_neighbor *on;
  633.   struct ospf6_interface *oi;
  634.   struct ospf6_area *oa;
  635.   listnode i, j, k;
  636.   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  637.   OSPF6_CMD_CHECK_RUNNING ();
  638.   showfunc = ospf6_neighbor_show;
  639.   if (argc)
  640.     {
  641.       if (! strncmp (argv[0], "de", 2))
  642.         showfunc = ospf6_neighbor_show_detail;
  643.       else if (! strncmp (argv[0], "dr", 2))
  644.         showfunc = ospf6_neighbor_show_drchoice;
  645.     }
  646.   if (showfunc == ospf6_neighbor_show)
  647.     vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
  648.              "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
  649.              "I/F", "State", VNL);
  650.   else if (showfunc == ospf6_neighbor_show_drchoice)
  651.     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  652.              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
  653.              "State", VNL);
  654.   for (i = listhead (ospf6->area_list); i; nextnode (i))
  655.     {
  656.       oa = (struct ospf6_area *) getdata (i);
  657.       for (j = listhead (oa->if_list); j; nextnode (j))
  658.         {
  659.           oi = (struct ospf6_interface *) getdata (j);
  660.           for (k = listhead (oi->neighbor_list); k; nextnode (k))
  661.             {
  662.               on = (struct ospf6_neighbor *) getdata (k);
  663.               (*showfunc) (vty, on);
  664.             }
  665.         }
  666.     }
  667.   return CMD_SUCCESS;
  668. }
  669. ALIAS (show_ipv6_ospf6_neighbor,
  670.        show_ipv6_ospf6_neighbor_detail_cmd,
  671.        "show ipv6 ospf6 neighbor (detail|drchoice)",
  672.        SHOW_STR
  673.        IP6_STR
  674.        OSPF6_STR
  675.        "Neighbor listn"
  676.        "Display detailsn"
  677.        "Display DR choicesn"
  678.       );
  679. DEFUN (show_ipv6_ospf6_neighbor_one,
  680.        show_ipv6_ospf6_neighbor_one_cmd,
  681.        "show ipv6 ospf6 neighbor A.B.C.D",
  682.        SHOW_STR
  683.        IP6_STR
  684.        OSPF6_STR
  685.        "Neighbor listn"
  686.        "Specify Router-ID as IPv4 address notationn"
  687.       )
  688. {
  689.   struct ospf6_neighbor *on;
  690.   struct ospf6_interface *oi;
  691.   struct ospf6_area *oa;
  692.   listnode i, j, k;
  693.   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  694.   u_int32_t router_id;
  695.   OSPF6_CMD_CHECK_RUNNING ();
  696.   showfunc = ospf6_neighbor_show_detail;
  697.   if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
  698.     {
  699.       vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
  700.                VNL);
  701.       return CMD_SUCCESS;
  702.     }
  703.   for (i = listhead (ospf6->area_list); i; nextnode (i))
  704.     {
  705.       oa = (struct ospf6_area *) getdata (i);
  706.       for (j = listhead (oa->if_list); j; nextnode (j))
  707.         {
  708.           oi = (struct ospf6_interface *) getdata (j);
  709.           for (k = listhead (oi->neighbor_list); k; nextnode (k))
  710.             {
  711.               on = (struct ospf6_neighbor *) getdata (k);
  712.               if (on->router_id == router_id)
  713.                 (*showfunc) (vty, on);
  714.             }
  715.         }
  716.     }
  717.   return CMD_SUCCESS;
  718. }
  719. void
  720. ospf6_neighbor_init ()
  721. {
  722.   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
  723.   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  724.   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
  725.   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  726. }
  727. DEFUN (debug_ospf6_neighbor,
  728.        debug_ospf6_neighbor_cmd,
  729.        "debug ospf6 neighbor",
  730.        DEBUG_STR
  731.        OSPF6_STR
  732.        "Debug OSPFv3 Neighborn"
  733.       )
  734. {
  735.   unsigned char level = 0;
  736.   if (argc)
  737.     {
  738.       if (! strncmp (argv[0], "s", 1))
  739.         level = OSPF6_DEBUG_NEIGHBOR_STATE;
  740.       if (! strncmp (argv[0], "e", 1))
  741.         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
  742.     }
  743.   else
  744.     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
  745.   OSPF6_DEBUG_NEIGHBOR_ON (level);
  746.   return CMD_SUCCESS;
  747. }
  748. ALIAS (debug_ospf6_neighbor,
  749.        debug_ospf6_neighbor_detail_cmd,
  750.        "debug ospf6 neighbor (state|event)",
  751.        DEBUG_STR
  752.        OSPF6_STR
  753.        "Debug OSPFv3 Neighborn"
  754.        "Debug OSPFv3 Neighbor State Changen"
  755.        "Debug OSPFv3 Neighbor Eventn"
  756.       );
  757. DEFUN (no_debug_ospf6_neighbor,
  758.        no_debug_ospf6_neighbor_cmd,
  759.        "no debug ospf6 neighbor",
  760.        NO_STR
  761.        DEBUG_STR
  762.        OSPF6_STR
  763.        "Debug OSPFv3 Neighborn"
  764.       )
  765. {
  766.   unsigned char level = 0;
  767.   if (argc)
  768.     {
  769.       if (! strncmp (argv[0], "s", 1))
  770.         level = OSPF6_DEBUG_NEIGHBOR_STATE;
  771.       if (! strncmp (argv[0], "e", 1))
  772.         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
  773.     }
  774.   else
  775.     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
  776.   OSPF6_DEBUG_NEIGHBOR_OFF (level);
  777.   return CMD_SUCCESS;
  778. }
  779. ALIAS (no_debug_ospf6_neighbor,
  780.        no_debug_ospf6_neighbor_detail_cmd,
  781.        "no debug ospf6 neighbor (state|event)",
  782.        NO_STR
  783.        DEBUG_STR
  784.        OSPF6_STR
  785.        "Debug OSPFv3 Neighborn"
  786.        "Debug OSPFv3 Neighbor State Changen"
  787.        "Debug OSPFv3 Neighbor Eventn"
  788.       );
  789. int
  790. config_write_ospf6_debug_neighbor (struct vty *vty)
  791. {
  792.   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
  793.       IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  794.     vty_out (vty, "debug ospf6 neighbor%s", VNL);
  795.   else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
  796.     vty_out (vty, "debug ospf6 neighbor state%s", VNL);
  797.   else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  798.     vty_out (vty, "debug ospf6 neighbor event%s", VNL);
  799.   return 0;
  800. }
  801. void
  802. install_element_ospf6_debug_neighbor ()
  803. {
  804.   install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
  805.   install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
  806.   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
  807.   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
  808.   install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
  809.   install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
  810.   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
  811.   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
  812. }