blob: acfd1a429d6866765597b6bc86c43e354007fbd3 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
hasso508e53e2004-05-18 18:57:06 +00002 * Copyright (C) 2003 Yasuhiro Ohara
paul718e3742002-12-13 20:15:29 +00003 *
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
paul718e3742002-12-13 20:15:29 +000022#include <zebra.h>
23
24#include "log.h"
hasso508e53e2004-05-18 18:57:06 +000025#include "memory.h"
paul718e3742002-12-13 20:15:29 +000026#include "thread.h"
27#include "linklist.h"
28#include "vty.h"
29#include "command.h"
30
hasso508e53e2004-05-18 18:57:06 +000031#include "ospf6d.h"
32#include "ospf6_proto.h"
paul718e3742002-12-13 20:15:29 +000033#include "ospf6_lsa.h"
34#include "ospf6_lsdb.h"
hasso508e53e2004-05-18 18:57:06 +000035#include "ospf6_message.h"
36#include "ospf6_top.h"
37#include "ospf6_area.h"
38#include "ospf6_interface.h"
39#include "ospf6_neighbor.h"
40#include "ospf6_intra.h"
paul718e3742002-12-13 20:15:29 +000041
hasso508e53e2004-05-18 18:57:06 +000042unsigned char conf_debug_ospf6_neighbor = 0;
43
44char *ospf6_neighbor_state_str[] =
45{ "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
46 "Loading", "Full", NULL };
paul718e3742002-12-13 20:15:29 +000047
48int
hasso508e53e2004-05-18 18:57:06 +000049ospf6_neighbor_cmp (void *va, void *vb)
paul718e3742002-12-13 20:15:29 +000050{
hasso508e53e2004-05-18 18:57:06 +000051 struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
52 struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
53 return (ntohl (ona->router_id) - ntohl (onb->router_id));
paul718e3742002-12-13 20:15:29 +000054}
55
hasso508e53e2004-05-18 18:57:06 +000056struct ospf6_neighbor *
57ospf6_neighbor_lookup (u_int32_t router_id,
58 struct ospf6_interface *oi)
paul718e3742002-12-13 20:15:29 +000059{
hasso508e53e2004-05-18 18:57:06 +000060 listnode n;
61 struct ospf6_neighbor *on;
paul718e3742002-12-13 20:15:29 +000062
hasso508e53e2004-05-18 18:57:06 +000063 for (n = listhead (oi->neighbor_list); n; nextnode (n))
paul718e3742002-12-13 20:15:29 +000064 {
hasso508e53e2004-05-18 18:57:06 +000065 on = (struct ospf6_neighbor *) getdata (n);
66 if (on->router_id == router_id)
67 return on;
paul718e3742002-12-13 20:15:29 +000068 }
hasso508e53e2004-05-18 18:57:06 +000069 return (struct ospf6_neighbor *) NULL;
paul718e3742002-12-13 20:15:29 +000070}
71
72/* create ospf6_neighbor */
73struct ospf6_neighbor *
hasso508e53e2004-05-18 18:57:06 +000074ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
paul718e3742002-12-13 20:15:29 +000075{
hasso508e53e2004-05-18 18:57:06 +000076 struct ospf6_neighbor *on;
77 char buf[16];
paul718e3742002-12-13 20:15:29 +000078
hasso508e53e2004-05-18 18:57:06 +000079 on = (struct ospf6_neighbor *)
paul718e3742002-12-13 20:15:29 +000080 XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
hasso508e53e2004-05-18 18:57:06 +000081 if (on == NULL)
paul718e3742002-12-13 20:15:29 +000082 {
83 zlog_warn ("neighbor: malloc failed");
84 return NULL;
85 }
86
hasso508e53e2004-05-18 18:57:06 +000087 memset (on, 0, sizeof (struct ospf6_neighbor));
paul718e3742002-12-13 20:15:29 +000088 inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
hasso508e53e2004-05-18 18:57:06 +000089 snprintf (on->name, sizeof (on->name), "%s%%%s",
90 buf, oi->interface->name);
91 on->ospf6_if = oi;
92 on->state = OSPF6_NEIGHBOR_DOWN;
93 gettimeofday (&on->last_changed, (struct timezone *) NULL);
94 on->router_id = router_id;
paul718e3742002-12-13 20:15:29 +000095
hasso508e53e2004-05-18 18:57:06 +000096 on->summary_list = ospf6_lsdb_create ();
97 on->request_list = ospf6_lsdb_create ();
98 on->retrans_list = ospf6_lsdb_create ();
paul718e3742002-12-13 20:15:29 +000099
hasso508e53e2004-05-18 18:57:06 +0000100 on->dbdesc_list = ospf6_lsdb_create ();
101 on->lsreq_list = ospf6_lsdb_create ();
102 on->lsupdate_list = ospf6_lsdb_create ();
103 on->lsack_list = ospf6_lsdb_create ();
paul718e3742002-12-13 20:15:29 +0000104
hasso508e53e2004-05-18 18:57:06 +0000105 listnode_add_sort (oi->neighbor_list, on);
106 return on;
paul718e3742002-12-13 20:15:29 +0000107}
108
109void
hasso508e53e2004-05-18 18:57:06 +0000110ospf6_neighbor_delete (struct ospf6_neighbor *on)
paul718e3742002-12-13 20:15:29 +0000111{
hasso508e53e2004-05-18 18:57:06 +0000112 ospf6_lsdb_remove_all (on->summary_list);
113 ospf6_lsdb_remove_all (on->request_list);
114 ospf6_lsdb_remove_all (on->retrans_list);
paul718e3742002-12-13 20:15:29 +0000115
hasso508e53e2004-05-18 18:57:06 +0000116 ospf6_lsdb_remove_all (on->dbdesc_list);
117 ospf6_lsdb_remove_all (on->lsreq_list);
118 ospf6_lsdb_remove_all (on->lsupdate_list);
119 ospf6_lsdb_remove_all (on->lsack_list);
paul718e3742002-12-13 20:15:29 +0000120
hasso508e53e2004-05-18 18:57:06 +0000121 ospf6_lsdb_delete (on->summary_list);
122 ospf6_lsdb_delete (on->request_list);
123 ospf6_lsdb_delete (on->retrans_list);
paul718e3742002-12-13 20:15:29 +0000124
hasso508e53e2004-05-18 18:57:06 +0000125 ospf6_lsdb_delete (on->dbdesc_list);
126 ospf6_lsdb_delete (on->lsreq_list);
127 ospf6_lsdb_delete (on->lsupdate_list);
128 ospf6_lsdb_delete (on->lsack_list);
paul718e3742002-12-13 20:15:29 +0000129
hasso508e53e2004-05-18 18:57:06 +0000130 THREAD_OFF (on->inactivity_timer);
131
132 THREAD_OFF (on->thread_send_dbdesc);
133 THREAD_OFF (on->thread_send_lsreq);
134 THREAD_OFF (on->thread_send_lsupdate);
135 THREAD_OFF (on->thread_send_lsack);
136
137 XFREE (MTYPE_OSPF6_NEIGHBOR, on);
paul718e3742002-12-13 20:15:29 +0000138}
139
hasso508e53e2004-05-18 18:57:06 +0000140static void
141ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
paul718e3742002-12-13 20:15:29 +0000142{
hasso508e53e2004-05-18 18:57:06 +0000143 u_char prev_state;
paul718e3742002-12-13 20:15:29 +0000144
hasso508e53e2004-05-18 18:57:06 +0000145 prev_state = on->state;
146 on->state = next_state;
147
148 if (prev_state == next_state)
149 return;
150
151 gettimeofday (&on->last_changed, (struct timezone *) NULL);
152
153 /* log */
154 if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
paul718e3742002-12-13 20:15:29 +0000155 {
hasso508e53e2004-05-18 18:57:06 +0000156 zlog_info ("Neighbor state change %s: [%s]->[%s]", on->name,
157 ospf6_neighbor_state_str[prev_state],
158 ospf6_neighbor_state_str[next_state]);
paul718e3742002-12-13 20:15:29 +0000159 }
hasso508e53e2004-05-18 18:57:06 +0000160
161 if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
162 {
163 OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
164 if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
165 {
166 OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
167 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
168 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
169 }
170 }
171
172#ifdef XXX
173 if (prev_state == NBS_FULL || next_state == NBS_FULL)
174 nbs_full_change (on->ospf6_interface);
175
176 /* check for LSAs that already reached MaxAge */
177 if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
178 prev_state == OSPF6_NEIGHBOR_LOADING) &&
179 (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
180 next_state != OSPF6_NEIGHBOR_LOADING))
181 {
182 ospf6_maxage_remover ();
183 }
184#endif /*XXX*/
185
paul718e3742002-12-13 20:15:29 +0000186}
187
hasso508e53e2004-05-18 18:57:06 +0000188/* RFC2328 section 10.4 */
189int
190need_adjacency (struct ospf6_neighbor *on)
191{
192 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
193 on->ospf6_if->state == OSPF6_INTERFACE_DR ||
194 on->ospf6_if->state == OSPF6_INTERFACE_BDR)
195 return 1;
196
197 if (on->ospf6_if->drouter == on->router_id ||
198 on->ospf6_if->bdrouter == on->router_id)
199 return 1;
200
201 return 0;
202}
203
204int
205hello_received (struct thread *thread)
206{
207 struct ospf6_neighbor *on;
208
209 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
210 assert (on);
211
212 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
213 zlog_info ("Neighbor Event %s: *HelloReceived*", on->name);
214
215 /* reset Inactivity Timer */
216 THREAD_OFF (on->inactivity_timer);
217 on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
218 on->ospf6_if->dead_interval);
219
220 if (on->state <= OSPF6_NEIGHBOR_DOWN)
221 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
222
223 return 0;
224}
225
226int
227twoway_received (struct thread *thread)
228{
229 struct ospf6_neighbor *on;
230
231 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
232 assert (on);
233
234 if (on->state > OSPF6_NEIGHBOR_INIT)
235 return 0;
236
237 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
238 zlog_info ("Neighbor Event %s: *2Way-Received*", on->name);
239
240 thread_add_event (master, neighbor_change, on->ospf6_if, 0);
241
242 if (! need_adjacency (on))
243 {
244 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
245 return 0;
246 }
247
248 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
249 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
250 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
251 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
252
253 THREAD_OFF (on->thread_send_dbdesc);
254 on->thread_send_dbdesc =
255 thread_add_event (master, ospf6_dbdesc_send, on, 0);
256
257 return 0;
258}
259
260int
261negotiation_done (struct thread *thread)
262{
263 struct ospf6_neighbor *on;
264 struct ospf6_lsa *lsa;
265
266 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
267 assert (on);
268
269 if (on->state != OSPF6_NEIGHBOR_EXSTART)
270 return 0;
271
272 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
273 zlog_info ("Neighbor Event %s: *NegotiationDone*", on->name);
274
275 /* clear ls-list */
276 ospf6_lsdb_remove_all (on->summary_list);
277 ospf6_lsdb_remove_all (on->request_list);
278 ospf6_lsdb_remove_all (on->retrans_list);
279
280 /* Interface scoped LSAs */
281 for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
282 lsa = ospf6_lsdb_next (lsa))
283 {
284 if (IS_OSPF6_DEBUG_LSA (DATABASE))
285 zlog_info ("Add copy of %s to %s of %s", lsa->name,
286 (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
287 "summary_list"), on->name);
288 if (OSPF6_LSA_IS_MAXAGE (lsa))
289 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
290 else
291 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
292 }
293
294 /* Area scoped LSAs */
295 for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
296 lsa = ospf6_lsdb_next (lsa))
297 {
298 if (IS_OSPF6_DEBUG_LSA (DATABASE))
299 zlog_info ("Add copy of %s to %s of %s", lsa->name,
300 (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
301 "summary_list"), on->name);
302 if (OSPF6_LSA_IS_MAXAGE (lsa))
303 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
304 else
305 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
306 }
307
308 /* AS scoped LSAs */
309 for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
310 lsa = ospf6_lsdb_next (lsa))
311 {
312 if (IS_OSPF6_DEBUG_LSA (DATABASE))
313 zlog_info ("Add copy of %s to %s of %s", lsa->name,
314 (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
315 "summary_list"), on->name);
316 if (OSPF6_LSA_IS_MAXAGE (lsa))
317 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
318 else
319 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
320 }
321
322 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
323 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on);
324
325 return 0;
326}
327
328int
329exchange_done (struct thread *thread)
330{
331 struct ospf6_neighbor *on;
332
333 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
334 assert (on);
335
336 if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
337 return 0;
338
339 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
340 zlog_info ("Neighbor Event %s: *ExchangeDone*", on->name);
341
342 THREAD_OFF (on->thread_send_dbdesc);
343 ospf6_lsdb_remove_all (on->dbdesc_list);
344
345/* XXX
346 thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
347 on->ospf6_if->dead_interval);
348*/
349
350 if (on->request_list->count == 0)
351 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
352 else
353 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on);
354
355 return 0;
356}
357
358int
359loading_done (struct thread *thread)
360{
361 struct ospf6_neighbor *on;
362
363 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
364 assert (on);
365
366 if (on->state != OSPF6_NEIGHBOR_LOADING)
367 return 0;
368
369 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
370 zlog_info ("Neighbor Event %s: *LoadingDone*", on->name);
371
372 assert (on->request_list->count == 0);
373
374 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
375
376 return 0;
377}
378
379int
380adj_ok (struct thread *thread)
381{
382 struct ospf6_neighbor *on;
383
384 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
385 assert (on);
386
387 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
388 zlog_info ("Neighbor Event %s: *AdjOK?*", on->name);
389
390 if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
391 {
392 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
393 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
394 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
395 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
396
397 THREAD_OFF (on->thread_send_dbdesc);
398 on->thread_send_dbdesc =
399 thread_add_event (master, ospf6_dbdesc_send, on, 0);
400
401 }
402 else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
403 ! need_adjacency (on))
404 {
405 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
406 ospf6_lsdb_remove_all (on->summary_list);
407 ospf6_lsdb_remove_all (on->request_list);
408 ospf6_lsdb_remove_all (on->retrans_list);
409 }
410
411 return 0;
412}
413
414int
415seqnumber_mismatch (struct thread *thread)
416{
417 struct ospf6_neighbor *on;
418
419 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
420 assert (on);
421
422 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
423 return 0;
424
425 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
426 zlog_info ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
427
428 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
429 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
430 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
431 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
432
433 ospf6_lsdb_remove_all (on->summary_list);
434 ospf6_lsdb_remove_all (on->request_list);
435 ospf6_lsdb_remove_all (on->retrans_list);
436
437 THREAD_OFF (on->thread_send_dbdesc);
438 on->thread_send_dbdesc =
439 thread_add_event (master, ospf6_dbdesc_send, on, 0);
440
441 return 0;
442}
443
444int
445bad_lsreq (struct thread *thread)
446{
447 struct ospf6_neighbor *on;
448
449 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
450 assert (on);
451
452 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
453 return 0;
454
455 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
456 zlog_info ("Neighbor Event %s: *BadLSReq*", on->name);
457
458 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
459 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
460 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
461 SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
462
463 ospf6_lsdb_remove_all (on->summary_list);
464 ospf6_lsdb_remove_all (on->request_list);
465 ospf6_lsdb_remove_all (on->retrans_list);
466
467 THREAD_OFF (on->thread_send_dbdesc);
468 on->thread_send_dbdesc =
469 thread_add_event (master, ospf6_dbdesc_send, on, 0);
470
471 return 0;
472}
473
474int
475oneway_received (struct thread *thread)
476{
477 struct ospf6_neighbor *on;
478
479 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
480 assert (on);
481
482 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
483 return 0;
484
485 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
486 zlog_info ("Neighbor Event %s: *1Way-Received*", on->name);
487
488 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
489 thread_add_event (master, neighbor_change, on->ospf6_if, 0);
490
491 ospf6_lsdb_remove_all (on->summary_list);
492 ospf6_lsdb_remove_all (on->request_list);
493 ospf6_lsdb_remove_all (on->retrans_list);
494
495 THREAD_OFF (on->thread_send_dbdesc);
496 THREAD_OFF (on->thread_send_lsreq);
497 THREAD_OFF (on->thread_send_lsupdate);
498 THREAD_OFF (on->thread_send_lsack);
499
500 return 0;
501}
502
503int
504inactivity_timer (struct thread *thread)
505{
506 struct ospf6_neighbor *on;
507
508 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
509 assert (on);
510
511 if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
512 zlog_info ("Neighbor Event %s: *InactivityTimer*", on->name);
513
514 on->inactivity_timer = NULL;
515 on->drouter = on->prev_drouter = 0;
516 on->bdrouter = on->prev_bdrouter = 0;
517
518 ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on);
519 thread_add_event (master, neighbor_change, on->ospf6_if, 0);
520
521 listnode_delete (on->ospf6_if->neighbor_list, on);
522 ospf6_neighbor_delete (on);
523
524 return 0;
525}
526
527
paul718e3742002-12-13 20:15:29 +0000528
529/* vty functions */
530/* show neighbor structure */
531void
hasso508e53e2004-05-18 18:57:06 +0000532ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
paul718e3742002-12-13 20:15:29 +0000533{
534 char router_id[16];
hasso508e53e2004-05-18 18:57:06 +0000535 char duration[16];
536 struct timeval now, res;
537 char nstate[16];
538 char deadtime[16];
539 long h, m, s;
540
541 /* Router-ID (Name) */
542 inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
543#ifdef HAVE_GETNAMEINFO
544 {
545 }
546#endif /*HAVE_GETNAMEINFO*/
547
548 gettimeofday (&now, NULL);
549
550 /* Dead time */
551 h = m = s = 0;
552 if (on->inactivity_timer)
553 {
554 s = on->inactivity_timer->u.sands.tv_sec - now.tv_sec;
555 h = s / 3600;
556 s -= h * 3600;
557 m = s / 60;
558 s -= m * 60;
559 }
560 snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
561
562 /* Neighbor State */
563 if (if_is_pointopoint (on->ospf6_if->interface))
564 snprintf (nstate, sizeof (nstate), "PointToPoint");
565 else
566 {
567 if (on->router_id == on->drouter)
568 snprintf (nstate, sizeof (nstate), "DR");
569 else if (on->router_id == on->bdrouter)
570 snprintf (nstate, sizeof (nstate), "BDR");
571 else
572 snprintf (nstate, sizeof (nstate), "DROther");
573 }
574
575 /* Duration */
576 timersub (&now, &on->last_changed, &res);
577 timerstring (&res, duration, sizeof (duration));
578
579 /*
580 vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
581 "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
582 "I/F", "State", VTY_NEWLINE);
583 */
584
585 vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
586 router_id, on->priority, deadtime,
587 ospf6_neighbor_state_str[on->state], nstate, duration,
588 on->ospf6_if->interface->name,
589 ospf6_interface_state_str[on->ospf6_if->state], VTY_NEWLINE);
590}
591
592void
593ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
594{
595 char router_id[16];
596 char drouter[16], bdrouter[16];
paul718e3742002-12-13 20:15:29 +0000597 char duration[16];
598 struct timeval now, res;
599
600/*
601 vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
602 "RouterID", "State", "Duration", "DR", "BDR", "I/F",
603 "State", VTY_NEWLINE);
604*/
605
hasso508e53e2004-05-18 18:57:06 +0000606 inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
607 inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
608 inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
paul718e3742002-12-13 20:15:29 +0000609
610 gettimeofday (&now, NULL);
hasso508e53e2004-05-18 18:57:06 +0000611 timersub (&now, &on->last_changed, &res);
612 timerstring (&res, duration, sizeof (duration));
paul718e3742002-12-13 20:15:29 +0000613
614 vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
hasso508e53e2004-05-18 18:57:06 +0000615 router_id, ospf6_neighbor_state_str[on->state],
616 duration, drouter, bdrouter, on->ospf6_if->interface->name,
617 ospf6_interface_state_str[on->ospf6_if->state],
paul718e3742002-12-13 20:15:29 +0000618 VTY_NEWLINE);
619}
620
621void
hasso508e53e2004-05-18 18:57:06 +0000622ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
paul718e3742002-12-13 20:15:29 +0000623{
hasso508e53e2004-05-18 18:57:06 +0000624 char drouter[16], bdrouter[16];
625 char linklocal_addr[64], duration[32];
paul718e3742002-12-13 20:15:29 +0000626 struct timeval now, res;
hasso508e53e2004-05-18 18:57:06 +0000627 struct ospf6_lsa *lsa;
paul718e3742002-12-13 20:15:29 +0000628
hasso508e53e2004-05-18 18:57:06 +0000629 inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
630 sizeof (linklocal_addr));
631 inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
632 inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
paul718e3742002-12-13 20:15:29 +0000633
634 gettimeofday (&now, NULL);
hasso508e53e2004-05-18 18:57:06 +0000635 timersub (&now, &on->last_changed, &res);
636 timerstring (&res, duration, sizeof (duration));
paul718e3742002-12-13 20:15:29 +0000637
hasso508e53e2004-05-18 18:57:06 +0000638 vty_out (vty, " Neighbor %s%s", on->name,
639 VTY_NEWLINE);
640 vty_out (vty, " Area %s via interface %s (ifindex %d)%s",
641 on->ospf6_if->area->name,
642 on->ospf6_if->interface->name,
643 on->ospf6_if->interface->ifindex,
644 VTY_NEWLINE);
645 vty_out (vty, " His IfIndex: %d Link-local address: %s%s",
646 on->ifindex, linklocal_addr,
647 VTY_NEWLINE);
648 vty_out (vty, " State %s for a duration of %s%s",
649 ospf6_neighbor_state_str[on->state], duration,
650 VTY_NEWLINE);
651 vty_out (vty, " His choice of DR/BDR %s/%s, Priority %d%s",
652 drouter, bdrouter, on->priority,
653 VTY_NEWLINE);
654 vty_out (vty, " DbDesc status: %s%s%s SeqNum: %#lx%s",
655 (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
656 (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
657 (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
658 "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
paul718e3742002-12-13 20:15:29 +0000659 VTY_NEWLINE);
660
hasso508e53e2004-05-18 18:57:06 +0000661 vty_out (vty, " Summary-List: %d LSAs%s", on->summary_list->count,
662 VTY_NEWLINE);
663 for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
664 lsa = ospf6_lsdb_next (lsa))
665 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000666
hasso508e53e2004-05-18 18:57:06 +0000667 vty_out (vty, " Request-List: %d LSAs%s", on->request_list->count,
668 VTY_NEWLINE);
669 for (lsa = ospf6_lsdb_head (on->request_list); lsa;
670 lsa = ospf6_lsdb_next (lsa))
671 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
672
673 vty_out (vty, " Retrans-List: %d LSAs%s", on->retrans_list->count,
674 VTY_NEWLINE);
675 for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
676 lsa = ospf6_lsdb_next (lsa))
677 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
678
679 timerclear (&res);
680 if (on->thread_send_dbdesc)
681 timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
682 timerstring (&res, duration, sizeof (duration));
683 vty_out (vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
684 on->dbdesc_list->count, duration,
685 (on->thread_send_dbdesc ? "on" : "off"),
686 VTY_NEWLINE);
687 for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
688 lsa = ospf6_lsdb_next (lsa))
689 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
690
691 timerclear (&res);
692 if (on->thread_send_lsreq)
693 timersub (&on->thread_send_lsreq->u.sands, &now, &res);
694 timerstring (&res, duration, sizeof (duration));
695 vty_out (vty, " %d Pending LSAs for LSReq in Time %s [thread %s]%s",
696 on->lsreq_list->count, duration,
697 (on->thread_send_lsreq ? "on" : "off"),
698 VTY_NEWLINE);
699 for (lsa = ospf6_lsdb_head (on->lsreq_list); lsa;
700 lsa = ospf6_lsdb_next (lsa))
701 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
702
703 timerclear (&res);
704 if (on->thread_send_lsupdate)
705 timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
706 timerstring (&res, duration, sizeof (duration));
707 vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
708 on->lsupdate_list->count, duration,
709 (on->thread_send_lsupdate ? "on" : "off"),
710 VTY_NEWLINE);
711 for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
712 lsa = ospf6_lsdb_next (lsa))
713 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
714
715 timerclear (&res);
716 if (on->thread_send_lsack)
717 timersub (&on->thread_send_lsack->u.sands, &now, &res);
718 timerstring (&res, duration, sizeof (duration));
719 vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s",
720 on->lsack_list->count, duration,
721 (on->thread_send_lsack ? "on" : "off"),
722 VTY_NEWLINE);
723 for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
724 lsa = ospf6_lsdb_next (lsa))
725 vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
726
paul718e3742002-12-13 20:15:29 +0000727}
728
hasso508e53e2004-05-18 18:57:06 +0000729DEFUN (show_ipv6_ospf6_neighbor,
paul718e3742002-12-13 20:15:29 +0000730 show_ipv6_ospf6_neighbor_cmd,
731 "show ipv6 ospf6 neighbor",
732 SHOW_STR
733 IP6_STR
734 OSPF6_STR
735 "Neighbor list\n"
hasso508e53e2004-05-18 18:57:06 +0000736 )
paul718e3742002-12-13 20:15:29 +0000737{
hasso508e53e2004-05-18 18:57:06 +0000738 struct ospf6_neighbor *on;
739 struct ospf6_interface *oi;
740 struct ospf6_area *oa;
741 listnode i, j, k;
742 void (*showfunc) (struct vty *, struct ospf6_neighbor *);
paul718e3742002-12-13 20:15:29 +0000743
744 OSPF6_CMD_CHECK_RUNNING ();
hasso508e53e2004-05-18 18:57:06 +0000745 showfunc = ospf6_neighbor_show;
746
747 if (argc)
748 {
749 if (! strncmp (argv[0], "de", 2))
750 showfunc = ospf6_neighbor_show_detail;
751 else if (! strncmp (argv[0], "dr", 2))
752 showfunc = ospf6_neighbor_show_drchoice;
753 }
754
755 if (showfunc == ospf6_neighbor_show)
756 vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
757 "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
758 "I/F", "State", VTY_NEWLINE);
759 else if (showfunc == ospf6_neighbor_show_drchoice)
760 vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
761 "RouterID", "State", "Duration", "DR", "BDR", "I/F",
762 "State", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000763
764 for (i = listhead (ospf6->area_list); i; nextnode (i))
765 {
hasso508e53e2004-05-18 18:57:06 +0000766 oa = (struct ospf6_area *) getdata (i);
767 for (j = listhead (oa->if_list); j; nextnode (j))
paul718e3742002-12-13 20:15:29 +0000768 {
hasso508e53e2004-05-18 18:57:06 +0000769 oi = (struct ospf6_interface *) getdata (j);
770 for (k = listhead (oi->neighbor_list); k; nextnode (k))
paul718e3742002-12-13 20:15:29 +0000771 {
hasso508e53e2004-05-18 18:57:06 +0000772 on = (struct ospf6_neighbor *) getdata (k);
773 (*showfunc) (vty, on);
paul718e3742002-12-13 20:15:29 +0000774 }
775 }
776 }
hasso508e53e2004-05-18 18:57:06 +0000777 return CMD_SUCCESS;
778}
paul718e3742002-12-13 20:15:29 +0000779
hasso508e53e2004-05-18 18:57:06 +0000780ALIAS (show_ipv6_ospf6_neighbor,
781 show_ipv6_ospf6_neighbor_detail_cmd,
782 "show ipv6 ospf6 neighbor (detail|drchoice)",
783 SHOW_STR
784 IP6_STR
785 OSPF6_STR
786 "Neighbor list\n"
787 "Display details\n"
788 "Display DR choices\n"
789 );
790
791DEFUN (show_ipv6_ospf6_neighbor_one,
792 show_ipv6_ospf6_neighbor_one_cmd,
793 "show ipv6 ospf6 neighbor A.B.C.D",
794 SHOW_STR
795 IP6_STR
796 OSPF6_STR
797 "Neighbor list\n"
798 "Specify Router-ID as IPv4 address notation\n"
799 )
800{
801 struct ospf6_neighbor *on;
802 struct ospf6_interface *oi;
803 struct ospf6_area *oa;
804 listnode i, j, k;
805 void (*showfunc) (struct vty *, struct ospf6_neighbor *);
806 u_int32_t router_id;
807
808 OSPF6_CMD_CHECK_RUNNING ();
809 showfunc = ospf6_neighbor_show_detail;
810
811 if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
812 {
813 vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
814 VTY_NEWLINE);
815 return CMD_SUCCESS;
816 }
817
818 for (i = listhead (ospf6->area_list); i; nextnode (i))
819 {
820 oa = (struct ospf6_area *) getdata (i);
821 for (j = listhead (oa->if_list); j; nextnode (j))
822 {
823 oi = (struct ospf6_interface *) getdata (j);
824 for (k = listhead (oi->neighbor_list); k; nextnode (k))
825 {
826 on = (struct ospf6_neighbor *) getdata (k);
827 if (on->router_id == router_id)
828 (*showfunc) (vty, on);
829 }
830 }
831 }
paul718e3742002-12-13 20:15:29 +0000832 return CMD_SUCCESS;
833}
834
835void
836ospf6_neighbor_init ()
837{
838 install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
hasso508e53e2004-05-18 18:57:06 +0000839 install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
paul718e3742002-12-13 20:15:29 +0000840 install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
hasso508e53e2004-05-18 18:57:06 +0000841 install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
paul718e3742002-12-13 20:15:29 +0000842}
843
hasso508e53e2004-05-18 18:57:06 +0000844DEFUN (debug_ospf6_neighbor,
845 debug_ospf6_neighbor_cmd,
846 "debug ospf6 neighbor",
847 DEBUG_STR
848 OSPF6_STR
849 "Debug OSPFv3 Neighbor\n"
850 )
851{
852 unsigned char level = 0;
853 if (argc)
854 {
855 if (! strncmp (argv[0], "s", 1))
856 level = OSPF6_DEBUG_NEIGHBOR_STATE;
857 if (! strncmp (argv[0], "e", 1))
858 level = OSPF6_DEBUG_NEIGHBOR_EVENT;
859 }
860 else
861 level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
862
863 OSPF6_DEBUG_NEIGHBOR_ON (level);
864 return CMD_SUCCESS;
865}
866
867ALIAS (debug_ospf6_neighbor,
868 debug_ospf6_neighbor_detail_cmd,
869 "debug ospf6 neighbor (state|event)",
870 DEBUG_STR
871 OSPF6_STR
872 "Debug OSPFv3 Neighbor\n"
873 "Debug OSPFv3 Neighbor State Change\n"
874 "Debug OSPFv3 Neighbor Event\n"
875 );
876
877DEFUN (no_debug_ospf6_neighbor,
878 no_debug_ospf6_neighbor_cmd,
879 "no debug ospf6 neighbor",
880 NO_STR
881 DEBUG_STR
882 OSPF6_STR
883 "Debug OSPFv3 Neighbor\n"
884 )
885{
886 unsigned char level = 0;
887 if (argc)
888 {
889 if (! strncmp (argv[0], "s", 1))
890 level = OSPF6_DEBUG_NEIGHBOR_STATE;
891 if (! strncmp (argv[0], "e", 1))
892 level = OSPF6_DEBUG_NEIGHBOR_EVENT;
893 }
894 else
895 level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
896
897 OSPF6_DEBUG_NEIGHBOR_OFF (level);
898 return CMD_SUCCESS;
899}
900
901ALIAS (no_debug_ospf6_neighbor,
902 no_debug_ospf6_neighbor_detail_cmd,
903 "no debug ospf6 neighbor (state|event)",
904 NO_STR
905 DEBUG_STR
906 OSPF6_STR
907 "Debug OSPFv3 Neighbor\n"
908 "Debug OSPFv3 Neighbor State Change\n"
909 "Debug OSPFv3 Neighbor Event\n"
910 );
911
912int
913config_write_ospf6_debug_neighbor (struct vty *vty)
914{
915 if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
916 IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
917 vty_out (vty, "debug ospf6 neighbor%s", VTY_NEWLINE);
918 else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
919 vty_out (vty, "debug ospf6 neighbor state%s", VTY_NEWLINE);
920 else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
921 vty_out (vty, "debug ospf6 neighbor event%s", VTY_NEWLINE);
922 return 0;
923}
924
925void
926install_element_ospf6_debug_neighbor ()
927{
928 install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
929 install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
930 install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
931 install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
932 install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
933 install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
934 install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
935 install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
936}
937
938
paul718e3742002-12-13 20:15:29 +0000939