2 * Copyright (C) 1999 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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.
32 #include "ospf6_lsa.h"
33 #include "ospf6_message.h"
34 #include "ospf6_neighbor.h"
35 #include "ospf6_nsm.h"
36 #include "ospf6_lsa.h"
37 #include "ospf6_lsdb.h"
39 char *ospf6_neighbor_state_string
[] =
41 "None", "Down", "Attempt", "Init", "Twoway",
42 "ExStart", "ExChange", "Loading", "Full", NULL
46 ospf6_neighbor_last_dbdesc_release (struct thread
*thread
)
48 struct ospf6_neighbor
*o6n
;
50 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
52 memset (&o6n
->last_dd
, 0, sizeof (struct ospf6_dbdesc
));
59 ospf6_neighbor_thread_cancel_all (struct ospf6_neighbor
*o6n
)
61 if (o6n
->inactivity_timer
)
62 thread_cancel (o6n
->inactivity_timer
);
63 o6n
->inactivity_timer
= (struct thread
*) NULL
;
66 thread_cancel (o6n
->send_update
);
67 o6n
->send_update
= (struct thread
*) NULL
;
69 if (o6n
->thread_send_dbdesc
)
70 thread_cancel (o6n
->thread_send_dbdesc
);
71 o6n
->thread_send_dbdesc
= (struct thread
*) NULL
;
72 if (o6n
->thread_rxmt_dbdesc
)
73 thread_cancel (o6n
->thread_rxmt_dbdesc
);
74 o6n
->thread_rxmt_dbdesc
= (struct thread
*) NULL
;
76 if (o6n
->thread_rxmt_lsreq
)
77 thread_cancel (o6n
->thread_rxmt_lsreq
);
78 o6n
->thread_rxmt_lsreq
= (struct thread
*) NULL
;
82 ospf6_neighbor_lslist_clear (struct ospf6_neighbor
*nei
)
84 ospf6_lsdb_remove_all (nei
->summary_list
);
85 ospf6_lsdb_remove_all (nei
->request_list
);
86 ospf6_lsdb_remove_all (nei
->retrans_list
);
87 ospf6_lsdb_remove_all (nei
->dbdesc_list
);
91 ospf6_neighbor_summary_add (struct ospf6_lsa
*lsa
,
92 struct ospf6_neighbor
*nei
)
94 struct ospf6_lsa
*summary
;
96 if (IS_OSPF6_DUMP_NEIGHBOR
)
98 zlog_info ("Neighbor %s summary-list:", nei
->str
);
99 zlog_info (" Add %s", lsa
->str
);
102 ospf6_lsa_age_current (lsa
);
103 summary
= ospf6_lsa_summary_create (lsa
->header
);
104 ospf6_lsdb_add (summary
, nei
->summary_list
);
108 ospf6_neighbor_summary_remove (struct ospf6_lsa
*lsa
,
109 struct ospf6_neighbor
*nei
)
111 struct ospf6_lsa
*summary
;
113 if (IS_OSPF6_DUMP_NEIGHBOR
)
115 zlog_info ("Neighbor %s summary-list:", nei
->str
);
116 zlog_info (" Remove %s", lsa
->str
);
119 summary
= ospf6_lsdb_lookup_lsdb (lsa
->header
->type
, lsa
->header
->id
,
120 lsa
->header
->adv_router
, nei
->summary_list
);
121 ospf6_lsdb_remove (summary
, nei
->summary_list
);
125 ospf6_neighbor_request_add (struct ospf6_lsa
*lsa
,
126 struct ospf6_neighbor
*nei
)
128 struct ospf6_lsa
*summary
;
130 if (IS_OSPF6_DUMP_NEIGHBOR
)
132 zlog_info ("Neighbor %s request-list:", nei
->str
);
133 zlog_info (" Add %s", lsa
->str
);
136 ospf6_lsa_age_current (lsa
);
137 summary
= ospf6_lsa_summary_create (lsa
->header
);
138 ospf6_lsdb_add (summary
, nei
->request_list
);
142 ospf6_neighbor_request_remove (struct ospf6_lsa
*lsa
,
143 struct ospf6_neighbor
*nei
)
145 struct ospf6_lsa
*summary
;
147 if (IS_OSPF6_DUMP_NEIGHBOR
)
149 zlog_info ("Neighbor %s request-list:", nei
->str
);
150 zlog_info (" Remove %s", lsa
->str
);
153 summary
= ospf6_lsdb_lookup_lsdb (lsa
->header
->type
, lsa
->header
->id
,
154 lsa
->header
->adv_router
, nei
->request_list
);
155 ospf6_lsdb_remove (summary
, nei
->request_list
);
159 ospf6_neighbor_retrans_add (struct ospf6_lsa
*lsa
,
160 struct ospf6_neighbor
*nei
)
162 if (IS_OSPF6_DUMP_NEIGHBOR
)
164 zlog_info ("Neighbor %s retrans-list:", nei
->str
);
165 zlog_info (" Add %s", lsa
->str
);
168 ospf6_lsdb_add (lsa
, nei
->retrans_list
);
172 ospf6_neighbor_retrans_remove (struct ospf6_lsa
*lsa
,
173 struct ospf6_neighbor
*nei
)
175 if (IS_OSPF6_DUMP_NEIGHBOR
)
177 zlog_info ("Neighbor %s retrans-list:", nei
->str
);
178 zlog_info (" Remove %s", lsa
->str
);
181 ospf6_lsdb_remove (lsa
, nei
->retrans_list
);
183 if (nei
->retrans_list
->count
== 0)
185 if (nei
->send_update
)
186 thread_cancel (nei
->send_update
);
187 nei
->send_update
= NULL
;
192 ospf6_neighbor_dbdesc_add (struct ospf6_lsa
*lsa
,
193 struct ospf6_neighbor
*nei
)
195 if (IS_OSPF6_DUMP_NEIGHBOR
)
197 zlog_info ("Neighbor %s dbdesc-list:", nei
->str
);
198 zlog_info (" Add %s", lsa
->str
);
201 ospf6_lsdb_add (lsa
, nei
->dbdesc_list
);
205 ospf6_neighbor_dbdesc_remove (struct ospf6_lsa
*lsa
,
206 struct ospf6_neighbor
*nei
)
208 if (IS_OSPF6_DUMP_NEIGHBOR
)
210 zlog_info ("Neighbor %s dbdesc-list:", nei
->str
);
211 zlog_info (" Remove %s", lsa
->str
);
214 ospf6_lsdb_remove (lsa
, nei
->dbdesc_list
);
218 /* prepare summary-list of his neighbor structure */
220 ospf6_neighbor_dbex_init (struct ospf6_neighbor
*nei
)
222 struct ospf6_lsdb_node node
;
225 ospf6_neighbor_lslist_clear (nei
);
228 for (ospf6_lsdb_head (&node
, nei
->ospf6_interface
->area
->ospf6
->lsdb
);
229 ! ospf6_lsdb_is_end (&node
); ospf6_lsdb_next (&node
))
231 if (IS_LSA_MAXAGE (node
.lsa
))
232 ospf6_neighbor_retrans_add (node
.lsa
, nei
);
234 ospf6_neighbor_summary_add (node
.lsa
, nei
);
237 /* AREA scope LSAs */
238 for (ospf6_lsdb_head (&node
, nei
->ospf6_interface
->area
->lsdb
);
239 ! ospf6_lsdb_is_end (&node
); ospf6_lsdb_next (&node
))
241 if (IS_LSA_MAXAGE (node
.lsa
))
242 ospf6_neighbor_retrans_add (node
.lsa
, nei
);
244 ospf6_neighbor_summary_add (node
.lsa
, nei
);
247 /* INTERFACE scope LSAs */
248 for (ospf6_lsdb_head (&node
, nei
->ospf6_interface
->lsdb
);
249 ! ospf6_lsdb_is_end (&node
); ospf6_lsdb_next (&node
))
251 if (IS_LSA_MAXAGE (node
.lsa
))
252 ospf6_neighbor_retrans_add (node
.lsa
, nei
);
254 ospf6_neighbor_summary_add (node
.lsa
, nei
);
258 /* create ospf6_neighbor */
259 struct ospf6_neighbor
*
260 ospf6_neighbor_create (u_int32_t router_id
, struct ospf6_interface
*o6i
)
262 struct ospf6_neighbor
*new;
265 new = (struct ospf6_neighbor
*)
266 XMALLOC (MTYPE_OSPF6_NEIGHBOR
, sizeof (struct ospf6_neighbor
));
269 zlog_warn ("neighbor: malloc failed");
273 memset (new, 0, sizeof (struct ospf6_neighbor
));
275 new->state
= OSPF6_NEIGHBOR_STATE_DOWN
;
277 new->router_id
= router_id
;
278 inet_ntop (AF_INET
, &router_id
, buf
, sizeof (buf
));
279 snprintf (new->str
, sizeof (new->str
), "%s%%%s", buf
, o6i
->interface
->name
);
280 new->inactivity_timer
= (struct thread
*) NULL
;
282 new->summary_list
= ospf6_lsdb_create ();
283 new->request_list
= ospf6_lsdb_create ();
284 new->retrans_list
= ospf6_lsdb_create ();
285 new->dbdesc_list
= ospf6_lsdb_create ();
287 listnode_add (o6i
->neighbor_list
, new);
288 new->ospf6_interface
= o6i
;
290 CALL_ADD_HOOK (&neighbor_hook
, new);
296 ospf6_neighbor_delete (struct ospf6_neighbor
*o6n
)
298 CALL_REMOVE_HOOK (&neighbor_hook
, o6n
);
300 ospf6_neighbor_thread_cancel_all (o6n
);
301 ospf6_neighbor_lslist_clear (o6n
);
303 list_free (o6n
->dbdesc_lsa
);
305 ospf6_lsdb_delete (o6n
->summary_list
);
306 ospf6_lsdb_delete (o6n
->request_list
);
307 ospf6_lsdb_delete (o6n
->retrans_list
);
308 ospf6_lsdb_delete (o6n
->dbdesc_list
);
310 XFREE (MTYPE_OSPF6_NEIGHBOR
, o6n
);
313 struct ospf6_neighbor
*
314 ospf6_neighbor_lookup (u_int32_t router_id
,
315 struct ospf6_interface
*o6i
)
318 struct ospf6_neighbor
*o6n
;
320 for (n
= listhead (o6i
->neighbor_list
); n
; nextnode (n
))
322 o6n
= (struct ospf6_neighbor
*) getdata (n
);
323 if (o6n
->router_id
== router_id
)
326 return (struct ospf6_neighbor
*) NULL
;
331 /* show neighbor structure */
333 ospf6_neighbor_show_summary (struct vty
*vty
, struct ospf6_neighbor
*o6n
)
336 char dr
[16], bdr
[16];
338 struct timeval now
, res
;
341 vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
342 "RouterID", "State", "Duration", "DR", "BDR", "I/F",
343 "State", VTY_NEWLINE);
346 inet_ntop (AF_INET
, &o6n
->router_id
, router_id
, sizeof (router_id
));
347 inet_ntop (AF_INET
, &o6n
->dr
, dr
, sizeof (dr
));
348 inet_ntop (AF_INET
, &o6n
->bdr
, bdr
, sizeof (bdr
));
350 gettimeofday (&now
, NULL
);
351 ospf6_timeval_sub (&now
, &o6n
->last_changed
, &res
);
352 ospf6_timeval_string_summary (&res
, duration
, sizeof (duration
));
354 vty_out (vty
, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
355 router_id
, ospf6_neighbor_state_string
[o6n
->state
],
356 duration
, dr
, bdr
, o6n
->ospf6_interface
->interface
->name
,
357 ospf6_interface_state_string
[o6n
->ospf6_interface
->state
],
362 ospf6_neighbor_show (struct vty
*vty
, struct ospf6_neighbor
*o6n
)
364 char hisaddr
[64], timestring
[32];
365 struct timeval now
, res
;
367 inet_ntop (AF_INET6
, &o6n
->hisaddr
, hisaddr
, sizeof (hisaddr
));
368 vty_out (vty
, " Neighbor %s, interface address %s%s",
369 o6n
->str
, hisaddr
, VTY_NEWLINE
);
370 vty_out (vty
, " Area %s via interface %s (ifindex %d)%s",
371 o6n
->ospf6_interface
->area
->str
,
372 o6n
->ospf6_interface
->interface
->name
,
373 o6n
->ospf6_interface
->interface
->ifindex
,
375 vty_out (vty
, " Priority: %d, State: %s, %d state changes%s",
376 o6n
->priority
, ospf6_neighbor_state_string
[o6n
->state
],
377 o6n
->ospf6_stat_state_changed
, VTY_NEWLINE
);
379 gettimeofday (&now
, NULL
);
380 ospf6_timeval_sub (&now
, &o6n
->last_changed
, &res
);
381 ospf6_timeval_string_summary (&res
, timestring
, sizeof (timestring
));
382 vty_out (vty
, " Last state changed: %s ago%s", timestring
, VTY_NEWLINE
);
386 ospf6_neighbor_show_detail (struct vty
*vty
, struct ospf6_neighbor
*o6n
)
388 char hisdr
[16], hisbdr
[16];
390 ospf6_neighbor_show (vty
, o6n
);
392 inet_ntop (AF_INET
, &o6n
->dr
, hisdr
, sizeof (hisdr
));
393 inet_ntop (AF_INET
, &o6n
->bdr
, hisbdr
, sizeof (hisbdr
));
395 vty_out (vty
, " His Ifindex of myside: %d%s",
396 o6n
->ifid
, VTY_NEWLINE
);
397 vty_out (vty
, " His DR Election: DR %s, BDR %s%s",
398 hisdr
, hisbdr
, VTY_NEWLINE
);
400 vty_out (vty
, " Last received DbDesc: opt:%s"
401 " ifmtu:%hu bit:%s%s%s seqnum:%ld%s",
402 "xxx", ntohs (o6n
->last_dd
.ifmtu
),
403 (DD_IS_IBIT_SET (o6n
->last_dd
.bits
) ? "I" : "-"),
404 (DD_IS_MBIT_SET (o6n
->last_dd
.bits
) ? "M" : "-"),
405 (DD_IS_MSBIT_SET (o6n
->last_dd
.bits
) ? "m" : "s"),
406 (u_long
)ntohl (o6n
->last_dd
.seqnum
), VTY_NEWLINE
);
407 vty_out (vty
, " My DbDesc bit for this neighbor: %s%s%s%s",
408 (DD_IS_IBIT_SET (o6n
->dbdesc_bits
) ? "I" : "-"),
409 (DD_IS_MBIT_SET (o6n
->dbdesc_bits
) ? "M" : "-"),
410 (DD_IS_MSBIT_SET (o6n
->dbdesc_bits
) ? "m" : "s"),
413 vty_out (vty
, " %-16s %5d times, %-16s %5d times%s",
414 "SeqnumMismatch", o6n
->ospf6_stat_seqnum_mismatch
,
415 "BadLSReq", o6n
->ospf6_stat_bad_lsreq
, VTY_NEWLINE
);
416 vty_out (vty
, " %-16s %5d times, %-16s %5d times%s",
417 "OnewayReceived", o6n
->ospf6_stat_oneway_received
,
418 "InactivityTimer", o6n
->ospf6_stat_inactivity_timer
,
420 vty_out (vty
, " %-16s %5d times, %-16s %5d times%s",
421 "DbDescRetrans", o6n
->ospf6_stat_retrans_dbdesc
,
422 "LSReqRetrans", o6n
->ospf6_stat_retrans_lsreq
,
424 vty_out (vty
, " %-16s %5d times%s",
425 "LSUpdateRetrans", o6n
->ospf6_stat_retrans_lsupdate
,
427 vty_out (vty
, " %-16s %5d times, %-16s %5d times%s",
428 "LSAReceived", o6n
->ospf6_stat_received_lsa
,
429 "LSUpdateReceived", o6n
->ospf6_stat_received_lsupdate
,
432 vty_out (vty
, " %-12s %-12s %-12s%s",
433 "Message", "DbDesc", "LSReq", VTY_NEWLINE
);
434 vty_out (vty
, " %-12s %12d %12d%s", "LSA Send",
435 o6n
->lsa_send
[OSPF6_MESSAGE_TYPE_DBDESC
],
436 o6n
->lsa_send
[OSPF6_MESSAGE_TYPE_LSREQ
], VTY_NEWLINE
);
437 vty_out (vty
, " %-12s %12d %12d%s", "LSA Receive",
438 o6n
->lsa_receive
[OSPF6_MESSAGE_TYPE_DBDESC
],
439 o6n
->lsa_receive
[OSPF6_MESSAGE_TYPE_LSREQ
], VTY_NEWLINE
);
440 vty_out (vty
, "%s", VTY_NEWLINE
);
444 ospf6_neighbor_timestamp_hello (struct ospf6_neighbor
*o6n
)
446 struct timeval now
, interval
;
447 gettimeofday (&now
, (struct timezone
*) NULL
);
448 if (o6n
->tv_last_hello_received
.tv_sec
)
450 ospf6_timeval_sub (&now
, &o6n
->tv_last_hello_received
, &interval
);
451 zlog_info ("Hello Interval %s : %ld msec",
452 o6n
->str
, interval
.tv_sec
* 1000 + interval
.tv_usec
% 1000);
454 o6n
->tv_last_hello_received
.tv_sec
= now
.tv_sec
;
455 o6n
->tv_last_hello_received
.tv_usec
= now
.tv_usec
;
458 DEFUN (show_ipv6_ospf6_neighbor_routerid
,
459 show_ipv6_ospf6_neighbor_routerid_cmd
,
460 "show ipv6 ospf6 neighbor A.B.C.D",
465 "OSPF6 neighbor Router ID in IP address format\n"
469 struct ospf6_neighbor
*o6n
;
470 struct ospf6_interface
*o6i
;
471 struct ospf6_area
*o6a
;
472 listnode nodei
, nodej
, nodek
;
474 OSPF6_CMD_CHECK_RUNNING ();
477 vty_out (vty
, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
478 "RouterID", "State", "Duration", "DR", "BDR", "I/F",
479 "State", VTY_NEWLINE
);
480 else if (inet_pton (AF_INET
, argv
[0], &router_id
) != 1)
482 vty_out (vty
, "Malformed Router-ID: %s%s", argv
[0], VTY_NEWLINE
);
486 for (nodei
= listhead (ospf6
->area_list
); nodei
; nextnode (nodei
))
488 o6a
= getdata (nodei
);
489 for (nodej
= listhead (o6a
->if_list
); nodej
; nextnode (nodej
))
491 o6i
= getdata (nodej
);
492 for (nodek
= listhead (o6i
->neighbor_list
); nodek
; nextnode (nodek
))
494 o6n
= getdata (nodek
);
496 ospf6_neighbor_show_summary (vty
, o6n
);
497 else if (o6n
->router_id
== router_id
)
498 ospf6_neighbor_show_detail (vty
, o6n
);
505 ALIAS (show_ipv6_ospf6_neighbor_routerid
,
506 show_ipv6_ospf6_neighbor_cmd
,
507 "show ipv6 ospf6 neighbor",
514 DEFUN (show_ipv6_ospf6_neighborlist
,
515 show_ipv6_ospf6_neighborlist_cmd
,
516 "show ipv6 ospf6 (summary-list|request-list|retrans-list|dbdesc-list)",
520 "Link State summary list\n"
521 "Link State request list\n"
522 "Link State retransmission list\n"
523 "Link State Description list (Used to retrans DbDesc)\n"
526 struct ospf6_area
*o6a
;
527 struct ospf6_interface
*o6i
;
528 struct ospf6_neighbor
*o6n
;
530 struct ospf6_lsa
*lsa
;
531 struct ospf6_lsdb
*lsdb
= NULL
;
532 char type
[16], id
[16], adv_router
[16];
533 struct ospf6_lsdb_node node
;
534 u_int16_t age
, cksum
, len
;
537 OSPF6_CMD_CHECK_RUNNING ();
538 i
= j
= k
= l
= NULL
;
540 for (i
= listhead (ospf6
->area_list
); i
; nextnode (i
))
542 o6a
= (struct ospf6_area
*) getdata (i
);
543 for (j
= listhead (o6a
->if_list
); j
; nextnode (j
))
545 o6i
= (struct ospf6_interface
*) getdata (j
);
546 for (k
= listhead (o6i
->neighbor_list
); k
; nextnode (k
))
548 o6n
= (struct ospf6_neighbor
*) getdata (k
);
550 if (strncmp (argv
[0], "sum", 3) == 0)
551 lsdb
= o6n
->summary_list
;
552 else if (strncmp (argv
[0], "req", 3) == 0)
553 lsdb
= o6n
->request_list
;
554 else if (strncmp (argv
[0], "ret", 3) == 0)
555 lsdb
= o6n
->retrans_list
;
556 else if (strncmp (argv
[0], "dbd", 3) == 0)
557 lsdb
= o6n
->dbdesc_list
;
559 vty_out (vty
, "neighbor %s on interface %s: %d%s", o6n
->str
,
560 o6i
->interface
->name
, lsdb
->count
,
562 for (ospf6_lsdb_head (&node
, lsdb
); ! ospf6_lsdb_is_end (&node
);
563 ospf6_lsdb_next (&node
))
566 ospf6_lsa_age_current (lsa
);
568 ospf6_lsa_type_string (lsa
->header
->type
, type
,
570 inet_ntop (AF_INET
, &lsa
->header
->id
, id
, sizeof (id
));
571 inet_ntop (AF_INET
, &lsa
->header
->adv_router
, adv_router
,
572 sizeof (adv_router
));
573 age
= ntohs (lsa
->header
->age
);
574 seqnum
= ntohl (lsa
->header
->seqnum
);
575 cksum
= ntohs (lsa
->header
->checksum
);
576 len
= ntohs (lsa
->header
->length
);
578 vty_out (vty
, " %s-LSA ID=%s Adv=%s%s",
579 type
, id
, adv_router
, VTY_NEWLINE
);
580 vty_out (vty
, " Age: %hu SeqNum: %#x Cksum: %hx Len: %hu%s",
581 age
, seqnum
, cksum
, len
, VTY_NEWLINE
);
591 ospf6_neighbor_init ()
593 install_element (VIEW_NODE
, &show_ipv6_ospf6_neighbor_cmd
);
594 install_element (VIEW_NODE
, &show_ipv6_ospf6_neighbor_routerid_cmd
);
595 install_element (VIEW_NODE
, &show_ipv6_ospf6_neighborlist_cmd
);
597 install_element (ENABLE_NODE
, &show_ipv6_ospf6_neighbor_cmd
);
598 install_element (ENABLE_NODE
, &show_ipv6_ospf6_neighbor_routerid_cmd
);
599 install_element (ENABLE_NODE
, &show_ipv6_ospf6_neighborlist_cmd
);