]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_neighbor.c
Merge pull request #2829 from donaldsharp/more_upstream
[mirror_frr.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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "memory.h"
25 #include "thread.h"
26 #include "linklist.h"
27 #include "vty.h"
28 #include "command.h"
29
30 #include "ospf6_proto.h"
31 #include "ospf6_lsa.h"
32 #include "ospf6_lsdb.h"
33 #include "ospf6_message.h"
34 #include "ospf6_top.h"
35 #include "ospf6_area.h"
36 #include "ospf6_interface.h"
37 #include "ospf6_neighbor.h"
38 #include "ospf6_intra.h"
39 #include "ospf6_flood.h"
40 #include "ospf6d.h"
41 #include "ospf6_bfd.h"
42 #include "ospf6_abr.h"
43 #include "ospf6_asbr.h"
44 #include "ospf6_lsa.h"
45 #include "ospf6_spf.h"
46 #include "ospf6_zebra.h"
47
48 DEFINE_HOOK(ospf6_neighbor_change,
49 (struct ospf6_neighbor * on, int state, int next_state),
50 (on, state, next_state))
51
52 unsigned char conf_debug_ospf6_neighbor = 0;
53
54 const char *ospf6_neighbor_state_str[] = {
55 "None", "Down", "Attempt", "Init", "Twoway",
56 "ExStart", "ExChange", "Loading", "Full", NULL};
57
58 int ospf6_neighbor_cmp(void *va, void *vb)
59 {
60 struct ospf6_neighbor *ona = (struct ospf6_neighbor *)va;
61 struct ospf6_neighbor *onb = (struct ospf6_neighbor *)vb;
62 return (ntohl(ona->router_id) < ntohl(onb->router_id) ? -1 : 1);
63 }
64
65 struct ospf6_neighbor *ospf6_neighbor_lookup(uint32_t router_id,
66 struct ospf6_interface *oi)
67 {
68 struct listnode *n;
69 struct ospf6_neighbor *on;
70
71 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, n, on))
72 if (on->router_id == router_id)
73 return on;
74
75 return (struct ospf6_neighbor *)NULL;
76 }
77
78 /* create ospf6_neighbor */
79 struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
80 struct ospf6_interface *oi)
81 {
82 struct ospf6_neighbor *on;
83 char buf[16];
84
85 on = (struct ospf6_neighbor *)XMALLOC(MTYPE_OSPF6_NEIGHBOR,
86 sizeof(struct ospf6_neighbor));
87
88 memset(on, 0, sizeof(struct ospf6_neighbor));
89 inet_ntop(AF_INET, &router_id, buf, sizeof(buf));
90 snprintf(on->name, sizeof(on->name), "%s%%%s", buf,
91 oi->interface->name);
92 on->ospf6_if = oi;
93 on->state = OSPF6_NEIGHBOR_DOWN;
94 on->state_change = 0;
95 monotime(&on->last_changed);
96 on->router_id = router_id;
97
98 on->summary_list = ospf6_lsdb_create(on);
99 on->request_list = ospf6_lsdb_create(on);
100 on->retrans_list = ospf6_lsdb_create(on);
101
102 on->dbdesc_list = ospf6_lsdb_create(on);
103 on->lsupdate_list = ospf6_lsdb_create(on);
104 on->lsack_list = ospf6_lsdb_create(on);
105
106 listnode_add_sort(oi->neighbor_list, on);
107
108 ospf6_bfd_info_nbr_create(oi, on);
109 return on;
110 }
111
112 void ospf6_neighbor_delete(struct ospf6_neighbor *on)
113 {
114 struct ospf6_lsa *lsa;
115
116 ospf6_lsdb_remove_all(on->summary_list);
117 ospf6_lsdb_remove_all(on->request_list);
118 for (ALL_LSDB(on->retrans_list, lsa)) {
119 ospf6_decrement_retrans_count(lsa);
120 ospf6_lsdb_remove(lsa, on->retrans_list);
121 }
122
123 ospf6_lsdb_remove_all(on->dbdesc_list);
124 ospf6_lsdb_remove_all(on->lsupdate_list);
125 ospf6_lsdb_remove_all(on->lsack_list);
126
127 ospf6_lsdb_delete(on->summary_list);
128 ospf6_lsdb_delete(on->request_list);
129 ospf6_lsdb_delete(on->retrans_list);
130
131 ospf6_lsdb_delete(on->dbdesc_list);
132 ospf6_lsdb_delete(on->lsupdate_list);
133 ospf6_lsdb_delete(on->lsack_list);
134
135 THREAD_OFF(on->inactivity_timer);
136
137 THREAD_OFF(on->thread_send_dbdesc);
138 THREAD_OFF(on->thread_send_lsreq);
139 THREAD_OFF(on->thread_send_lsupdate);
140 THREAD_OFF(on->thread_send_lsack);
141
142 ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER);
143 XFREE(MTYPE_OSPF6_NEIGHBOR, on);
144 }
145
146 static void ospf6_neighbor_state_change(uint8_t next_state,
147 struct ospf6_neighbor *on, int event)
148 {
149 uint8_t prev_state;
150
151 prev_state = on->state;
152 on->state = next_state;
153
154 if (prev_state == next_state)
155 return;
156
157 on->state_change++;
158 monotime(&on->last_changed);
159
160 /* log */
161 if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) {
162 zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)",
163 on->name, ospf6_neighbor_state_str[prev_state],
164 ospf6_neighbor_state_str[next_state],
165 ospf6_neighbor_event_string(event));
166 }
167
168 /* Optionally notify about adjacency changes */
169 if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
170 OSPF6_LOG_ADJACENCY_CHANGES)
171 && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
172 OSPF6_LOG_ADJACENCY_DETAIL)
173 || (next_state == OSPF6_NEIGHBOR_FULL)
174 || (next_state < prev_state)))
175 zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
176 ospf6_neighbor_state_str[prev_state],
177 ospf6_neighbor_state_str[next_state],
178 ospf6_neighbor_event_string(event));
179
180 if (prev_state == OSPF6_NEIGHBOR_FULL
181 || next_state == OSPF6_NEIGHBOR_FULL) {
182 OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
183 if (on->ospf6_if->state == OSPF6_INTERFACE_DR) {
184 OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if);
185 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if);
186 }
187 if (next_state == OSPF6_NEIGHBOR_FULL)
188 on->ospf6_if->area->intra_prefix_originate = 1;
189
190 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area);
191
192 if ((prev_state == OSPF6_NEIGHBOR_LOADING ||
193 prev_state == OSPF6_NEIGHBOR_EXCHANGE) &&
194 next_state == OSPF6_NEIGHBOR_FULL) {
195 OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if);
196 on->ospf6_if->area->full_nbrs++;
197 }
198
199 if (prev_state == OSPF6_NEIGHBOR_FULL)
200 on->ospf6_if->area->full_nbrs--;
201 }
202
203 if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE
204 || prev_state == OSPF6_NEIGHBOR_LOADING)
205 && (next_state != OSPF6_NEIGHBOR_EXCHANGE
206 && next_state != OSPF6_NEIGHBOR_LOADING))
207 ospf6_maxage_remove(on->ospf6_if->area->ospf6);
208
209 hook_call(ospf6_neighbor_change, on, next_state, prev_state);
210 ospf6_bfd_trigger_event(on, prev_state, next_state);
211 }
212
213 /* RFC2328 section 10.4 */
214 static int need_adjacency(struct ospf6_neighbor *on)
215 {
216 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT
217 || on->ospf6_if->state == OSPF6_INTERFACE_DR
218 || on->ospf6_if->state == OSPF6_INTERFACE_BDR)
219 return 1;
220
221 if (on->ospf6_if->drouter == on->router_id
222 || on->ospf6_if->bdrouter == on->router_id)
223 return 1;
224
225 return 0;
226 }
227
228 int hello_received(struct thread *thread)
229 {
230 struct ospf6_neighbor *on;
231
232 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
233 assert(on);
234
235 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
236 zlog_debug("Neighbor Event %s: *HelloReceived*", on->name);
237
238 /* reset Inactivity Timer */
239 THREAD_OFF(on->inactivity_timer);
240 on->inactivity_timer = NULL;
241 thread_add_timer(master, inactivity_timer, on,
242 on->ospf6_if->dead_interval, &on->inactivity_timer);
243
244 if (on->state <= OSPF6_NEIGHBOR_DOWN)
245 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
246 OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
247
248 return 0;
249 }
250
251 int twoway_received(struct thread *thread)
252 {
253 struct ospf6_neighbor *on;
254
255 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
256 assert(on);
257
258 if (on->state > OSPF6_NEIGHBOR_INIT)
259 return 0;
260
261 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
262 zlog_debug("Neighbor Event %s: *2Way-Received*", on->name);
263
264 thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
265
266 if (!need_adjacency(on)) {
267 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
268 OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
269 return 0;
270 }
271
272 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
273 OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
274 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
275 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
276 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
277
278 THREAD_OFF(on->thread_send_dbdesc);
279 on->thread_send_dbdesc = NULL;
280 thread_add_event(master, ospf6_dbdesc_send, on, 0,
281 &on->thread_send_dbdesc);
282
283 return 0;
284 }
285
286 int negotiation_done(struct thread *thread)
287 {
288 struct ospf6_neighbor *on;
289 struct ospf6_lsa *lsa;
290
291 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
292 assert(on);
293
294 if (on->state != OSPF6_NEIGHBOR_EXSTART)
295 return 0;
296
297 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
298 zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name);
299
300 /* clear ls-list */
301 ospf6_lsdb_remove_all(on->summary_list);
302 ospf6_lsdb_remove_all(on->request_list);
303 for (ALL_LSDB(on->retrans_list, lsa)) {
304 ospf6_decrement_retrans_count(lsa);
305 ospf6_lsdb_remove(lsa, on->retrans_list);
306 }
307
308 /* Interface scoped LSAs */
309 for (ALL_LSDB(on->ospf6_if->lsdb, lsa)) {
310 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
311 ospf6_increment_retrans_count(lsa);
312 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
313 } else
314 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
315 }
316
317 /* Area scoped LSAs */
318 for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa)) {
319 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
320 ospf6_increment_retrans_count(lsa);
321 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
322 } else
323 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
324 }
325
326 /* AS scoped LSAs */
327 for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa)) {
328 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
329 ospf6_increment_retrans_count(lsa);
330 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
331 } else
332 ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
333 }
334
335 UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
336 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on,
337 OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
338
339 return 0;
340 }
341
342 int exchange_done(struct thread *thread)
343 {
344 struct ospf6_neighbor *on;
345
346 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
347 assert(on);
348
349 if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
350 return 0;
351
352 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
353 zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name);
354
355 THREAD_OFF(on->thread_send_dbdesc);
356 ospf6_lsdb_remove_all(on->dbdesc_list);
357
358 /* XXX
359 thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
360 on->ospf6_if->dead_interval);
361 */
362
363 if (on->request_list->count == 0)
364 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
365 OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
366 else {
367 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on,
368 OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
369
370 thread_add_event(master, ospf6_lsreq_send, on, 0,
371 &on->thread_send_lsreq);
372 }
373
374 return 0;
375 }
376
377 /* Check loading state. */
378 void ospf6_check_nbr_loading(struct ospf6_neighbor *on)
379 {
380
381 /* RFC2328 Section 10.9: When the neighbor responds to these requests
382 with the proper Link State Update packet(s), the Link state request
383 list is truncated and a new Link State Request packet is sent.
384 */
385 if ((on->state == OSPF6_NEIGHBOR_LOADING)
386 || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) {
387 if (on->request_list->count == 0)
388 thread_add_event(master, loading_done, on, 0, NULL);
389 else if (on->last_ls_req == NULL) {
390 if (on->thread_send_lsreq != NULL)
391 THREAD_OFF(on->thread_send_lsreq);
392 on->thread_send_lsreq = NULL;
393 thread_add_event(master, ospf6_lsreq_send, on, 0,
394 &on->thread_send_lsreq);
395 }
396 }
397 }
398
399 int loading_done(struct thread *thread)
400 {
401 struct ospf6_neighbor *on;
402
403 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
404 assert(on);
405
406 if (on->state != OSPF6_NEIGHBOR_LOADING)
407 return 0;
408
409 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
410 zlog_debug("Neighbor Event %s: *LoadingDone*", on->name);
411
412 assert(on->request_list->count == 0);
413
414 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
415 OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
416
417 return 0;
418 }
419
420 int adj_ok(struct thread *thread)
421 {
422 struct ospf6_neighbor *on;
423 struct ospf6_lsa *lsa;
424
425 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
426 assert(on);
427
428 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
429 zlog_debug("Neighbor Event %s: *AdjOK?*", on->name);
430
431 if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency(on)) {
432 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
433 OSPF6_NEIGHBOR_EVENT_ADJ_OK);
434 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
435 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
436 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
437
438 THREAD_OFF(on->thread_send_dbdesc);
439 on->thread_send_dbdesc = NULL;
440 thread_add_event(master, ospf6_dbdesc_send, on, 0,
441 &on->thread_send_dbdesc);
442
443 } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) {
444 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
445 OSPF6_NEIGHBOR_EVENT_ADJ_OK);
446 ospf6_lsdb_remove_all(on->summary_list);
447 ospf6_lsdb_remove_all(on->request_list);
448 for (ALL_LSDB(on->retrans_list, lsa)) {
449 ospf6_decrement_retrans_count(lsa);
450 ospf6_lsdb_remove(lsa, on->retrans_list);
451 }
452 }
453
454 return 0;
455 }
456
457 int seqnumber_mismatch(struct thread *thread)
458 {
459 struct ospf6_neighbor *on;
460 struct ospf6_lsa *lsa;
461
462 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
463 assert(on);
464
465 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
466 return 0;
467
468 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
469 zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name);
470
471 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
472 OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
473 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
474 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
475 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
476
477 ospf6_lsdb_remove_all(on->summary_list);
478 ospf6_lsdb_remove_all(on->request_list);
479 for (ALL_LSDB(on->retrans_list, lsa)) {
480 ospf6_decrement_retrans_count(lsa);
481 ospf6_lsdb_remove(lsa, on->retrans_list);
482 }
483
484 THREAD_OFF(on->thread_send_dbdesc);
485 on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
486
487 on->thread_send_dbdesc = NULL;
488 thread_add_event(master, ospf6_dbdesc_send, on, 0,
489 &on->thread_send_dbdesc);
490
491 return 0;
492 }
493
494 int bad_lsreq(struct thread *thread)
495 {
496 struct ospf6_neighbor *on;
497 struct ospf6_lsa *lsa;
498
499 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
500 assert(on);
501
502 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
503 return 0;
504
505 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
506 zlog_debug("Neighbor Event %s: *BadLSReq*", on->name);
507
508 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
509 OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
510 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
511 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
512 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
513
514 ospf6_lsdb_remove_all(on->summary_list);
515 ospf6_lsdb_remove_all(on->request_list);
516 for (ALL_LSDB(on->retrans_list, lsa)) {
517 ospf6_decrement_retrans_count(lsa);
518 ospf6_lsdb_remove(lsa, on->retrans_list);
519 }
520
521 THREAD_OFF(on->thread_send_dbdesc);
522 on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
523
524 on->thread_send_dbdesc = NULL;
525 thread_add_event(master, ospf6_dbdesc_send, on, 0,
526 &on->thread_send_dbdesc);
527
528 return 0;
529 }
530
531 int oneway_received(struct thread *thread)
532 {
533 struct ospf6_neighbor *on;
534 struct ospf6_lsa *lsa;
535
536 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
537 assert(on);
538
539 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
540 return 0;
541
542 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
543 zlog_debug("Neighbor Event %s: *1Way-Received*", on->name);
544
545 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
546 OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
547 thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
548
549 ospf6_lsdb_remove_all(on->summary_list);
550 ospf6_lsdb_remove_all(on->request_list);
551 for (ALL_LSDB(on->retrans_list, lsa)) {
552 ospf6_decrement_retrans_count(lsa);
553 ospf6_lsdb_remove(lsa, on->retrans_list);
554 }
555
556 THREAD_OFF(on->thread_send_dbdesc);
557 THREAD_OFF(on->thread_send_lsreq);
558 THREAD_OFF(on->thread_send_lsupdate);
559 THREAD_OFF(on->thread_send_lsack);
560
561 return 0;
562 }
563
564 int inactivity_timer(struct thread *thread)
565 {
566 struct ospf6_neighbor *on;
567
568 on = (struct ospf6_neighbor *)THREAD_ARG(thread);
569 assert(on);
570
571 if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
572 zlog_debug("Neighbor Event %s: *InactivityTimer*", on->name);
573
574 on->inactivity_timer = NULL;
575 on->drouter = on->prev_drouter = 0;
576 on->bdrouter = on->prev_bdrouter = 0;
577
578 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_DOWN, on,
579 OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
580 thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
581
582 listnode_delete(on->ospf6_if->neighbor_list, on);
583 ospf6_neighbor_delete(on);
584
585 return 0;
586 }
587
588
589 /* vty functions */
590 /* show neighbor structure */
591 static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on)
592 {
593 char router_id[16];
594 char duration[64];
595 struct timeval res;
596 char nstate[16];
597 char deadtime[64];
598 long h, m, s;
599
600 /* Router-ID (Name) */
601 inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id));
602 #ifdef HAVE_GETNAMEINFO
603 {
604 }
605 #endif /*HAVE_GETNAMEINFO*/
606
607 /* Dead time */
608 h = m = s = 0;
609 if (on->inactivity_timer) {
610 s = monotime_until(&on->inactivity_timer->u.sands, NULL)
611 / 1000000LL;
612 h = s / 3600;
613 s -= h * 3600;
614 m = s / 60;
615 s -= m * 60;
616 }
617 snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s);
618
619 /* Neighbor State */
620 if (if_is_pointopoint(on->ospf6_if->interface))
621 snprintf(nstate, sizeof(nstate), "PointToPoint");
622 else {
623 if (on->router_id == on->drouter)
624 snprintf(nstate, sizeof(nstate), "DR");
625 else if (on->router_id == on->bdrouter)
626 snprintf(nstate, sizeof(nstate), "BDR");
627 else
628 snprintf(nstate, sizeof(nstate), "DROther");
629 }
630
631 /* Duration */
632 monotime_since(&on->last_changed, &res);
633 timerstring(&res, duration, sizeof(duration));
634
635 /*
636 vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n",
637 "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
638 "I/F", "State");
639 */
640
641 vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]\n", router_id,
642 on->priority, deadtime, ospf6_neighbor_state_str[on->state],
643 nstate, duration, on->ospf6_if->interface->name,
644 ospf6_interface_state_str[on->ospf6_if->state]);
645 }
646
647 static void ospf6_neighbor_show_drchoice(struct vty *vty,
648 struct ospf6_neighbor *on)
649 {
650 char router_id[16];
651 char drouter[16], bdrouter[16];
652 char duration[64];
653 struct timeval now, res;
654
655 /*
656 vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n",
657 "RouterID", "State", "Duration", "DR", "BDR", "I/F",
658 "State");
659 */
660
661 inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id));
662 inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter));
663 inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter));
664
665 monotime(&now);
666 timersub(&now, &on->last_changed, &res);
667 timerstring(&res, duration, sizeof(duration));
668
669 vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", router_id,
670 ospf6_neighbor_state_str[on->state], duration, drouter,
671 bdrouter, on->ospf6_if->interface->name,
672 ospf6_interface_state_str[on->ospf6_if->state]);
673 }
674
675 static void ospf6_neighbor_show_detail(struct vty *vty,
676 struct ospf6_neighbor *on)
677 {
678 char drouter[16], bdrouter[16];
679 char linklocal_addr[64], duration[32];
680 struct timeval now, res;
681 struct ospf6_lsa *lsa;
682
683 inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr,
684 sizeof(linklocal_addr));
685 inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter));
686 inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter));
687
688 monotime(&now);
689 timersub(&now, &on->last_changed, &res);
690 timerstring(&res, duration, sizeof(duration));
691
692 vty_out(vty, " Neighbor %s\n", on->name);
693 vty_out(vty, " Area %s via interface %s (ifindex %d)\n",
694 on->ospf6_if->area->name, on->ospf6_if->interface->name,
695 on->ospf6_if->interface->ifindex);
696 vty_out(vty, " His IfIndex: %d Link-local address: %s\n",
697 on->ifindex, linklocal_addr);
698 vty_out(vty, " State %s for a duration of %s\n",
699 ospf6_neighbor_state_str[on->state], duration);
700 vty_out(vty, " His choice of DR/BDR %s/%s, Priority %d\n", drouter,
701 bdrouter, on->priority);
702 vty_out(vty, " DbDesc status: %s%s%s SeqNum: %#lx\n",
703 (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial "
704 : ""),
705 (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
706 (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ? "Master"
707 : "Slave"),
708 (unsigned long)ntohl(on->dbdesc_seqnum));
709
710 vty_out(vty, " Summary-List: %d LSAs\n", on->summary_list->count);
711 for (ALL_LSDB(on->summary_list, lsa))
712 vty_out(vty, " %s\n", lsa->name);
713
714 vty_out(vty, " Request-List: %d LSAs\n", on->request_list->count);
715 for (ALL_LSDB(on->request_list, lsa))
716 vty_out(vty, " %s\n", lsa->name);
717
718 vty_out(vty, " Retrans-List: %d LSAs\n", on->retrans_list->count);
719 for (ALL_LSDB(on->retrans_list, lsa))
720 vty_out(vty, " %s\n", lsa->name);
721
722 timerclear(&res);
723 if (on->thread_send_dbdesc)
724 timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
725 timerstring(&res, duration, sizeof(duration));
726 vty_out(vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
727 on->dbdesc_list->count, duration,
728 (on->thread_send_dbdesc ? "on" : "off"));
729 for (ALL_LSDB(on->dbdesc_list, lsa))
730 vty_out(vty, " %s\n", lsa->name);
731
732 timerclear(&res);
733 if (on->thread_send_lsreq)
734 timersub(&on->thread_send_lsreq->u.sands, &now, &res);
735 timerstring(&res, duration, sizeof(duration));
736 vty_out(vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n",
737 on->request_list->count, duration,
738 (on->thread_send_lsreq ? "on" : "off"));
739 for (ALL_LSDB(on->request_list, lsa))
740 vty_out(vty, " %s\n", lsa->name);
741
742 timerclear(&res);
743 if (on->thread_send_lsupdate)
744 timersub(&on->thread_send_lsupdate->u.sands, &now, &res);
745 timerstring(&res, duration, sizeof(duration));
746 vty_out(vty,
747 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
748 on->lsupdate_list->count, duration,
749 (on->thread_send_lsupdate ? "on" : "off"));
750 for (ALL_LSDB(on->lsupdate_list, lsa))
751 vty_out(vty, " %s\n", lsa->name);
752
753 timerclear(&res);
754 if (on->thread_send_lsack)
755 timersub(&on->thread_send_lsack->u.sands, &now, &res);
756 timerstring(&res, duration, sizeof(duration));
757 vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
758 on->lsack_list->count, duration,
759 (on->thread_send_lsack ? "on" : "off"));
760 for (ALL_LSDB(on->lsack_list, lsa))
761 vty_out(vty, " %s\n", lsa->name);
762
763 ospf6_bfd_show_info(vty, on->bfd_info, 0);
764 }
765
766 DEFUN (show_ipv6_ospf6_neighbor,
767 show_ipv6_ospf6_neighbor_cmd,
768 "show ipv6 ospf6 neighbor [<detail|drchoice>]",
769 SHOW_STR
770 IP6_STR
771 OSPF6_STR
772 "Neighbor list\n"
773 "Display details\n"
774 "Display DR choices\n")
775 {
776 int idx_type = 4;
777 struct ospf6_neighbor *on;
778 struct ospf6_interface *oi;
779 struct ospf6_area *oa;
780 struct listnode *i, *j, *k;
781 void (*showfunc)(struct vty *, struct ospf6_neighbor *);
782
783 OSPF6_CMD_CHECK_RUNNING();
784 showfunc = ospf6_neighbor_show;
785
786 if (argc == 5) {
787 if (!strncmp(argv[idx_type]->arg, "de", 2))
788 showfunc = ospf6_neighbor_show_detail;
789 else if (!strncmp(argv[idx_type]->arg, "dr", 2))
790 showfunc = ospf6_neighbor_show_drchoice;
791 }
792
793 if (showfunc == ospf6_neighbor_show)
794 vty_out(vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n",
795 "Neighbor ID", "Pri", "DeadTime", "State", "IfState",
796 "Duration", "I/F", "State");
797 else if (showfunc == ospf6_neighbor_show_drchoice)
798 vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", "RouterID",
799 "State", "Duration", "DR", "BDR", "I/F", "State");
800
801 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
802 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
803 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on))
804 (*showfunc)(vty, on);
805
806 return CMD_SUCCESS;
807 }
808
809
810 DEFUN (show_ipv6_ospf6_neighbor_one,
811 show_ipv6_ospf6_neighbor_one_cmd,
812 "show ipv6 ospf6 neighbor A.B.C.D",
813 SHOW_STR
814 IP6_STR
815 OSPF6_STR
816 "Neighbor list\n"
817 "Specify Router-ID as IPv4 address notation\n"
818 )
819 {
820 int idx_ipv4 = 4;
821 struct ospf6_neighbor *on;
822 struct ospf6_interface *oi;
823 struct ospf6_area *oa;
824 struct listnode *i, *j, *k;
825 void (*showfunc)(struct vty *, struct ospf6_neighbor *);
826 uint32_t router_id;
827
828 OSPF6_CMD_CHECK_RUNNING();
829 showfunc = ospf6_neighbor_show_detail;
830
831 if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) {
832 vty_out(vty, "Router-ID is not parsable: %s\n",
833 argv[idx_ipv4]->arg);
834 return CMD_SUCCESS;
835 }
836
837 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
838 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
839 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on))
840 (*showfunc)(vty, on);
841
842 return CMD_SUCCESS;
843 }
844
845 void ospf6_neighbor_init(void)
846 {
847 install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
848 install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
849 }
850
851 DEFUN (debug_ospf6_neighbor,
852 debug_ospf6_neighbor_cmd,
853 "debug ospf6 neighbor [<state|event>]",
854 DEBUG_STR
855 OSPF6_STR
856 "Debug OSPFv3 Neighbor\n"
857 "Debug OSPFv3 Neighbor State Change\n"
858 "Debug OSPFv3 Neighbor Event\n")
859 {
860 int idx_type = 3;
861 unsigned char level = 0;
862
863 if (argc == 4) {
864 if (!strncmp(argv[idx_type]->arg, "s", 1))
865 level = OSPF6_DEBUG_NEIGHBOR_STATE;
866 else if (!strncmp(argv[idx_type]->arg, "e", 1))
867 level = OSPF6_DEBUG_NEIGHBOR_EVENT;
868 } else
869 level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
870
871 OSPF6_DEBUG_NEIGHBOR_ON(level);
872 return CMD_SUCCESS;
873 }
874
875
876 DEFUN (no_debug_ospf6_neighbor,
877 no_debug_ospf6_neighbor_cmd,
878 "no debug ospf6 neighbor [<state|event>]",
879 NO_STR
880 DEBUG_STR
881 OSPF6_STR
882 "Debug OSPFv3 Neighbor\n"
883 "Debug OSPFv3 Neighbor State Change\n"
884 "Debug OSPFv3 Neighbor Event\n")
885 {
886 int idx_type = 4;
887 unsigned char level = 0;
888
889 if (argc == 5) {
890 if (!strncmp(argv[idx_type]->arg, "s", 1))
891 level = OSPF6_DEBUG_NEIGHBOR_STATE;
892 if (!strncmp(argv[idx_type]->arg, "e", 1))
893 level = OSPF6_DEBUG_NEIGHBOR_EVENT;
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
901
902 DEFUN (no_debug_ospf6,
903 no_debug_ospf6_cmd,
904 "no debug ospf6",
905 NO_STR
906 DEBUG_STR
907 OSPF6_STR)
908 {
909 unsigned int i;
910 struct ospf6_lsa_handler *handler = NULL;
911
912 OSPF6_DEBUG_ABR_OFF();
913 OSPF6_DEBUG_ASBR_OFF();
914 OSPF6_DEBUG_BROUTER_OFF();
915 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF();
916 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF();
917 OSPF6_DEBUG_FLOODING_OFF();
918 OSPF6_DEBUG_INTERFACE_OFF();
919
920 for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) {
921 handler = vector_slot(ospf6_lsa_handler_vector, i);
922
923 if (handler != NULL) {
924 UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG);
925 }
926 }
927
928 for (i = 0; i < 6; i++)
929 OSPF6_DEBUG_MESSAGE_OFF(i,
930 OSPF6_DEBUG_NEIGHBOR_STATE
931 | OSPF6_DEBUG_NEIGHBOR_EVENT);
932
933 OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE
934 | OSPF6_DEBUG_NEIGHBOR_EVENT);
935 OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE);
936 OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA);
937 OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER);
938 OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_MEMORY);
939 OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_PROCESS);
940 OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_TIME);
941 OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_DATABASE);
942 OSPF6_DEBUG_ZEBRA_OFF(OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV);
943
944 return CMD_SUCCESS;
945 }
946
947 int config_write_ospf6_debug_neighbor(struct vty *vty)
948 {
949 if (IS_OSPF6_DEBUG_NEIGHBOR(STATE) && IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
950 vty_out(vty, "debug ospf6 neighbor\n");
951 else if (IS_OSPF6_DEBUG_NEIGHBOR(STATE))
952 vty_out(vty, "debug ospf6 neighbor state\n");
953 else if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
954 vty_out(vty, "debug ospf6 neighbor event\n");
955 return 0;
956 }
957
958 void install_element_ospf6_debug_neighbor(void)
959 {
960 install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd);
961 install_element(ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
962 install_element(ENABLE_NODE, &no_debug_ospf6_cmd);
963 install_element(CONFIG_NODE, &debug_ospf6_neighbor_cmd);
964 install_element(CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
965 install_element(CONFIG_NODE, &no_debug_ospf6_cmd);
966 }