]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
718e3744 | 2 | /* |
508e53e2 | 3 | * Copyright (C) 2003 Yasuhiro Ohara |
718e3744 | 4 | */ |
5 | ||
718e3744 | 6 | #include <zebra.h> |
7 | ||
8 | #include "log.h" | |
508e53e2 | 9 | #include "memory.h" |
718e3744 | 10 | #include "thread.h" |
11 | #include "linklist.h" | |
12 | #include "vty.h" | |
13 | #include "command.h" | |
d06cc416 | 14 | #include "lib/bfd.h" |
718e3744 | 15 | |
508e53e2 | 16 | #include "ospf6_proto.h" |
718e3744 | 17 | #include "ospf6_lsa.h" |
508e53e2 | 18 | #include "ospf6_lsdb.h" |
718e3744 | 19 | #include "ospf6_message.h" |
508e53e2 | 20 | #include "ospf6_top.h" |
21 | #include "ospf6_area.h" | |
22 | #include "ospf6_interface.h" | |
718e3744 | 23 | #include "ospf6_neighbor.h" |
508e53e2 | 24 | #include "ospf6_intra.h" |
3b4cd3a9 | 25 | #include "ospf6_flood.h" |
049207c3 | 26 | #include "ospf6d.h" |
7f342629 | 27 | #include "ospf6_bfd.h" |
4dfd8aff DW |
28 | #include "ospf6_abr.h" |
29 | #include "ospf6_asbr.h" | |
30 | #include "ospf6_lsa.h" | |
31 | #include "ospf6_spf.h" | |
32 | #include "ospf6_zebra.h" | |
0d1753a7 | 33 | #include "ospf6_gr.h" |
6a5bb300 | 34 | #include "lib/json.h" |
718e3744 | 35 | |
a526c055 | 36 | DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor"); |
30043e4c | 37 | |
3012671f | 38 | DEFINE_HOOK(ospf6_neighbor_change, |
d62a17ae | 39 | (struct ospf6_neighbor * on, int state, int next_state), |
8451921b | 40 | (on, state, next_state)); |
3012671f | 41 | |
508e53e2 | 42 | unsigned char conf_debug_ospf6_neighbor = 0; |
43 | ||
2b64873d | 44 | const char *const ospf6_neighbor_state_str[] = { |
d62a17ae | 45 | "None", "Down", "Attempt", "Init", "Twoway", |
46 | "ExStart", "ExChange", "Loading", "Full", NULL}; | |
718e3744 | 47 | |
2b64873d DL |
48 | const char *const ospf6_neighbor_event_str[] = { |
49 | "NoEvent", "HelloReceived", "2-WayReceived", "NegotiationDone", | |
50 | "ExchangeDone", "LoadingDone", "AdjOK?", "SeqNumberMismatch", | |
51 | "BadLSReq", "1-WayReceived", "InactivityTimer", | |
52 | }; | |
53 | ||
d62a17ae | 54 | int ospf6_neighbor_cmp(void *va, void *vb) |
718e3744 | 55 | { |
d62a17ae | 56 | struct ospf6_neighbor *ona = (struct ospf6_neighbor *)va; |
57 | struct ospf6_neighbor *onb = (struct ospf6_neighbor *)vb; | |
27fa3398 DS |
58 | |
59 | if (ona->router_id == onb->router_id) | |
60 | return 0; | |
61 | ||
62 | return (ntohl(ona->router_id) < ntohl(onb->router_id)) ? -1 : 1; | |
718e3744 | 63 | } |
64 | ||
d7c0a89a | 65 | struct ospf6_neighbor *ospf6_neighbor_lookup(uint32_t router_id, |
d62a17ae | 66 | struct ospf6_interface *oi) |
718e3744 | 67 | { |
d62a17ae | 68 | struct listnode *n; |
69 | struct ospf6_neighbor *on; | |
70 | ||
71 | for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, n, on)) | |
72 | if (on->router_id == router_id) | |
73 | return on; | |
74 | ||
75 | return (struct ospf6_neighbor *)NULL; | |
718e3744 | 76 | } |
77 | ||
71165098 RW |
78 | struct ospf6_neighbor *ospf6_area_neighbor_lookup(struct ospf6_area *area, |
79 | uint32_t router_id) | |
80 | { | |
81 | struct ospf6_interface *oi; | |
82 | struct ospf6_neighbor *nbr; | |
83 | struct listnode *node; | |
84 | ||
85 | for (ALL_LIST_ELEMENTS_RO(area->if_list, node, oi)) { | |
86 | nbr = ospf6_neighbor_lookup(router_id, oi); | |
87 | if (nbr) | |
88 | return nbr; | |
89 | } | |
90 | ||
91 | return NULL; | |
92 | } | |
93 | ||
47cd6348 MN |
94 | static void ospf6_neighbor_clear_ls_lists(struct ospf6_neighbor *on) |
95 | { | |
96 | struct ospf6_lsa *lsa; | |
97 | struct ospf6_lsa *lsanext; | |
98 | ||
99 | ospf6_lsdb_remove_all(on->summary_list); | |
100 | if (on->last_ls_req) { | |
101 | ospf6_lsa_unlock(on->last_ls_req); | |
102 | on->last_ls_req = NULL; | |
103 | } | |
104 | ospf6_lsdb_remove_all(on->request_list); | |
105 | for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { | |
106 | ospf6_decrement_retrans_count(lsa); | |
107 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
108 | } | |
109 | } | |
110 | ||
508e53e2 | 111 | /* create ospf6_neighbor */ |
d7c0a89a | 112 | struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id, |
d62a17ae | 113 | struct ospf6_interface *oi) |
718e3744 | 114 | { |
d62a17ae | 115 | struct ospf6_neighbor *on; |
116 | char buf[16]; | |
6cb85350 | 117 | int type; |
d62a17ae | 118 | |
aa406bbc | 119 | on = XCALLOC(MTYPE_OSPF6_NEIGHBOR, sizeof(struct ospf6_neighbor)); |
d62a17ae | 120 | inet_ntop(AF_INET, &router_id, buf, sizeof(buf)); |
121 | snprintf(on->name, sizeof(on->name), "%s%%%s", buf, | |
122 | oi->interface->name); | |
123 | on->ospf6_if = oi; | |
124 | on->state = OSPF6_NEIGHBOR_DOWN; | |
125 | on->state_change = 0; | |
126 | monotime(&on->last_changed); | |
127 | on->router_id = router_id; | |
128 | ||
129 | on->summary_list = ospf6_lsdb_create(on); | |
130 | on->request_list = ospf6_lsdb_create(on); | |
131 | on->retrans_list = ospf6_lsdb_create(on); | |
132 | ||
133 | on->dbdesc_list = ospf6_lsdb_create(on); | |
134 | on->lsupdate_list = ospf6_lsdb_create(on); | |
135 | on->lsack_list = ospf6_lsdb_create(on); | |
136 | ||
6cb85350 AR |
137 | for (type = 0; type < OSPF6_MESSAGE_TYPE_MAX; type++) { |
138 | on->seqnum_l[type] = 0; | |
139 | on->seqnum_h[type] = 0; | |
140 | } | |
141 | ||
142 | on->auth_present = false; | |
143 | ||
d62a17ae | 144 | listnode_add_sort(oi->neighbor_list, on); |
145 | ||
146 | ospf6_bfd_info_nbr_create(oi, on); | |
147 | return on; | |
718e3744 | 148 | } |
149 | ||
d62a17ae | 150 | void ospf6_neighbor_delete(struct ospf6_neighbor *on) |
718e3744 | 151 | { |
47cd6348 | 152 | ospf6_neighbor_clear_ls_lists(on); |
718e3744 | 153 | |
d62a17ae | 154 | ospf6_lsdb_remove_all(on->dbdesc_list); |
155 | ospf6_lsdb_remove_all(on->lsupdate_list); | |
156 | ospf6_lsdb_remove_all(on->lsack_list); | |
508e53e2 | 157 | |
d62a17ae | 158 | ospf6_lsdb_delete(on->summary_list); |
159 | ospf6_lsdb_delete(on->request_list); | |
160 | ospf6_lsdb_delete(on->retrans_list); | |
718e3744 | 161 | |
d62a17ae | 162 | ospf6_lsdb_delete(on->dbdesc_list); |
163 | ospf6_lsdb_delete(on->lsupdate_list); | |
164 | ospf6_lsdb_delete(on->lsack_list); | |
508e53e2 | 165 | |
d62a17ae | 166 | THREAD_OFF(on->inactivity_timer); |
508e53e2 | 167 | |
bc09f3e6 YR |
168 | THREAD_OFF(on->last_dbdesc_release_timer); |
169 | ||
d62a17ae | 170 | THREAD_OFF(on->thread_send_dbdesc); |
171 | THREAD_OFF(on->thread_send_lsreq); | |
172 | THREAD_OFF(on->thread_send_lsupdate); | |
173 | THREAD_OFF(on->thread_send_lsack); | |
9318fc6a | 174 | THREAD_OFF(on->thread_exchange_done); |
81e06dd3 DS |
175 | THREAD_OFF(on->thread_adj_ok); |
176 | ||
0d1753a7 | 177 | THREAD_OFF(on->gr_helper_info.t_grace_timer); |
508e53e2 | 178 | |
d06cc416 | 179 | bfd_sess_free(&on->bfd_session); |
d62a17ae | 180 | XFREE(MTYPE_OSPF6_NEIGHBOR, on); |
718e3744 | 181 | } |
182 | ||
d7c0a89a | 183 | static void ospf6_neighbor_state_change(uint8_t next_state, |
d62a17ae | 184 | struct ospf6_neighbor *on, int event) |
718e3744 | 185 | { |
d7c0a89a | 186 | uint8_t prev_state; |
d62a17ae | 187 | |
188 | prev_state = on->state; | |
189 | on->state = next_state; | |
190 | ||
191 | if (prev_state == next_state) | |
192 | return; | |
193 | ||
194 | on->state_change++; | |
195 | monotime(&on->last_changed); | |
196 | ||
197 | /* log */ | |
198 | if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) { | |
199 | zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)", | |
200 | on->name, ospf6_neighbor_state_str[prev_state], | |
201 | ospf6_neighbor_state_str[next_state], | |
202 | ospf6_neighbor_event_string(event)); | |
203 | } | |
204 | ||
205 | /* Optionally notify about adjacency changes */ | |
206 | if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, | |
207 | OSPF6_LOG_ADJACENCY_CHANGES) | |
208 | && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, | |
209 | OSPF6_LOG_ADJACENCY_DETAIL) | |
210 | || (next_state == OSPF6_NEIGHBOR_FULL) | |
211 | || (next_state < prev_state))) | |
212 | zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name, | |
213 | ospf6_neighbor_state_str[prev_state], | |
214 | ospf6_neighbor_state_str[next_state], | |
215 | ospf6_neighbor_event_string(event)); | |
216 | ||
217 | if (prev_state == OSPF6_NEIGHBOR_FULL | |
218 | || next_state == OSPF6_NEIGHBOR_FULL) { | |
0d1753a7 | 219 | if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) { |
220 | OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area); | |
221 | if (on->ospf6_if->state == OSPF6_INTERFACE_DR) { | |
222 | OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if); | |
223 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT( | |
224 | on->ospf6_if); | |
225 | } | |
d62a17ae | 226 | } |
690df177 CS |
227 | if (next_state == OSPF6_NEIGHBOR_FULL) |
228 | on->ospf6_if->area->intra_prefix_originate = 1; | |
229 | ||
0d1753a7 | 230 | if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) |
231 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB( | |
232 | on->ospf6_if->area); | |
76249532 | 233 | |
0d1753a7 | 234 | if ((prev_state == OSPF6_NEIGHBOR_LOADING |
235 | || prev_state == OSPF6_NEIGHBOR_EXCHANGE) | |
236 | && next_state == OSPF6_NEIGHBOR_FULL) { | |
76249532 | 237 | OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if); |
d6927cf3 | 238 | on->ospf6_if->area->full_nbrs++; |
76249532 | 239 | } |
d6927cf3 CS |
240 | |
241 | if (prev_state == OSPF6_NEIGHBOR_FULL) | |
242 | on->ospf6_if->area->full_nbrs--; | |
d62a17ae | 243 | } |
244 | ||
245 | if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE | |
246 | || prev_state == OSPF6_NEIGHBOR_LOADING) | |
247 | && (next_state != OSPF6_NEIGHBOR_EXCHANGE | |
248 | && next_state != OSPF6_NEIGHBOR_LOADING)) | |
249 | ospf6_maxage_remove(on->ospf6_if->area->ospf6); | |
250 | ||
251 | hook_call(ospf6_neighbor_change, on, next_state, prev_state); | |
252 | ospf6_bfd_trigger_event(on, prev_state, next_state); | |
718e3744 | 253 | } |
254 | ||
508e53e2 | 255 | /* RFC2328 section 10.4 */ |
d62a17ae | 256 | static int need_adjacency(struct ospf6_neighbor *on) |
718e3744 | 257 | { |
d62a17ae | 258 | if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT |
259 | || on->ospf6_if->state == OSPF6_INTERFACE_DR | |
260 | || on->ospf6_if->state == OSPF6_INTERFACE_BDR) | |
261 | return 1; | |
718e3744 | 262 | |
d62a17ae | 263 | if (on->ospf6_if->drouter == on->router_id |
264 | || on->ospf6_if->bdrouter == on->router_id) | |
265 | return 1; | |
508e53e2 | 266 | |
d62a17ae | 267 | return 0; |
718e3744 | 268 | } |
269 | ||
cc9f21da | 270 | void hello_received(struct thread *thread) |
718e3744 | 271 | { |
d62a17ae | 272 | struct ospf6_neighbor *on; |
718e3744 | 273 | |
d62a17ae | 274 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
275 | assert(on); | |
718e3744 | 276 | |
d62a17ae | 277 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
278 | zlog_debug("Neighbor Event %s: *HelloReceived*", on->name); | |
508e53e2 | 279 | |
d62a17ae | 280 | /* reset Inactivity Timer */ |
281 | THREAD_OFF(on->inactivity_timer); | |
d62a17ae | 282 | thread_add_timer(master, inactivity_timer, on, |
283 | on->ospf6_if->dead_interval, &on->inactivity_timer); | |
508e53e2 | 284 | |
d62a17ae | 285 | if (on->state <= OSPF6_NEIGHBOR_DOWN) |
286 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on, | |
287 | OSPF6_NEIGHBOR_EVENT_HELLO_RCVD); | |
718e3744 | 288 | } |
289 | ||
cc9f21da | 290 | void twoway_received(struct thread *thread) |
718e3744 | 291 | { |
d62a17ae | 292 | struct ospf6_neighbor *on; |
508e53e2 | 293 | |
d62a17ae | 294 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
295 | assert(on); | |
508e53e2 | 296 | |
d62a17ae | 297 | if (on->state > OSPF6_NEIGHBOR_INIT) |
cc9f21da | 298 | return; |
508e53e2 | 299 | |
d62a17ae | 300 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
301 | zlog_debug("Neighbor Event %s: *2Way-Received*", on->name); | |
508e53e2 | 302 | |
d62a17ae | 303 | thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); |
508e53e2 | 304 | |
d62a17ae | 305 | if (!need_adjacency(on)) { |
306 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on, | |
307 | OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); | |
cc9f21da | 308 | return; |
d62a17ae | 309 | } |
718e3744 | 310 | |
d62a17ae | 311 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, |
312 | OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); | |
313 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
314 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
315 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
508e53e2 | 316 | |
d62a17ae | 317 | THREAD_OFF(on->thread_send_dbdesc); |
d62a17ae | 318 | thread_add_event(master, ospf6_dbdesc_send, on, 0, |
319 | &on->thread_send_dbdesc); | |
718e3744 | 320 | } |
321 | ||
cc9f21da | 322 | void negotiation_done(struct thread *thread) |
718e3744 | 323 | { |
d62a17ae | 324 | struct ospf6_neighbor *on; |
2e37407f | 325 | struct ospf6_lsa *lsa, *lsanext; |
d62a17ae | 326 | |
327 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); | |
328 | assert(on); | |
329 | ||
330 | if (on->state != OSPF6_NEIGHBOR_EXSTART) | |
cc9f21da | 331 | return; |
d62a17ae | 332 | |
333 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) | |
334 | zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name); | |
335 | ||
336 | /* clear ls-list */ | |
47cd6348 | 337 | ospf6_neighbor_clear_ls_lists(on); |
d62a17ae | 338 | |
339 | /* Interface scoped LSAs */ | |
2e37407f | 340 | for (ALL_LSDB(on->ospf6_if->lsdb, lsa, lsanext)) { |
d62a17ae | 341 | if (OSPF6_LSA_IS_MAXAGE(lsa)) { |
342 | ospf6_increment_retrans_count(lsa); | |
343 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); | |
344 | } else | |
345 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); | |
346 | } | |
347 | ||
348 | /* Area scoped LSAs */ | |
2e37407f | 349 | for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa, lsanext)) { |
d62a17ae | 350 | if (OSPF6_LSA_IS_MAXAGE(lsa)) { |
351 | ospf6_increment_retrans_count(lsa); | |
352 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); | |
353 | } else | |
354 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); | |
355 | } | |
356 | ||
357 | /* AS scoped LSAs */ | |
2e37407f | 358 | for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa, lsanext)) { |
d62a17ae | 359 | if (OSPF6_LSA_IS_MAXAGE(lsa)) { |
360 | ospf6_increment_retrans_count(lsa); | |
361 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); | |
362 | } else | |
363 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); | |
364 | } | |
365 | ||
366 | UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
367 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on, | |
368 | OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE); | |
718e3744 | 369 | } |
370 | ||
cc9f21da | 371 | static void ospf6_neighbor_last_dbdesc_release(struct thread *thread) |
bc09f3e6 YR |
372 | { |
373 | struct ospf6_neighbor *on = THREAD_ARG(thread); | |
374 | ||
375 | assert(on); | |
376 | memset(&on->dbdesc_last, 0, sizeof(struct ospf6_dbdesc)); | |
bc09f3e6 YR |
377 | } |
378 | ||
cc9f21da | 379 | void exchange_done(struct thread *thread) |
718e3744 | 380 | { |
d62a17ae | 381 | struct ospf6_neighbor *on; |
718e3744 | 382 | |
d62a17ae | 383 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
384 | assert(on); | |
508e53e2 | 385 | |
d62a17ae | 386 | if (on->state != OSPF6_NEIGHBOR_EXCHANGE) |
cc9f21da | 387 | return; |
508e53e2 | 388 | |
d62a17ae | 389 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
390 | zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name); | |
508e53e2 | 391 | |
d62a17ae | 392 | THREAD_OFF(on->thread_send_dbdesc); |
393 | ospf6_lsdb_remove_all(on->dbdesc_list); | |
508e53e2 | 394 | |
bc09f3e6 YR |
395 | /* RFC 2328 (10.8): Release the last dbdesc after dead_interval */ |
396 | if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) { | |
397 | THREAD_OFF(on->last_dbdesc_release_timer); | |
398 | thread_add_timer(master, ospf6_neighbor_last_dbdesc_release, on, | |
399 | on->ospf6_if->dead_interval, | |
400 | &on->last_dbdesc_release_timer); | |
401 | } | |
508e53e2 | 402 | |
d62a17ae | 403 | if (on->request_list->count == 0) |
404 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on, | |
405 | OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); | |
406 | else { | |
407 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on, | |
408 | OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); | |
eb82e9ee | 409 | |
d62a17ae | 410 | thread_add_event(master, ospf6_lsreq_send, on, 0, |
411 | &on->thread_send_lsreq); | |
412 | } | |
508e53e2 | 413 | } |
414 | ||
eb82e9ee | 415 | /* Check loading state. */ |
d62a17ae | 416 | void ospf6_check_nbr_loading(struct ospf6_neighbor *on) |
eb82e9ee DD |
417 | { |
418 | ||
d62a17ae | 419 | /* RFC2328 Section 10.9: When the neighbor responds to these requests |
420 | with the proper Link State Update packet(s), the Link state request | |
421 | list is truncated and a new Link State Request packet is sent. | |
422 | */ | |
423 | if ((on->state == OSPF6_NEIGHBOR_LOADING) | |
424 | || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) { | |
425 | if (on->request_list->count == 0) | |
426 | thread_add_event(master, loading_done, on, 0, NULL); | |
427 | else if (on->last_ls_req == NULL) { | |
c905f04c | 428 | THREAD_OFF(on->thread_send_lsreq); |
d62a17ae | 429 | thread_add_event(master, ospf6_lsreq_send, on, 0, |
430 | &on->thread_send_lsreq); | |
431 | } | |
eb82e9ee | 432 | } |
eb82e9ee DD |
433 | } |
434 | ||
cc9f21da | 435 | void loading_done(struct thread *thread) |
508e53e2 | 436 | { |
d62a17ae | 437 | struct ospf6_neighbor *on; |
508e53e2 | 438 | |
d62a17ae | 439 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
440 | assert(on); | |
508e53e2 | 441 | |
d62a17ae | 442 | if (on->state != OSPF6_NEIGHBOR_LOADING) |
cc9f21da | 443 | return; |
508e53e2 | 444 | |
d62a17ae | 445 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
446 | zlog_debug("Neighbor Event %s: *LoadingDone*", on->name); | |
508e53e2 | 447 | |
d62a17ae | 448 | assert(on->request_list->count == 0); |
508e53e2 | 449 | |
d62a17ae | 450 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on, |
451 | OSPF6_NEIGHBOR_EVENT_LOADING_DONE); | |
508e53e2 | 452 | } |
453 | ||
cc9f21da | 454 | void adj_ok(struct thread *thread) |
508e53e2 | 455 | { |
d62a17ae | 456 | struct ospf6_neighbor *on; |
d62a17ae | 457 | |
458 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); | |
459 | assert(on); | |
460 | ||
461 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) | |
462 | zlog_debug("Neighbor Event %s: *AdjOK?*", on->name); | |
463 | ||
464 | if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency(on)) { | |
465 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, | |
466 | OSPF6_NEIGHBOR_EVENT_ADJ_OK); | |
467 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
468 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
469 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
470 | ||
471 | THREAD_OFF(on->thread_send_dbdesc); | |
d62a17ae | 472 | thread_add_event(master, ospf6_dbdesc_send, on, 0, |
473 | &on->thread_send_dbdesc); | |
474 | ||
475 | } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) { | |
476 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on, | |
477 | OSPF6_NEIGHBOR_EVENT_ADJ_OK); | |
47cd6348 | 478 | ospf6_neighbor_clear_ls_lists(on); |
d62a17ae | 479 | } |
508e53e2 | 480 | } |
718e3744 | 481 | |
cc9f21da | 482 | void seqnumber_mismatch(struct thread *thread) |
508e53e2 | 483 | { |
d62a17ae | 484 | struct ospf6_neighbor *on; |
718e3744 | 485 | |
d62a17ae | 486 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
487 | assert(on); | |
718e3744 | 488 | |
d62a17ae | 489 | if (on->state < OSPF6_NEIGHBOR_EXCHANGE) |
cc9f21da | 490 | return; |
718e3744 | 491 | |
d62a17ae | 492 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
493 | zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name); | |
718e3744 | 494 | |
d62a17ae | 495 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, |
496 | OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH); | |
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 | |
47cd6348 | 501 | ospf6_neighbor_clear_ls_lists(on); |
508e53e2 | 502 | |
d62a17ae | 503 | THREAD_OFF(on->thread_send_dbdesc); |
504 | on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ | |
931b1b8c | 505 | |
d62a17ae | 506 | thread_add_event(master, ospf6_dbdesc_send, on, 0, |
507 | &on->thread_send_dbdesc); | |
718e3744 | 508 | } |
509 | ||
cc9f21da | 510 | void bad_lsreq(struct thread *thread) |
718e3744 | 511 | { |
d62a17ae | 512 | struct ospf6_neighbor *on; |
508e53e2 | 513 | |
d62a17ae | 514 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
515 | assert(on); | |
508e53e2 | 516 | |
d62a17ae | 517 | if (on->state < OSPF6_NEIGHBOR_EXCHANGE) |
cc9f21da | 518 | return; |
718e3744 | 519 | |
d62a17ae | 520 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
521 | zlog_debug("Neighbor Event %s: *BadLSReq*", on->name); | |
718e3744 | 522 | |
d62a17ae | 523 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, |
524 | OSPF6_NEIGHBOR_EVENT_BAD_LSREQ); | |
525 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
526 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
527 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
718e3744 | 528 | |
47cd6348 | 529 | ospf6_neighbor_clear_ls_lists(on); |
718e3744 | 530 | |
d62a17ae | 531 | THREAD_OFF(on->thread_send_dbdesc); |
532 | on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ | |
931b1b8c | 533 | |
d62a17ae | 534 | thread_add_event(master, ospf6_dbdesc_send, on, 0, |
535 | &on->thread_send_dbdesc); | |
508e53e2 | 536 | |
718e3744 | 537 | } |
538 | ||
cc9f21da | 539 | void oneway_received(struct thread *thread) |
718e3744 | 540 | { |
d62a17ae | 541 | struct ospf6_neighbor *on; |
718e3744 | 542 | |
d62a17ae | 543 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
544 | assert(on); | |
508e53e2 | 545 | |
d62a17ae | 546 | if (on->state < OSPF6_NEIGHBOR_TWOWAY) |
cc9f21da | 547 | return; |
508e53e2 | 548 | |
d62a17ae | 549 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
550 | zlog_debug("Neighbor Event %s: *1Way-Received*", on->name); | |
508e53e2 | 551 | |
d62a17ae | 552 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on, |
553 | OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD); | |
554 | thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); | |
508e53e2 | 555 | |
47cd6348 | 556 | ospf6_neighbor_clear_ls_lists(on); |
508e53e2 | 557 | |
d62a17ae | 558 | THREAD_OFF(on->thread_send_dbdesc); |
559 | THREAD_OFF(on->thread_send_lsreq); | |
560 | THREAD_OFF(on->thread_send_lsupdate); | |
561 | THREAD_OFF(on->thread_send_lsack); | |
9318fc6a | 562 | THREAD_OFF(on->thread_exchange_done); |
81e06dd3 | 563 | THREAD_OFF(on->thread_adj_ok); |
508e53e2 | 564 | } |
565 | ||
cc9f21da | 566 | void inactivity_timer(struct thread *thread) |
508e53e2 | 567 | { |
d62a17ae | 568 | struct ospf6_neighbor *on; |
508e53e2 | 569 | |
d62a17ae | 570 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
571 | assert(on); | |
508e53e2 | 572 | |
d62a17ae | 573 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
574 | zlog_debug("Neighbor Event %s: *InactivityTimer*", on->name); | |
508e53e2 | 575 | |
d62a17ae | 576 | on->drouter = on->prev_drouter = 0; |
577 | on->bdrouter = on->prev_bdrouter = 0; | |
508e53e2 | 578 | |
0d1753a7 | 579 | if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) { |
580 | on->drouter = on->prev_drouter = 0; | |
581 | on->bdrouter = on->prev_bdrouter = 0; | |
582 | ||
583 | ospf6_neighbor_state_change( | |
584 | OSPF6_NEIGHBOR_DOWN, on, | |
585 | OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER); | |
586 | thread_add_event(master, neighbor_change, on->ospf6_if, 0, | |
587 | NULL); | |
588 | ||
589 | listnode_delete(on->ospf6_if->neighbor_list, on); | |
590 | ospf6_neighbor_delete(on); | |
508e53e2 | 591 | |
0d1753a7 | 592 | } else { |
0fc3e113 | 593 | if (IS_DEBUG_OSPF6_GR) |
0d1753a7 | 594 | zlog_debug( |
595 | "%s, Acting as HELPER for this neighbour, So restart the dead timer.", | |
596 | __PRETTY_FUNCTION__); | |
597 | ||
598 | thread_add_timer(master, inactivity_timer, on, | |
599 | on->ospf6_if->dead_interval, | |
600 | &on->inactivity_timer); | |
601 | } | |
718e3744 | 602 | } |
603 | ||
508e53e2 | 604 | |
718e3744 | 605 | /* vty functions */ |
606 | /* show neighbor structure */ | |
6a5bb300 | 607 | static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, |
608 | json_object *json_array, bool use_json) | |
718e3744 | 609 | { |
d62a17ae | 610 | char router_id[16]; |
68bfcc05 | 611 | char duration[64]; |
d62a17ae | 612 | struct timeval res; |
613 | char nstate[16]; | |
68bfcc05 | 614 | char deadtime[64]; |
d62a17ae | 615 | long h, m, s; |
6a5bb300 | 616 | json_object *json_route; |
d62a17ae | 617 | |
618 | /* Router-ID (Name) */ | |
619 | inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id)); | |
508e53e2 | 620 | #ifdef HAVE_GETNAMEINFO |
d62a17ae | 621 | { |
622 | } | |
508e53e2 | 623 | #endif /*HAVE_GETNAMEINFO*/ |
624 | ||
d62a17ae | 625 | /* Dead time */ |
626 | h = m = s = 0; | |
627 | if (on->inactivity_timer) { | |
628 | s = monotime_until(&on->inactivity_timer->u.sands, NULL) | |
629 | / 1000000LL; | |
630 | h = s / 3600; | |
631 | s -= h * 3600; | |
632 | m = s / 60; | |
633 | s -= m * 60; | |
634 | } | |
635 | snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s); | |
636 | ||
637 | /* Neighbor State */ | |
e5973353 | 638 | if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) |
d62a17ae | 639 | snprintf(nstate, sizeof(nstate), "PointToPoint"); |
640 | else { | |
641 | if (on->router_id == on->drouter) | |
642 | snprintf(nstate, sizeof(nstate), "DR"); | |
643 | else if (on->router_id == on->bdrouter) | |
644 | snprintf(nstate, sizeof(nstate), "BDR"); | |
645 | else | |
646 | snprintf(nstate, sizeof(nstate), "DROther"); | |
647 | } | |
648 | ||
649 | /* Duration */ | |
650 | monotime_since(&on->last_changed, &res); | |
651 | timerstring(&res, duration, sizeof(duration)); | |
652 | ||
653 | /* | |
654 | vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n", | |
6a5bb300 | 655 | "Neighbor ID", "Pri", "DeadTime", "State", "IfState", |
656 | "Duration", "I/F", "State"); | |
d62a17ae | 657 | */ |
6a5bb300 | 658 | if (use_json) { |
659 | json_route = json_object_new_object(); | |
660 | ||
661 | json_object_string_add(json_route, "neighborId", router_id); | |
662 | json_object_int_add(json_route, "priority", on->priority); | |
663 | json_object_string_add(json_route, "deadTime", deadtime); | |
664 | json_object_string_add(json_route, "state", | |
665 | ospf6_neighbor_state_str[on->state]); | |
666 | json_object_string_add(json_route, "ifState", nstate); | |
667 | json_object_string_add(json_route, "duration", duration); | |
668 | json_object_string_add(json_route, "interfaceName", | |
669 | on->ospf6_if->interface->name); | |
670 | json_object_string_add( | |
671 | json_route, "interfaceState", | |
672 | ospf6_interface_state_str[on->ospf6_if->state]); | |
673 | ||
674 | json_object_array_add(json_array, json_route); | |
675 | } else | |
676 | vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]\n", | |
677 | router_id, on->priority, deadtime, | |
678 | ospf6_neighbor_state_str[on->state], nstate, duration, | |
679 | on->ospf6_if->interface->name, | |
680 | ospf6_interface_state_str[on->ospf6_if->state]); | |
508e53e2 | 681 | } |
682 | ||
d62a17ae | 683 | static void ospf6_neighbor_show_drchoice(struct vty *vty, |
6a5bb300 | 684 | struct ospf6_neighbor *on, |
685 | json_object *json_array, bool use_json) | |
508e53e2 | 686 | { |
d62a17ae | 687 | char router_id[16]; |
688 | char drouter[16], bdrouter[16]; | |
68bfcc05 | 689 | char duration[64]; |
d62a17ae | 690 | struct timeval now, res; |
6a5bb300 | 691 | json_object *json_route; |
d62a17ae | 692 | |
693 | /* | |
694 | vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n", | |
695 | "RouterID", "State", "Duration", "DR", "BDR", "I/F", | |
696 | "State"); | |
697 | */ | |
698 | ||
699 | inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id)); | |
700 | inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); | |
701 | inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); | |
702 | ||
703 | monotime(&now); | |
704 | timersub(&now, &on->last_changed, &res); | |
705 | timerstring(&res, duration, sizeof(duration)); | |
706 | ||
6a5bb300 | 707 | if (use_json) { |
708 | json_route = json_object_new_object(); | |
709 | json_object_string_add(json_route, "routerId", router_id); | |
710 | json_object_string_add(json_route, "state", | |
711 | ospf6_neighbor_state_str[on->state]); | |
712 | json_object_string_add(json_route, "duration", duration); | |
713 | json_object_string_add(json_route, "dRouter", drouter); | |
714 | json_object_string_add(json_route, "bdRouter", bdrouter); | |
715 | json_object_string_add(json_route, "interfaceName", | |
716 | on->ospf6_if->interface->name); | |
717 | json_object_string_add( | |
718 | json_route, "interfaceState", | |
719 | ospf6_interface_state_str[on->ospf6_if->state]); | |
720 | ||
721 | json_object_array_add(json_array, json_route); | |
722 | } else | |
723 | vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", router_id, | |
724 | ospf6_neighbor_state_str[on->state], duration, drouter, | |
725 | bdrouter, on->ospf6_if->interface->name, | |
726 | ospf6_interface_state_str[on->ospf6_if->state]); | |
718e3744 | 727 | } |
728 | ||
d62a17ae | 729 | static void ospf6_neighbor_show_detail(struct vty *vty, |
6a5bb300 | 730 | struct ospf6_neighbor *on, |
731 | json_object *json, bool use_json) | |
718e3744 | 732 | { |
d62a17ae | 733 | char drouter[16], bdrouter[16]; |
734 | char linklocal_addr[64], duration[32]; | |
735 | struct timeval now, res; | |
2e37407f | 736 | struct ospf6_lsa *lsa, *lsanext; |
6a5bb300 | 737 | json_object *json_neighbor; |
738 | json_object *json_array; | |
739 | char db_desc_str[20]; | |
d62a17ae | 740 | |
741 | inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr, | |
742 | sizeof(linklocal_addr)); | |
743 | inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); | |
744 | inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); | |
745 | ||
746 | monotime(&now); | |
747 | timersub(&now, &on->last_changed, &res); | |
748 | timerstring(&res, duration, sizeof(duration)); | |
749 | ||
6a5bb300 | 750 | if (use_json) { |
751 | json_neighbor = json_object_new_object(); | |
752 | json_object_string_add(json_neighbor, "area", | |
753 | on->ospf6_if->area->name); | |
754 | json_object_string_add(json_neighbor, "interface", | |
755 | on->ospf6_if->interface->name); | |
756 | json_object_int_add(json_neighbor, "interfaceIndex", | |
757 | on->ospf6_if->interface->ifindex); | |
758 | json_object_int_add(json_neighbor, "neighborInterfaceIndex", | |
759 | on->ifindex); | |
760 | json_object_string_add(json_neighbor, "linkLocalAddress", | |
761 | linklocal_addr); | |
762 | json_object_string_add(json_neighbor, "neighborState", | |
763 | ospf6_neighbor_state_str[on->state]); | |
764 | json_object_string_add(json_neighbor, "neighborStateDuration", | |
765 | duration); | |
766 | json_object_string_add(json_neighbor, "neighborDRouter", | |
767 | drouter); | |
768 | json_object_string_add(json_neighbor, "neighborBdRouter", | |
769 | bdrouter); | |
770 | snprintf(db_desc_str, sizeof(db_desc_str), "%s%s%s", | |
771 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) | |
772 | ? "Initial " | |
773 | : ""), | |
774 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) | |
775 | ? "More" | |
776 | : ""), | |
777 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) | |
778 | ? "Master" | |
779 | : "Slave")); | |
780 | json_object_string_add(json_neighbor, "dbDescStatus", | |
781 | db_desc_str); | |
782 | ||
783 | json_object_int_add(json_neighbor, "dbDescSeqNumber", | |
784 | (unsigned long)ntohl(on->dbdesc_seqnum)); | |
785 | ||
786 | json_array = json_object_new_array(); | |
787 | json_object_int_add(json_neighbor, "summaryListCount", | |
788 | on->summary_list->count); | |
789 | for (ALL_LSDB(on->summary_list, lsa, lsanext)) | |
790 | json_object_array_add( | |
791 | json_array, json_object_new_string(lsa->name)); | |
792 | json_object_object_add(json_neighbor, "summaryListLsa", | |
793 | json_array); | |
794 | ||
795 | json_array = json_object_new_array(); | |
796 | json_object_int_add(json_neighbor, "requestListCount", | |
797 | on->request_list->count); | |
798 | for (ALL_LSDB(on->request_list, lsa, lsanext)) | |
799 | json_object_array_add( | |
800 | json_array, json_object_new_string(lsa->name)); | |
801 | json_object_object_add(json_neighbor, "requestListLsa", | |
802 | json_array); | |
803 | ||
804 | json_array = json_object_new_array(); | |
805 | json_object_int_add(json_neighbor, "reTransListCount", | |
806 | on->retrans_list->count); | |
807 | for (ALL_LSDB(on->retrans_list, lsa, lsanext)) | |
808 | json_object_array_add( | |
809 | json_array, json_object_new_string(lsa->name)); | |
810 | json_object_object_add(json_neighbor, "reTransListLsa", | |
811 | json_array); | |
812 | ||
813 | ||
814 | timerclear(&res); | |
c905f04c | 815 | if (thread_is_scheduled(on->thread_send_dbdesc)) |
6a5bb300 | 816 | timersub(&on->thread_send_dbdesc->u.sands, &now, &res); |
817 | timerstring(&res, duration, sizeof(duration)); | |
818 | json_object_int_add(json_neighbor, "pendingLsaDbDescCount", | |
819 | on->dbdesc_list->count); | |
820 | json_object_string_add(json_neighbor, "pendingLsaDbDescTime", | |
821 | duration); | |
c905f04c DS |
822 | json_object_string_add( |
823 | json_neighbor, "dbDescSendThread", | |
824 | (thread_is_scheduled(on->thread_send_dbdesc) ? "on" | |
825 | : "off")); | |
6a5bb300 | 826 | json_array = json_object_new_array(); |
827 | for (ALL_LSDB(on->dbdesc_list, lsa, lsanext)) | |
828 | json_object_array_add( | |
829 | json_array, json_object_new_string(lsa->name)); | |
830 | json_object_object_add(json_neighbor, "pendingLsaDbDesc", | |
831 | json_array); | |
832 | ||
833 | timerclear(&res); | |
c905f04c | 834 | if (thread_is_scheduled(on->thread_send_lsreq)) |
6a5bb300 | 835 | timersub(&on->thread_send_lsreq->u.sands, &now, &res); |
836 | timerstring(&res, duration, sizeof(duration)); | |
837 | json_object_int_add(json_neighbor, "pendingLsaLsReqCount", | |
838 | on->request_list->count); | |
839 | json_object_string_add(json_neighbor, "pendingLsaLsReqTime", | |
840 | duration); | |
c905f04c DS |
841 | json_object_string_add( |
842 | json_neighbor, "lsReqSendThread", | |
843 | (thread_is_scheduled(on->thread_send_lsreq) ? "on" | |
844 | : "off")); | |
6a5bb300 | 845 | json_array = json_object_new_array(); |
846 | for (ALL_LSDB(on->request_list, lsa, lsanext)) | |
847 | json_object_array_add( | |
848 | json_array, json_object_new_string(lsa->name)); | |
849 | json_object_object_add(json_neighbor, "pendingLsaLsReq", | |
850 | json_array); | |
851 | ||
852 | ||
853 | timerclear(&res); | |
c905f04c | 854 | if (thread_is_scheduled(on->thread_send_lsupdate)) |
6a5bb300 | 855 | timersub(&on->thread_send_lsupdate->u.sands, &now, |
856 | &res); | |
857 | timerstring(&res, duration, sizeof(duration)); | |
858 | json_object_int_add(json_neighbor, "pendingLsaLsUpdateCount", | |
859 | on->lsupdate_list->count); | |
860 | json_object_string_add(json_neighbor, "pendingLsaLsUpdateTime", | |
861 | duration); | |
862 | json_object_string_add( | |
863 | json_neighbor, "lsUpdateSendThread", | |
c905f04c DS |
864 | (thread_is_scheduled(on->thread_send_lsupdate) |
865 | ? "on" | |
866 | : "off")); | |
6a5bb300 | 867 | json_array = json_object_new_array(); |
868 | for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) | |
869 | json_object_array_add( | |
870 | json_array, json_object_new_string(lsa->name)); | |
871 | json_object_object_add(json_neighbor, "pendingLsaLsUpdate", | |
872 | json_array); | |
873 | ||
874 | timerclear(&res); | |
c905f04c | 875 | if (thread_is_scheduled(on->thread_send_lsack)) |
6a5bb300 | 876 | timersub(&on->thread_send_lsack->u.sands, &now, &res); |
877 | timerstring(&res, duration, sizeof(duration)); | |
878 | json_object_int_add(json_neighbor, "pendingLsaLsAckCount", | |
879 | on->lsack_list->count); | |
880 | json_object_string_add(json_neighbor, "pendingLsaLsAckTime", | |
881 | duration); | |
c905f04c DS |
882 | json_object_string_add( |
883 | json_neighbor, "lsAckSendThread", | |
884 | (thread_is_scheduled(on->thread_send_lsack) ? "on" | |
885 | : "off")); | |
6a5bb300 | 886 | json_array = json_object_new_array(); |
887 | for (ALL_LSDB(on->lsack_list, lsa, lsanext)) | |
888 | json_object_array_add( | |
889 | json_array, json_object_new_string(lsa->name)); | |
890 | json_object_object_add(json_neighbor, "pendingLsaLsAck", | |
891 | json_array); | |
892 | ||
d06cc416 | 893 | bfd_sess_show(vty, json_neighbor, on->bfd_session); |
6a5bb300 | 894 | |
6cb85350 AR |
895 | if (on->auth_present == true) { |
896 | json_object_string_add(json_neighbor, "authStatus", | |
897 | "enabled"); | |
898 | json_object_int_add( | |
899 | json_neighbor, "recvdHelloHigherSeqNo", | |
900 | on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO]); | |
901 | json_object_int_add( | |
902 | json_neighbor, "recvdHelloLowerSeqNo", | |
903 | on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO]); | |
904 | json_object_int_add( | |
905 | json_neighbor, "recvdDBDescHigherSeqNo", | |
906 | on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC]); | |
907 | json_object_int_add( | |
908 | json_neighbor, "recvdDBDescLowerSeqNo", | |
909 | on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC]); | |
910 | json_object_int_add( | |
911 | json_neighbor, "recvdLSReqHigherSeqNo", | |
912 | on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ]); | |
913 | json_object_int_add( | |
914 | json_neighbor, "recvdLSReqLowerSeqNo", | |
915 | on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ]); | |
916 | json_object_int_add( | |
917 | json_neighbor, "recvdLSUpdHigherSeqNo", | |
918 | on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE]); | |
919 | json_object_int_add( | |
920 | json_neighbor, "recvdLSUpdLowerSeqNo", | |
921 | on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE]); | |
922 | json_object_int_add( | |
923 | json_neighbor, "recvdLSAckHigherSeqNo", | |
924 | on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]); | |
925 | json_object_int_add( | |
926 | json_neighbor, "recvdLSAckLowerSeqNo", | |
927 | on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]); | |
928 | } else | |
929 | json_object_string_add(json_neighbor, "authStatus", | |
930 | "disabled"); | |
6a5bb300 | 931 | |
6cb85350 | 932 | json_object_object_add(json, on->name, json_neighbor); |
6a5bb300 | 933 | |
934 | } else { | |
935 | vty_out(vty, " Neighbor %s\n", on->name); | |
936 | vty_out(vty, " Area %s via interface %s (ifindex %d)\n", | |
937 | on->ospf6_if->area->name, on->ospf6_if->interface->name, | |
938 | on->ospf6_if->interface->ifindex); | |
939 | vty_out(vty, " His IfIndex: %d Link-local address: %s\n", | |
940 | on->ifindex, linklocal_addr); | |
941 | vty_out(vty, " State %s for a duration of %s\n", | |
942 | ospf6_neighbor_state_str[on->state], duration); | |
943 | vty_out(vty, " His choice of DR/BDR %s/%s, Priority %d\n", | |
944 | drouter, bdrouter, on->priority); | |
945 | vty_out(vty, " DbDesc status: %s%s%s SeqNum: %#lx\n", | |
946 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) | |
947 | ? "Initial " | |
948 | : ""), | |
949 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) | |
950 | ? "More " | |
951 | : ""), | |
952 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) | |
953 | ? "Master" | |
954 | : "Slave"), | |
955 | (unsigned long)ntohl(on->dbdesc_seqnum)); | |
956 | ||
957 | vty_out(vty, " Summary-List: %d LSAs\n", | |
958 | on->summary_list->count); | |
959 | for (ALL_LSDB(on->summary_list, lsa, lsanext)) | |
960 | vty_out(vty, " %s\n", lsa->name); | |
961 | ||
962 | vty_out(vty, " Request-List: %d LSAs\n", | |
963 | on->request_list->count); | |
964 | for (ALL_LSDB(on->request_list, lsa, lsanext)) | |
965 | vty_out(vty, " %s\n", lsa->name); | |
966 | ||
967 | vty_out(vty, " Retrans-List: %d LSAs\n", | |
968 | on->retrans_list->count); | |
969 | for (ALL_LSDB(on->retrans_list, lsa, lsanext)) | |
970 | vty_out(vty, " %s\n", lsa->name); | |
971 | ||
972 | timerclear(&res); | |
c905f04c | 973 | if (thread_is_scheduled(on->thread_send_dbdesc)) |
6a5bb300 | 974 | timersub(&on->thread_send_dbdesc->u.sands, &now, &res); |
975 | timerstring(&res, duration, sizeof(duration)); | |
976 | vty_out(vty, | |
977 | " %d Pending LSAs for DbDesc in Time %s [thread %s]\n", | |
978 | on->dbdesc_list->count, duration, | |
c905f04c DS |
979 | (thread_is_scheduled(on->thread_send_dbdesc) ? "on" |
980 | : "off")); | |
6a5bb300 | 981 | for (ALL_LSDB(on->dbdesc_list, lsa, lsanext)) |
982 | vty_out(vty, " %s\n", lsa->name); | |
983 | ||
984 | timerclear(&res); | |
c905f04c | 985 | if (thread_is_scheduled(on->thread_send_lsreq)) |
6a5bb300 | 986 | timersub(&on->thread_send_lsreq->u.sands, &now, &res); |
987 | timerstring(&res, duration, sizeof(duration)); | |
988 | vty_out(vty, | |
989 | " %d Pending LSAs for LSReq in Time %s [thread %s]\n", | |
990 | on->request_list->count, duration, | |
c905f04c DS |
991 | (thread_is_scheduled(on->thread_send_lsreq) ? "on" |
992 | : "off")); | |
6a5bb300 | 993 | for (ALL_LSDB(on->request_list, lsa, lsanext)) |
994 | vty_out(vty, " %s\n", lsa->name); | |
995 | ||
996 | timerclear(&res); | |
c905f04c | 997 | if (thread_is_scheduled(on->thread_send_lsupdate)) |
6a5bb300 | 998 | timersub(&on->thread_send_lsupdate->u.sands, &now, |
999 | &res); | |
1000 | timerstring(&res, duration, sizeof(duration)); | |
1001 | vty_out(vty, | |
1002 | " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", | |
1003 | on->lsupdate_list->count, duration, | |
c905f04c DS |
1004 | (thread_is_scheduled(on->thread_send_lsupdate) |
1005 | ? "on" | |
1006 | : "off")); | |
6a5bb300 | 1007 | for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) |
1008 | vty_out(vty, " %s\n", lsa->name); | |
1009 | ||
1010 | timerclear(&res); | |
c905f04c | 1011 | if (thread_is_scheduled(on->thread_send_lsack)) |
6a5bb300 | 1012 | timersub(&on->thread_send_lsack->u.sands, &now, &res); |
1013 | timerstring(&res, duration, sizeof(duration)); | |
1014 | vty_out(vty, | |
1015 | " %d Pending LSAs for LSAck in Time %s [thread %s]\n", | |
1016 | on->lsack_list->count, duration, | |
c905f04c DS |
1017 | (thread_is_scheduled(on->thread_send_lsack) ? "on" |
1018 | : "off")); | |
6a5bb300 | 1019 | for (ALL_LSDB(on->lsack_list, lsa, lsanext)) |
1020 | vty_out(vty, " %s\n", lsa->name); | |
1021 | ||
d06cc416 | 1022 | bfd_sess_show(vty, NULL, on->bfd_session); |
6cb85350 AR |
1023 | |
1024 | if (on->auth_present == true) { | |
1025 | vty_out(vty, " Authentication header present\n"); | |
1026 | vty_out(vty, | |
1027 | "\t\t\t hello DBDesc LSReq LSUpd LSAck\n"); | |
1028 | vty_out(vty, | |
1029 | " Higher sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n", | |
1030 | on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO], | |
1031 | on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC], | |
1032 | on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ], | |
1033 | on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE], | |
1034 | on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]); | |
1035 | vty_out(vty, | |
1036 | " Lower sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n", | |
1037 | on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO], | |
1038 | on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC], | |
1039 | on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ], | |
1040 | on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE], | |
1041 | on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]); | |
1042 | } else | |
1043 | vty_out(vty, " Authentication header not present\n"); | |
6a5bb300 | 1044 | } |
718e3744 | 1045 | } |
1046 | ||
ee3e6d7f IR |
1047 | static void ospf6_neighbor_show_detail_common(struct vty *vty, |
1048 | struct ospf6 *ospf6, bool uj, | |
1049 | bool detail, bool drchoice) | |
718e3744 | 1050 | { |
d62a17ae | 1051 | struct ospf6_neighbor *on; |
1052 | struct ospf6_interface *oi; | |
1053 | struct ospf6_area *oa; | |
1054 | struct listnode *i, *j, *k; | |
6a5bb300 | 1055 | json_object *json = NULL; |
1056 | json_object *json_array = NULL; | |
6a5bb300 | 1057 | void (*showfunc)(struct vty *, struct ospf6_neighbor *, |
1058 | json_object *json, bool use_json); | |
d62a17ae | 1059 | |
ee3e6d7f IR |
1060 | if (detail) |
1061 | showfunc = ospf6_neighbor_show_detail; | |
1062 | else if (drchoice) | |
1063 | showfunc = ospf6_neighbor_show_drchoice; | |
1064 | else | |
1065 | showfunc = ospf6_neighbor_show; | |
d62a17ae | 1066 | |
6a5bb300 | 1067 | if (uj) { |
1068 | json = json_object_new_object(); | |
1069 | json_array = json_object_new_array(); | |
1070 | } else { | |
1071 | if (showfunc == ospf6_neighbor_show) | |
1072 | vty_out(vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n", | |
1073 | "Neighbor ID", "Pri", "DeadTime", "State", | |
1074 | "IfState", "Duration", "I/F", "State"); | |
1075 | else if (showfunc == ospf6_neighbor_show_drchoice) | |
1076 | vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", | |
1077 | "RouterID", "State", "Duration", "DR", "BDR", | |
1078 | "I/F", "State"); | |
1079 | } | |
d62a17ae | 1080 | |
1081 | for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) | |
1082 | for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) | |
6a5bb300 | 1083 | for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) { |
1084 | if (showfunc == ospf6_neighbor_show_detail) | |
1085 | (*showfunc)(vty, on, json, uj); | |
1086 | else | |
1087 | (*showfunc)(vty, on, json_array, uj); | |
1088 | } | |
1089 | ||
1090 | if (uj) { | |
1091 | if (showfunc != ospf6_neighbor_show_detail) | |
1092 | json_object_object_add(json, "neighbors", json_array); | |
1093 | else | |
1094 | json_object_free(json_array); | |
5a6c232b | 1095 | vty_json(vty, json); |
6a5bb300 | 1096 | } |
718e3744 | 1097 | } |
1098 | ||
d48ef099 | 1099 | DEFUN(show_ipv6_ospf6_neighbor, show_ipv6_ospf6_neighbor_cmd, |
1100 | "show ipv6 ospf6 [vrf <NAME|all>] neighbor [<detail|drchoice>] [json]", | |
1101 | SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR | |
1102 | "All VRFs\n" | |
1103 | "Neighbor list\n" | |
1104 | "Display details\n" | |
1105 | "Display DR choices\n" JSON_STR) | |
1106 | { | |
d48ef099 | 1107 | struct ospf6 *ospf6; |
1108 | struct listnode *node; | |
1109 | const char *vrf_name = NULL; | |
1110 | bool all_vrf = false; | |
1111 | int idx_vrf = 0; | |
ee3e6d7f IR |
1112 | int idx_type = 4; |
1113 | bool uj = use_json(argc, argv); | |
1114 | bool detail = false; | |
1115 | bool drchoice = false; | |
d48ef099 | 1116 | |
d48ef099 | 1117 | OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); |
ee3e6d7f IR |
1118 | |
1119 | if (argv_find(argv, argc, "detail", &idx_type)) | |
1120 | detail = true; | |
1121 | else if (argv_find(argv, argc, "drchoice", &idx_type)) | |
1122 | drchoice = true; | |
d48ef099 | 1123 | |
1124 | for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { | |
1125 | if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) { | |
ee3e6d7f IR |
1126 | ospf6_neighbor_show_detail_common(vty, ospf6, uj, |
1127 | detail, drchoice); | |
d48ef099 | 1128 | if (!all_vrf) |
1129 | break; | |
1130 | } | |
1131 | } | |
718e3744 | 1132 | |
d6b901ac | 1133 | OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6); |
1134 | ||
d48ef099 | 1135 | return CMD_SUCCESS; |
1136 | } | |
1137 | ||
1138 | static int ospf6_neighbor_show_common(struct vty *vty, int argc, | |
1139 | struct cmd_token **argv, | |
d6b901ac | 1140 | struct ospf6 *ospf6, int idx_ipv4, |
1141 | bool uj) | |
718e3744 | 1142 | { |
d62a17ae | 1143 | struct ospf6_neighbor *on; |
1144 | struct ospf6_interface *oi; | |
1145 | struct ospf6_area *oa; | |
1146 | struct listnode *i, *j, *k; | |
6a5bb300 | 1147 | void (*showfunc)(struct vty *, struct ospf6_neighbor *, |
1148 | json_object *json, bool use_json); | |
d7c0a89a | 1149 | uint32_t router_id; |
6a5bb300 | 1150 | json_object *json = NULL; |
d62a17ae | 1151 | |
d62a17ae | 1152 | showfunc = ospf6_neighbor_show_detail; |
6a5bb300 | 1153 | if (uj) |
1154 | json = json_object_new_object(); | |
d62a17ae | 1155 | |
1156 | if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) { | |
1157 | vty_out(vty, "Router-ID is not parsable: %s\n", | |
1158 | argv[idx_ipv4]->arg); | |
1159 | return CMD_SUCCESS; | |
1160 | } | |
1161 | ||
1162 | for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) | |
1163 | for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) | |
786b76d0 YR |
1164 | for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) { |
1165 | if (router_id == on->router_id) | |
1166 | (*showfunc)(vty, on, json, uj); | |
1167 | } | |
d62a17ae | 1168 | |
c48349e3 | 1169 | if (uj) |
5a6c232b | 1170 | vty_json(vty, json); |
d48ef099 | 1171 | |
1172 | return CMD_SUCCESS; | |
1173 | } | |
1174 | ||
1175 | DEFUN(show_ipv6_ospf6_neighbor_one, show_ipv6_ospf6_neighbor_one_cmd, | |
1176 | "show ipv6 ospf6 [vrf <NAME|all>] neighbor A.B.C.D [json]", | |
1177 | SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR | |
1178 | "All VRFs\n" | |
1179 | "Neighbor list\n" | |
1180 | "Specify Router-ID as IPv4 address notation\n" JSON_STR) | |
1181 | { | |
1182 | int idx_ipv4 = 4; | |
1183 | struct ospf6 *ospf6; | |
1184 | struct listnode *node; | |
1185 | const char *vrf_name = NULL; | |
1186 | bool all_vrf = false; | |
1187 | int idx_vrf = 0; | |
d6b901ac | 1188 | bool uj = use_json(argc, argv); |
d48ef099 | 1189 | |
d48ef099 | 1190 | OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); |
1191 | if (idx_vrf > 0) | |
1192 | idx_ipv4 += 2; | |
1193 | ||
1194 | for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { | |
1195 | if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) { | |
1196 | ospf6_neighbor_show_common(vty, argc, argv, ospf6, | |
d6b901ac | 1197 | idx_ipv4, uj); |
d48ef099 | 1198 | |
1199 | if (!all_vrf) | |
1200 | break; | |
1201 | } | |
1202 | } | |
1203 | ||
d6b901ac | 1204 | OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6); |
1205 | ||
d62a17ae | 1206 | return CMD_SUCCESS; |
718e3744 | 1207 | } |
1208 | ||
d62a17ae | 1209 | void ospf6_neighbor_init(void) |
718e3744 | 1210 | { |
d62a17ae | 1211 | install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd); |
1212 | install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd); | |
508e53e2 | 1213 | } |
1214 | ||
1215 | DEFUN (debug_ospf6_neighbor, | |
1216 | debug_ospf6_neighbor_cmd, | |
6de69f83 | 1217 | "debug ospf6 neighbor [<state|event>]", |
508e53e2 | 1218 | DEBUG_STR |
1219 | OSPF6_STR | |
1220 | "Debug OSPFv3 Neighbor\n" | |
1d68dbfe DW |
1221 | "Debug OSPFv3 Neighbor State Change\n" |
1222 | "Debug OSPFv3 Neighbor Event\n") | |
508e53e2 | 1223 | { |
d62a17ae | 1224 | int idx_type = 3; |
1225 | unsigned char level = 0; | |
1226 | ||
1227 | if (argc == 4) { | |
1228 | if (!strncmp(argv[idx_type]->arg, "s", 1)) | |
1229 | level = OSPF6_DEBUG_NEIGHBOR_STATE; | |
1230 | else if (!strncmp(argv[idx_type]->arg, "e", 1)) | |
1231 | level = OSPF6_DEBUG_NEIGHBOR_EVENT; | |
1232 | } else | |
1233 | level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; | |
1234 | ||
1235 | OSPF6_DEBUG_NEIGHBOR_ON(level); | |
1236 | return CMD_SUCCESS; | |
718e3744 | 1237 | } |
1238 | ||
508e53e2 | 1239 | |
1240 | DEFUN (no_debug_ospf6_neighbor, | |
1241 | no_debug_ospf6_neighbor_cmd, | |
6de69f83 | 1242 | "no debug ospf6 neighbor [<state|event>]", |
508e53e2 | 1243 | NO_STR |
1244 | DEBUG_STR | |
1245 | OSPF6_STR | |
1246 | "Debug OSPFv3 Neighbor\n" | |
1d68dbfe DW |
1247 | "Debug OSPFv3 Neighbor State Change\n" |
1248 | "Debug OSPFv3 Neighbor Event\n") | |
508e53e2 | 1249 | { |
d62a17ae | 1250 | int idx_type = 4; |
1251 | unsigned char level = 0; | |
1252 | ||
1253 | if (argc == 5) { | |
1254 | if (!strncmp(argv[idx_type]->arg, "s", 1)) | |
1255 | level = OSPF6_DEBUG_NEIGHBOR_STATE; | |
1256 | if (!strncmp(argv[idx_type]->arg, "e", 1)) | |
1257 | level = OSPF6_DEBUG_NEIGHBOR_EVENT; | |
1258 | } else | |
1259 | level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; | |
1260 | ||
1261 | OSPF6_DEBUG_NEIGHBOR_OFF(level); | |
1262 | return CMD_SUCCESS; | |
508e53e2 | 1263 | } |
1264 | ||
508e53e2 | 1265 | |
4dfd8aff DW |
1266 | DEFUN (no_debug_ospf6, |
1267 | no_debug_ospf6_cmd, | |
1268 | "no debug ospf6", | |
1269 | NO_STR | |
1270 | DEBUG_STR | |
1271 | OSPF6_STR) | |
1272 | { | |
d7c0a89a | 1273 | unsigned int i; |
d62a17ae | 1274 | |
1275 | OSPF6_DEBUG_ABR_OFF(); | |
1276 | OSPF6_DEBUG_ASBR_OFF(); | |
1277 | OSPF6_DEBUG_BROUTER_OFF(); | |
1278 | OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF(); | |
1279 | OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF(); | |
1280 | OSPF6_DEBUG_FLOODING_OFF(); | |
1281 | OSPF6_DEBUG_INTERFACE_OFF(); | |
1282 | ||
067967b8 | 1283 | ospf6_lsa_debug_set_all(false); |
d62a17ae | 1284 | |
1285 | for (i = 0; i < 6; i++) | |
1286 | OSPF6_DEBUG_MESSAGE_OFF(i, | |
1287 | OSPF6_DEBUG_NEIGHBOR_STATE | |
1288 | | OSPF6_DEBUG_NEIGHBOR_EVENT); | |
1289 | ||
1290 | OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE | |
1291 | | OSPF6_DEBUG_NEIGHBOR_EVENT); | |
1292 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE); | |
1293 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA); | |
1294 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER); | |
1295 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_MEMORY); | |
1296 | OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_PROCESS); | |
1297 | OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_TIME); | |
1298 | OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_DATABASE); | |
1299 | OSPF6_DEBUG_ZEBRA_OFF(OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV); | |
1300 | ||
1301 | return CMD_SUCCESS; | |
4dfd8aff DW |
1302 | } |
1303 | ||
d62a17ae | 1304 | int config_write_ospf6_debug_neighbor(struct vty *vty) |
508e53e2 | 1305 | { |
d62a17ae | 1306 | if (IS_OSPF6_DEBUG_NEIGHBOR(STATE) && IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
1307 | vty_out(vty, "debug ospf6 neighbor\n"); | |
1308 | else if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) | |
1309 | vty_out(vty, "debug ospf6 neighbor state\n"); | |
1310 | else if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) | |
1311 | vty_out(vty, "debug ospf6 neighbor event\n"); | |
1312 | return 0; | |
508e53e2 | 1313 | } |
1314 | ||
d62a17ae | 1315 | void install_element_ospf6_debug_neighbor(void) |
508e53e2 | 1316 | { |
d62a17ae | 1317 | install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd); |
1318 | install_element(ENABLE_NODE, &no_debug_ospf6_neighbor_cmd); | |
1319 | install_element(ENABLE_NODE, &no_debug_ospf6_cmd); | |
1320 | install_element(CONFIG_NODE, &debug_ospf6_neighbor_cmd); | |
1321 | install_element(CONFIG_NODE, &no_debug_ospf6_neighbor_cmd); | |
1322 | install_element(CONFIG_NODE, &no_debug_ospf6_cmd); | |
508e53e2 | 1323 | } |