2  * Copyright (C) 2003 Yasuhiro Ohara
 
   4  * This file is part of GNU Zebra.
 
   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
 
  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.
 
  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.  
 
  31 #include "ospf6_proto.h"
 
  32 #include "ospf6_lsa.h"
 
  33 #include "ospf6_lsdb.h"
 
  34 #include "ospf6_message.h"
 
  35 #include "ospf6_top.h"
 
  36 #include "ospf6_area.h"
 
  37 #include "ospf6_interface.h"
 
  38 #include "ospf6_neighbor.h"
 
  39 #include "ospf6_intra.h"
 
  40 #include "ospf6_flood.h"
 
  41 #include "ospf6_snmp.h"
 
  44 unsigned char conf_debug_ospf6_neighbor = 0;
 
  46 const char *ospf6_neighbor_state_str[] =
 
  47 { "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
 
  48   "Loading", "Full", NULL };
 
  50 static const char *ospf6_neighbor_event_str[] =
 
  66 ospf6_neighbor_event_string (int event)
 
  68   #define OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING "UnknownEvent"
 
  70   if (event < OSPF6_NEIGHBOR_EVENT_MAX_EVENT)
 
  71       return ospf6_neighbor_event_str[event];
 
  72   return OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING;
 
  76 ospf6_neighbor_cmp (void *va, void *vb)
 
  78   struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
 
  79   struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
 
  80   return (ntohl (ona->router_id) < ntohl (onb->router_id) ? -1 : 1);
 
  83 struct ospf6_neighbor *
 
  84 ospf6_neighbor_lookup (u_int32_t router_id,
 
  85                        struct ospf6_interface *oi)
 
  88   struct ospf6_neighbor *on;
 
  90   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, n, on))
 
  91     if (on->router_id == router_id)
 
  94   return (struct ospf6_neighbor *) NULL;
 
  97 /* create ospf6_neighbor */
 
  98 struct ospf6_neighbor *
 
  99 ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
 
 101   struct ospf6_neighbor *on;
 
 104   on = (struct ospf6_neighbor *)
 
 105     XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
 
 108       zlog_warn ("neighbor: malloc failed");
 
 112   memset (on, 0, sizeof (struct ospf6_neighbor));
 
 113   inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
 
 114   snprintf (on->name, sizeof (on->name), "%s%%%s",
 
 115             buf, oi->interface->name);
 
 117   on->state = OSPF6_NEIGHBOR_DOWN;
 
 118   on->state_change = 0;
 
 119   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
 
 120   on->router_id = router_id;
 
 122   on->summary_list = ospf6_lsdb_create (on);
 
 123   on->request_list = ospf6_lsdb_create (on);
 
 124   on->retrans_list = ospf6_lsdb_create (on);
 
 126   on->dbdesc_list = ospf6_lsdb_create (on);
 
 127   on->lsupdate_list = ospf6_lsdb_create (on);
 
 128   on->lsack_list = ospf6_lsdb_create (on);
 
 130   listnode_add_sort (oi->neighbor_list, on);
 
 135 ospf6_neighbor_delete (struct ospf6_neighbor *on)
 
 137   struct ospf6_lsa *lsa;
 
 139   ospf6_lsdb_remove_all (on->summary_list);
 
 140   ospf6_lsdb_remove_all (on->request_list);
 
 141   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 142        lsa = ospf6_lsdb_next (lsa))
 
 144       ospf6_decrement_retrans_count (lsa);
 
 145       ospf6_lsdb_remove (lsa, on->retrans_list);
 
 148   ospf6_lsdb_remove_all (on->dbdesc_list);
 
 149   ospf6_lsdb_remove_all (on->lsupdate_list);
 
 150   ospf6_lsdb_remove_all (on->lsack_list);
 
 152   ospf6_lsdb_delete (on->summary_list);
 
 153   ospf6_lsdb_delete (on->request_list);
 
 154   ospf6_lsdb_delete (on->retrans_list);
 
 156   ospf6_lsdb_delete (on->dbdesc_list);
 
 157   ospf6_lsdb_delete (on->lsupdate_list);
 
 158   ospf6_lsdb_delete (on->lsack_list);
 
 160   THREAD_OFF (on->inactivity_timer);
 
 162   THREAD_OFF (on->thread_send_dbdesc);
 
 163   THREAD_OFF (on->thread_send_lsreq);
 
 164   THREAD_OFF (on->thread_send_lsupdate);
 
 165   THREAD_OFF (on->thread_send_lsack);
 
 167   XFREE (MTYPE_OSPF6_NEIGHBOR, on);
 
 171 ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int event)
 
 175   prev_state = on->state;
 
 176   on->state = next_state;
 
 178   if (prev_state == next_state)
 
 182   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
 
 185   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
 
 187       zlog_debug ("Neighbor state change %s: [%s]->[%s] (%s)", on->name,
 
 188                   ospf6_neighbor_state_str[prev_state],
 
 189                   ospf6_neighbor_state_str[next_state],
 
 190                   ospf6_neighbor_event_string(event));
 
 193   /* Optionally notify about adjacency changes */
 
 194   if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
 
 195                  OSPF6_LOG_ADJACENCY_CHANGES) &&
 
 196       (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
 
 197                   OSPF6_LOG_ADJACENCY_DETAIL) ||
 
 198        (next_state == OSPF6_NEIGHBOR_FULL) || (next_state < prev_state)))
 
 199     zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
 
 200                 ospf6_neighbor_state_str[prev_state],
 
 201                 ospf6_neighbor_state_str[next_state],
 
 202                 ospf6_neighbor_event_string(event));
 
 204   if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
 
 206       OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
 
 207       if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
 
 209           OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
 
 210           OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
 
 212       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
 
 215   if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
 
 216        prev_state == OSPF6_NEIGHBOR_LOADING) &&
 
 217       (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
 
 218        next_state != OSPF6_NEIGHBOR_LOADING))
 
 219     ospf6_maxage_remove (on->ospf6_if->area->ospf6);
 
 222   /* Terminal state or regression */ 
 
 223   if ((next_state == OSPF6_NEIGHBOR_FULL)  ||
 
 224       (next_state == OSPF6_NEIGHBOR_TWOWAY) ||
 
 225       (next_state < prev_state))
 
 226     ospf6TrapNbrStateChange (on);
 
 231 /* RFC2328 section 10.4 */
 
 233 need_adjacency (struct ospf6_neighbor *on)
 
 235   if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
 
 236       on->ospf6_if->state == OSPF6_INTERFACE_DR ||
 
 237       on->ospf6_if->state == OSPF6_INTERFACE_BDR)
 
 240   if (on->ospf6_if->drouter == on->router_id ||
 
 241       on->ospf6_if->bdrouter == on->router_id)
 
 248 hello_received (struct thread *thread)
 
 250   struct ospf6_neighbor *on;
 
 252   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 255   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 256     zlog_debug ("Neighbor Event %s: *HelloReceived*", on->name);
 
 258   /* reset Inactivity Timer */
 
 259   THREAD_OFF (on->inactivity_timer);
 
 260   on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
 
 261                                            on->ospf6_if->dead_interval);
 
 263   if (on->state <= OSPF6_NEIGHBOR_DOWN)
 
 264     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
 
 265                                  OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
 
 271 twoway_received (struct thread *thread)
 
 273   struct ospf6_neighbor *on;
 
 275   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 278   if (on->state > OSPF6_NEIGHBOR_INIT)
 
 281   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 282     zlog_debug ("Neighbor Event %s: *2Way-Received*", on->name);
 
 284   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
 
 286   if (! need_adjacency (on))
 
 288       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
 
 289                                    OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
 
 293   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
 
 294                                OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
 
 295   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
 
 296   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
 
 297   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
 
 299   THREAD_OFF (on->thread_send_dbdesc);
 
 300   on->thread_send_dbdesc =
 
 301     thread_add_event (master, ospf6_dbdesc_send, on, 0);
 
 307 negotiation_done (struct thread *thread)
 
 309   struct ospf6_neighbor *on;
 
 310   struct ospf6_lsa *lsa;
 
 312   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 315   if (on->state != OSPF6_NEIGHBOR_EXSTART)
 
 318   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 319     zlog_debug ("Neighbor Event %s: *NegotiationDone*", on->name);
 
 322   ospf6_lsdb_remove_all (on->summary_list);
 
 323   ospf6_lsdb_remove_all (on->request_list);
 
 324   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 325        lsa = ospf6_lsdb_next (lsa))
 
 327       ospf6_decrement_retrans_count (lsa);
 
 328       ospf6_lsdb_remove (lsa, on->retrans_list);
 
 331   /* Interface scoped LSAs */
 
 332   for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
 
 333        lsa = ospf6_lsdb_next (lsa))
 
 335       if (OSPF6_LSA_IS_MAXAGE (lsa))
 
 337           ospf6_increment_retrans_count (lsa);
 
 338           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
 
 341         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
 
 344   /* Area scoped LSAs */
 
 345   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
 
 346        lsa = ospf6_lsdb_next (lsa))
 
 348       if (OSPF6_LSA_IS_MAXAGE (lsa))
 
 350           ospf6_increment_retrans_count (lsa);
 
 351           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
 
 354         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
 
 358   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
 
 359        lsa = ospf6_lsdb_next (lsa))
 
 361       if (OSPF6_LSA_IS_MAXAGE (lsa))
 
 363           ospf6_increment_retrans_count (lsa);
 
 364           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
 
 367         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
 
 370   UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
 
 371   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on,
 
 372                                OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
 
 378 exchange_done (struct thread *thread)
 
 380   struct ospf6_neighbor *on;
 
 382   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 385   if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
 
 388   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 389     zlog_debug ("Neighbor Event %s: *ExchangeDone*", on->name);
 
 391   THREAD_OFF (on->thread_send_dbdesc);
 
 392   ospf6_lsdb_remove_all (on->dbdesc_list);
 
 395   thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
 
 396                     on->ospf6_if->dead_interval);
 
 399   if (on->request_list->count == 0)
 
 400     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
 
 401                                  OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
 
 404       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on,
 
 405                                    OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
 
 407       if (on->thread_send_lsreq == NULL)
 
 408         on->thread_send_lsreq =
 
 409           thread_add_event (master, ospf6_lsreq_send, on, 0);
 
 415 /* Check loading state. */
 
 417 ospf6_check_nbr_loading (struct ospf6_neighbor *on)
 
 420   /* RFC2328 Section 10.9: When the neighbor responds to these requests
 
 421      with the proper Link State Update packet(s), the Link state request
 
 422      list is truncated and a new Link State Request packet is sent.
 
 424   if ((on->state == OSPF6_NEIGHBOR_LOADING) ||
 
 425       (on->state == OSPF6_NEIGHBOR_EXCHANGE))
 
 427       if (on->request_list->count == 0)
 
 428         thread_add_event (master, loading_done, on, 0);
 
 429       else if (on->last_ls_req == NULL)
 
 431           if (on->thread_send_lsreq != NULL)
 
 432             THREAD_OFF (on->thread_send_lsreq);
 
 433           on->thread_send_lsreq =
 
 434             thread_add_event (master, ospf6_lsreq_send, on, 0);
 
 440 loading_done (struct thread *thread)
 
 442   struct ospf6_neighbor *on;
 
 444   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 447   if (on->state != OSPF6_NEIGHBOR_LOADING)
 
 450   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 451     zlog_debug ("Neighbor Event %s: *LoadingDone*", on->name);
 
 453   assert (on->request_list->count == 0);
 
 455   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
 
 456                                OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
 
 462 adj_ok (struct thread *thread)
 
 464   struct ospf6_neighbor *on;
 
 465   struct ospf6_lsa *lsa;
 
 467   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 470   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 471     zlog_debug ("Neighbor Event %s: *AdjOK?*", on->name);
 
 473   if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
 
 475       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
 
 476                                    OSPF6_NEIGHBOR_EVENT_ADJ_OK);
 
 477       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
 
 478       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
 
 479       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
 
 481       THREAD_OFF (on->thread_send_dbdesc);
 
 482       on->thread_send_dbdesc =
 
 483         thread_add_event (master, ospf6_dbdesc_send, on, 0);
 
 486   else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
 
 487            ! need_adjacency (on))
 
 489       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
 
 490                                    OSPF6_NEIGHBOR_EVENT_ADJ_OK);
 
 491       ospf6_lsdb_remove_all (on->summary_list);
 
 492       ospf6_lsdb_remove_all (on->request_list);
 
 493       for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 494            lsa = ospf6_lsdb_next (lsa))
 
 496           ospf6_decrement_retrans_count (lsa);
 
 497           ospf6_lsdb_remove (lsa, on->retrans_list);
 
 505 seqnumber_mismatch (struct thread *thread)
 
 507   struct ospf6_neighbor *on;
 
 508   struct ospf6_lsa *lsa;
 
 510   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 513   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
 
 516   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 517     zlog_debug ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
 
 519   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
 
 520                                OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
 
 521   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
 
 522   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
 
 523   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
 
 525   ospf6_lsdb_remove_all (on->summary_list);
 
 526   ospf6_lsdb_remove_all (on->request_list);
 
 527   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 528        lsa = ospf6_lsdb_next (lsa))
 
 530       ospf6_decrement_retrans_count (lsa);
 
 531       ospf6_lsdb_remove (lsa, on->retrans_list);
 
 534   THREAD_OFF (on->thread_send_dbdesc);
 
 535   on->dbdesc_seqnum++;          /* Incr seqnum as per RFC2328, sec 10.3 */
 
 537   on->thread_send_dbdesc =
 
 538     thread_add_event (master, ospf6_dbdesc_send, on, 0);
 
 544 bad_lsreq (struct thread *thread)
 
 546   struct ospf6_neighbor *on;
 
 547   struct ospf6_lsa *lsa;
 
 549   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 552   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
 
 555   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 556     zlog_debug ("Neighbor Event %s: *BadLSReq*", on->name);
 
 558   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
 
 559                                OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
 
 560   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
 
 561   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
 
 562   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
 
 564   ospf6_lsdb_remove_all (on->summary_list);
 
 565   ospf6_lsdb_remove_all (on->request_list);
 
 566   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 567        lsa = ospf6_lsdb_next (lsa))
 
 569       ospf6_decrement_retrans_count (lsa);
 
 570       ospf6_lsdb_remove (lsa, on->retrans_list);
 
 573   THREAD_OFF (on->thread_send_dbdesc);
 
 574   on->dbdesc_seqnum++;          /* Incr seqnum as per RFC2328, sec 10.3 */
 
 576   on->thread_send_dbdesc =
 
 577     thread_add_event (master, ospf6_dbdesc_send, on, 0);
 
 583 oneway_received (struct thread *thread)
 
 585   struct ospf6_neighbor *on;
 
 586   struct ospf6_lsa *lsa;
 
 588   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 591   if (on->state < OSPF6_NEIGHBOR_TWOWAY)
 
 594   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 595     zlog_debug ("Neighbor Event %s: *1Way-Received*", on->name);
 
 597   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
 
 598                                OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
 
 599   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
 
 601   ospf6_lsdb_remove_all (on->summary_list);
 
 602   ospf6_lsdb_remove_all (on->request_list);
 
 603   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 604        lsa = ospf6_lsdb_next (lsa))
 
 606       ospf6_decrement_retrans_count (lsa);
 
 607       ospf6_lsdb_remove (lsa, on->retrans_list);
 
 610   THREAD_OFF (on->thread_send_dbdesc);
 
 611   THREAD_OFF (on->thread_send_lsreq);
 
 612   THREAD_OFF (on->thread_send_lsupdate);
 
 613   THREAD_OFF (on->thread_send_lsack);
 
 619 inactivity_timer (struct thread *thread)
 
 621   struct ospf6_neighbor *on;
 
 623   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
 
 626   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
 627     zlog_debug ("Neighbor Event %s: *InactivityTimer*", on->name);
 
 629   on->inactivity_timer = NULL;
 
 630   on->drouter = on->prev_drouter = 0;
 
 631   on->bdrouter = on->prev_bdrouter = 0;
 
 633   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on,
 
 634                                OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
 
 635   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
 
 637   listnode_delete (on->ospf6_if->neighbor_list, on);
 
 638   ospf6_neighbor_delete (on);
 
 646 /* show neighbor structure */
 
 648 ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
 
 652   struct timeval now, res;
 
 657   /* Router-ID (Name) */
 
 658   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
 
 659 #ifdef HAVE_GETNAMEINFO
 
 662 #endif /*HAVE_GETNAMEINFO*/
 
 664   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
 
 668   if (on->inactivity_timer)
 
 670       s = on->inactivity_timer->u.sands.tv_sec - recent_relative_time().tv_sec;
 
 676   snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
 
 679   if (if_is_pointopoint (on->ospf6_if->interface))
 
 680     snprintf (nstate, sizeof (nstate), "PointToPoint");
 
 683       if (on->router_id == on->drouter)
 
 684         snprintf (nstate, sizeof (nstate), "DR");
 
 685       else if (on->router_id == on->bdrouter)
 
 686         snprintf (nstate, sizeof (nstate), "BDR");
 
 688         snprintf (nstate, sizeof (nstate), "DROther");
 
 692   timersub (&now, &on->last_changed, &res);
 
 693   timerstring (&res, duration, sizeof (duration));
 
 696   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
 
 697            "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
 
 698            "I/F", "State", VNL);
 
 701   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
 
 702            router_id, on->priority, deadtime,
 
 703            ospf6_neighbor_state_str[on->state], nstate, duration,
 
 704            on->ospf6_if->interface->name,
 
 705            ospf6_interface_state_str[on->ospf6_if->state], VNL);
 
 709 ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
 
 712   char drouter[16], bdrouter[16];
 
 714   struct timeval now, res;
 
 717     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
 
 718              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
 
 722   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
 
 723   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
 
 724   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
 
 726   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
 
 727   timersub (&now, &on->last_changed, &res);
 
 728   timerstring (&res, duration, sizeof (duration));
 
 730   vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
 
 731            router_id, ospf6_neighbor_state_str[on->state],
 
 732            duration, drouter, bdrouter, on->ospf6_if->interface->name,
 
 733            ospf6_interface_state_str[on->ospf6_if->state],
 
 738 ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
 
 740   char drouter[16], bdrouter[16];
 
 741   char linklocal_addr[64], duration[32];
 
 742   struct timeval now, res;
 
 743   struct ospf6_lsa *lsa;
 
 745   inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
 
 746              sizeof (linklocal_addr));
 
 747   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
 
 748   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
 
 750   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
 
 751   timersub (&now, &on->last_changed, &res);
 
 752   timerstring (&res, duration, sizeof (duration));
 
 754   vty_out (vty, " Neighbor %s%s", on->name,
 
 756   vty_out (vty, "    Area %s via interface %s (ifindex %d)%s",
 
 757            on->ospf6_if->area->name,
 
 758            on->ospf6_if->interface->name,
 
 759            on->ospf6_if->interface->ifindex,
 
 761   vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
 
 762            on->ifindex, linklocal_addr,
 
 764   vty_out (vty, "    State %s for a duration of %s%s",
 
 765            ospf6_neighbor_state_str[on->state], duration,
 
 767   vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
 
 768            drouter, bdrouter, on->priority,
 
 770   vty_out (vty, "    DbDesc status: %s%s%s SeqNum: %#lx%s",
 
 771            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
 
 772            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
 
 773            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
 
 774             "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
 
 777   vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
 
 779   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
 
 780        lsa = ospf6_lsdb_next (lsa))
 
 781     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 783   vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
 
 785   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
 
 786        lsa = ospf6_lsdb_next (lsa))
 
 787     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 789   vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
 
 791   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
 
 792        lsa = ospf6_lsdb_next (lsa))
 
 793     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 796   if (on->thread_send_dbdesc)
 
 797     timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
 
 798   timerstring (&res, duration, sizeof (duration));
 
 799   vty_out (vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
 
 800            on->dbdesc_list->count, duration,
 
 801            (on->thread_send_dbdesc ? "on" : "off"),
 
 803   for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
 
 804        lsa = ospf6_lsdb_next (lsa))
 
 805     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 808   if (on->thread_send_lsreq)
 
 809     timersub (&on->thread_send_lsreq->u.sands, &now, &res);
 
 810   timerstring (&res, duration, sizeof (duration));
 
 811   vty_out (vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]%s",
 
 812            on->request_list->count, duration,
 
 813            (on->thread_send_lsreq ? "on" : "off"),
 
 815   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
 
 816        lsa = ospf6_lsdb_next (lsa))
 
 817     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 820   if (on->thread_send_lsupdate)
 
 821     timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
 
 822   timerstring (&res, duration, sizeof (duration));
 
 823   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
 
 824            on->lsupdate_list->count, duration,
 
 825            (on->thread_send_lsupdate ? "on" : "off"),
 
 827   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
 
 828        lsa = ospf6_lsdb_next (lsa))
 
 829     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 832   if (on->thread_send_lsack)
 
 833     timersub (&on->thread_send_lsack->u.sands, &now, &res);
 
 834   timerstring (&res, duration, sizeof (duration));
 
 835   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
 
 836            on->lsack_list->count, duration,
 
 837            (on->thread_send_lsack ? "on" : "off"),
 
 839   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
 
 840        lsa = ospf6_lsdb_next (lsa))
 
 841     vty_out (vty, "      %s%s", lsa->name, VNL);
 
 845 DEFUN (show_ipv6_ospf6_neighbor,
 
 846        show_ipv6_ospf6_neighbor_cmd,
 
 847        "show ipv6 ospf6 neighbor",
 
 854   struct ospf6_neighbor *on;
 
 855   struct ospf6_interface *oi;
 
 856   struct ospf6_area *oa;
 
 857   struct listnode *i, *j, *k;
 
 858   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
 
 860   OSPF6_CMD_CHECK_RUNNING ();
 
 861   showfunc = ospf6_neighbor_show;
 
 865       if (! strncmp (argv[0], "de", 2))
 
 866         showfunc = ospf6_neighbor_show_detail;
 
 867       else if (! strncmp (argv[0], "dr", 2))
 
 868         showfunc = ospf6_neighbor_show_drchoice;
 
 871   if (showfunc == ospf6_neighbor_show)
 
 872     vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
 
 873              "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
 
 874              "I/F", "State", VNL);
 
 875   else if (showfunc == ospf6_neighbor_show_drchoice)
 
 876     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
 
 877              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
 
 880   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa))
 
 881     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
 
 882       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
 
 883         (*showfunc) (vty, on);
 
 888 ALIAS (show_ipv6_ospf6_neighbor,
 
 889        show_ipv6_ospf6_neighbor_detail_cmd,
 
 890        "show ipv6 ospf6 neighbor (detail|drchoice)",
 
 896        "Display DR choices\n"
 
 899 DEFUN (show_ipv6_ospf6_neighbor_one,
 
 900        show_ipv6_ospf6_neighbor_one_cmd,
 
 901        "show ipv6 ospf6 neighbor A.B.C.D",
 
 906        "Specify Router-ID as IPv4 address notation\n"
 
 909   struct ospf6_neighbor *on;
 
 910   struct ospf6_interface *oi;
 
 911   struct ospf6_area *oa;
 
 912   struct listnode *i, *j, *k;
 
 913   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
 
 916   OSPF6_CMD_CHECK_RUNNING ();
 
 917   showfunc = ospf6_neighbor_show_detail;
 
 919   if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
 
 921       vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
 
 926   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa))
 
 927     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
 
 928       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
 
 929         (*showfunc) (vty, on);
 
 935 ospf6_neighbor_init (void)
 
 937   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
 
 938   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
 
 941 DEFUN (debug_ospf6_neighbor,
 
 942        debug_ospf6_neighbor_cmd,
 
 943        "debug ospf6 neighbor",
 
 946        "Debug OSPFv3 Neighbor\n"
 
 949   unsigned char level = 0;
 
 952       if (! strncmp (argv[0], "s", 1))
 
 953         level = OSPF6_DEBUG_NEIGHBOR_STATE;
 
 954       if (! strncmp (argv[0], "e", 1))
 
 955         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
 
 958     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
 
 960   OSPF6_DEBUG_NEIGHBOR_ON (level);
 
 964 ALIAS (debug_ospf6_neighbor,
 
 965        debug_ospf6_neighbor_detail_cmd,
 
 966        "debug ospf6 neighbor (state|event)",
 
 969        "Debug OSPFv3 Neighbor\n"
 
 970        "Debug OSPFv3 Neighbor State Change\n"
 
 971        "Debug OSPFv3 Neighbor Event\n"
 
 974 DEFUN (no_debug_ospf6_neighbor,
 
 975        no_debug_ospf6_neighbor_cmd,
 
 976        "no debug ospf6 neighbor",
 
 980        "Debug OSPFv3 Neighbor\n"
 
 983   unsigned char level = 0;
 
 986       if (! strncmp (argv[0], "s", 1))
 
 987         level = OSPF6_DEBUG_NEIGHBOR_STATE;
 
 988       if (! strncmp (argv[0], "e", 1))
 
 989         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
 
 992     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
 
 994   OSPF6_DEBUG_NEIGHBOR_OFF (level);
 
 998 ALIAS (no_debug_ospf6_neighbor,
 
 999        no_debug_ospf6_neighbor_detail_cmd,
 
1000        "no debug ospf6 neighbor (state|event)",
 
1004        "Debug OSPFv3 Neighbor\n"
 
1005        "Debug OSPFv3 Neighbor State Change\n"
 
1006        "Debug OSPFv3 Neighbor Event\n"
 
1010 config_write_ospf6_debug_neighbor (struct vty *vty)
 
1012   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
 
1013       IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
1014     vty_out (vty, "debug ospf6 neighbor%s", VNL);
 
1015   else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
 
1016     vty_out (vty, "debug ospf6 neighbor state%s", VNL);
 
1017   else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 
1018     vty_out (vty, "debug ospf6 neighbor event%s", VNL);
 
1023 install_element_ospf6_debug_neighbor (void)
 
1025   install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
 
1026   install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
 
1027   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
 
1028   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
 
1029   install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
 
1030   install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
 
1031   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
 
1032   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);