Merge tag 'upstream/1.2.4'
[quagga-debian.git] / ospf6d / ospf6_neighbor.c
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
22 #include <zebra.h>
23
24 #include "log.h"
25 #include "memory.h"
26 #include "thread.h"
27 #include "linklist.h"
28 #include "vty.h"
29 #include "command.h"
30
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"
42 #include "ospf6d.h"
43
44 unsigned char conf_debug_ospf6_neighbor = 0;
45
46 const char *ospf6_neighbor_state_str[] =
47 { "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
48   "Loading", "Full", NULL };
49
50 static const char *ospf6_neighbor_event_str[] =
51   {
52     "NoEvent",
53     "HelloReceived",
54     "2-WayReceived",
55     "NegotiationDone",
56     "ExchangeDone",
57     "LoadingDone",
58     "AdjOK?",
59     "SeqNumberMismatch",
60     "BadLSReq",
61     "1-WayReceived",
62     "InactivityTimer",
63   };
64
65 static const char *
66 ospf6_neighbor_event_string (int event)
67 {
68   #define OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING "UnknownEvent"
69
70   if (event < OSPF6_NEIGHBOR_EVENT_MAX_EVENT)
71       return ospf6_neighbor_event_str[event];
72   return OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING;
73 }
74
75 int
76 ospf6_neighbor_cmp (void *va, void *vb)
77 {
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);
81 }
82
83 struct ospf6_neighbor *
84 ospf6_neighbor_lookup (u_int32_t router_id,
85                        struct ospf6_interface *oi)
86 {
87   struct listnode *n;
88   struct ospf6_neighbor *on;
89
90   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, n, on))
91     if (on->router_id == router_id)
92       return on;
93   
94   return (struct ospf6_neighbor *) NULL;
95 }
96
97 /* create ospf6_neighbor */
98 struct ospf6_neighbor *
99 ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
100 {
101   struct ospf6_neighbor *on;
102   char buf[16];
103
104   on = (struct ospf6_neighbor *)
105     XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
106   if (on == NULL)
107     {
108       zlog_warn ("neighbor: malloc failed");
109       return NULL;
110     }
111
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);
116   on->ospf6_if = oi;
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;
121
122   on->summary_list = ospf6_lsdb_create (on);
123   on->request_list = ospf6_lsdb_create (on);
124   on->retrans_list = ospf6_lsdb_create (on);
125
126   on->dbdesc_list = ospf6_lsdb_create (on);
127   on->lsupdate_list = ospf6_lsdb_create (on);
128   on->lsack_list = ospf6_lsdb_create (on);
129
130   listnode_add_sort (oi->neighbor_list, on);
131   return on;
132 }
133
134 void
135 ospf6_neighbor_delete (struct ospf6_neighbor *on)
136 {
137   struct ospf6_lsa *lsa;
138
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))
143     {
144       ospf6_decrement_retrans_count (lsa);
145       ospf6_lsdb_remove (lsa, on->retrans_list);
146     }
147
148   ospf6_lsdb_remove_all (on->dbdesc_list);
149   ospf6_lsdb_remove_all (on->lsupdate_list);
150   ospf6_lsdb_remove_all (on->lsack_list);
151
152   ospf6_lsdb_delete (on->summary_list);
153   ospf6_lsdb_delete (on->request_list);
154   ospf6_lsdb_delete (on->retrans_list);
155
156   ospf6_lsdb_delete (on->dbdesc_list);
157   ospf6_lsdb_delete (on->lsupdate_list);
158   ospf6_lsdb_delete (on->lsack_list);
159
160   THREAD_OFF (on->inactivity_timer);
161
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);
166
167   XFREE (MTYPE_OSPF6_NEIGHBOR, on);
168 }
169
170 static void
171 ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int event)
172 {
173   u_char prev_state;
174
175   prev_state = on->state;
176   on->state = next_state;
177
178   if (prev_state == next_state)
179     return;
180
181   on->state_change++;
182   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
183
184   /* log */
185   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
186     {
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));
191     }
192
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));
203
204   if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
205     {
206       OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
207       if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
208         {
209           OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
210           OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
211         }
212       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
213     }
214
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);
220
221 #ifdef HAVE_SNMP
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);
227 #endif
228
229 }
230
231 /* RFC2328 section 10.4 */
232 static int
233 need_adjacency (struct ospf6_neighbor *on)
234 {
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)
238     return 1;
239
240   if (on->ospf6_if->drouter == on->router_id ||
241       on->ospf6_if->bdrouter == on->router_id)
242     return 1;
243
244   return 0;
245 }
246
247 int
248 hello_received (struct thread *thread)
249 {
250   struct ospf6_neighbor *on;
251
252   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
253   assert (on);
254
255   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
256     zlog_debug ("Neighbor Event %s: *HelloReceived*", on->name);
257
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);
262
263   if (on->state <= OSPF6_NEIGHBOR_DOWN)
264     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
265                                  OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
266
267   return 0;
268 }
269
270 int
271 twoway_received (struct thread *thread)
272 {
273   struct ospf6_neighbor *on;
274
275   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
276   assert (on);
277
278   if (on->state > OSPF6_NEIGHBOR_INIT)
279     return 0;
280
281   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
282     zlog_debug ("Neighbor Event %s: *2Way-Received*", on->name);
283
284   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
285
286   if (! need_adjacency (on))
287     {
288       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
289                                    OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
290       return 0;
291     }
292
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);
298
299   THREAD_OFF (on->thread_send_dbdesc);
300   on->thread_send_dbdesc =
301     thread_add_event (master, ospf6_dbdesc_send, on, 0);
302
303   return 0;
304 }
305
306 int
307 negotiation_done (struct thread *thread)
308 {
309   struct ospf6_neighbor *on;
310   struct ospf6_lsa *lsa;
311
312   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
313   assert (on);
314
315   if (on->state != OSPF6_NEIGHBOR_EXSTART)
316     return 0;
317
318   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
319     zlog_debug ("Neighbor Event %s: *NegotiationDone*", on->name);
320
321   /* clear ls-list */
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))
326     {
327       ospf6_decrement_retrans_count (lsa);
328       ospf6_lsdb_remove (lsa, on->retrans_list);
329     }
330
331   /* Interface scoped LSAs */
332   for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
333        lsa = ospf6_lsdb_next (lsa))
334     {
335       if (OSPF6_LSA_IS_MAXAGE (lsa))
336         {
337           ospf6_increment_retrans_count (lsa);
338           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
339         }
340       else
341         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
342     }
343
344   /* Area scoped LSAs */
345   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
346        lsa = ospf6_lsdb_next (lsa))
347     {
348       if (OSPF6_LSA_IS_MAXAGE (lsa))
349         {
350           ospf6_increment_retrans_count (lsa);
351           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
352         }
353       else
354         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
355     }
356
357   /* AS scoped LSAs */
358   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
359        lsa = ospf6_lsdb_next (lsa))
360     {
361       if (OSPF6_LSA_IS_MAXAGE (lsa))
362         {
363           ospf6_increment_retrans_count (lsa);
364           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
365         }
366       else
367         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
368     }
369
370   UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
371   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on,
372                                OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
373
374   return 0;
375 }
376
377 int
378 exchange_done (struct thread *thread)
379 {
380   struct ospf6_neighbor *on;
381
382   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
383   assert (on);
384
385   if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
386     return 0;
387
388   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
389     zlog_debug ("Neighbor Event %s: *ExchangeDone*", on->name);
390
391   THREAD_OFF (on->thread_send_dbdesc);
392   ospf6_lsdb_remove_all (on->dbdesc_list);
393
394 /* XXX
395   thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
396                     on->ospf6_if->dead_interval);
397 */
398
399   if (on->request_list->count == 0)
400     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
401                                  OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
402   else
403     {
404       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on,
405                                    OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
406
407       if (on->thread_send_lsreq == NULL)
408         on->thread_send_lsreq =
409           thread_add_event (master, ospf6_lsreq_send, on, 0);
410     }
411
412   return 0;
413 }
414
415 /* Check loading state. */
416 void
417 ospf6_check_nbr_loading (struct ospf6_neighbor *on)
418 {
419
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.
423   */
424   if ((on->state == OSPF6_NEIGHBOR_LOADING) ||
425       (on->state == OSPF6_NEIGHBOR_EXCHANGE))
426     {
427       if (on->request_list->count == 0)
428         thread_add_event (master, loading_done, on, 0);
429       else if (on->last_ls_req == NULL)
430         {
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);
435         }
436     }
437 }
438
439 int
440 loading_done (struct thread *thread)
441 {
442   struct ospf6_neighbor *on;
443
444   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
445   assert (on);
446
447   if (on->state != OSPF6_NEIGHBOR_LOADING)
448     return 0;
449
450   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
451     zlog_debug ("Neighbor Event %s: *LoadingDone*", on->name);
452
453   assert (on->request_list->count == 0);
454
455   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
456                                OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
457
458   return 0;
459 }
460
461 int
462 adj_ok (struct thread *thread)
463 {
464   struct ospf6_neighbor *on;
465   struct ospf6_lsa *lsa;
466
467   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
468   assert (on);
469
470   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
471     zlog_debug ("Neighbor Event %s: *AdjOK?*", on->name);
472
473   if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
474     {
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);
480
481       THREAD_OFF (on->thread_send_dbdesc);
482       on->thread_send_dbdesc =
483         thread_add_event (master, ospf6_dbdesc_send, on, 0);
484
485     }
486   else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
487            ! need_adjacency (on))
488     {
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))
495         {
496           ospf6_decrement_retrans_count (lsa);
497           ospf6_lsdb_remove (lsa, on->retrans_list);
498         }
499     }
500
501   return 0;
502 }
503
504 int
505 seqnumber_mismatch (struct thread *thread)
506 {
507   struct ospf6_neighbor *on;
508   struct ospf6_lsa *lsa;
509
510   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
511   assert (on);
512
513   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
514     return 0;
515
516   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
517     zlog_debug ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
518
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);
524
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))
529     {
530       ospf6_decrement_retrans_count (lsa);
531       ospf6_lsdb_remove (lsa, on->retrans_list);
532     }
533
534   THREAD_OFF (on->thread_send_dbdesc);
535   on->dbdesc_seqnum++;          /* Incr seqnum as per RFC2328, sec 10.3 */
536
537   on->thread_send_dbdesc =
538     thread_add_event (master, ospf6_dbdesc_send, on, 0);
539
540   return 0;
541 }
542
543 int
544 bad_lsreq (struct thread *thread)
545 {
546   struct ospf6_neighbor *on;
547   struct ospf6_lsa *lsa;
548
549   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
550   assert (on);
551
552   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
553     return 0;
554
555   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
556     zlog_debug ("Neighbor Event %s: *BadLSReq*", on->name);
557
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);
563
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))
568     {
569       ospf6_decrement_retrans_count (lsa);
570       ospf6_lsdb_remove (lsa, on->retrans_list);
571     }
572
573   THREAD_OFF (on->thread_send_dbdesc);
574   on->dbdesc_seqnum++;          /* Incr seqnum as per RFC2328, sec 10.3 */
575
576   on->thread_send_dbdesc =
577     thread_add_event (master, ospf6_dbdesc_send, on, 0);
578
579   return 0;
580 }
581
582 int
583 oneway_received (struct thread *thread)
584 {
585   struct ospf6_neighbor *on;
586   struct ospf6_lsa *lsa;
587
588   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
589   assert (on);
590
591   if (on->state < OSPF6_NEIGHBOR_TWOWAY)
592     return 0;
593
594   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
595     zlog_debug ("Neighbor Event %s: *1Way-Received*", on->name);
596
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);
600
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))
605     {
606       ospf6_decrement_retrans_count (lsa);
607       ospf6_lsdb_remove (lsa, on->retrans_list);
608     }
609
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);
614
615   return 0;
616 }
617
618 int
619 inactivity_timer (struct thread *thread)
620 {
621   struct ospf6_neighbor *on;
622
623   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
624   assert (on);
625
626   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
627     zlog_debug ("Neighbor Event %s: *InactivityTimer*", on->name);
628
629   on->inactivity_timer = NULL;
630   on->drouter = on->prev_drouter = 0;
631   on->bdrouter = on->prev_bdrouter = 0;
632
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);
636
637   listnode_delete (on->ospf6_if->neighbor_list, on);
638   ospf6_neighbor_delete (on);
639
640   return 0;
641 }
642
643
644
645 /* vty functions */
646 /* show neighbor structure */
647 static void
648 ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
649 {
650   char router_id[16];
651   char duration[16];
652   struct timeval now, res;
653   char nstate[16];
654   char deadtime[16];
655   long h, m, s;
656
657   /* Router-ID (Name) */
658   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
659 #ifdef HAVE_GETNAMEINFO
660   {
661   }
662 #endif /*HAVE_GETNAMEINFO*/
663
664   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
665
666   /* Dead time */
667   h = m = s = 0;
668   if (on->inactivity_timer)
669     {
670       s = on->inactivity_timer->u.sands.tv_sec - recent_relative_time().tv_sec;
671       h = s / 3600;
672       s -= h * 3600;
673       m = s / 60;
674       s -= m * 60;
675     }
676   snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
677
678   /* Neighbor State */
679   if (if_is_pointopoint (on->ospf6_if->interface))
680     snprintf (nstate, sizeof (nstate), "PointToPoint");
681   else
682     {
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");
687       else
688         snprintf (nstate, sizeof (nstate), "DROther");
689     }
690
691   /* Duration */
692   timersub (&now, &on->last_changed, &res);
693   timerstring (&res, duration, sizeof (duration));
694
695   /*
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);
699   */
700
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);
706 }
707
708 static void
709 ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
710 {
711   char router_id[16];
712   char drouter[16], bdrouter[16];
713   char duration[16];
714   struct timeval now, res;
715
716 /*
717     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
718              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
719              "State", VNL);
720 */
721
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));
725
726   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
727   timersub (&now, &on->last_changed, &res);
728   timerstring (&res, duration, sizeof (duration));
729
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],
734            VNL);
735 }
736
737 static void
738 ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
739 {
740   char drouter[16], bdrouter[16];
741   char linklocal_addr[64], duration[32];
742   struct timeval now, res;
743   struct ospf6_lsa *lsa;
744
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));
749
750   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
751   timersub (&now, &on->last_changed, &res);
752   timerstring (&res, duration, sizeof (duration));
753
754   vty_out (vty, " Neighbor %s%s", on->name,
755            VNL);
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,
760            VNL);
761   vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
762            on->ifindex, linklocal_addr,
763            VNL);
764   vty_out (vty, "    State %s for a duration of %s%s",
765            ospf6_neighbor_state_str[on->state], duration,
766            VNL);
767   vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
768            drouter, bdrouter, on->priority,
769            VNL);
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),
775            VNL);
776
777   vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
778            VNL);
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);
782
783   vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
784            VNL);
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);
788
789   vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
790            VNL);
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);
794
795   timerclear (&res);
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"),
802            VNL);
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);
806
807   timerclear (&res);
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"),
814            VNL);
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);
818
819   timerclear (&res);
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"),
826            VNL);
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);
830
831   timerclear (&res);
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"),
838            VNL);
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);
842
843 }
844
845 DEFUN (show_ipv6_ospf6_neighbor,
846        show_ipv6_ospf6_neighbor_cmd,
847        "show ipv6 ospf6 neighbor",
848        SHOW_STR
849        IP6_STR
850        OSPF6_STR
851        "Neighbor list\n"
852       )
853 {
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 *);
859
860   OSPF6_CMD_CHECK_RUNNING ();
861   showfunc = ospf6_neighbor_show;
862
863   if (argc)
864     {
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;
869     }
870
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",
878              "State", VNL);
879
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);
884
885   return CMD_SUCCESS;
886 }
887
888 ALIAS (show_ipv6_ospf6_neighbor,
889        show_ipv6_ospf6_neighbor_detail_cmd,
890        "show ipv6 ospf6 neighbor (detail|drchoice)",
891        SHOW_STR
892        IP6_STR
893        OSPF6_STR
894        "Neighbor list\n"
895        "Display details\n"
896        "Display DR choices\n"
897       )
898
899 DEFUN (show_ipv6_ospf6_neighbor_one,
900        show_ipv6_ospf6_neighbor_one_cmd,
901        "show ipv6 ospf6 neighbor A.B.C.D",
902        SHOW_STR
903        IP6_STR
904        OSPF6_STR
905        "Neighbor list\n"
906        "Specify Router-ID as IPv4 address notation\n"
907       )
908 {
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 *);
914   u_int32_t router_id;
915
916   OSPF6_CMD_CHECK_RUNNING ();
917   showfunc = ospf6_neighbor_show_detail;
918
919   if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
920     {
921       vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
922                VNL);
923       return CMD_SUCCESS;
924     }
925
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);
930   
931   return CMD_SUCCESS;
932 }
933
934 void
935 ospf6_neighbor_init (void)
936 {
937   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
938   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
939 }
940
941 DEFUN (debug_ospf6_neighbor,
942        debug_ospf6_neighbor_cmd,
943        "debug ospf6 neighbor",
944        DEBUG_STR
945        OSPF6_STR
946        "Debug OSPFv3 Neighbor\n"
947       )
948 {
949   unsigned char level = 0;
950   if (argc)
951     {
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;
956     }
957   else
958     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
959
960   OSPF6_DEBUG_NEIGHBOR_ON (level);
961   return CMD_SUCCESS;
962 }
963
964 ALIAS (debug_ospf6_neighbor,
965        debug_ospf6_neighbor_detail_cmd,
966        "debug ospf6 neighbor (state|event)",
967        DEBUG_STR
968        OSPF6_STR
969        "Debug OSPFv3 Neighbor\n"
970        "Debug OSPFv3 Neighbor State Change\n"
971        "Debug OSPFv3 Neighbor Event\n"
972       )
973
974 DEFUN (no_debug_ospf6_neighbor,
975        no_debug_ospf6_neighbor_cmd,
976        "no debug ospf6 neighbor",
977        NO_STR
978        DEBUG_STR
979        OSPF6_STR
980        "Debug OSPFv3 Neighbor\n"
981       )
982 {
983   unsigned char level = 0;
984   if (argc)
985     {
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;
990     }
991   else
992     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
993
994   OSPF6_DEBUG_NEIGHBOR_OFF (level);
995   return CMD_SUCCESS;
996 }
997
998 ALIAS (no_debug_ospf6_neighbor,
999        no_debug_ospf6_neighbor_detail_cmd,
1000        "no debug ospf6 neighbor (state|event)",
1001        NO_STR
1002        DEBUG_STR
1003        OSPF6_STR
1004        "Debug OSPFv3 Neighbor\n"
1005        "Debug OSPFv3 Neighbor State Change\n"
1006        "Debug OSPFv3 Neighbor Event\n"
1007       )
1008
1009 int
1010 config_write_ospf6_debug_neighbor (struct vty *vty)
1011 {
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);
1019   return 0;
1020 }
1021
1022 void
1023 install_element_ospf6_debug_neighbor (void)
1024 {
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);
1033 }
1034
1035
1036