Annotation of embedaddon/quagga/ospf6d/ospf6_neighbor.c, revision 1.1.1.3
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"
1.1.1.3 ! misho 41: #include "ospf6_snmp.h"
1.1 misho 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:
1.1.1.3 ! misho 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:
1.1 misho 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;
1.1.1.2 misho 118: on->state_change = 0;
1.1 misho 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
1.1.1.3 ! misho 171: ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int event)
1.1 misho 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:
1.1.1.2 misho 181: on->state_change++;
1.1 misho 182: quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
183:
184: /* log */
185: if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
186: {
1.1.1.3 ! misho 187: zlog_debug ("Neighbor state change %s: [%s]->[%s] (%s)", on->name,
1.1 misho 188: ospf6_neighbor_state_str[prev_state],
1.1.1.3 ! misho 189: ospf6_neighbor_state_str[next_state],
! 190: ospf6_neighbor_event_string(event));
1.1 misho 191: }
192:
1.1.1.3 ! misho 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:
1.1 misho 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);
1.1.1.2 misho 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:
1.1 misho 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)
1.1.1.3 ! misho 264: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
! 265: OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
1.1 misho 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: {
1.1.1.3 ! misho 288: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
! 289: OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
1.1 misho 290: return 0;
291: }
292:
1.1.1.3 ! misho 293: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
! 294: OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
1.1 misho 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);
1.1.1.3 ! misho 371: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on,
! 372: OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
1.1 misho 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)
1.1.1.3 ! misho 400: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
! 401: OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
1.1 misho 402: else
1.1.1.3 ! misho 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: }
1.1 misho 411:
412: return 0;
413: }
414:
1.1.1.3 ! misho 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:
1.1 misho 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:
1.1.1.3 ! misho 455: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
! 456: OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
1.1 misho 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: {
1.1.1.3 ! misho 475: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
! 476: OSPF6_NEIGHBOR_EVENT_ADJ_OK);
1.1 misho 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: {
1.1.1.3 ! misho 489: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
! 490: OSPF6_NEIGHBOR_EVENT_ADJ_OK);
1.1 misho 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:
1.1.1.3 ! misho 519: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
! 520: OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
1.1 misho 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);
1.1.1.3 ! misho 535: on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
! 536:
1.1 misho 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:
1.1.1.3 ! misho 558: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
! 559: OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
1.1 misho 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);
1.1.1.3 ! misho 574: on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
! 575:
1.1 misho 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:
1.1.1.3 ! misho 597: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
! 598: OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
1.1 misho 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:
1.1.1.3 ! misho 633: ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on,
! 634: OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
1.1 misho 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:
1.1.1.3 ! misho 644:
1.1 misho 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",
1.1.1.3 ! misho 812: on->request_list->count, duration,
1.1 misho 813: (on->thread_send_lsreq ? "on" : "off"),
814: VNL);
1.1.1.3 ! misho 815: for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1.1 misho 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: install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
940: install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
941: }
942:
943: DEFUN (debug_ospf6_neighbor,
944: debug_ospf6_neighbor_cmd,
945: "debug ospf6 neighbor",
946: DEBUG_STR
947: OSPF6_STR
948: "Debug OSPFv3 Neighbor\n"
949: )
950: {
951: unsigned char level = 0;
952: if (argc)
953: {
954: if (! strncmp (argv[0], "s", 1))
955: level = OSPF6_DEBUG_NEIGHBOR_STATE;
956: if (! strncmp (argv[0], "e", 1))
957: level = OSPF6_DEBUG_NEIGHBOR_EVENT;
958: }
959: else
960: level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
961:
962: OSPF6_DEBUG_NEIGHBOR_ON (level);
963: return CMD_SUCCESS;
964: }
965:
966: ALIAS (debug_ospf6_neighbor,
967: debug_ospf6_neighbor_detail_cmd,
968: "debug ospf6 neighbor (state|event)",
969: DEBUG_STR
970: OSPF6_STR
971: "Debug OSPFv3 Neighbor\n"
972: "Debug OSPFv3 Neighbor State Change\n"
973: "Debug OSPFv3 Neighbor Event\n"
974: )
975:
976: DEFUN (no_debug_ospf6_neighbor,
977: no_debug_ospf6_neighbor_cmd,
978: "no debug ospf6 neighbor",
979: NO_STR
980: DEBUG_STR
981: OSPF6_STR
982: "Debug OSPFv3 Neighbor\n"
983: )
984: {
985: unsigned char level = 0;
986: if (argc)
987: {
988: if (! strncmp (argv[0], "s", 1))
989: level = OSPF6_DEBUG_NEIGHBOR_STATE;
990: if (! strncmp (argv[0], "e", 1))
991: level = OSPF6_DEBUG_NEIGHBOR_EVENT;
992: }
993: else
994: level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
995:
996: OSPF6_DEBUG_NEIGHBOR_OFF (level);
997: return CMD_SUCCESS;
998: }
999:
1000: ALIAS (no_debug_ospf6_neighbor,
1001: no_debug_ospf6_neighbor_detail_cmd,
1002: "no debug ospf6 neighbor (state|event)",
1003: NO_STR
1004: DEBUG_STR
1005: OSPF6_STR
1006: "Debug OSPFv3 Neighbor\n"
1007: "Debug OSPFv3 Neighbor State Change\n"
1008: "Debug OSPFv3 Neighbor Event\n"
1009: )
1010:
1011: int
1012: config_write_ospf6_debug_neighbor (struct vty *vty)
1013: {
1014: if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
1015: IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
1016: vty_out (vty, "debug ospf6 neighbor%s", VNL);
1017: else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
1018: vty_out (vty, "debug ospf6 neighbor state%s", VNL);
1019: else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
1020: vty_out (vty, "debug ospf6 neighbor event%s", VNL);
1021: return 0;
1022: }
1023:
1024: void
1025: install_element_ospf6_debug_neighbor (void)
1026: {
1027: install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
1028: install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
1029: install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
1030: install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
1031: install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
1032: install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
1033: install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
1034: install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
1035: }
1036:
1037:
1038:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>