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