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