Line data Source code
1 : /*
2 : * Copyright (C) 2003 Yasuhiro Ohara
3 : *
4 : * This file is part of GNU Zebra.
5 : *
6 : * GNU Zebra is free software; you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by the
8 : * Free Software Foundation; either version 2, or (at your option) any
9 : * later version.
10 : *
11 : * GNU Zebra is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License 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
19 : */
20 :
21 : #include <zebra.h>
22 :
23 : #include "log.h"
24 : #include "memory.h"
25 : #include "thread.h"
26 : #include "linklist.h"
27 : #include "vty.h"
28 : #include "command.h"
29 : #include "lib/bfd.h"
30 :
31 : #include "ospf6_proto.h"
32 : #include "ospf6_lsa.h"
33 : #include "ospf6_lsdb.h"
34 : #include "ospf6_message.h"
35 : #include "ospf6_top.h"
36 : #include "ospf6_area.h"
37 : #include "ospf6_interface.h"
38 : #include "ospf6_neighbor.h"
39 : #include "ospf6_intra.h"
40 : #include "ospf6_flood.h"
41 : #include "ospf6d.h"
42 : #include "ospf6_bfd.h"
43 : #include "ospf6_abr.h"
44 : #include "ospf6_asbr.h"
45 : #include "ospf6_lsa.h"
46 : #include "ospf6_spf.h"
47 : #include "ospf6_zebra.h"
48 : #include "ospf6_gr.h"
49 : #include "ospf6_vlink.h"
50 : #include "lib/json.h"
51 :
52 48 : DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor");
53 48 : DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR_P2XP_CFG,
54 : "OSPF6 PtP/PtMP neighbor config");
55 :
56 : static int ospf6_if_p2xp_neighcfg_cmp(const struct ospf6_if_p2xp_neighcfg *a,
57 : const struct ospf6_if_p2xp_neighcfg *b);
58 :
59 9 : DECLARE_RBTREE_UNIQ(ospf6_if_p2xp_neighcfgs, struct ospf6_if_p2xp_neighcfg,
60 : item, ospf6_if_p2xp_neighcfg_cmp);
61 :
62 : static void p2xp_neigh_refresh(struct ospf6_neighbor *on, uint32_t prev_cost);
63 :
64 364 : DEFINE_HOOK(ospf6_neighbor_change,
65 : (struct ospf6_neighbor * on, int state, int next_state),
66 : (on, state, next_state));
67 :
68 : unsigned char conf_debug_ospf6_neighbor = 0;
69 :
70 : const char *const ospf6_neighbor_state_str[] = {
71 : "None", "Down", "Attempt", "Init", "Twoway",
72 : "ExStart", "ExChange", "Loading", "Full", NULL};
73 :
74 : const char *const ospf6_neighbor_event_str[] = {
75 : "NoEvent", "HelloReceived", "2-WayReceived", "NegotiationDone",
76 : "ExchangeDone", "LoadingDone", "AdjOK?", "SeqNumberMismatch",
77 : "BadLSReq", "1-WayReceived", "InactivityTimer", "VLinkUnreachable",
78 : "VLinkReachable",
79 : };
80 :
81 9 : int ospf6_neighbor_cmp(void *va, void *vb)
82 : {
83 9 : struct ospf6_neighbor *ona = (struct ospf6_neighbor *)va;
84 9 : struct ospf6_neighbor *onb = (struct ospf6_neighbor *)vb;
85 :
86 9 : if (ona->router_id == onb->router_id)
87 : return 0;
88 :
89 9 : return (ntohl(ona->router_id) < ntohl(onb->router_id)) ? -1 : 1;
90 : }
91 :
92 1796 : struct ospf6_neighbor *ospf6_neighbor_lookup(uint32_t router_id,
93 : struct ospf6_interface *oi)
94 : {
95 1796 : struct listnode *n;
96 1796 : struct ospf6_neighbor *on;
97 :
98 4098 : for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, n, on))
99 2230 : if (on->router_id == router_id)
100 1724 : return on;
101 :
102 : return (struct ospf6_neighbor *)NULL;
103 : }
104 :
105 0 : struct ospf6_neighbor *ospf6_area_neighbor_lookup(struct ospf6_area *area,
106 : uint32_t router_id)
107 : {
108 0 : struct ospf6_interface *oi;
109 0 : struct ospf6_neighbor *nbr;
110 0 : struct listnode *node;
111 :
112 0 : for (ALL_LIST_ELEMENTS_RO(area->if_list, node, oi)) {
113 0 : nbr = ospf6_neighbor_lookup(router_id, oi);
114 0 : if (nbr)
115 0 : return nbr;
116 : }
117 :
118 : return NULL;
119 : }
120 :
121 68 : static void ospf6_neighbor_clear_ls_lists(struct ospf6_neighbor *on)
122 : {
123 68 : struct ospf6_lsa *lsa;
124 68 : struct ospf6_lsa *lsanext;
125 :
126 68 : ospf6_lsdb_remove_all(on->summary_list);
127 68 : if (on->last_ls_req) {
128 0 : ospf6_lsa_unlock(on->last_ls_req);
129 0 : on->last_ls_req = NULL;
130 : }
131 68 : ospf6_lsdb_remove_all(on->request_list);
132 100 : for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
133 32 : ospf6_decrement_retrans_count(lsa);
134 32 : ospf6_lsdb_remove(lsa, on->retrans_list);
135 : }
136 68 : }
137 :
138 : /* create ospf6_neighbor */
139 34 : struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
140 : struct ospf6_interface *oi)
141 : {
142 34 : struct ospf6_neighbor *on;
143 34 : char buf[16];
144 34 : int type;
145 :
146 34 : on = XCALLOC(MTYPE_OSPF6_NEIGHBOR, sizeof(struct ospf6_neighbor));
147 34 : inet_ntop(AF_INET, &router_id, buf, sizeof(buf));
148 34 : snprintfrr(on->name, sizeof(on->name), "%s%%%pOI", buf, oi);
149 34 : on->ospf6_if = oi;
150 34 : on->state = OSPF6_NEIGHBOR_DOWN;
151 34 : on->state_change = 0;
152 34 : monotime(&on->last_changed);
153 34 : on->router_id = router_id;
154 :
155 34 : on->summary_list = ospf6_lsdb_create(on);
156 34 : on->request_list = ospf6_lsdb_create(on);
157 34 : on->retrans_list = ospf6_lsdb_create(on);
158 :
159 34 : on->dbdesc_list = ospf6_lsdb_create(on);
160 34 : on->lsupdate_list = ospf6_lsdb_create(on);
161 34 : on->lsack_list = ospf6_lsdb_create(on);
162 :
163 238 : for (type = 0; type < OSPF6_MESSAGE_TYPE_MAX; type++) {
164 204 : on->seqnum_l[type] = 0;
165 204 : on->seqnum_h[type] = 0;
166 : }
167 :
168 34 : on->auth_present = false;
169 :
170 34 : listnode_add_sort(oi->neighbor_list, on);
171 :
172 34 : ospf6_bfd_info_nbr_create(oi, on);
173 34 : return on;
174 : }
175 :
176 34 : void ospf6_neighbor_delete(struct ospf6_neighbor *on)
177 : {
178 34 : assertf(!on->vlink, "on->name=%pSQ on->router_id=%pI4", on->name,
179 : &on->router_id);
180 :
181 34 : listnode_delete(on->ospf6_if->neighbor_list, on);
182 :
183 34 : if (on->p2xp_cfg)
184 0 : on->p2xp_cfg->active = NULL;
185 :
186 34 : ospf6_neighbor_clear_ls_lists(on);
187 :
188 34 : ospf6_lsdb_remove_all(on->dbdesc_list);
189 34 : ospf6_lsdb_remove_all(on->lsupdate_list);
190 34 : ospf6_lsdb_remove_all(on->lsack_list);
191 :
192 34 : ospf6_lsdb_delete(on->summary_list);
193 34 : ospf6_lsdb_delete(on->request_list);
194 34 : ospf6_lsdb_delete(on->retrans_list);
195 :
196 34 : ospf6_lsdb_delete(on->dbdesc_list);
197 34 : ospf6_lsdb_delete(on->lsupdate_list);
198 34 : ospf6_lsdb_delete(on->lsack_list);
199 :
200 34 : THREAD_OFF(on->inactivity_timer);
201 :
202 34 : THREAD_OFF(on->last_dbdesc_release_timer);
203 :
204 34 : THREAD_OFF(on->thread_send_dbdesc);
205 34 : THREAD_OFF(on->thread_send_lsreq);
206 34 : THREAD_OFF(on->thread_send_lsupdate);
207 34 : THREAD_OFF(on->thread_send_lsack);
208 34 : THREAD_OFF(on->thread_exchange_done);
209 34 : THREAD_OFF(on->thread_adj_ok);
210 :
211 34 : THREAD_OFF(on->gr_helper_info.t_grace_timer);
212 :
213 34 : bfd_sess_free(&on->bfd_session);
214 34 : XFREE(MTYPE_OSPF6_NEIGHBOR, on);
215 34 : }
216 :
217 318 : void ospf6_neighbor_lladdr_set(struct ospf6_neighbor *on,
218 : const struct in6_addr *addr)
219 : {
220 318 : if (IPV6_ADDR_SAME(addr, &on->linklocal_addr))
221 : return;
222 :
223 34 : memcpy(&on->linklocal_addr, addr, sizeof(struct in6_addr));
224 :
225 34 : if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT
226 34 : || on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
227 6 : uint32_t prev_cost = ospf6_neighbor_cost(on);
228 :
229 6 : p2xp_neigh_refresh(on, prev_cost);
230 : }
231 : }
232 :
233 182 : static void ospf6_neighbor_state_change(uint8_t next_state,
234 : struct ospf6_neighbor *on, int event)
235 : {
236 182 : uint8_t prev_state;
237 :
238 182 : prev_state = on->state;
239 182 : on->state = next_state;
240 :
241 182 : if (prev_state == next_state)
242 : return;
243 :
244 182 : on->state_change++;
245 182 : monotime(&on->last_changed);
246 :
247 : /* log */
248 182 : if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) {
249 0 : zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)",
250 : on->name, ospf6_neighbor_state_str[prev_state],
251 : ospf6_neighbor_state_str[next_state],
252 : ospf6_neighbor_event_string(event));
253 : }
254 :
255 : /* Optionally notify about adjacency changes */
256 182 : if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
257 : OSPF6_LOG_ADJACENCY_CHANGES)
258 137 : && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
259 : OSPF6_LOG_ADJACENCY_DETAIL)
260 137 : || (next_state == OSPF6_NEIGHBOR_FULL)
261 137 : || (next_state < prev_state)))
262 52 : zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
263 : ospf6_neighbor_state_str[prev_state],
264 : ospf6_neighbor_state_str[next_state],
265 : ospf6_neighbor_event_string(event));
266 :
267 182 : if (prev_state == OSPF6_NEIGHBOR_FULL
268 182 : || next_state == OSPF6_NEIGHBOR_FULL) {
269 36 : if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) {
270 36 : OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
271 36 : if (on->ospf6_if->state == OSPF6_INTERFACE_DR) {
272 12 : OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if);
273 12 : OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(
274 : on->ospf6_if);
275 : }
276 : }
277 36 : if (next_state == OSPF6_NEIGHBOR_FULL)
278 34 : on->ospf6_if->area->intra_prefix_originate = 1;
279 :
280 36 : if (!OSPF6_GR_IS_ACTIVE_HELPER(on))
281 36 : OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(
282 : on->ospf6_if->area);
283 :
284 : /* note for virtual links:
285 : * on->ospf6_if->area != on->vlink->area
286 : * (backbone) (non-backbone)
287 : */
288 :
289 36 : if ((prev_state == OSPF6_NEIGHBOR_LOADING
290 36 : || prev_state == OSPF6_NEIGHBOR_EXCHANGE)
291 34 : && next_state == OSPF6_NEIGHBOR_FULL) {
292 34 : OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if);
293 34 : on->ospf6_if->area->full_nbrs++;
294 34 : if (on->vlink) {
295 0 : on->vlink->area->virtual_link_full++;
296 0 : if (on->vlink->area->virtual_link_full == 1)
297 0 : OSPF6_ROUTER_LSA_SCHEDULE(
298 : on->vlink->area);
299 : }
300 : }
301 :
302 36 : if (prev_state == OSPF6_NEIGHBOR_FULL) {
303 2 : on->ospf6_if->area->full_nbrs--;
304 2 : if (on->vlink) {
305 0 : on->vlink->area->virtual_link_full--;
306 0 : if (!on->vlink->area->virtual_link_full)
307 0 : OSPF6_ROUTER_LSA_SCHEDULE(
308 : on->vlink->area);
309 : }
310 : }
311 : }
312 :
313 182 : if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE
314 182 : || prev_state == OSPF6_NEIGHBOR_LOADING)
315 50 : && (next_state != OSPF6_NEIGHBOR_EXCHANGE
316 50 : && next_state != OSPF6_NEIGHBOR_LOADING))
317 34 : ospf6_maxage_remove(on->ospf6_if->area->ospf6);
318 :
319 182 : hook_call(ospf6_neighbor_change, on, next_state, prev_state);
320 182 : ospf6_bfd_trigger_event(on, prev_state, next_state);
321 : }
322 :
323 0 : void ospf6_neighbor_vlink_change(struct ospf6_neighbor *nbr, bool up)
324 : {
325 0 : if (nbr->state <= OSPF6_NEIGHBOR_DOWN && up)
326 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_ATTEMPT, nbr,
327 : OSPF6_NEIGHBOR_EVENT_VLINK_REACHABLE);
328 0 : if (nbr->state > OSPF6_NEIGHBOR_DOWN && !up)
329 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_DOWN, nbr,
330 : OSPF6_NEIGHBOR_EVENT_VLINK_UNREACHABLE);
331 0 : }
332 :
333 : /* RFC2328 section 10.4 */
334 76 : static int need_adjacency(struct ospf6_neighbor *on)
335 : {
336 76 : if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT
337 : || on->ospf6_if->state == OSPF6_INTERFACE_POINTTOMULTIPOINT
338 76 : || on->ospf6_if->state == OSPF6_INTERFACE_DR
339 57 : || on->ospf6_if->state == OSPF6_INTERFACE_BDR
340 44 : || on->ospf6_if->state == OSPF6_INTERFACE_VIRTUALLINK)
341 : return 1;
342 :
343 44 : if (on->ospf6_if->drouter == on->router_id
344 34 : || on->ospf6_if->bdrouter == on->router_id)
345 12 : return 1;
346 :
347 : return 0;
348 : }
349 :
350 318 : void hello_received(struct thread *thread)
351 : {
352 318 : struct ospf6_neighbor *on;
353 :
354 318 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
355 318 : assert(on);
356 :
357 318 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
358 0 : zlog_debug("Neighbor Event %s: *HelloReceived*", on->name);
359 :
360 : /* reset Inactivity Timer */
361 318 : THREAD_OFF(on->inactivity_timer);
362 318 : thread_add_timer(master, inactivity_timer, on,
363 : on->vlink ? on->vlink->dead_interval
364 : : on->ospf6_if->dead_interval,
365 : &on->inactivity_timer);
366 :
367 318 : if (on->state <= OSPF6_NEIGHBOR_ATTEMPT)
368 34 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
369 : OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
370 318 : }
371 :
372 304 : void twoway_received(struct thread *thread)
373 : {
374 304 : struct ospf6_neighbor *on;
375 :
376 304 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
377 304 : assert(on);
378 :
379 304 : if (on->state > OSPF6_NEIGHBOR_INIT)
380 : return;
381 :
382 34 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
383 0 : zlog_debug("Neighbor Event %s: *2Way-Received*", on->name);
384 :
385 34 : thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
386 :
387 34 : if (!need_adjacency(on)) {
388 28 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
389 : OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
390 28 : return;
391 : }
392 :
393 6 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
394 : OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
395 6 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
396 6 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
397 6 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
398 :
399 6 : THREAD_OFF(on->thread_send_dbdesc);
400 6 : thread_add_event(master, ospf6_dbdesc_send, on, 0,
401 : &on->thread_send_dbdesc);
402 : }
403 :
404 34 : void negotiation_done(struct thread *thread)
405 : {
406 34 : struct ospf6_neighbor *on;
407 34 : struct ospf6_lsa *lsa, *lsanext;
408 :
409 34 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
410 34 : assert(on);
411 :
412 34 : if (on->state != OSPF6_NEIGHBOR_EXSTART)
413 0 : return;
414 :
415 34 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
416 0 : zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name);
417 :
418 : /* clear ls-list */
419 34 : ospf6_neighbor_clear_ls_lists(on);
420 :
421 : /* Interface scoped LSAs */
422 34 : if (on->ospf6_if->lsdb)
423 72 : for (ALL_LSDB(on->ospf6_if->lsdb, lsa, lsanext)) {
424 38 : if (OSPF6_LSA_IS_MAXAGE(lsa)) {
425 0 : ospf6_increment_retrans_count(lsa);
426 0 : ospf6_lsdb_add(ospf6_lsa_copy(lsa),
427 : on->retrans_list);
428 : } else
429 38 : ospf6_lsdb_add(ospf6_lsa_copy(lsa),
430 : on->summary_list);
431 : }
432 :
433 : /* Area scoped LSAs */
434 140 : for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa, lsanext)) {
435 106 : if (OSPF6_LSA_IS_MAXAGE(lsa)) {
436 6 : ospf6_increment_retrans_count(lsa);
437 6 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
438 : } else
439 100 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
440 : }
441 :
442 : /* AS scoped LSAs */
443 94 : for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa, lsanext)) {
444 60 : if (OSPF6_LSA_IS_MAXAGE(lsa)) {
445 17 : ospf6_increment_retrans_count(lsa);
446 17 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
447 : } else
448 43 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
449 : }
450 :
451 34 : UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
452 34 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on,
453 : OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
454 : }
455 :
456 17 : static void ospf6_neighbor_last_dbdesc_release(struct thread *thread)
457 : {
458 17 : struct ospf6_neighbor *on = THREAD_ARG(thread);
459 :
460 17 : assert(on);
461 17 : memset(&on->dbdesc_last, 0, sizeof(struct ospf6_dbdesc));
462 17 : }
463 :
464 34 : void exchange_done(struct thread *thread)
465 : {
466 34 : struct ospf6_neighbor *on;
467 :
468 34 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
469 34 : assert(on);
470 :
471 34 : if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
472 : return;
473 :
474 34 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
475 0 : zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name);
476 :
477 34 : THREAD_OFF(on->thread_send_dbdesc);
478 34 : ospf6_lsdb_remove_all(on->dbdesc_list);
479 :
480 : /* RFC 2328 (10.8): Release the last dbdesc after dead_interval */
481 34 : if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) {
482 17 : THREAD_OFF(on->last_dbdesc_release_timer);
483 17 : thread_add_timer(master, ospf6_neighbor_last_dbdesc_release, on,
484 : on->vlink ? on->vlink->dead_interval
485 : : on->ospf6_if->dead_interval,
486 : &on->last_dbdesc_release_timer);
487 : }
488 :
489 34 : if (on->request_list->count == 0)
490 18 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
491 : OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
492 : else {
493 16 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on,
494 : OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
495 :
496 16 : thread_add_event(master, ospf6_lsreq_send, on, 0,
497 : &on->thread_send_lsreq);
498 : }
499 : }
500 :
501 : /* Check loading state. */
502 147 : void ospf6_check_nbr_loading(struct ospf6_neighbor *on)
503 : {
504 :
505 : /* RFC2328 Section 10.9: When the neighbor responds to these requests
506 : with the proper Link State Update packet(s), the Link state request
507 : list is truncated and a new Link State Request packet is sent.
508 : */
509 147 : if ((on->state == OSPF6_NEIGHBOR_LOADING)
510 147 : || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) {
511 147 : if (on->request_list->count == 0)
512 34 : thread_add_event(master, loading_done, on, 0, NULL);
513 113 : else if (on->last_ls_req == NULL) {
514 7 : THREAD_OFF(on->thread_send_lsreq);
515 7 : thread_add_event(master, ospf6_lsreq_send, on, 0,
516 : &on->thread_send_lsreq);
517 : }
518 : }
519 147 : }
520 :
521 36 : void loading_done(struct thread *thread)
522 : {
523 36 : struct ospf6_neighbor *on;
524 :
525 36 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
526 36 : assert(on);
527 :
528 36 : if (on->state != OSPF6_NEIGHBOR_LOADING)
529 : return;
530 :
531 16 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
532 0 : zlog_debug("Neighbor Event %s: *LoadingDone*", on->name);
533 :
534 16 : assert(on->request_list->count == 0);
535 :
536 16 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
537 : OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
538 : }
539 :
540 42 : void adj_ok(struct thread *thread)
541 : {
542 42 : struct ospf6_neighbor *on;
543 :
544 42 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
545 42 : assert(on);
546 :
547 42 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
548 0 : zlog_debug("Neighbor Event %s: *AdjOK?*", on->name);
549 :
550 42 : if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency(on)) {
551 28 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
552 : OSPF6_NEIGHBOR_EVENT_ADJ_OK);
553 28 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
554 28 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
555 28 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
556 :
557 28 : THREAD_OFF(on->thread_send_dbdesc);
558 28 : thread_add_event(master, ospf6_dbdesc_send, on, 0,
559 : &on->thread_send_dbdesc);
560 :
561 14 : } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) {
562 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
563 : OSPF6_NEIGHBOR_EVENT_ADJ_OK);
564 0 : ospf6_neighbor_clear_ls_lists(on);
565 : }
566 42 : }
567 :
568 0 : void seqnumber_mismatch(struct thread *thread)
569 : {
570 0 : struct ospf6_neighbor *on;
571 :
572 0 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
573 0 : assert(on);
574 :
575 0 : if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
576 : return;
577 :
578 0 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
579 0 : zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name);
580 :
581 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
582 : OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
583 0 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
584 0 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
585 0 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
586 :
587 0 : ospf6_neighbor_clear_ls_lists(on);
588 :
589 0 : THREAD_OFF(on->thread_send_dbdesc);
590 0 : on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
591 :
592 0 : thread_add_event(master, ospf6_dbdesc_send, on, 0,
593 : &on->thread_send_dbdesc);
594 : }
595 :
596 0 : void bad_lsreq(struct thread *thread)
597 : {
598 0 : struct ospf6_neighbor *on;
599 :
600 0 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
601 0 : assert(on);
602 :
603 0 : if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
604 : return;
605 :
606 0 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
607 0 : zlog_debug("Neighbor Event %s: *BadLSReq*", on->name);
608 :
609 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
610 : OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
611 0 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
612 0 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
613 0 : SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
614 :
615 0 : ospf6_neighbor_clear_ls_lists(on);
616 :
617 0 : THREAD_OFF(on->thread_send_dbdesc);
618 0 : on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
619 :
620 0 : thread_add_event(master, ospf6_dbdesc_send, on, 0,
621 : &on->thread_send_dbdesc);
622 :
623 : }
624 :
625 17 : void oneway_received(struct thread *thread)
626 : {
627 17 : struct ospf6_neighbor *on;
628 :
629 17 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
630 17 : assert(on);
631 :
632 17 : if (on->state < OSPF6_NEIGHBOR_TWOWAY)
633 : return;
634 :
635 0 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
636 0 : zlog_debug("Neighbor Event %s: *1Way-Received*", on->name);
637 :
638 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
639 : OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
640 0 : thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
641 :
642 0 : ospf6_neighbor_clear_ls_lists(on);
643 :
644 0 : THREAD_OFF(on->thread_send_dbdesc);
645 0 : THREAD_OFF(on->thread_send_lsreq);
646 0 : THREAD_OFF(on->thread_send_lsupdate);
647 0 : THREAD_OFF(on->thread_send_lsack);
648 0 : THREAD_OFF(on->thread_exchange_done);
649 0 : THREAD_OFF(on->thread_adj_ok);
650 : }
651 :
652 2 : void inactivity_timer(struct thread *thread)
653 : {
654 2 : struct ospf6_neighbor *on;
655 :
656 2 : on = (struct ospf6_neighbor *)THREAD_ARG(thread);
657 2 : assert(on);
658 :
659 2 : if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
660 0 : zlog_debug("Neighbor Event %s: *InactivityTimer*", on->name);
661 :
662 2 : on->drouter = on->prev_drouter = 0;
663 2 : on->bdrouter = on->prev_bdrouter = 0;
664 :
665 2 : if (on->vlink) {
666 0 : ospf6_neighbor_state_change(OSPF6_NEIGHBOR_ATTEMPT, on,
667 : OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
668 0 : return;
669 : }
670 :
671 2 : if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) {
672 2 : on->drouter = on->prev_drouter = 0;
673 2 : on->bdrouter = on->prev_bdrouter = 0;
674 :
675 2 : ospf6_neighbor_state_change(
676 : OSPF6_NEIGHBOR_DOWN, on,
677 : OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
678 2 : thread_add_event(master, neighbor_change, on->ospf6_if, 0,
679 : NULL);
680 :
681 2 : ospf6_neighbor_delete(on);
682 :
683 : } else {
684 0 : if (IS_DEBUG_OSPF6_GR)
685 0 : zlog_debug(
686 : "%s, Acting as HELPER for this neighbour, So restart the dead timer.",
687 : __PRETTY_FUNCTION__);
688 :
689 0 : thread_add_timer(master, inactivity_timer, on,
690 : on->ospf6_if->dead_interval,
691 : &on->inactivity_timer);
692 : }
693 : }
694 :
695 : /* P2P/P2MP stuff */
696 :
697 24 : uint32_t ospf6_neighbor_cost(struct ospf6_neighbor *on)
698 : {
699 24 : if (on->p2xp_cfg && on->p2xp_cfg->cfg_cost)
700 0 : return on->p2xp_cfg->cost;
701 24 : if (on->vlink)
702 0 : return on->vlink->spf_cost;
703 24 : return on->ospf6_if->cost;
704 : }
705 :
706 0 : static int ospf6_if_p2xp_neighcfg_cmp(const struct ospf6_if_p2xp_neighcfg *a,
707 : const struct ospf6_if_p2xp_neighcfg *b)
708 : {
709 0 : return IPV6_ADDR_CMP(&a->addr, &b->addr);
710 : }
711 :
712 6 : struct ospf6_if_p2xp_neighcfg *ospf6_if_p2xp_find(struct ospf6_interface *oi,
713 : const struct in6_addr *addr)
714 : {
715 6 : struct ospf6_if_p2xp_neighcfg ref;
716 :
717 6 : if (!oi)
718 : return NULL;
719 :
720 6 : ref.addr = *addr;
721 6 : return ospf6_if_p2xp_neighcfgs_find(&oi->p2xp_neighs, &ref);
722 : }
723 :
724 : static struct ospf6_if_p2xp_neighcfg *
725 0 : ospf6_if_p2xp_get(struct ospf6_interface *oi, const struct in6_addr *addr)
726 : {
727 0 : struct ospf6_if_p2xp_neighcfg ref, *ret;
728 :
729 0 : if (!oi)
730 : return NULL;
731 :
732 0 : ref.addr = *addr;
733 0 : ret = ospf6_if_p2xp_neighcfgs_find(&oi->p2xp_neighs, &ref);
734 0 : if (!ret) {
735 0 : ret = XCALLOC(MTYPE_OSPF6_NEIGHBOR_P2XP_CFG, sizeof(*ret));
736 0 : ret->addr = *addr;
737 0 : ret->ospf6_if = oi;
738 :
739 0 : ospf6_if_p2xp_neighcfgs_add(&oi->p2xp_neighs, ret);
740 : }
741 :
742 : return ret;
743 : }
744 :
745 0 : static void ospf6_if_p2xp_destroy(struct ospf6_if_p2xp_neighcfg *p2xp_cfg)
746 : {
747 0 : THREAD_OFF(p2xp_cfg->t_unicast_hello);
748 0 : ospf6_if_p2xp_neighcfgs_del(&p2xp_cfg->ospf6_if->p2xp_neighs, p2xp_cfg);
749 :
750 0 : XFREE(MTYPE_OSPF6_NEIGHBOR_P2XP_CFG, p2xp_cfg);
751 0 : }
752 :
753 6 : static void p2xp_neigh_refresh(struct ospf6_neighbor *on, uint32_t prev_cost)
754 : {
755 6 : if (on->p2xp_cfg)
756 0 : on->p2xp_cfg->active = NULL;
757 6 : on->p2xp_cfg = ospf6_if_p2xp_find(on->ospf6_if, &on->linklocal_addr);
758 6 : if (on->p2xp_cfg)
759 0 : on->p2xp_cfg->active = on;
760 :
761 6 : if (ospf6_neighbor_cost(on) != prev_cost)
762 0 : OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
763 6 : }
764 :
765 : /* vty functions */
766 :
767 : #ifndef VTYSH_EXTRACT_PL
768 : #include "ospf6d/ospf6_neighbor_clippy.c"
769 : #endif
770 :
771 0 : DEFPY (ipv6_ospf6_p2xp_neigh,
772 : ipv6_ospf6_p2xp_neigh_cmd,
773 : "[no] ipv6 ospf6 neighbor X:X::X:X",
774 : NO_STR
775 : IP6_STR
776 : OSPF6_STR
777 : "Configure static neighbor\n"
778 : "Neighbor link-local address\n")
779 : {
780 0 : VTY_DECLVAR_CONTEXT(interface, ifp);
781 0 : struct ospf6_interface *oi = ifp->info;
782 0 : struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
783 :
784 0 : if (!oi) {
785 0 : if (no)
786 : return CMD_SUCCESS;
787 0 : oi = ospf6_interface_create(ifp);
788 : }
789 :
790 0 : if (no) {
791 0 : struct ospf6_neighbor *on;
792 0 : uint32_t prev_cost = 0;
793 :
794 0 : p2xp_cfg = ospf6_if_p2xp_find(oi, &neighbor);
795 0 : if (!p2xp_cfg)
796 : return CMD_SUCCESS;
797 :
798 0 : on = p2xp_cfg->active;
799 0 : if (on)
800 0 : prev_cost = ospf6_neighbor_cost(on);
801 :
802 0 : p2xp_cfg->active = NULL;
803 0 : ospf6_if_p2xp_destroy(p2xp_cfg);
804 :
805 0 : if (on) {
806 0 : on->p2xp_cfg = NULL;
807 0 : p2xp_neigh_refresh(on, prev_cost);
808 : }
809 0 : return CMD_SUCCESS;
810 : }
811 :
812 0 : p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
813 0 : return CMD_SUCCESS;
814 : }
815 :
816 0 : DEFPY (ipv6_ospf6_p2xp_neigh_cost,
817 : ipv6_ospf6_p2xp_neigh_cost_cmd,
818 : "[no] ipv6 ospf6 neighbor X:X::X:X cost (1-65535)",
819 : NO_STR
820 : IP6_STR
821 : OSPF6_STR
822 : "Configure static neighbor\n"
823 : "Neighbor link-local address\n"
824 : "Outgoing metric for this neighbor\n"
825 : "Outgoing metric for this neighbor\n")
826 : {
827 0 : VTY_DECLVAR_CONTEXT(interface, ifp);
828 0 : struct ospf6_interface *oi = ifp->info;
829 0 : struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
830 :
831 0 : if (!oi) {
832 0 : if (no)
833 : return CMD_SUCCESS;
834 0 : oi = ospf6_interface_create(ifp);
835 : }
836 :
837 0 : p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
838 :
839 0 : uint32_t prev_cost;
840 0 : if (p2xp_cfg->active)
841 0 : prev_cost = ospf6_neighbor_cost(p2xp_cfg->active);
842 :
843 0 : if (no) {
844 0 : p2xp_cfg->cfg_cost = false;
845 0 : p2xp_cfg->cost = 0;
846 : } else {
847 0 : p2xp_cfg->cfg_cost = true;
848 0 : p2xp_cfg->cost = cost;
849 : }
850 :
851 0 : if (p2xp_cfg->active)
852 0 : p2xp_neigh_refresh(p2xp_cfg->active, prev_cost);
853 : return CMD_SUCCESS;
854 : }
855 :
856 : static void p2xp_unicast_hello_send(struct thread *thread);
857 :
858 0 : static void p2xp_unicast_hello_sched(struct ospf6_if_p2xp_neighcfg *p2xp_cfg)
859 : {
860 0 : if (!p2xp_cfg->poll_interval
861 0 : || (p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOMULTIPOINT
862 0 : && p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOPOINT))
863 : /* state check covers DOWN state too */
864 0 : THREAD_OFF(p2xp_cfg->t_unicast_hello);
865 : else
866 0 : thread_add_timer(master, p2xp_unicast_hello_send, p2xp_cfg,
867 : p2xp_cfg->poll_interval,
868 : &p2xp_cfg->t_unicast_hello);
869 0 : }
870 :
871 3 : void ospf6_if_p2xp_up(struct ospf6_interface *oi)
872 : {
873 3 : struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
874 :
875 6 : frr_each (ospf6_if_p2xp_neighcfgs, &oi->p2xp_neighs, p2xp_cfg)
876 0 : p2xp_unicast_hello_sched(p2xp_cfg);
877 3 : }
878 :
879 0 : static void p2xp_unicast_hello_send(struct thread *thread)
880 : {
881 0 : struct ospf6_if_p2xp_neighcfg *p2xp_cfg = THREAD_ARG(thread);
882 0 : struct ospf6_interface *oi = p2xp_cfg->ospf6_if;
883 :
884 0 : if (oi->state != OSPF6_INTERFACE_POINTTOPOINT
885 0 : && oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT)
886 : return;
887 :
888 0 : p2xp_unicast_hello_sched(p2xp_cfg);
889 :
890 0 : if (p2xp_cfg->active && p2xp_cfg->active->state >= OSPF6_NEIGHBOR_INIT)
891 : return;
892 :
893 0 : ospf6_hello_send_addr(oi, NULL, &p2xp_cfg->addr);
894 : }
895 :
896 0 : DEFPY (ipv6_ospf6_p2xp_neigh_poll_interval,
897 : ipv6_ospf6_p2xp_neigh_poll_interval_cmd,
898 : "[no] ipv6 ospf6 neighbor X:X::X:X poll-interval (1-65535)",
899 : NO_STR
900 : IP6_STR
901 : OSPF6_STR
902 : "Configure static neighbor\n"
903 : "Neighbor link-local address\n"
904 : "Send unicast hellos to neighbor when down\n"
905 : "Unicast hello interval when down (seconds)\n")
906 : {
907 0 : VTY_DECLVAR_CONTEXT(interface, ifp);
908 0 : struct ospf6_interface *oi = ifp->info;
909 0 : struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
910 :
911 0 : if (!oi) {
912 0 : if (no)
913 : return CMD_SUCCESS;
914 0 : oi = ospf6_interface_create(ifp);
915 : }
916 0 : if (no)
917 0 : poll_interval = 0;
918 :
919 0 : p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
920 0 : p2xp_cfg->poll_interval = poll_interval;
921 :
922 0 : p2xp_unicast_hello_sched(p2xp_cfg);
923 0 : return CMD_SUCCESS;
924 : }
925 :
926 : /* show neighbor structure */
927 77 : static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on,
928 : json_object *json_array, bool use_json)
929 : {
930 77 : char router_id[16];
931 77 : char duration[64];
932 77 : struct timeval res;
933 77 : char nstate[16];
934 77 : char deadtime[64];
935 77 : long h, m, s;
936 77 : json_object *json_route;
937 :
938 : /* Router-ID (Name) */
939 77 : inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id));
940 : #ifdef HAVE_GETNAMEINFO
941 : {
942 : }
943 : #endif /*HAVE_GETNAMEINFO*/
944 :
945 : /* Dead time */
946 77 : h = m = s = 0;
947 77 : if (on->inactivity_timer) {
948 77 : s = monotime_until(&on->inactivity_timer->u.sands, NULL)
949 : / 1000000LL;
950 77 : h = s / 3600;
951 77 : s -= h * 3600;
952 77 : m = s / 60;
953 77 : s -= m * 60;
954 : }
955 77 : snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s);
956 :
957 : /* Neighbor State */
958 77 : if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT)
959 0 : snprintf(nstate, sizeof(nstate), "PointToPoint");
960 77 : else if (on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT)
961 66 : snprintf(nstate, sizeof(nstate), "PtMultipoint");
962 11 : else if (on->ospf6_if->type == OSPF_IFTYPE_VIRTUALLINK)
963 0 : snprintf(nstate, sizeof(nstate), "VirtualLink");
964 : else {
965 11 : if (on->router_id == on->drouter)
966 10 : snprintf(nstate, sizeof(nstate), "DR");
967 1 : else if (on->router_id == on->bdrouter)
968 1 : snprintf(nstate, sizeof(nstate), "BDR");
969 : else
970 0 : snprintf(nstate, sizeof(nstate), "DROther");
971 : }
972 :
973 : /* Duration */
974 77 : monotime_since(&on->last_changed, &res);
975 77 : timerstring(&res, duration, sizeof(duration));
976 :
977 : /*
978 : vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n",
979 : "Neighbor ID", "Pri", "DeadTime", "State", "IfState",
980 : "Duration", "I/F", "State");
981 : */
982 77 : if (use_json) {
983 77 : json_route = json_object_new_object();
984 :
985 77 : json_object_string_add(json_route, "neighborId", router_id);
986 77 : json_object_int_add(json_route, "priority", on->priority);
987 77 : json_object_string_add(json_route, "deadTime", deadtime);
988 77 : json_object_string_add(json_route, "state",
989 77 : ospf6_neighbor_state_str[on->state]);
990 77 : json_object_string_add(json_route, "ifState", nstate);
991 77 : json_object_string_add(json_route, "duration", duration);
992 77 : json_object_string_add(json_route, "interfaceName",
993 77 : ospf6_ifname(on->ospf6_if));
994 77 : json_object_string_add(
995 : json_route, "interfaceState",
996 77 : ospf6_interface_state_str[on->ospf6_if->state]);
997 :
998 77 : json_object_array_add(json_array, json_route);
999 : } else
1000 0 : vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %pOI[%s]\n",
1001 0 : router_id, on->priority, deadtime,
1002 0 : ospf6_neighbor_state_str[on->state], nstate, duration,
1003 : on->ospf6_if,
1004 0 : ospf6_interface_state_str[on->ospf6_if->state]);
1005 77 : }
1006 :
1007 0 : static void ospf6_neighbor_show_drchoice(struct vty *vty,
1008 : struct ospf6_neighbor *on,
1009 : json_object *json_array, bool use_json)
1010 : {
1011 0 : char router_id[16];
1012 0 : char drouter[16], bdrouter[16];
1013 0 : char duration[64];
1014 0 : struct timeval now, res;
1015 0 : json_object *json_route;
1016 :
1017 : /*
1018 : vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n",
1019 : "RouterID", "State", "Duration", "DR", "BDR", "I/F",
1020 : "State");
1021 : */
1022 :
1023 0 : inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id));
1024 0 : inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter));
1025 0 : inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter));
1026 :
1027 0 : monotime(&now);
1028 0 : timersub(&now, &on->last_changed, &res);
1029 0 : timerstring(&res, duration, sizeof(duration));
1030 :
1031 0 : if (use_json) {
1032 0 : json_route = json_object_new_object();
1033 0 : json_object_string_add(json_route, "routerId", router_id);
1034 0 : json_object_string_add(json_route, "state",
1035 0 : ospf6_neighbor_state_str[on->state]);
1036 0 : json_object_string_add(json_route, "duration", duration);
1037 0 : json_object_string_add(json_route, "dRouter", drouter);
1038 0 : json_object_string_add(json_route, "bdRouter", bdrouter);
1039 0 : json_object_string_add(json_route, "interfaceName",
1040 0 : ospf6_ifname(on->ospf6_if));
1041 0 : json_object_string_add(
1042 : json_route, "interfaceState",
1043 0 : ospf6_interface_state_str[on->ospf6_if->state]);
1044 :
1045 0 : json_object_array_add(json_array, json_route);
1046 : } else
1047 0 : vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %pOI[%s]\n",
1048 0 : router_id, ospf6_neighbor_state_str[on->state],
1049 : duration, drouter, bdrouter, on->ospf6_if,
1050 0 : ospf6_interface_state_str[on->ospf6_if->state]);
1051 0 : }
1052 :
1053 0 : static void ospf6_neighbor_show_detail(struct vty *vty,
1054 : struct ospf6_neighbor *on,
1055 : json_object *json, bool use_json)
1056 : {
1057 0 : char drouter[16], bdrouter[16];
1058 0 : char linklocal_addr[64], duration[32];
1059 0 : struct timeval now, res;
1060 0 : struct ospf6_lsa *lsa, *lsanext;
1061 0 : json_object *json_neighbor;
1062 0 : json_object *json_array;
1063 0 : char db_desc_str[20];
1064 :
1065 0 : inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr,
1066 : sizeof(linklocal_addr));
1067 0 : inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter));
1068 0 : inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter));
1069 :
1070 0 : monotime(&now);
1071 0 : timersub(&now, &on->last_changed, &res);
1072 0 : timerstring(&res, duration, sizeof(duration));
1073 :
1074 0 : if (use_json) {
1075 0 : json_neighbor = json_object_new_object();
1076 0 : json_object_string_add(json_neighbor, "area",
1077 0 : on->ospf6_if->area->name);
1078 0 : json_object_string_add(json_neighbor, "interface",
1079 0 : ospf6_ifname(on->ospf6_if));
1080 0 : json_object_int_add(json_neighbor, "interfaceIndex",
1081 0 : on->ospf6_if->interface->ifindex);
1082 0 : json_object_int_add(json_neighbor, "neighborInterfaceIndex",
1083 0 : on->ifindex);
1084 0 : json_object_string_add(json_neighbor, "linkLocalAddress",
1085 : linklocal_addr);
1086 0 : json_object_string_add(json_neighbor, "neighborState",
1087 0 : ospf6_neighbor_state_str[on->state]);
1088 0 : json_object_string_add(json_neighbor, "neighborStateDuration",
1089 : duration);
1090 0 : json_object_string_add(json_neighbor, "neighborDRouter",
1091 : drouter);
1092 0 : json_object_string_add(json_neighbor, "neighborBdRouter",
1093 : bdrouter);
1094 0 : snprintf(db_desc_str, sizeof(db_desc_str), "%s%s%s",
1095 : (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
1096 : ? "Initial "
1097 : : ""),
1098 : (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)
1099 : ? "More"
1100 : : ""),
1101 0 : (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)
1102 : ? "Master"
1103 : : "Slave"));
1104 0 : json_object_string_add(json_neighbor, "dbDescStatus",
1105 : db_desc_str);
1106 :
1107 0 : json_object_int_add(json_neighbor, "dbDescSeqNumber",
1108 0 : (unsigned long)ntohl(on->dbdesc_seqnum));
1109 :
1110 0 : json_array = json_object_new_array();
1111 0 : json_object_int_add(json_neighbor, "summaryListCount",
1112 0 : on->summary_list->count);
1113 0 : for (ALL_LSDB(on->summary_list, lsa, lsanext))
1114 0 : json_object_array_add(
1115 0 : json_array, json_object_new_string(lsa->name));
1116 0 : json_object_object_add(json_neighbor, "summaryListLsa",
1117 : json_array);
1118 :
1119 0 : json_array = json_object_new_array();
1120 0 : json_object_int_add(json_neighbor, "requestListCount",
1121 0 : on->request_list->count);
1122 0 : for (ALL_LSDB(on->request_list, lsa, lsanext))
1123 0 : json_object_array_add(
1124 0 : json_array, json_object_new_string(lsa->name));
1125 0 : json_object_object_add(json_neighbor, "requestListLsa",
1126 : json_array);
1127 :
1128 0 : json_array = json_object_new_array();
1129 0 : json_object_int_add(json_neighbor, "reTransListCount",
1130 0 : on->retrans_list->count);
1131 0 : for (ALL_LSDB(on->retrans_list, lsa, lsanext))
1132 0 : json_object_array_add(
1133 0 : json_array, json_object_new_string(lsa->name));
1134 0 : json_object_object_add(json_neighbor, "reTransListLsa",
1135 : json_array);
1136 :
1137 :
1138 0 : timerclear(&res);
1139 0 : if (thread_is_scheduled(on->thread_send_dbdesc))
1140 0 : timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
1141 0 : timerstring(&res, duration, sizeof(duration));
1142 0 : json_object_int_add(json_neighbor, "pendingLsaDbDescCount",
1143 0 : on->dbdesc_list->count);
1144 0 : json_object_string_add(json_neighbor, "pendingLsaDbDescTime",
1145 : duration);
1146 0 : json_object_string_add(
1147 : json_neighbor, "dbDescSendThread",
1148 0 : (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
1149 : : "off"));
1150 0 : json_array = json_object_new_array();
1151 0 : for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
1152 0 : json_object_array_add(
1153 0 : json_array, json_object_new_string(lsa->name));
1154 0 : json_object_object_add(json_neighbor, "pendingLsaDbDesc",
1155 : json_array);
1156 :
1157 0 : timerclear(&res);
1158 0 : if (thread_is_scheduled(on->thread_send_lsreq))
1159 0 : timersub(&on->thread_send_lsreq->u.sands, &now, &res);
1160 0 : timerstring(&res, duration, sizeof(duration));
1161 0 : json_object_int_add(json_neighbor, "pendingLsaLsReqCount",
1162 0 : on->request_list->count);
1163 0 : json_object_string_add(json_neighbor, "pendingLsaLsReqTime",
1164 : duration);
1165 0 : json_object_string_add(
1166 : json_neighbor, "lsReqSendThread",
1167 0 : (thread_is_scheduled(on->thread_send_lsreq) ? "on"
1168 : : "off"));
1169 0 : json_array = json_object_new_array();
1170 0 : for (ALL_LSDB(on->request_list, lsa, lsanext))
1171 0 : json_object_array_add(
1172 0 : json_array, json_object_new_string(lsa->name));
1173 0 : json_object_object_add(json_neighbor, "pendingLsaLsReq",
1174 : json_array);
1175 :
1176 :
1177 0 : timerclear(&res);
1178 0 : if (thread_is_scheduled(on->thread_send_lsupdate))
1179 0 : timersub(&on->thread_send_lsupdate->u.sands, &now,
1180 : &res);
1181 0 : timerstring(&res, duration, sizeof(duration));
1182 0 : json_object_int_add(json_neighbor, "pendingLsaLsUpdateCount",
1183 0 : on->lsupdate_list->count);
1184 0 : json_object_string_add(json_neighbor, "pendingLsaLsUpdateTime",
1185 : duration);
1186 0 : json_object_string_add(
1187 : json_neighbor, "lsUpdateSendThread",
1188 0 : (thread_is_scheduled(on->thread_send_lsupdate)
1189 : ? "on"
1190 : : "off"));
1191 0 : json_array = json_object_new_array();
1192 0 : for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
1193 0 : json_object_array_add(
1194 0 : json_array, json_object_new_string(lsa->name));
1195 0 : json_object_object_add(json_neighbor, "pendingLsaLsUpdate",
1196 : json_array);
1197 :
1198 0 : timerclear(&res);
1199 0 : if (thread_is_scheduled(on->thread_send_lsack))
1200 0 : timersub(&on->thread_send_lsack->u.sands, &now, &res);
1201 0 : timerstring(&res, duration, sizeof(duration));
1202 0 : json_object_int_add(json_neighbor, "pendingLsaLsAckCount",
1203 0 : on->lsack_list->count);
1204 0 : json_object_string_add(json_neighbor, "pendingLsaLsAckTime",
1205 : duration);
1206 0 : json_object_string_add(
1207 : json_neighbor, "lsAckSendThread",
1208 0 : (thread_is_scheduled(on->thread_send_lsack) ? "on"
1209 : : "off"));
1210 0 : json_array = json_object_new_array();
1211 0 : for (ALL_LSDB(on->lsack_list, lsa, lsanext))
1212 0 : json_object_array_add(
1213 0 : json_array, json_object_new_string(lsa->name));
1214 0 : json_object_object_add(json_neighbor, "pendingLsaLsAck",
1215 : json_array);
1216 :
1217 0 : bfd_sess_show(vty, json_neighbor, on->bfd_session);
1218 :
1219 0 : if (on->auth_present == true) {
1220 0 : json_object_string_add(json_neighbor, "authStatus",
1221 : "enabled");
1222 0 : json_object_int_add(
1223 : json_neighbor, "recvdHelloHigherSeqNo",
1224 0 : on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO]);
1225 0 : json_object_int_add(
1226 : json_neighbor, "recvdHelloLowerSeqNo",
1227 0 : on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO]);
1228 0 : json_object_int_add(
1229 : json_neighbor, "recvdDBDescHigherSeqNo",
1230 0 : on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC]);
1231 0 : json_object_int_add(
1232 : json_neighbor, "recvdDBDescLowerSeqNo",
1233 0 : on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC]);
1234 0 : json_object_int_add(
1235 : json_neighbor, "recvdLSReqHigherSeqNo",
1236 0 : on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ]);
1237 0 : json_object_int_add(
1238 : json_neighbor, "recvdLSReqLowerSeqNo",
1239 0 : on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ]);
1240 0 : json_object_int_add(
1241 : json_neighbor, "recvdLSUpdHigherSeqNo",
1242 0 : on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE]);
1243 0 : json_object_int_add(
1244 : json_neighbor, "recvdLSUpdLowerSeqNo",
1245 0 : on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE]);
1246 0 : json_object_int_add(
1247 : json_neighbor, "recvdLSAckHigherSeqNo",
1248 0 : on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
1249 0 : json_object_int_add(
1250 : json_neighbor, "recvdLSAckLowerSeqNo",
1251 0 : on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
1252 : } else
1253 0 : json_object_string_add(json_neighbor, "authStatus",
1254 : "disabled");
1255 :
1256 0 : json_object_object_add(json, on->name, json_neighbor);
1257 :
1258 : } else {
1259 0 : vty_out(vty, " Neighbor %s\n", on->name);
1260 0 : vty_out(vty, " Area %s via interface %pOI (ifindex %d)\n",
1261 0 : on->ospf6_if->area->name, on->ospf6_if,
1262 0 : on->ospf6_if->interface->ifindex);
1263 0 : vty_out(vty, " His IfIndex: %d Link-local address: %s\n",
1264 : on->ifindex, linklocal_addr);
1265 0 : vty_out(vty, " State %s for a duration of %s\n",
1266 0 : ospf6_neighbor_state_str[on->state], duration);
1267 0 : vty_out(vty, " His choice of DR/BDR %s/%s, Priority %d\n",
1268 0 : drouter, bdrouter, on->priority);
1269 0 : vty_out(vty, " DbDesc status: %s%s%s SeqNum: %#lx\n",
1270 : (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
1271 : ? "Initial "
1272 : : ""),
1273 : (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)
1274 : ? "More "
1275 : : ""),
1276 0 : (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)
1277 : ? "Master"
1278 : : "Slave"),
1279 0 : (unsigned long)ntohl(on->dbdesc_seqnum));
1280 :
1281 0 : vty_out(vty, " Summary-List: %d LSAs\n",
1282 0 : on->summary_list->count);
1283 0 : for (ALL_LSDB(on->summary_list, lsa, lsanext))
1284 0 : vty_out(vty, " %s\n", lsa->name);
1285 :
1286 0 : vty_out(vty, " Request-List: %d LSAs\n",
1287 0 : on->request_list->count);
1288 0 : for (ALL_LSDB(on->request_list, lsa, lsanext))
1289 0 : vty_out(vty, " %s\n", lsa->name);
1290 :
1291 0 : vty_out(vty, " Retrans-List: %d LSAs\n",
1292 0 : on->retrans_list->count);
1293 0 : for (ALL_LSDB(on->retrans_list, lsa, lsanext))
1294 0 : vty_out(vty, " %s\n", lsa->name);
1295 :
1296 0 : timerclear(&res);
1297 0 : if (thread_is_scheduled(on->thread_send_dbdesc))
1298 0 : timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
1299 0 : timerstring(&res, duration, sizeof(duration));
1300 0 : vty_out(vty,
1301 : " %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
1302 0 : on->dbdesc_list->count, duration,
1303 0 : (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
1304 : : "off"));
1305 0 : for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
1306 0 : vty_out(vty, " %s\n", lsa->name);
1307 :
1308 0 : timerclear(&res);
1309 0 : if (thread_is_scheduled(on->thread_send_lsreq))
1310 0 : timersub(&on->thread_send_lsreq->u.sands, &now, &res);
1311 0 : timerstring(&res, duration, sizeof(duration));
1312 0 : vty_out(vty,
1313 : " %d Pending LSAs for LSReq in Time %s [thread %s]\n",
1314 0 : on->request_list->count, duration,
1315 0 : (thread_is_scheduled(on->thread_send_lsreq) ? "on"
1316 : : "off"));
1317 0 : for (ALL_LSDB(on->request_list, lsa, lsanext))
1318 0 : vty_out(vty, " %s\n", lsa->name);
1319 :
1320 0 : timerclear(&res);
1321 0 : if (thread_is_scheduled(on->thread_send_lsupdate))
1322 0 : timersub(&on->thread_send_lsupdate->u.sands, &now,
1323 : &res);
1324 0 : timerstring(&res, duration, sizeof(duration));
1325 0 : vty_out(vty,
1326 : " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1327 0 : on->lsupdate_list->count, duration,
1328 0 : (thread_is_scheduled(on->thread_send_lsupdate)
1329 : ? "on"
1330 : : "off"));
1331 0 : for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
1332 0 : vty_out(vty, " %s\n", lsa->name);
1333 :
1334 0 : timerclear(&res);
1335 0 : if (thread_is_scheduled(on->thread_send_lsack))
1336 0 : timersub(&on->thread_send_lsack->u.sands, &now, &res);
1337 0 : timerstring(&res, duration, sizeof(duration));
1338 0 : vty_out(vty,
1339 : " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1340 0 : on->lsack_list->count, duration,
1341 0 : (thread_is_scheduled(on->thread_send_lsack) ? "on"
1342 : : "off"));
1343 0 : for (ALL_LSDB(on->lsack_list, lsa, lsanext))
1344 0 : vty_out(vty, " %s\n", lsa->name);
1345 :
1346 0 : bfd_sess_show(vty, NULL, on->bfd_session);
1347 :
1348 0 : if (on->auth_present == true) {
1349 0 : vty_out(vty, " Authentication header present\n");
1350 0 : vty_out(vty,
1351 : "\t\t\t hello DBDesc LSReq LSUpd LSAck\n");
1352 0 : vty_out(vty,
1353 : " Higher sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n",
1354 : on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO],
1355 : on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC],
1356 : on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ],
1357 : on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE],
1358 : on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
1359 0 : vty_out(vty,
1360 : " Lower sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n",
1361 : on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO],
1362 : on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC],
1363 : on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ],
1364 : on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE],
1365 : on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
1366 : } else
1367 0 : vty_out(vty, " Authentication header not present\n");
1368 : }
1369 0 : }
1370 :
1371 51 : static void ospf6_neighbor_show_detail_common(struct vty *vty,
1372 : struct ospf6 *ospf6, bool uj,
1373 : bool detail, bool drchoice)
1374 : {
1375 51 : struct ospf6_neighbor *on;
1376 51 : struct ospf6_interface *oi;
1377 51 : struct ospf6_area *oa;
1378 51 : struct listnode *i, *j, *k;
1379 51 : json_object *json = NULL;
1380 51 : json_object *json_array = NULL;
1381 51 : void (*showfunc)(struct vty *, struct ospf6_neighbor *,
1382 : json_object *json, bool use_json);
1383 :
1384 51 : if (detail)
1385 : showfunc = ospf6_neighbor_show_detail;
1386 51 : else if (drchoice)
1387 : showfunc = ospf6_neighbor_show_drchoice;
1388 : else
1389 51 : showfunc = ospf6_neighbor_show;
1390 :
1391 51 : if (uj) {
1392 51 : json = json_object_new_object();
1393 51 : json_array = json_object_new_array();
1394 : } else {
1395 0 : if (showfunc == ospf6_neighbor_show)
1396 0 : vty_out(vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n",
1397 : "Neighbor ID", "Pri", "DeadTime", "State",
1398 : "IfState", "Duration", "I/F", "State");
1399 0 : else if (showfunc == ospf6_neighbor_show_drchoice)
1400 0 : vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n",
1401 : "RouterID", "State", "Duration", "DR", "BDR",
1402 : "I/F", "State");
1403 : }
1404 :
1405 153 : for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
1406 154 : for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1407 181 : for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
1408 77 : if (showfunc == ospf6_neighbor_show_detail)
1409 0 : (*showfunc)(vty, on, json, uj);
1410 : else
1411 77 : (*showfunc)(vty, on, json_array, uj);
1412 : }
1413 :
1414 51 : if (uj) {
1415 51 : if (showfunc != ospf6_neighbor_show_detail)
1416 51 : json_object_object_add(json, "neighbors", json_array);
1417 : else
1418 0 : json_object_free(json_array);
1419 51 : vty_json(vty, json);
1420 : }
1421 51 : }
1422 :
1423 51 : DEFUN(show_ipv6_ospf6_neighbor, show_ipv6_ospf6_neighbor_cmd,
1424 : "show ipv6 ospf6 [vrf <NAME|all>] neighbor [<detail|drchoice>] [json]",
1425 : SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1426 : "All VRFs\n"
1427 : "Neighbor list\n"
1428 : "Display details\n"
1429 : "Display DR choices\n" JSON_STR)
1430 : {
1431 51 : struct ospf6 *ospf6;
1432 51 : struct listnode *node;
1433 51 : const char *vrf_name = NULL;
1434 51 : bool all_vrf = false;
1435 51 : int idx_vrf = 0;
1436 51 : int idx_type = 4;
1437 51 : bool uj = use_json(argc, argv);
1438 51 : bool detail = false;
1439 51 : bool drchoice = false;
1440 :
1441 51 : OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1442 :
1443 51 : if (argv_find(argv, argc, "detail", &idx_type))
1444 : detail = true;
1445 51 : else if (argv_find(argv, argc, "drchoice", &idx_type))
1446 0 : drchoice = true;
1447 :
1448 102 : for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1449 51 : if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1450 51 : ospf6_neighbor_show_detail_common(vty, ospf6, uj,
1451 : detail, drchoice);
1452 51 : if (!all_vrf)
1453 : break;
1454 : }
1455 : }
1456 :
1457 51 : OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1458 :
1459 : return CMD_SUCCESS;
1460 : }
1461 :
1462 0 : static int ospf6_neighbor_show_common(struct vty *vty, int argc,
1463 : struct cmd_token **argv,
1464 : struct ospf6 *ospf6, int idx_ipv4,
1465 : bool uj)
1466 : {
1467 0 : struct ospf6_neighbor *on;
1468 0 : struct ospf6_interface *oi;
1469 0 : struct ospf6_area *oa;
1470 0 : struct listnode *i, *j, *k;
1471 0 : void (*showfunc)(struct vty *, struct ospf6_neighbor *,
1472 : json_object *json, bool use_json);
1473 0 : uint32_t router_id;
1474 0 : json_object *json = NULL;
1475 :
1476 0 : showfunc = ospf6_neighbor_show_detail;
1477 0 : if (uj)
1478 0 : json = json_object_new_object();
1479 :
1480 0 : if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) {
1481 0 : vty_out(vty, "Router-ID is not parsable: %s\n",
1482 0 : argv[idx_ipv4]->arg);
1483 0 : return CMD_SUCCESS;
1484 : }
1485 :
1486 0 : for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
1487 0 : for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1488 0 : for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
1489 0 : if (router_id == on->router_id)
1490 0 : (*showfunc)(vty, on, json, uj);
1491 : }
1492 :
1493 0 : if (uj)
1494 0 : vty_json(vty, json);
1495 :
1496 : return CMD_SUCCESS;
1497 : }
1498 :
1499 0 : DEFUN(show_ipv6_ospf6_neighbor_one, show_ipv6_ospf6_neighbor_one_cmd,
1500 : "show ipv6 ospf6 [vrf <NAME|all>] neighbor A.B.C.D [json]",
1501 : SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1502 : "All VRFs\n"
1503 : "Neighbor list\n"
1504 : "Specify Router-ID as IPv4 address notation\n" JSON_STR)
1505 : {
1506 0 : int idx_ipv4 = 4;
1507 0 : struct ospf6 *ospf6;
1508 0 : struct listnode *node;
1509 0 : const char *vrf_name = NULL;
1510 0 : bool all_vrf = false;
1511 0 : int idx_vrf = 0;
1512 0 : bool uj = use_json(argc, argv);
1513 :
1514 0 : OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1515 0 : if (idx_vrf > 0)
1516 0 : idx_ipv4 += 2;
1517 :
1518 0 : for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1519 0 : if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1520 0 : ospf6_neighbor_show_common(vty, argc, argv, ospf6,
1521 : idx_ipv4, uj);
1522 :
1523 0 : if (!all_vrf)
1524 : break;
1525 : }
1526 : }
1527 :
1528 0 : OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1529 :
1530 : return CMD_SUCCESS;
1531 : }
1532 :
1533 16 : void ospf6_neighbor_init(void)
1534 : {
1535 16 : install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
1536 16 : install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
1537 :
1538 16 : install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_neigh_cmd);
1539 16 : install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_neigh_cost_cmd);
1540 16 : install_element(INTERFACE_NODE,
1541 : &ipv6_ospf6_p2xp_neigh_poll_interval_cmd);
1542 16 : }
1543 :
1544 0 : DEFUN (debug_ospf6_neighbor,
1545 : debug_ospf6_neighbor_cmd,
1546 : "debug ospf6 neighbor [<state|event>]",
1547 : DEBUG_STR
1548 : OSPF6_STR
1549 : "Debug OSPFv3 Neighbor\n"
1550 : "Debug OSPFv3 Neighbor State Change\n"
1551 : "Debug OSPFv3 Neighbor Event\n")
1552 : {
1553 0 : int idx_type = 3;
1554 0 : unsigned char level = 0;
1555 :
1556 0 : if (argc == 4) {
1557 0 : if (!strncmp(argv[idx_type]->arg, "s", 1))
1558 : level = OSPF6_DEBUG_NEIGHBOR_STATE;
1559 0 : else if (!strncmp(argv[idx_type]->arg, "e", 1))
1560 0 : level = OSPF6_DEBUG_NEIGHBOR_EVENT;
1561 : } else
1562 : level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
1563 :
1564 0 : OSPF6_DEBUG_NEIGHBOR_ON(level);
1565 0 : return CMD_SUCCESS;
1566 : }
1567 :
1568 :
1569 0 : DEFUN (no_debug_ospf6_neighbor,
1570 : no_debug_ospf6_neighbor_cmd,
1571 : "no debug ospf6 neighbor [<state|event>]",
1572 : NO_STR
1573 : DEBUG_STR
1574 : OSPF6_STR
1575 : "Debug OSPFv3 Neighbor\n"
1576 : "Debug OSPFv3 Neighbor State Change\n"
1577 : "Debug OSPFv3 Neighbor Event\n")
1578 : {
1579 0 : int idx_type = 4;
1580 0 : unsigned char level = 0;
1581 :
1582 0 : if (argc == 5) {
1583 0 : if (!strncmp(argv[idx_type]->arg, "s", 1))
1584 0 : level = OSPF6_DEBUG_NEIGHBOR_STATE;
1585 0 : if (!strncmp(argv[idx_type]->arg, "e", 1))
1586 0 : level = OSPF6_DEBUG_NEIGHBOR_EVENT;
1587 : } else
1588 : level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
1589 :
1590 0 : OSPF6_DEBUG_NEIGHBOR_OFF(level);
1591 0 : return CMD_SUCCESS;
1592 : }
1593 :
1594 :
1595 0 : DEFUN (no_debug_ospf6,
1596 : no_debug_ospf6_cmd,
1597 : "no debug ospf6",
1598 : NO_STR
1599 : DEBUG_STR
1600 : OSPF6_STR)
1601 : {
1602 0 : unsigned int i;
1603 :
1604 0 : OSPF6_DEBUG_ABR_OFF();
1605 0 : OSPF6_DEBUG_ASBR_OFF();
1606 0 : OSPF6_DEBUG_BROUTER_OFF();
1607 0 : OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF();
1608 0 : OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF();
1609 0 : OSPF6_DEBUG_FLOODING_OFF();
1610 0 : OSPF6_DEBUG_INTERFACE_OFF();
1611 :
1612 0 : ospf6_lsa_debug_set_all(false);
1613 :
1614 0 : for (i = 0; i < 6; i++)
1615 0 : OSPF6_DEBUG_MESSAGE_OFF(i,
1616 : OSPF6_DEBUG_NEIGHBOR_STATE
1617 : | OSPF6_DEBUG_NEIGHBOR_EVENT);
1618 :
1619 0 : OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE
1620 : | OSPF6_DEBUG_NEIGHBOR_EVENT);
1621 0 : OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE);
1622 0 : OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA);
1623 0 : OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER);
1624 0 : OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_MEMORY);
1625 0 : OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_PROCESS);
1626 0 : OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_TIME);
1627 0 : OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_DATABASE);
1628 0 : OSPF6_DEBUG_ZEBRA_OFF(OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV);
1629 :
1630 0 : return CMD_SUCCESS;
1631 : }
1632 :
1633 0 : int config_write_ospf6_debug_neighbor(struct vty *vty)
1634 : {
1635 0 : if (IS_OSPF6_DEBUG_NEIGHBOR(STATE) && IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
1636 0 : vty_out(vty, "debug ospf6 neighbor\n");
1637 0 : else if (IS_OSPF6_DEBUG_NEIGHBOR(STATE))
1638 0 : vty_out(vty, "debug ospf6 neighbor state\n");
1639 0 : else if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
1640 0 : vty_out(vty, "debug ospf6 neighbor event\n");
1641 0 : return 0;
1642 : }
1643 :
1644 0 : int config_write_ospf6_p2xp_neighbor(struct vty *vty,
1645 : struct ospf6_interface *oi)
1646 : {
1647 0 : struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
1648 :
1649 0 : frr_each (ospf6_if_p2xp_neighcfgs, &oi->p2xp_neighs, p2xp_cfg) {
1650 0 : vty_out(vty, " ipv6 ospf6 neighbor %pI6\n", &p2xp_cfg->addr);
1651 :
1652 0 : if (p2xp_cfg->poll_interval)
1653 0 : vty_out(vty,
1654 : " ipv6 ospf6 neighbor %pI6 poll-interval %u\n",
1655 : &p2xp_cfg->addr, p2xp_cfg->poll_interval);
1656 :
1657 0 : if (p2xp_cfg->cfg_cost)
1658 0 : vty_out(vty, " ipv6 ospf6 neighbor %pI6 cost %u\n",
1659 : &p2xp_cfg->addr, p2xp_cfg->cost);
1660 : }
1661 0 : return 0;
1662 : }
1663 :
1664 16 : void install_element_ospf6_debug_neighbor(void)
1665 : {
1666 16 : install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd);
1667 16 : install_element(ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
1668 16 : install_element(ENABLE_NODE, &no_debug_ospf6_cmd);
1669 16 : install_element(CONFIG_NODE, &debug_ospf6_neighbor_cmd);
1670 16 : install_element(CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
1671 16 : install_element(CONFIG_NODE, &no_debug_ospf6_cmd);
1672 16 : }
|