]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isisd.c
Merge pull request #13345 from donaldsharp/pim_after_dark
[mirror_frr.git] / isisd / isisd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * IS-IS Rout(e)ing protocol - isisd.c
4 *
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
8 */
9
10 #include <zebra.h>
11
12 #include "frrevent.h"
13 #include "vty.h"
14 #include "command.h"
15 #include "log.h"
16 #include "memory.h"
17 #include "time.h"
18 #include "linklist.h"
19 #include "if.h"
20 #include "hash.h"
21 #include "filter.h"
22 #include "plist.h"
23 #include "stream.h"
24 #include "prefix.h"
25 #include "table.h"
26 #include "qobj.h"
27 #include "zclient.h"
28 #include "vrf.h"
29 #include "spf_backoff.h"
30 #include "flex_algo.h"
31 #include "lib/northbound_cli.h"
32 #include "bfd.h"
33
34 #include "isisd/isis_constants.h"
35 #include "isisd/isis_common.h"
36 #include "isisd/isis_flags.h"
37 #include "isisd/isis_circuit.h"
38 #include "isisd/isis_csm.h"
39 #include "isisd/isisd.h"
40 #include "isisd/isis_dynhn.h"
41 #include "isisd/isis_adjacency.h"
42 #include "isisd/isis_pdu.h"
43 #include "isisd/isis_misc.h"
44 #include "isisd/isis_constants.h"
45 #include "isisd/isis_lsp.h"
46 #include "isisd/isis_spf.h"
47 #include "isisd/isis_route.h"
48 #include "isisd/isis_zebra.h"
49 #include "isisd/isis_events.h"
50 #include "isisd/isis_te.h"
51 #include "isisd/isis_mt.h"
52 #include "isisd/isis_sr.h"
53 #include "isisd/isis_flex_algo.h"
54 #include "isisd/fabricd.h"
55 #include "isisd/isis_nb.h"
56
57 /* For debug statement. */
58 unsigned long debug_adj_pkt;
59 unsigned long debug_snp_pkt;
60 unsigned long debug_update_pkt;
61 unsigned long debug_spf_events;
62 unsigned long debug_rte_events;
63 unsigned long debug_events;
64 unsigned long debug_pkt_dump;
65 unsigned long debug_lsp_gen;
66 unsigned long debug_lsp_sched;
67 unsigned long debug_flooding;
68 unsigned long debug_bfd;
69 unsigned long debug_tx_queue;
70 unsigned long debug_sr;
71 unsigned long debug_ldp_sync;
72 unsigned long debug_lfa;
73 unsigned long debug_te;
74
75 DEFINE_MGROUP(ISISD, "isisd");
76
77 DEFINE_MTYPE_STATIC(ISISD, ISIS, "ISIS process");
78 DEFINE_MTYPE_STATIC(ISISD, ISIS_NAME, "ISIS process name");
79 DEFINE_MTYPE_STATIC(ISISD, ISIS_AREA, "ISIS area");
80 DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address");
81 DEFINE_MTYPE(ISISD, ISIS_ACL_NAME, "ISIS access-list name");
82 DEFINE_MTYPE(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name");
83
84 DEFINE_QOBJ_TYPE(isis_area);
85
86 /* ISIS process wide configuration. */
87 static struct isis_master isis_master;
88
89 /* ISIS process wide configuration pointer to export. */
90 struct isis_master *im;
91
92 /* ISIS config processing thread */
93 struct event *t_isis_cfg;
94
95 #ifndef FABRICD
96 DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area));
97 #endif /* ifndef FABRICD */
98
99 /*
100 * Prototypes.
101 */
102 int isis_area_get(struct vty *, const char *);
103 int area_net_title(struct vty *, const char *);
104 int area_clear_net_title(struct vty *, const char *);
105 int show_isis_interface_common(struct vty *, struct json_object *json,
106 const char *ifname, char, const char *vrf_name,
107 bool all_vrf);
108 int show_isis_interface_common_vty(struct vty *, const char *ifname, char,
109 const char *vrf_name, bool all_vrf);
110 int show_isis_interface_common_json(struct json_object *json,
111 const char *ifname, char,
112 const char *vrf_name, bool all_vrf);
113 int show_isis_neighbor_common(struct vty *, struct json_object *json,
114 const char *id, char, const char *vrf_name,
115 bool all_vrf);
116 int clear_isis_neighbor_common(struct vty *, const char *id,
117 const char *vrf_name, bool all_vrf);
118
119 /* Link ISIS instance to VRF. */
120 void isis_vrf_link(struct isis *isis, struct vrf *vrf)
121 {
122 isis->vrf_id = vrf->vrf_id;
123 if (vrf->info != (void *)isis)
124 vrf->info = (void *)isis;
125 }
126
127 /* Unlink ISIS instance to VRF. */
128 void isis_vrf_unlink(struct isis *isis, struct vrf *vrf)
129 {
130 if (vrf->info == (void *)isis)
131 vrf->info = NULL;
132 isis->vrf_id = VRF_UNKNOWN;
133 }
134
135 struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
136 {
137 struct isis *isis;
138 struct listnode *node;
139
140 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
141 if (isis->vrf_id == vrf_id)
142 return isis;
143
144 return NULL;
145 }
146
147 struct isis *isis_lookup_by_vrfname(const char *vrfname)
148 {
149 struct isis *isis;
150 struct listnode *node;
151
152 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
153 if (isis->name && vrfname && strcmp(isis->name, vrfname) == 0)
154 return isis;
155
156 return NULL;
157 }
158
159 struct isis *isis_lookup_by_sysid(const uint8_t *sysid)
160 {
161 struct isis *isis;
162 struct listnode *node;
163
164 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
165 if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
166 return isis;
167
168 return NULL;
169 }
170
171 void isis_master_init(struct event_loop *master)
172 {
173 memset(&isis_master, 0, sizeof(isis_master));
174 im = &isis_master;
175 im->isis = list_new();
176 im->master = master;
177 }
178
179 struct isis *isis_new(const char *vrf_name)
180 {
181 struct vrf *vrf;
182 struct isis *isis;
183
184 isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
185
186 isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name);
187
188 vrf = vrf_lookup_by_name(vrf_name);
189
190 if (vrf)
191 isis_vrf_link(isis, vrf);
192 else
193 isis->vrf_id = VRF_UNKNOWN;
194
195 isis_zebra_vrf_register(isis);
196
197 if (IS_DEBUG_EVENTS)
198 zlog_debug(
199 "%s: Create new isis instance with vrf_name %s vrf_id %u",
200 __func__, isis->name, isis->vrf_id);
201
202 /*
203 * Default values
204 */
205 isis->max_area_addrs = ISIS_DEFAULT_MAX_AREA_ADDRESSES;
206 isis->process_id = getpid();
207 isis->router_id = 0;
208 isis->area_list = list_new();
209 isis->uptime = time(NULL);
210 isis->snmp_notifications = 1;
211 dyn_cache_init(isis);
212
213 listnode_add(im->isis, isis);
214
215 return isis;
216 }
217
218 void isis_finish(struct isis *isis)
219 {
220 struct isis_area *area;
221 struct listnode *node, *nnode;
222
223 for (ALL_LIST_ELEMENTS(isis->area_list, node, nnode, area))
224 isis_area_destroy(area);
225
226 struct vrf *vrf = NULL;
227
228 listnode_delete(im->isis, isis);
229
230 isis_zebra_vrf_deregister(isis);
231
232 vrf = vrf_lookup_by_name(isis->name);
233 if (vrf)
234 isis_vrf_unlink(isis, vrf);
235 XFREE(MTYPE_ISIS_NAME, isis->name);
236
237 isis_redist_free(isis);
238 list_delete(&isis->area_list);
239 dyn_cache_finish(isis);
240 XFREE(MTYPE_ISIS, isis);
241 }
242
243 void isis_area_add_circuit(struct isis_area *area, struct isis_circuit *circuit)
244 {
245 isis_csm_state_change(ISIS_ENABLE, circuit, area);
246
247 area->ip_circuits += circuit->ip_router;
248 area->ipv6_circuits += circuit->ipv6_router;
249
250 area->lfa_protected_links[0] += circuit->lfa_protection[0];
251 area->rlfa_protected_links[0] += circuit->rlfa_protection[0];
252 area->tilfa_protected_links[0] += circuit->tilfa_protection[0];
253
254 area->lfa_protected_links[1] += circuit->lfa_protection[1];
255 area->rlfa_protected_links[1] += circuit->rlfa_protection[1];
256 area->tilfa_protected_links[1] += circuit->tilfa_protection[1];
257 }
258
259 void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit)
260 {
261 area->ip_circuits -= circuit->ip_router;
262 area->ipv6_circuits -= circuit->ipv6_router;
263
264 area->lfa_protected_links[0] -= circuit->lfa_protection[0];
265 area->rlfa_protected_links[0] -= circuit->rlfa_protection[0];
266 area->tilfa_protected_links[0] -= circuit->tilfa_protection[0];
267
268 area->lfa_protected_links[1] -= circuit->lfa_protection[1];
269 area->rlfa_protected_links[1] -= circuit->rlfa_protection[1];
270 area->tilfa_protected_links[1] -= circuit->tilfa_protection[1];
271
272 isis_csm_state_change(ISIS_DISABLE, circuit, area);
273 }
274
275 static void delete_area_addr(void *arg)
276 {
277 struct iso_address *addr = (struct iso_address *)arg;
278
279 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
280 }
281
282 struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
283 {
284 struct isis_area *area;
285 struct isis *isis = NULL;
286 struct vrf *vrf = NULL;
287 struct interface *ifp;
288 struct isis_circuit *circuit;
289
290 area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
291
292 if (!vrf_name)
293 vrf_name = VRF_DEFAULT_NAME;
294
295 vrf = vrf_lookup_by_name(vrf_name);
296 isis = isis_lookup_by_vrfname(vrf_name);
297
298 if (isis == NULL)
299 isis = isis_new(vrf_name);
300
301 listnode_add(isis->area_list, area);
302 area->isis = isis;
303
304 /*
305 * Fabricd runs only as level-2.
306 * For IS-IS, the default is level-1-2
307 */
308 if (fabricd)
309 area->is_type = IS_LEVEL_2;
310 else
311 area->is_type = yang_get_default_enum(
312 "/frr-isisd:isis/instance/is-type");
313
314 /*
315 * intialize the databases
316 */
317 if (area->is_type & IS_LEVEL_1)
318 lsp_db_init(&area->lspdb[0]);
319 if (area->is_type & IS_LEVEL_2)
320 lsp_db_init(&area->lspdb[1]);
321
322 #ifndef FABRICD
323 /* Flex-Algo */
324 area->flex_algos = flex_algos_alloc(isis_flex_algo_data_alloc,
325 isis_flex_algo_data_free);
326 #endif /* ifndef FABRICD */
327
328 spftree_area_init(area);
329
330 area->circuit_list = list_new();
331 area->adjacency_list = list_new();
332 area->area_addrs = list_new();
333 area->area_addrs->del = delete_area_addr;
334
335 if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
336 event_add_timer(master, lsp_tick, area, 1, &area->t_tick);
337 flags_initialize(&area->flags);
338
339 isis_sr_area_init(area);
340
341 /*
342 * Default values
343 */
344 #ifndef FABRICD
345 enum isis_metric_style default_style;
346
347 area->max_lsp_lifetime[0] = yang_get_default_uint16(
348 "/frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime");
349 area->max_lsp_lifetime[1] = yang_get_default_uint16(
350 "/frr-isisd:isis/instance/lsp/timers/level-2/maximum-lifetime");
351 area->lsp_refresh[0] = yang_get_default_uint16(
352 "/frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval");
353 area->lsp_refresh[1] = yang_get_default_uint16(
354 "/frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval");
355 area->lsp_gen_interval[0] = yang_get_default_uint16(
356 "/frr-isisd:isis/instance/lsp/timers/level-1/generation-interval");
357 area->lsp_gen_interval[1] = yang_get_default_uint16(
358 "/frr-isisd:isis/instance/lsp/timers/level-2/generation-interval");
359 area->min_spf_interval[0] = yang_get_default_uint16(
360 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
361 area->min_spf_interval[1] = yang_get_default_uint16(
362 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
363 area->dynhostname = yang_get_default_bool(
364 "/frr-isisd:isis/instance/dynamic-hostname");
365 default_style =
366 yang_get_default_enum("/frr-isisd:isis/instance/metric-style");
367 area->oldmetric = default_style == ISIS_WIDE_METRIC ? 0 : 1;
368 area->newmetric = default_style == ISIS_NARROW_METRIC ? 0 : 1;
369 area->lsp_frag_threshold = 90; /* not currently configurable */
370 area->lsp_mtu =
371 yang_get_default_uint16("/frr-isisd:isis/instance/lsp/mtu");
372 area->lfa_load_sharing[0] = yang_get_default_bool(
373 "/frr-isisd:isis/instance/fast-reroute/level-1/lfa/load-sharing");
374 area->lfa_load_sharing[1] = yang_get_default_bool(
375 "/frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing");
376 area->attached_bit_send =
377 yang_get_default_bool("/frr-isisd:isis/instance/attach-send");
378 area->attached_bit_rcv_ignore = yang_get_default_bool(
379 "/frr-isisd:isis/instance/attach-receive-ignore");
380
381 #else
382 area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */
383 area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */
384 area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
385 area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
386 area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL;
387 area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL;
388 area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
389 area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
390 area->dynhostname = 1;
391 area->oldmetric = 0;
392 area->newmetric = 1;
393 area->lsp_frag_threshold = 90;
394 area->lsp_mtu = DEFAULT_LSP_MTU;
395 area->lfa_load_sharing[0] = true;
396 area->lfa_load_sharing[1] = true;
397 area->attached_bit_send = true;
398 area->attached_bit_rcv_ignore = false;
399 #endif /* ifndef FABRICD */
400 area->lfa_priority_limit[0] = SPF_PREFIX_PRIO_LOW;
401 area->lfa_priority_limit[1] = SPF_PREFIX_PRIO_LOW;
402 isis_lfa_tiebreakers_init(area, ISIS_LEVEL1);
403 isis_lfa_tiebreakers_init(area, ISIS_LEVEL2);
404
405 area_mt_init(area);
406
407 area->area_tag = strdup(area_tag);
408
409 if (fabricd)
410 area->fabricd = fabricd_new(area);
411
412 area->lsp_refresh_arg[0].area = area;
413 area->lsp_refresh_arg[0].level = IS_LEVEL_1;
414 area->lsp_refresh_arg[1].area = area;
415 area->lsp_refresh_arg[1].level = IS_LEVEL_2;
416
417 area->bfd_signalled_down = false;
418 area->bfd_force_spf_refresh = false;
419
420 QOBJ_REG(area, isis_area);
421
422 if (vrf) {
423 FOR_ALL_INTERFACES (vrf, ifp) {
424 if (ifp->ifindex == IFINDEX_INTERNAL)
425 continue;
426
427 circuit = ifp->info;
428 if (circuit && strmatch(circuit->tag, area->area_tag))
429 isis_area_add_circuit(area, circuit);
430 }
431 }
432
433 return area;
434 }
435
436 struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
437 const char *vrf_name)
438 {
439 struct isis_area *area;
440 struct listnode *node;
441 struct isis *isis = NULL;
442
443 isis = isis_lookup_by_vrfname(vrf_name);
444 if (isis == NULL)
445 return NULL;
446
447 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
448 if (strcmp(area->area_tag, area_tag) == 0)
449 return area;
450
451 return NULL;
452 }
453
454 struct isis_area *isis_area_lookup(const char *area_tag, vrf_id_t vrf_id)
455 {
456 struct isis_area *area;
457 struct listnode *node;
458 struct isis *isis;
459
460 isis = isis_lookup_by_vrfid(vrf_id);
461 if (isis == NULL)
462 return NULL;
463
464 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
465 if ((area->area_tag == NULL && area_tag == NULL)
466 || (area->area_tag && area_tag
467 && strcmp(area->area_tag, area_tag) == 0))
468 return area;
469
470 return NULL;
471 }
472
473 int isis_area_get(struct vty *vty, const char *area_tag)
474 {
475 struct isis_area *area;
476
477 area = isis_area_lookup(area_tag, VRF_DEFAULT);
478
479 if (area) {
480 VTY_PUSH_CONTEXT(ROUTER_NODE, area);
481 return CMD_SUCCESS;
482 }
483
484 area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
485
486 if (IS_DEBUG_EVENTS)
487 zlog_debug("New IS-IS area instance %s", area->area_tag);
488
489 VTY_PUSH_CONTEXT(ROUTER_NODE, area);
490
491 return CMD_SUCCESS;
492 }
493
494 void isis_area_destroy(struct isis_area *area)
495 {
496 struct listnode *node, *nnode;
497 struct isis_circuit *circuit;
498
499 QOBJ_UNREG(area);
500
501 if (fabricd)
502 fabricd_finish(area->fabricd);
503
504 if (area->circuit_list) {
505 for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
506 circuit))
507 isis_area_del_circuit(area, circuit);
508
509 list_delete(&area->circuit_list);
510 }
511 if (area->flags.free_idcs)
512 list_delete(&area->flags.free_idcs);
513
514 list_delete(&area->adjacency_list);
515
516 lsp_db_fini(&area->lspdb[0]);
517 lsp_db_fini(&area->lspdb[1]);
518
519 /* invalidate and verify to delete all routes from zebra */
520 isis_area_invalidate_routes(area, area->is_type);
521 isis_area_verify_routes(area);
522
523 isis_sr_area_term(area);
524
525 isis_mpls_te_term(area);
526
527 spftree_area_del(area);
528
529 if (area->spf_timer[0])
530 isis_spf_timer_free(EVENT_ARG(area->spf_timer[0]));
531 EVENT_OFF(area->spf_timer[0]);
532 if (area->spf_timer[1])
533 isis_spf_timer_free(EVENT_ARG(area->spf_timer[1]));
534 EVENT_OFF(area->spf_timer[1]);
535
536 spf_backoff_free(area->spf_delay_ietf[0]);
537 spf_backoff_free(area->spf_delay_ietf[1]);
538
539 if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
540 isis_redist_area_finish(area);
541
542 list_delete(&area->area_addrs);
543
544 for (int i = SPF_PREFIX_PRIO_CRITICAL; i <= SPF_PREFIX_PRIO_MEDIUM;
545 i++) {
546 struct spf_prefix_priority_acl *ppa;
547
548 ppa = &area->spf_prefix_priorities[i];
549 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
550 }
551 isis_lfa_tiebreakers_clear(area, ISIS_LEVEL1);
552 isis_lfa_tiebreakers_clear(area, ISIS_LEVEL2);
553
554 EVENT_OFF(area->t_tick);
555 EVENT_OFF(area->t_lsp_refresh[0]);
556 EVENT_OFF(area->t_lsp_refresh[1]);
557 EVENT_OFF(area->t_rlfa_rib_update);
558
559 event_cancel_event(master, area);
560
561 listnode_delete(area->isis->area_list, area);
562
563 free(area->area_tag);
564
565 area_mt_finish(area);
566
567 if (area->rlfa_plist_name[0])
568 XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[0]);
569 if (area->rlfa_plist_name[1])
570 XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[1]);
571
572 XFREE(MTYPE_ISIS_AREA, area);
573
574 }
575
576 /* This is hook function for vrf create called as part of vrf_init */
577 static int isis_vrf_new(struct vrf *vrf)
578 {
579 if (IS_DEBUG_EVENTS)
580 zlog_debug("%s: VRF Created: %s(%u)", __func__, vrf->name,
581 vrf->vrf_id);
582
583 return 0;
584 }
585
586 /* This is hook function for vrf delete call as part of vrf_init */
587 static int isis_vrf_delete(struct vrf *vrf)
588 {
589 if (IS_DEBUG_EVENTS)
590 zlog_debug("%s: VRF Deletion: %s(%u)", __func__, vrf->name,
591 vrf->vrf_id);
592
593 return 0;
594 }
595
596 static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set)
597 {
598 struct listnode *node;
599 struct isis_area *area;
600 int type;
601 int level;
602 int protocol;
603
604 char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1];
605
606 memset(do_subscribe, 0, sizeof(do_subscribe));
607
608 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
609 for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
610 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
611 for (level = 0; level < ISIS_LEVELS; level++)
612 if (area->redist_settings[protocol]
613 [type][level]
614 .redist
615 == 1)
616 do_subscribe[protocol][type] =
617 1;
618
619 for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
620 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) {
621 /* This field is actually controlling transmission of
622 * the IS-IS
623 * routes to Zebra and has nothing to do with
624 * redistribution,
625 * so skip it. */
626 if (type == PROTO_TYPE)
627 continue;
628
629 if (!do_subscribe[protocol][type])
630 continue;
631
632 afi_t afi = afi_for_redist_protocol(protocol);
633
634 if (type == DEFAULT_ROUTE) {
635 if (set)
636 vrf_bitmap_set(
637 zclient->default_information
638 [afi],
639 isis->vrf_id);
640 else
641 vrf_bitmap_unset(
642 zclient->default_information
643 [afi],
644 isis->vrf_id);
645 } else {
646 if (set)
647 vrf_bitmap_set(
648 zclient->redist[afi][type],
649 isis->vrf_id);
650 else
651 vrf_bitmap_unset(
652 zclient->redist[afi][type],
653 isis->vrf_id);
654 }
655 }
656 }
657
658 static int isis_vrf_enable(struct vrf *vrf)
659 {
660 struct isis *isis;
661 vrf_id_t old_vrf_id;
662
663 if (IS_DEBUG_EVENTS)
664 zlog_debug("%s: VRF %s id %u enabled", __func__, vrf->name,
665 vrf->vrf_id);
666
667 isis = isis_lookup_by_vrfname(vrf->name);
668 if (isis && isis->vrf_id != vrf->vrf_id) {
669 old_vrf_id = isis->vrf_id;
670 /* We have instance configured, link to VRF and make it "up". */
671 isis_vrf_link(isis, vrf);
672 if (IS_DEBUG_EVENTS)
673 zlog_debug(
674 "%s: isis linked to vrf %s vrf_id %u (old id %u)",
675 __func__, vrf->name, isis->vrf_id, old_vrf_id);
676 /* start zebra redist to us for new vrf */
677 isis_set_redist_vrf_bitmaps(isis, true);
678
679 isis_zebra_vrf_register(isis);
680 }
681
682 return 0;
683 }
684
685 static int isis_vrf_disable(struct vrf *vrf)
686 {
687 struct isis *isis;
688 vrf_id_t old_vrf_id = VRF_UNKNOWN;
689
690 if (vrf->vrf_id == VRF_DEFAULT)
691 return 0;
692
693 if (IS_DEBUG_EVENTS)
694 zlog_debug("%s: VRF %s id %d disabled.", __func__, vrf->name,
695 vrf->vrf_id);
696 isis = isis_lookup_by_vrfname(vrf->name);
697 if (isis) {
698 old_vrf_id = isis->vrf_id;
699
700 isis_zebra_vrf_deregister(isis);
701
702 isis_set_redist_vrf_bitmaps(isis, false);
703
704 /* We have instance configured, unlink
705 * from VRF and make it "down".
706 */
707 isis_vrf_unlink(isis, vrf);
708 if (IS_DEBUG_EVENTS)
709 zlog_debug("%s: isis old_vrf_id %d unlinked", __func__,
710 old_vrf_id);
711 }
712
713 return 0;
714 }
715
716 void isis_vrf_init(void)
717 {
718 vrf_init(isis_vrf_new, isis_vrf_enable, isis_vrf_disable,
719 isis_vrf_delete);
720
721 vrf_cmd_init(NULL);
722 }
723
724 void isis_terminate(void)
725 {
726 struct isis *isis;
727 struct listnode *node, *nnode;
728
729 bfd_protocol_integration_set_shutdown(true);
730
731 if (listcount(im->isis) == 0)
732 return;
733
734 for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
735 isis_finish(isis);
736 }
737
738 void isis_filter_update(struct access_list *access)
739 {
740 struct isis *isis;
741 struct isis_area *area;
742 struct listnode *node, *anode;
743
744 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
745 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
746 for (int i = SPF_PREFIX_PRIO_CRITICAL;
747 i <= SPF_PREFIX_PRIO_MEDIUM; i++) {
748 struct spf_prefix_priority_acl *ppa;
749
750 ppa = &area->spf_prefix_priorities[i];
751 ppa->list_v4 =
752 access_list_lookup(AFI_IP, ppa->name);
753 ppa->list_v6 =
754 access_list_lookup(AFI_IP6, ppa->name);
755 }
756 lsp_regenerate_schedule(area, area->is_type, 0);
757 }
758 }
759 }
760
761 void isis_prefix_list_update(struct prefix_list *plist)
762 {
763 struct isis *isis;
764 struct isis_area *area;
765 struct listnode *node, *anode;
766
767 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
768 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
769 for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS;
770 level++) {
771 const char *plist_name =
772 prefix_list_name(plist);
773
774 if (!area->rlfa_plist_name[level - 1])
775 continue;
776
777 if (!strmatch(area->rlfa_plist_name[level - 1],
778 plist_name))
779 continue;
780
781 area->rlfa_plist[level - 1] =
782 prefix_list_lookup(AFI_IP, plist_name);
783 lsp_regenerate_schedule(area, area->is_type, 0);
784 }
785 }
786 }
787 }
788
789 #ifdef FABRICD
790 static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid,
791 bool enabled)
792 {
793 struct isis_area_mt_setting *setting;
794
795 setting = area_get_mt_setting(area, mtid);
796 if (setting->enabled != enabled) {
797 setting->enabled = enabled;
798 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
799 }
800 }
801
802 static void area_set_mt_overload(struct isis_area *area, uint16_t mtid,
803 bool overload)
804 {
805 struct isis_area_mt_setting *setting;
806
807 setting = area_get_mt_setting(area, mtid);
808 if (setting->overload != overload) {
809 setting->overload = overload;
810 if (setting->enabled)
811 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2,
812 0);
813 }
814 }
815 #endif /* ifdef FABRICD */
816
817 int area_net_title(struct vty *vty, const char *net_title)
818 {
819 VTY_DECLVAR_CONTEXT(isis_area, area);
820 struct iso_address *addr;
821 struct iso_address *addrp;
822 struct listnode *node;
823
824 uint8_t buff[255];
825
826 /* We check that we are not over the maximal number of addresses */
827 if (listcount(area->area_addrs) >= area->isis->max_area_addrs) {
828 vty_out(vty,
829 "Maximum of area addresses (%d) already reached \n",
830 area->isis->max_area_addrs);
831 return CMD_ERR_NOTHING_TODO;
832 }
833
834 addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct iso_address));
835 addr->addr_len = dotformat2buff(buff, net_title);
836 memcpy(addr->area_addr, buff, addr->addr_len);
837 #ifdef EXTREME_DEBUG
838 zlog_debug("added area address %s for area %s (address length %d)",
839 net_title, area->area_tag, addr->addr_len);
840 #endif /* EXTREME_DEBUG */
841 if (addr->addr_len < ISO_ADDR_MIN || addr->addr_len > ISO_ADDR_SIZE) {
842 vty_out(vty,
843 "area address must be at least 8..20 octets long (%d)\n",
844 addr->addr_len);
845 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
846 return CMD_WARNING_CONFIG_FAILED;
847 }
848
849 if (addr->area_addr[addr->addr_len - 1] != 0) {
850 vty_out(vty,
851 "nsel byte (last byte) in area address must be 0\n");
852 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
853 return CMD_WARNING_CONFIG_FAILED;
854 }
855
856 if (area->isis->sysid_set == 0) {
857 /*
858 * First area address - get the SystemID for this router
859 */
860 memcpy(area->isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
861 area->isis->sysid_set = 1;
862 if (IS_DEBUG_EVENTS)
863 zlog_debug("Router has SystemID %pSY",
864 area->isis->sysid);
865 } else {
866 /*
867 * Check that the SystemID portions match
868 */
869 if (memcmp(area->isis->sysid, GETSYSID(addr),
870 ISIS_SYS_ID_LEN)) {
871 vty_out(vty,
872 "System ID must not change when defining additional area addresses\n");
873 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
874 return CMD_WARNING_CONFIG_FAILED;
875 }
876
877 /* now we see that we don't already have this address */
878 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
879 if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN)
880 != (addr->addr_len))
881 continue;
882 if (!memcmp(addrp->area_addr, addr->area_addr,
883 addr->addr_len)) {
884 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
885 return CMD_SUCCESS; /* silent fail */
886 }
887 }
888 }
889
890 /*
891 * Forget the systemID part of the address
892 */
893 addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
894 listnode_add(area->area_addrs, addr);
895
896 /* only now we can safely generate our LSPs for this area */
897 if (listcount(area->area_addrs) > 0) {
898 if (area->is_type & IS_LEVEL_1)
899 lsp_generate(area, IS_LEVEL_1);
900 if (area->is_type & IS_LEVEL_2)
901 lsp_generate(area, IS_LEVEL_2);
902 }
903
904 return CMD_SUCCESS;
905 }
906
907 int area_clear_net_title(struct vty *vty, const char *net_title)
908 {
909 VTY_DECLVAR_CONTEXT(isis_area, area);
910 struct iso_address addr, *addrp = NULL;
911 struct listnode *node;
912 uint8_t buff[255];
913
914 addr.addr_len = dotformat2buff(buff, net_title);
915 if (addr.addr_len < ISO_ADDR_MIN || addr.addr_len > ISO_ADDR_SIZE) {
916 vty_out(vty,
917 "Unsupported area address length %d, should be 8...20 \n",
918 addr.addr_len);
919 return CMD_WARNING_CONFIG_FAILED;
920 }
921
922 memcpy(addr.area_addr, buff, (int)addr.addr_len);
923
924 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp))
925 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
926 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
927 break;
928
929 if (!addrp) {
930 vty_out(vty, "No area address %s for area %s \n", net_title,
931 area->area_tag);
932 return CMD_ERR_NO_MATCH;
933 }
934
935 listnode_delete(area->area_addrs, addrp);
936 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
937
938 /*
939 * Last area address - reset the SystemID for this router
940 */
941 if (listcount(area->area_addrs) == 0) {
942 memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
943 area->isis->sysid_set = 0;
944 if (IS_DEBUG_EVENTS)
945 zlog_debug("Router has no SystemID");
946 }
947
948 return CMD_SUCCESS;
949 }
950
951 /*
952 * 'show isis interface' command
953 */
954 int show_isis_interface_common(struct vty *vty, struct json_object *json,
955 const char *ifname, char detail,
956 const char *vrf_name, bool all_vrf)
957 {
958 if (json) {
959 return show_isis_interface_common_json(json, ifname, detail,
960 vrf_name, all_vrf);
961 } else {
962 return show_isis_interface_common_vty(vty, ifname, detail,
963 vrf_name, all_vrf);
964 }
965 }
966
967 int show_isis_interface_common_json(struct json_object *json,
968 const char *ifname, char detail,
969 const char *vrf_name, bool all_vrf)
970 {
971 struct listnode *anode, *cnode, *inode;
972 struct isis_area *area;
973 struct isis_circuit *circuit;
974 struct isis *isis;
975 struct json_object *areas_json, *area_json;
976 struct json_object *circuits_json, *circuit_json;
977 if (!im) {
978 // IS-IS Routing Process not enabled
979 json_object_string_add(json, "is-is-routing-process-enabled",
980 "no");
981 return CMD_SUCCESS;
982 }
983 if (vrf_name) {
984 if (all_vrf) {
985 for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
986 areas_json = json_object_new_array();
987 json_object_object_add(json, "areas",
988 areas_json);
989 for (ALL_LIST_ELEMENTS_RO(isis->area_list,
990 anode, area)) {
991 area_json = json_object_new_object();
992 json_object_string_add(
993 area_json, "area",
994 area->area_tag ? area->area_tag
995 : "null");
996 circuits_json = json_object_new_array();
997 json_object_object_add(area_json,
998 "circuits",
999 circuits_json);
1000 for (ALL_LIST_ELEMENTS_RO(
1001 area->circuit_list, cnode,
1002 circuit)) {
1003 circuit_json =
1004 json_object_new_object();
1005 json_object_int_add(
1006 circuit_json, "circuit",
1007 circuit->circuit_id);
1008 if (!ifname)
1009 isis_circuit_print_json(
1010 circuit,
1011 circuit_json,
1012 detail);
1013 else if (strcmp(circuit->interface->name, ifname) == 0)
1014 isis_circuit_print_json(
1015 circuit,
1016 circuit_json,
1017 detail);
1018 json_object_array_add(
1019 circuits_json,
1020 circuit_json);
1021 }
1022 json_object_array_add(areas_json,
1023 area_json);
1024 }
1025 }
1026 return CMD_SUCCESS;
1027 }
1028 isis = isis_lookup_by_vrfname(vrf_name);
1029 if (isis != NULL) {
1030 areas_json = json_object_new_array();
1031 json_object_object_add(json, "areas", areas_json);
1032 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
1033 area)) {
1034 area_json = json_object_new_object();
1035 json_object_string_add(area_json, "area",
1036 area->area_tag
1037 ? area->area_tag
1038 : "null");
1039
1040 circuits_json = json_object_new_array();
1041 json_object_object_add(area_json, "circuits",
1042 circuits_json);
1043 for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
1044 cnode, circuit)) {
1045 circuit_json = json_object_new_object();
1046 json_object_int_add(
1047 circuit_json, "circuit",
1048 circuit->circuit_id);
1049 if (!ifname)
1050 isis_circuit_print_json(
1051 circuit, circuit_json,
1052 detail);
1053 else if (
1054 strcmp(circuit->interface->name,
1055 ifname) == 0)
1056 isis_circuit_print_json(
1057 circuit, circuit_json,
1058 detail);
1059 json_object_array_add(circuits_json,
1060 circuit_json);
1061 }
1062 json_object_array_add(areas_json, area_json);
1063 }
1064 }
1065 }
1066 return CMD_SUCCESS;
1067 }
1068
1069 int show_isis_interface_common_vty(struct vty *vty, const char *ifname,
1070 char detail, const char *vrf_name,
1071 bool all_vrf)
1072 {
1073 struct listnode *anode, *cnode, *inode;
1074 struct isis_area *area;
1075 struct isis_circuit *circuit;
1076 struct isis *isis;
1077
1078 if (!im) {
1079 vty_out(vty, "IS-IS Routing Process not enabled\n");
1080 return CMD_SUCCESS;
1081 }
1082 if (vrf_name) {
1083 if (all_vrf) {
1084 for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
1085 for (ALL_LIST_ELEMENTS_RO(isis->area_list,
1086 anode, area)) {
1087 vty_out(vty, "Area %s:\n",
1088 area->area_tag);
1089
1090 if (detail == ISIS_UI_LEVEL_BRIEF)
1091 vty_out(vty,
1092 " Interface CircId State Type Level\n");
1093
1094 for (ALL_LIST_ELEMENTS_RO(
1095 area->circuit_list, cnode,
1096 circuit))
1097 if (!ifname)
1098 isis_circuit_print_vty(
1099 circuit, vty,
1100 detail);
1101 else if (strcmp(circuit->interface->name, ifname) == 0)
1102 isis_circuit_print_vty(
1103 circuit, vty,
1104 detail);
1105 }
1106 }
1107 return CMD_SUCCESS;
1108 }
1109 isis = isis_lookup_by_vrfname(vrf_name);
1110 if (isis != NULL) {
1111 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
1112 area)) {
1113 vty_out(vty, "Area %s:\n", area->area_tag);
1114
1115 if (detail == ISIS_UI_LEVEL_BRIEF)
1116 vty_out(vty,
1117 " Interface CircId State Type Level\n");
1118
1119 for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
1120 cnode, circuit))
1121 if (!ifname)
1122 isis_circuit_print_vty(
1123 circuit, vty, detail);
1124 else if (
1125 strcmp(circuit->interface->name,
1126 ifname) == 0)
1127 isis_circuit_print_vty(
1128 circuit, vty, detail);
1129 }
1130 }
1131 }
1132
1133 return CMD_SUCCESS;
1134 }
1135
1136 DEFUN(show_isis_interface,
1137 show_isis_interface_cmd,
1138 "show " PROTO_NAME " [vrf <NAME|all>] interface [json]",
1139 SHOW_STR
1140 PROTO_HELP
1141 VRF_CMD_HELP_STR
1142 "All VRFs\n"
1143 "json output\n"
1144 "IS-IS interface\n")
1145 {
1146 int res = CMD_SUCCESS;
1147 const char *vrf_name = VRF_DEFAULT_NAME;
1148 bool all_vrf = false;
1149 int idx_vrf = 0;
1150 bool uj = use_json(argc, argv);
1151 json_object *json = NULL;
1152
1153 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1154 if (uj)
1155 json = json_object_new_object();
1156 res = show_isis_interface_common(vty, json, NULL, ISIS_UI_LEVEL_BRIEF,
1157 vrf_name, all_vrf);
1158 if (uj)
1159 vty_json(vty, json);
1160 return res;
1161 }
1162
1163 DEFUN(show_isis_interface_detail,
1164 show_isis_interface_detail_cmd,
1165 "show " PROTO_NAME " [vrf <NAME|all>] interface detail [json]",
1166 SHOW_STR
1167 PROTO_HELP
1168 VRF_CMD_HELP_STR
1169 "All VRFs\n"
1170 "IS-IS interface\n"
1171 "show detailed information\n"
1172 "json output\n")
1173 {
1174 int res = CMD_SUCCESS;
1175 const char *vrf_name = VRF_DEFAULT_NAME;
1176 bool all_vrf = false;
1177 int idx_vrf = 0;
1178 bool uj = use_json(argc, argv);
1179 json_object *json = NULL;
1180
1181 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1182 if (uj)
1183 json = json_object_new_object();
1184 res = show_isis_interface_common(vty, json, NULL, ISIS_UI_LEVEL_DETAIL,
1185 vrf_name, all_vrf);
1186 if (uj)
1187 vty_json(vty, json);
1188 return res;
1189 }
1190
1191 DEFUN(show_isis_interface_arg,
1192 show_isis_interface_arg_cmd,
1193 "show " PROTO_NAME " [vrf <NAME|all>] interface WORD [json]",
1194 SHOW_STR
1195 PROTO_HELP
1196 VRF_CMD_HELP_STR
1197 "All VRFs\n"
1198 "IS-IS interface\n"
1199 "IS-IS interface name\n"
1200 "json output\n")
1201 {
1202 int res = CMD_SUCCESS;
1203 int idx_word = 0;
1204 const char *vrf_name = VRF_DEFAULT_NAME;
1205 bool all_vrf = false;
1206 int idx_vrf = 0;
1207 bool uj = use_json(argc, argv);
1208 json_object *json = NULL;
1209
1210 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1211 if (uj)
1212 json = json_object_new_object();
1213
1214 char *ifname = argv_find(argv, argc, "WORD", &idx_word)
1215 ? argv[idx_word]->arg
1216 : NULL;
1217 res = show_isis_interface_common(
1218 vty, json, ifname, ISIS_UI_LEVEL_DETAIL, vrf_name, all_vrf);
1219 if (uj)
1220 vty_json(vty, json);
1221 return res;
1222 }
1223
1224 static int id_to_sysid(struct isis *isis, const char *id, uint8_t *sysid)
1225 {
1226 struct isis_dynhn *dynhn;
1227
1228 memset(sysid, 0, ISIS_SYS_ID_LEN);
1229 if (id) {
1230 if (sysid2buff(sysid, id) == 0) {
1231 dynhn = dynhn_find_by_name(isis, id);
1232 if (dynhn == NULL)
1233 return -1;
1234 memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
1235 }
1236 }
1237
1238 return 0;
1239 }
1240
1241 static void isis_neighbor_common_json(struct json_object *json, const char *id,
1242 char detail, struct isis *isis,
1243 uint8_t *sysid)
1244 {
1245 struct listnode *anode, *cnode, *node;
1246 struct isis_area *area;
1247 struct isis_circuit *circuit;
1248 struct list *adjdb;
1249 struct isis_adjacency *adj;
1250 struct json_object *areas_json, *area_json;
1251 struct json_object *circuits_json, *circuit_json;
1252 int i;
1253
1254 areas_json = json_object_new_array();
1255 json_object_object_add(json, "areas", areas_json);
1256 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
1257 area_json = json_object_new_object();
1258 json_object_string_add(area_json, "area",
1259 area->area_tag ? area->area_tag
1260 : "null");
1261 circuits_json = json_object_new_array();
1262 json_object_object_add(area_json, "circuits", circuits_json);
1263 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
1264 circuit_json = json_object_new_object();
1265 json_object_int_add(circuit_json, "circuit",
1266 circuit->circuit_id);
1267 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
1268 for (i = 0; i < 2; i++) {
1269 adjdb = circuit->u.bc.adjdb[i];
1270 if (adjdb && adjdb->count) {
1271 for (ALL_LIST_ELEMENTS_RO(
1272 adjdb, node, adj))
1273 if (!id ||
1274 !memcmp(adj->sysid,
1275 sysid,
1276 ISIS_SYS_ID_LEN))
1277 isis_adj_print_json(
1278 adj,
1279 circuit_json,
1280 detail);
1281 }
1282 }
1283 } else if (circuit->circ_type == CIRCUIT_T_P2P &&
1284 circuit->u.p2p.neighbor) {
1285 adj = circuit->u.p2p.neighbor;
1286 if (!id ||
1287 !memcmp(adj->sysid, sysid, ISIS_SYS_ID_LEN))
1288 isis_adj_print_json(adj, circuit_json,
1289 detail);
1290 }
1291 json_object_array_add(circuits_json, circuit_json);
1292 }
1293 json_object_array_add(areas_json, area_json);
1294 }
1295 }
1296
1297 static void isis_neighbor_common_vty(struct vty *vty, const char *id,
1298 char detail, struct isis *isis,
1299 uint8_t *sysid)
1300 {
1301 struct listnode *anode, *cnode, *node;
1302 struct isis_area *area;
1303 struct isis_circuit *circuit;
1304 struct list *adjdb;
1305 struct isis_adjacency *adj;
1306 int i;
1307
1308 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
1309 vty_out(vty, "Area %s:\n", area->area_tag);
1310
1311 if (detail == ISIS_UI_LEVEL_BRIEF)
1312 vty_out(vty,
1313 " System Id Interface L State Holdtime SNPA\n");
1314
1315 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
1316 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
1317 for (i = 0; i < 2; i++) {
1318 adjdb = circuit->u.bc.adjdb[i];
1319 if (adjdb && adjdb->count) {
1320 for (ALL_LIST_ELEMENTS_RO(
1321 adjdb, node, adj))
1322 if (!id ||
1323 !memcmp(adj->sysid,
1324 sysid,
1325 ISIS_SYS_ID_LEN))
1326 isis_adj_print_vty(
1327 adj,
1328 vty,
1329 detail);
1330 }
1331 }
1332 } else if (circuit->circ_type == CIRCUIT_T_P2P &&
1333 circuit->u.p2p.neighbor) {
1334 adj = circuit->u.p2p.neighbor;
1335 if (!id ||
1336 !memcmp(adj->sysid, sysid, ISIS_SYS_ID_LEN))
1337 isis_adj_print_vty(adj, vty, detail);
1338 }
1339 }
1340 }
1341 }
1342
1343 static void isis_neighbor_common(struct vty *vty, struct json_object *json,
1344 const char *id, char detail, struct isis *isis,
1345 uint8_t *sysid)
1346 {
1347 if (json) {
1348 isis_neighbor_common_json(json, id, detail,isis,sysid);
1349 } else {
1350 isis_neighbor_common_vty(vty, id, detail,isis,sysid);
1351 }
1352 }
1353
1354 /*
1355 * 'show isis neighbor' command
1356 */
1357
1358 int show_isis_neighbor_common(struct vty *vty, struct json_object *json,
1359 const char *id, char detail, const char *vrf_name,
1360 bool all_vrf)
1361 {
1362 struct listnode *node;
1363 uint8_t sysid[ISIS_SYS_ID_LEN];
1364 struct isis *isis;
1365
1366 if (!im) {
1367 vty_out(vty, "IS-IS Routing Process not enabled\n");
1368 return CMD_SUCCESS;
1369 }
1370
1371 if (vrf_name) {
1372 if (all_vrf) {
1373 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
1374 if (id_to_sysid(isis, id, sysid)) {
1375 vty_out(vty, "Invalid system id %s\n",
1376 id);
1377 return CMD_SUCCESS;
1378 }
1379 isis_neighbor_common(vty, json, id, detail,
1380 isis, sysid);
1381 }
1382 return CMD_SUCCESS;
1383 }
1384 isis = isis_lookup_by_vrfname(vrf_name);
1385 if (isis != NULL) {
1386 if (id_to_sysid(isis, id, sysid)) {
1387 vty_out(vty, "Invalid system id %s\n", id);
1388 return CMD_SUCCESS;
1389 }
1390 isis_neighbor_common(vty, json, id, detail, isis,
1391 sysid);
1392 }
1393 }
1394
1395 return CMD_SUCCESS;
1396 }
1397
1398 static void isis_neighbor_common_clear(struct vty *vty, const char *id,
1399 uint8_t *sysid, struct isis *isis)
1400 {
1401 struct listnode *anode, *cnode, *node, *nnode;
1402 struct isis_area *area;
1403 struct isis_circuit *circuit;
1404 struct list *adjdb;
1405 struct isis_adjacency *adj;
1406 int i;
1407
1408 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
1409 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
1410 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
1411 for (i = 0; i < 2; i++) {
1412 adjdb = circuit->u.bc.adjdb[i];
1413 if (adjdb && adjdb->count) {
1414 for (ALL_LIST_ELEMENTS(
1415 adjdb, node, nnode,
1416 adj))
1417 if (!id
1418 || !memcmp(
1419 adj->sysid,
1420 sysid,
1421 ISIS_SYS_ID_LEN))
1422 isis_adj_state_change(
1423 &adj,
1424 ISIS_ADJ_DOWN,
1425 "clear user request");
1426 }
1427 }
1428 } else if (circuit->circ_type == CIRCUIT_T_P2P
1429 && circuit->u.p2p.neighbor) {
1430 adj = circuit->u.p2p.neighbor;
1431 if (!id
1432 || !memcmp(adj->sysid, sysid,
1433 ISIS_SYS_ID_LEN))
1434 isis_adj_state_change(
1435 &adj, ISIS_ADJ_DOWN,
1436 "clear user request");
1437 }
1438 }
1439 }
1440 }
1441 /*
1442 * 'clear isis neighbor' command
1443 */
1444 int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
1445 bool all_vrf)
1446 {
1447 struct listnode *node;
1448 uint8_t sysid[ISIS_SYS_ID_LEN];
1449 struct isis *isis;
1450
1451 if (!im) {
1452 vty_out(vty, "IS-IS Routing Process not enabled\n");
1453 return CMD_SUCCESS;
1454 }
1455
1456 if (vrf_name) {
1457 if (all_vrf) {
1458 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
1459 if (id_to_sysid(isis, id, sysid)) {
1460 vty_out(vty, "Invalid system id %s\n",
1461 id);
1462 return CMD_SUCCESS;
1463 }
1464 isis_neighbor_common_clear(vty, id, sysid,
1465 isis);
1466 }
1467 return CMD_SUCCESS;
1468 }
1469 isis = isis_lookup_by_vrfname(vrf_name);
1470 if (isis != NULL) {
1471 if (id_to_sysid(isis, id, sysid)) {
1472 vty_out(vty, "Invalid system id %s\n", id);
1473 return CMD_SUCCESS;
1474 }
1475 isis_neighbor_common_clear(vty, id, sysid, isis);
1476 }
1477 }
1478
1479 return CMD_SUCCESS;
1480 }
1481
1482 DEFUN(show_isis_neighbor,
1483 show_isis_neighbor_cmd,
1484 "show " PROTO_NAME " [vrf <NAME|all>] neighbor [json]",
1485 SHOW_STR
1486 PROTO_HELP
1487 VRF_CMD_HELP_STR
1488 "All vrfs\n"
1489 "IS-IS neighbor adjacencies\n"
1490 "json output\n")
1491 {
1492 int res = CMD_SUCCESS;
1493 const char *vrf_name = VRF_DEFAULT_NAME;
1494 bool all_vrf = false;
1495 int idx_vrf = 0;
1496 bool uj = use_json(argc, argv);
1497 json_object *json = NULL;
1498
1499 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1500 if (uj)
1501 json = json_object_new_object();
1502 res = show_isis_neighbor_common(vty, json, NULL, ISIS_UI_LEVEL_BRIEF,
1503 vrf_name, all_vrf);
1504 if (uj)
1505 vty_json(vty, json);
1506 return res;
1507 }
1508
1509 DEFUN(show_isis_neighbor_detail,
1510 show_isis_neighbor_detail_cmd,
1511 "show " PROTO_NAME " [vrf <NAME|all>] neighbor detail [json]",
1512 SHOW_STR
1513 PROTO_HELP
1514 VRF_CMD_HELP_STR
1515 "all vrfs\n"
1516 "IS-IS neighbor adjacencies\n"
1517 "show detailed information\n"
1518 "json output\n")
1519 {
1520 int res = CMD_SUCCESS;
1521 const char *vrf_name = VRF_DEFAULT_NAME;
1522 bool all_vrf = false;
1523 int idx_vrf = 0;
1524 bool uj = use_json(argc, argv);
1525 json_object *json = NULL;
1526
1527 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1528 if (uj)
1529 json = json_object_new_object();
1530
1531 res = show_isis_neighbor_common(vty, json, NULL, ISIS_UI_LEVEL_DETAIL,
1532 vrf_name, all_vrf);
1533 if (uj)
1534 vty_json(vty, json);
1535 return res;
1536 }
1537
1538 DEFUN(show_isis_neighbor_arg,
1539 show_isis_neighbor_arg_cmd,
1540 "show " PROTO_NAME " [vrf <NAME|all>] neighbor WORD [json]",
1541 SHOW_STR
1542 PROTO_HELP
1543 VRF_CMD_HELP_STR
1544 "All vrfs\n"
1545 "IS-IS neighbor adjacencies\n"
1546 "System id\n"
1547 "json output\n")
1548 {
1549 int res = CMD_SUCCESS;
1550 int idx_word = 0;
1551 const char *vrf_name = VRF_DEFAULT_NAME;
1552 bool all_vrf = false;
1553 int idx_vrf = 0;
1554 bool uj = use_json(argc, argv);
1555 json_object *json = NULL;
1556
1557 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1558 if (uj)
1559 json = json_object_new_object();
1560 char *id = argv_find(argv, argc, "WORD", &idx_word)
1561 ? argv[idx_word]->arg
1562 : NULL;
1563
1564 res = show_isis_neighbor_common(vty, json, id, ISIS_UI_LEVEL_DETAIL,
1565 vrf_name, all_vrf);
1566 if (uj)
1567 vty_json(vty, json);
1568 return res;
1569 }
1570
1571 DEFUN(clear_isis_neighbor,
1572 clear_isis_neighbor_cmd,
1573 "clear " PROTO_NAME " [vrf <NAME|all>] neighbor",
1574 CLEAR_STR
1575 PROTO_HELP
1576 VRF_CMD_HELP_STR
1577 "All vrfs\n"
1578 "IS-IS neighbor adjacencies\n")
1579 {
1580 const char *vrf_name = VRF_DEFAULT_NAME;
1581 bool all_vrf = false;
1582 int idx_vrf = 0;
1583
1584 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1585 return clear_isis_neighbor_common(vty, NULL, vrf_name, all_vrf);
1586 }
1587
1588 DEFUN(clear_isis_neighbor_arg,
1589 clear_isis_neighbor_arg_cmd,
1590 "clear " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
1591 CLEAR_STR
1592 PROTO_HELP
1593 VRF_CMD_HELP_STR
1594 "All vrfs\n"
1595 "IS-IS neighbor adjacencies\n"
1596 "System id\n")
1597 {
1598 int idx_word = 0;
1599 const char *vrf_name = VRF_DEFAULT_NAME;
1600 bool all_vrf = false;
1601 int idx_vrf = 0;
1602
1603 char *id = argv_find(argv, argc, "WORD", &idx_word)
1604 ? argv[idx_word]->arg
1605 : NULL;
1606 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1607 return clear_isis_neighbor_common(vty, id, vrf_name, all_vrf);
1608 }
1609
1610 /*
1611 * 'isis debug', 'show debugging'
1612 */
1613 void print_debug(struct vty *vty, int flags, int onoff)
1614 {
1615 const char *onoffs = onoff ? "on" : "off";
1616
1617 if (flags & DEBUG_ADJ_PACKETS)
1618 vty_out(vty,
1619 "IS-IS Adjacency related packets debugging is %s\n",
1620 onoffs);
1621 if (flags & DEBUG_TX_QUEUE)
1622 vty_out(vty, "IS-IS TX queue debugging is %s\n",
1623 onoffs);
1624 if (flags & DEBUG_SNP_PACKETS)
1625 vty_out(vty, "IS-IS CSNP/PSNP packets debugging is %s\n",
1626 onoffs);
1627 if (flags & DEBUG_SPF_EVENTS)
1628 vty_out(vty, "IS-IS SPF events debugging is %s\n", onoffs);
1629 if (flags & DEBUG_SR)
1630 vty_out(vty, "IS-IS Segment Routing events debugging is %s\n",
1631 onoffs);
1632 if (flags & DEBUG_TE)
1633 vty_out(vty,
1634 "IS-IS Traffic Engineering events debugging is %s\n",
1635 onoffs);
1636 if (flags & DEBUG_LFA)
1637 vty_out(vty, "IS-IS LFA events debugging is %s\n", onoffs);
1638 if (flags & DEBUG_UPDATE_PACKETS)
1639 vty_out(vty, "IS-IS Update related packet debugging is %s\n",
1640 onoffs);
1641 if (flags & DEBUG_RTE_EVENTS)
1642 vty_out(vty, "IS-IS Route related debugging is %s\n", onoffs);
1643 if (flags & DEBUG_EVENTS)
1644 vty_out(vty, "IS-IS Event debugging is %s\n", onoffs);
1645 if (flags & DEBUG_PACKET_DUMP)
1646 vty_out(vty, "IS-IS Packet dump debugging is %s\n", onoffs);
1647 if (flags & DEBUG_LSP_GEN)
1648 vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs);
1649 if (flags & DEBUG_LSP_SCHED)
1650 vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs);
1651 if (flags & DEBUG_FLOODING)
1652 vty_out(vty, "IS-IS Flooding debugging is %s\n", onoffs);
1653 if (flags & DEBUG_BFD)
1654 vty_out(vty, "IS-IS BFD debugging is %s\n", onoffs);
1655 if (flags & DEBUG_LDP_SYNC)
1656 vty_out(vty, "IS-IS ldp-sync debugging is %s\n", onoffs);
1657 }
1658
1659 DEFUN_NOSH (show_debugging,
1660 show_debugging_isis_cmd,
1661 "show debugging [" PROTO_NAME "]",
1662 SHOW_STR
1663 "State of each debugging option\n"
1664 PROTO_HELP)
1665 {
1666 vty_out(vty, PROTO_NAME " debugging status:\n");
1667
1668 if (IS_DEBUG_ADJ_PACKETS)
1669 print_debug(vty, DEBUG_ADJ_PACKETS, 1);
1670 if (IS_DEBUG_TX_QUEUE)
1671 print_debug(vty, DEBUG_TX_QUEUE, 1);
1672 if (IS_DEBUG_SNP_PACKETS)
1673 print_debug(vty, DEBUG_SNP_PACKETS, 1);
1674 if (IS_DEBUG_SPF_EVENTS)
1675 print_debug(vty, DEBUG_SPF_EVENTS, 1);
1676 if (IS_DEBUG_SR)
1677 print_debug(vty, DEBUG_SR, 1);
1678 if (IS_DEBUG_TE)
1679 print_debug(vty, DEBUG_TE, 1);
1680 if (IS_DEBUG_UPDATE_PACKETS)
1681 print_debug(vty, DEBUG_UPDATE_PACKETS, 1);
1682 if (IS_DEBUG_RTE_EVENTS)
1683 print_debug(vty, DEBUG_RTE_EVENTS, 1);
1684 if (IS_DEBUG_EVENTS)
1685 print_debug(vty, DEBUG_EVENTS, 1);
1686 if (IS_DEBUG_PACKET_DUMP)
1687 print_debug(vty, DEBUG_PACKET_DUMP, 1);
1688 if (IS_DEBUG_LSP_GEN)
1689 print_debug(vty, DEBUG_LSP_GEN, 1);
1690 if (IS_DEBUG_LSP_SCHED)
1691 print_debug(vty, DEBUG_LSP_SCHED, 1);
1692 if (IS_DEBUG_FLOODING)
1693 print_debug(vty, DEBUG_FLOODING, 1);
1694 if (IS_DEBUG_BFD)
1695 print_debug(vty, DEBUG_BFD, 1);
1696 if (IS_DEBUG_LDP_SYNC)
1697 print_debug(vty, DEBUG_LDP_SYNC, 1);
1698 if (IS_DEBUG_LFA)
1699 print_debug(vty, DEBUG_LFA, 1);
1700
1701 cmd_show_lib_debugs(vty);
1702
1703 return CMD_SUCCESS;
1704 }
1705
1706 static int config_write_debug(struct vty *vty);
1707 /* Debug node. */
1708 static struct cmd_node debug_node = {
1709 .name = "debug",
1710 .node = DEBUG_NODE,
1711 .prompt = "",
1712 .config_write = config_write_debug,
1713 };
1714
1715 static int config_write_debug(struct vty *vty)
1716 {
1717 int write = 0;
1718
1719 if (IS_DEBUG_ADJ_PACKETS) {
1720 vty_out(vty, "debug " PROTO_NAME " adj-packets\n");
1721 write++;
1722 }
1723 if (IS_DEBUG_TX_QUEUE) {
1724 vty_out(vty, "debug " PROTO_NAME " tx-queue\n");
1725 write++;
1726 }
1727 if (IS_DEBUG_SNP_PACKETS) {
1728 vty_out(vty, "debug " PROTO_NAME " snp-packets\n");
1729 write++;
1730 }
1731 if (IS_DEBUG_SPF_EVENTS) {
1732 vty_out(vty, "debug " PROTO_NAME " spf-events\n");
1733 write++;
1734 }
1735 if (IS_DEBUG_SR) {
1736 vty_out(vty, "debug " PROTO_NAME " sr-events\n");
1737 write++;
1738 }
1739 if (IS_DEBUG_TE) {
1740 vty_out(vty, "debug " PROTO_NAME " te-events\n");
1741 write++;
1742 }
1743 if (IS_DEBUG_LFA) {
1744 vty_out(vty, "debug " PROTO_NAME " lfa\n");
1745 write++;
1746 }
1747 if (IS_DEBUG_UPDATE_PACKETS) {
1748 vty_out(vty, "debug " PROTO_NAME " update-packets\n");
1749 write++;
1750 }
1751 if (IS_DEBUG_RTE_EVENTS) {
1752 vty_out(vty, "debug " PROTO_NAME " route-events\n");
1753 write++;
1754 }
1755 if (IS_DEBUG_EVENTS) {
1756 vty_out(vty, "debug " PROTO_NAME " events\n");
1757 write++;
1758 }
1759 if (IS_DEBUG_PACKET_DUMP) {
1760 vty_out(vty, "debug " PROTO_NAME " packet-dump\n");
1761 write++;
1762 }
1763 if (IS_DEBUG_LSP_GEN) {
1764 vty_out(vty, "debug " PROTO_NAME " lsp-gen\n");
1765 write++;
1766 }
1767 if (IS_DEBUG_LSP_SCHED) {
1768 vty_out(vty, "debug " PROTO_NAME " lsp-sched\n");
1769 write++;
1770 }
1771 if (IS_DEBUG_FLOODING) {
1772 vty_out(vty, "debug " PROTO_NAME " flooding\n");
1773 write++;
1774 }
1775 if (IS_DEBUG_BFD) {
1776 vty_out(vty, "debug " PROTO_NAME " bfd\n");
1777 write++;
1778 }
1779 if (IS_DEBUG_LDP_SYNC) {
1780 vty_out(vty, "debug " PROTO_NAME " ldp-sync\n");
1781 write++;
1782 }
1783 write += spf_backoff_write_config(vty);
1784
1785 return write;
1786 }
1787
1788 DEFUN (debug_isis_adj,
1789 debug_isis_adj_cmd,
1790 "debug " PROTO_NAME " adj-packets",
1791 DEBUG_STR
1792 PROTO_HELP
1793 "IS-IS Adjacency related packets\n")
1794 {
1795 debug_adj_pkt |= DEBUG_ADJ_PACKETS;
1796 print_debug(vty, DEBUG_ADJ_PACKETS, 1);
1797
1798 return CMD_SUCCESS;
1799 }
1800
1801 DEFUN (no_debug_isis_adj,
1802 no_debug_isis_adj_cmd,
1803 "no debug " PROTO_NAME " adj-packets",
1804 NO_STR
1805 UNDEBUG_STR
1806 PROTO_HELP
1807 "IS-IS Adjacency related packets\n")
1808 {
1809 debug_adj_pkt &= ~DEBUG_ADJ_PACKETS;
1810 print_debug(vty, DEBUG_ADJ_PACKETS, 0);
1811
1812 return CMD_SUCCESS;
1813 }
1814
1815 DEFUN (debug_isis_tx_queue,
1816 debug_isis_tx_queue_cmd,
1817 "debug " PROTO_NAME " tx-queue",
1818 DEBUG_STR
1819 PROTO_HELP
1820 "IS-IS TX queues\n")
1821 {
1822 debug_tx_queue |= DEBUG_TX_QUEUE;
1823 print_debug(vty, DEBUG_TX_QUEUE, 1);
1824
1825 return CMD_SUCCESS;
1826 }
1827
1828 DEFUN (no_debug_isis_tx_queue,
1829 no_debug_isis_tx_queue_cmd,
1830 "no debug " PROTO_NAME " tx-queue",
1831 NO_STR
1832 UNDEBUG_STR
1833 PROTO_HELP
1834 "IS-IS TX queues\n")
1835 {
1836 debug_tx_queue &= ~DEBUG_TX_QUEUE;
1837 print_debug(vty, DEBUG_TX_QUEUE, 0);
1838
1839 return CMD_SUCCESS;
1840 }
1841
1842 DEFUN (debug_isis_flooding,
1843 debug_isis_flooding_cmd,
1844 "debug " PROTO_NAME " flooding",
1845 DEBUG_STR
1846 PROTO_HELP
1847 "Flooding algorithm\n")
1848 {
1849 debug_flooding |= DEBUG_FLOODING;
1850 print_debug(vty, DEBUG_FLOODING, 1);
1851
1852 return CMD_SUCCESS;
1853 }
1854
1855 DEFUN (no_debug_isis_flooding,
1856 no_debug_isis_flooding_cmd,
1857 "no debug " PROTO_NAME " flooding",
1858 NO_STR
1859 UNDEBUG_STR
1860 PROTO_HELP
1861 "Flooding algorithm\n")
1862 {
1863 debug_flooding &= ~DEBUG_FLOODING;
1864 print_debug(vty, DEBUG_FLOODING, 0);
1865
1866 return CMD_SUCCESS;
1867 }
1868
1869 DEFUN (debug_isis_snp,
1870 debug_isis_snp_cmd,
1871 "debug " PROTO_NAME " snp-packets",
1872 DEBUG_STR
1873 PROTO_HELP
1874 "IS-IS CSNP/PSNP packets\n")
1875 {
1876 debug_snp_pkt |= DEBUG_SNP_PACKETS;
1877 print_debug(vty, DEBUG_SNP_PACKETS, 1);
1878
1879 return CMD_SUCCESS;
1880 }
1881
1882 DEFUN (no_debug_isis_snp,
1883 no_debug_isis_snp_cmd,
1884 "no debug " PROTO_NAME " snp-packets",
1885 NO_STR
1886 UNDEBUG_STR
1887 PROTO_HELP
1888 "IS-IS CSNP/PSNP packets\n")
1889 {
1890 debug_snp_pkt &= ~DEBUG_SNP_PACKETS;
1891 print_debug(vty, DEBUG_SNP_PACKETS, 0);
1892
1893 return CMD_SUCCESS;
1894 }
1895
1896 DEFUN (debug_isis_upd,
1897 debug_isis_upd_cmd,
1898 "debug " PROTO_NAME " update-packets",
1899 DEBUG_STR
1900 PROTO_HELP
1901 "IS-IS Update related packets\n")
1902 {
1903 debug_update_pkt |= DEBUG_UPDATE_PACKETS;
1904 print_debug(vty, DEBUG_UPDATE_PACKETS, 1);
1905
1906 return CMD_SUCCESS;
1907 }
1908
1909 DEFUN (no_debug_isis_upd,
1910 no_debug_isis_upd_cmd,
1911 "no debug " PROTO_NAME " update-packets",
1912 NO_STR
1913 UNDEBUG_STR
1914 PROTO_HELP
1915 "IS-IS Update related packets\n")
1916 {
1917 debug_update_pkt &= ~DEBUG_UPDATE_PACKETS;
1918 print_debug(vty, DEBUG_UPDATE_PACKETS, 0);
1919
1920 return CMD_SUCCESS;
1921 }
1922
1923 DEFUN (debug_isis_spfevents,
1924 debug_isis_spfevents_cmd,
1925 "debug " PROTO_NAME " spf-events",
1926 DEBUG_STR
1927 PROTO_HELP
1928 "IS-IS Shortest Path First Events\n")
1929 {
1930 debug_spf_events |= DEBUG_SPF_EVENTS;
1931 print_debug(vty, DEBUG_SPF_EVENTS, 1);
1932
1933 return CMD_SUCCESS;
1934 }
1935
1936 DEFUN (no_debug_isis_spfevents,
1937 no_debug_isis_spfevents_cmd,
1938 "no debug " PROTO_NAME " spf-events",
1939 NO_STR
1940 UNDEBUG_STR
1941 PROTO_HELP
1942 "IS-IS Shortest Path First Events\n")
1943 {
1944 debug_spf_events &= ~DEBUG_SPF_EVENTS;
1945 print_debug(vty, DEBUG_SPF_EVENTS, 0);
1946
1947 return CMD_SUCCESS;
1948 }
1949
1950 DEFUN (debug_isis_srevents,
1951 debug_isis_srevents_cmd,
1952 "debug " PROTO_NAME " sr-events",
1953 DEBUG_STR
1954 PROTO_HELP
1955 "IS-IS Segment Routing Events\n")
1956 {
1957 debug_sr |= DEBUG_SR;
1958 print_debug(vty, DEBUG_SR, 1);
1959
1960 return CMD_SUCCESS;
1961 }
1962
1963 DEFUN (no_debug_isis_srevents,
1964 no_debug_isis_srevents_cmd,
1965 "no debug " PROTO_NAME " sr-events",
1966 NO_STR
1967 UNDEBUG_STR
1968 PROTO_HELP
1969 "IS-IS Segment Routing Events\n")
1970 {
1971 debug_sr &= ~DEBUG_SR;
1972 print_debug(vty, DEBUG_SR, 0);
1973
1974 return CMD_SUCCESS;
1975 }
1976
1977 DEFUN (debug_isis_teevents,
1978 debug_isis_teevents_cmd,
1979 "debug " PROTO_NAME " te-events",
1980 DEBUG_STR
1981 PROTO_HELP
1982 "IS-IS Traffic Engineering Events\n")
1983 {
1984 debug_te |= DEBUG_TE;
1985 print_debug(vty, DEBUG_TE, 1);
1986
1987 return CMD_SUCCESS;
1988 }
1989
1990 DEFUN (no_debug_isis_teevents,
1991 no_debug_isis_teevents_cmd,
1992 "no debug " PROTO_NAME " te-events",
1993 NO_STR
1994 UNDEBUG_STR
1995 PROTO_HELP
1996 "IS-IS Traffic Engineering Events\n")
1997 {
1998 debug_te &= ~DEBUG_TE;
1999 print_debug(vty, DEBUG_TE, 0);
2000
2001 return CMD_SUCCESS;
2002 }
2003
2004 DEFUN (debug_isis_lfa,
2005 debug_isis_lfa_cmd,
2006 "debug " PROTO_NAME " lfa",
2007 DEBUG_STR
2008 PROTO_HELP
2009 "IS-IS LFA Events\n")
2010 {
2011 debug_lfa |= DEBUG_LFA;
2012 print_debug(vty, DEBUG_LFA, 1);
2013
2014 return CMD_SUCCESS;
2015 }
2016
2017 DEFUN (no_debug_isis_lfa,
2018 no_debug_isis_lfa_cmd,
2019 "no debug " PROTO_NAME " lfa",
2020 NO_STR
2021 UNDEBUG_STR
2022 PROTO_HELP
2023 "IS-IS LFA Events\n")
2024 {
2025 debug_lfa &= ~DEBUG_LFA;
2026 print_debug(vty, DEBUG_LFA, 0);
2027
2028 return CMD_SUCCESS;
2029 }
2030
2031 DEFUN (debug_isis_rtevents,
2032 debug_isis_rtevents_cmd,
2033 "debug " PROTO_NAME " route-events",
2034 DEBUG_STR
2035 PROTO_HELP
2036 "IS-IS Route related events\n")
2037 {
2038 debug_rte_events |= DEBUG_RTE_EVENTS;
2039 print_debug(vty, DEBUG_RTE_EVENTS, 1);
2040
2041 return CMD_SUCCESS;
2042 }
2043
2044 DEFUN (no_debug_isis_rtevents,
2045 no_debug_isis_rtevents_cmd,
2046 "no debug " PROTO_NAME " route-events",
2047 NO_STR
2048 UNDEBUG_STR
2049 PROTO_HELP
2050 "IS-IS Route related events\n")
2051 {
2052 debug_rte_events &= ~DEBUG_RTE_EVENTS;
2053 print_debug(vty, DEBUG_RTE_EVENTS, 0);
2054
2055 return CMD_SUCCESS;
2056 }
2057
2058 DEFUN (debug_isis_events,
2059 debug_isis_events_cmd,
2060 "debug " PROTO_NAME " events",
2061 DEBUG_STR
2062 PROTO_HELP
2063 "IS-IS Events\n")
2064 {
2065 debug_events |= DEBUG_EVENTS;
2066 print_debug(vty, DEBUG_EVENTS, 1);
2067
2068 return CMD_SUCCESS;
2069 }
2070
2071 DEFUN (no_debug_isis_events,
2072 no_debug_isis_events_cmd,
2073 "no debug " PROTO_NAME " events",
2074 NO_STR
2075 UNDEBUG_STR
2076 PROTO_HELP
2077 "IS-IS Events\n")
2078 {
2079 debug_events &= ~DEBUG_EVENTS;
2080 print_debug(vty, DEBUG_EVENTS, 0);
2081
2082 return CMD_SUCCESS;
2083 }
2084
2085 DEFUN (debug_isis_packet_dump,
2086 debug_isis_packet_dump_cmd,
2087 "debug " PROTO_NAME " packet-dump",
2088 DEBUG_STR
2089 PROTO_HELP
2090 "IS-IS packet dump\n")
2091 {
2092 debug_pkt_dump |= DEBUG_PACKET_DUMP;
2093 print_debug(vty, DEBUG_PACKET_DUMP, 1);
2094
2095 return CMD_SUCCESS;
2096 }
2097
2098 DEFUN (no_debug_isis_packet_dump,
2099 no_debug_isis_packet_dump_cmd,
2100 "no debug " PROTO_NAME " packet-dump",
2101 NO_STR
2102 UNDEBUG_STR
2103 PROTO_HELP
2104 "IS-IS packet dump\n")
2105 {
2106 debug_pkt_dump &= ~DEBUG_PACKET_DUMP;
2107 print_debug(vty, DEBUG_PACKET_DUMP, 0);
2108
2109 return CMD_SUCCESS;
2110 }
2111
2112 DEFUN (debug_isis_lsp_gen,
2113 debug_isis_lsp_gen_cmd,
2114 "debug " PROTO_NAME " lsp-gen",
2115 DEBUG_STR
2116 PROTO_HELP
2117 "IS-IS generation of own LSPs\n")
2118 {
2119 debug_lsp_gen |= DEBUG_LSP_GEN;
2120 print_debug(vty, DEBUG_LSP_GEN, 1);
2121
2122 return CMD_SUCCESS;
2123 }
2124
2125 DEFUN (no_debug_isis_lsp_gen,
2126 no_debug_isis_lsp_gen_cmd,
2127 "no debug " PROTO_NAME " lsp-gen",
2128 NO_STR
2129 UNDEBUG_STR
2130 PROTO_HELP
2131 "IS-IS generation of own LSPs\n")
2132 {
2133 debug_lsp_gen &= ~DEBUG_LSP_GEN;
2134 print_debug(vty, DEBUG_LSP_GEN, 0);
2135
2136 return CMD_SUCCESS;
2137 }
2138
2139 DEFUN (debug_isis_lsp_sched,
2140 debug_isis_lsp_sched_cmd,
2141 "debug " PROTO_NAME " lsp-sched",
2142 DEBUG_STR
2143 PROTO_HELP
2144 "IS-IS scheduling of LSP generation\n")
2145 {
2146 debug_lsp_sched |= DEBUG_LSP_SCHED;
2147 print_debug(vty, DEBUG_LSP_SCHED, 1);
2148
2149 return CMD_SUCCESS;
2150 }
2151
2152 DEFUN (no_debug_isis_lsp_sched,
2153 no_debug_isis_lsp_sched_cmd,
2154 "no debug " PROTO_NAME " lsp-sched",
2155 NO_STR
2156 UNDEBUG_STR
2157 PROTO_HELP
2158 "IS-IS scheduling of LSP generation\n")
2159 {
2160 debug_lsp_sched &= ~DEBUG_LSP_SCHED;
2161 print_debug(vty, DEBUG_LSP_SCHED, 0);
2162
2163 return CMD_SUCCESS;
2164 }
2165
2166 DEFUN (debug_isis_bfd,
2167 debug_isis_bfd_cmd,
2168 "debug " PROTO_NAME " bfd",
2169 DEBUG_STR
2170 PROTO_HELP
2171 PROTO_NAME " interaction with BFD\n")
2172 {
2173 debug_bfd |= DEBUG_BFD;
2174 bfd_protocol_integration_set_debug(true);
2175 print_debug(vty, DEBUG_BFD, 1);
2176
2177 return CMD_SUCCESS;
2178 }
2179
2180 DEFUN (no_debug_isis_bfd,
2181 no_debug_isis_bfd_cmd,
2182 "no debug " PROTO_NAME " bfd",
2183 NO_STR
2184 UNDEBUG_STR
2185 PROTO_HELP
2186 PROTO_NAME " interaction with BFD\n")
2187 {
2188 debug_bfd &= ~DEBUG_BFD;
2189 bfd_protocol_integration_set_debug(false);
2190 print_debug(vty, DEBUG_BFD, 0);
2191
2192 return CMD_SUCCESS;
2193 }
2194
2195 DEFUN(debug_isis_ldp_sync, debug_isis_ldp_sync_cmd,
2196 "debug " PROTO_NAME " ldp-sync",
2197 DEBUG_STR PROTO_HELP PROTO_NAME " interaction with LDP-Sync\n")
2198 {
2199 debug_ldp_sync |= DEBUG_LDP_SYNC;
2200 print_debug(vty, DEBUG_LDP_SYNC, 1);
2201
2202 return CMD_SUCCESS;
2203 }
2204
2205 DEFUN(no_debug_isis_ldp_sync, no_debug_isis_ldp_sync_cmd,
2206 "no debug " PROTO_NAME " ldp-sync",
2207 NO_STR UNDEBUG_STR PROTO_HELP PROTO_NAME " interaction with LDP-Sync\n")
2208 {
2209 debug_ldp_sync &= ~DEBUG_LDP_SYNC;
2210 print_debug(vty, DEBUG_LDP_SYNC, 0);
2211
2212 return CMD_SUCCESS;
2213 }
2214
2215 DEFUN (show_hostname,
2216 show_hostname_cmd,
2217 "show " PROTO_NAME " [vrf <NAME|all>] hostname",
2218 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2219 "All VRFs\n"
2220 "IS-IS Dynamic hostname mapping\n")
2221 {
2222 struct listnode *node;
2223 const char *vrf_name = VRF_DEFAULT_NAME;
2224 bool all_vrf = false;
2225 int idx_vrf = 0;
2226 struct isis *isis;
2227
2228 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
2229 if (vrf_name) {
2230 if (all_vrf) {
2231 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2232 dynhn_print_all(vty, isis);
2233
2234 return CMD_SUCCESS;
2235 }
2236 isis = isis_lookup_by_vrfname(vrf_name);
2237 if (isis != NULL)
2238 dynhn_print_all(vty, isis);
2239 }
2240
2241 return CMD_SUCCESS;
2242 }
2243
2244 static void isis_spf_ietf_common(struct vty *vty, struct isis *isis)
2245 {
2246 struct listnode *node;
2247 struct isis_area *area;
2248 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2249
2250 vty_out(vty, "vrf : %s\n", isis->name);
2251 vty_out(vty, "Area %s:\n",
2252 area->area_tag ? area->area_tag : "null");
2253
2254 for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
2255 if ((area->is_type & level) == 0)
2256 continue;
2257
2258 vty_out(vty, " Level-%d:\n", level);
2259 vty_out(vty, " SPF delay status: ");
2260 if (area->spf_timer[level - 1]) {
2261 struct timeval remain = event_timer_remain(
2262 area->spf_timer[level - 1]);
2263 vty_out(vty, "Pending, due in %lld msec\n",
2264 (long long)remain.tv_sec * 1000
2265 + remain.tv_usec / 1000);
2266 } else {
2267 vty_out(vty, "Not scheduled\n");
2268 }
2269
2270 if (area->spf_delay_ietf[level - 1]) {
2271 vty_out(vty,
2272 " Using draft-ietf-rtgwg-backoff-algo-04\n");
2273 spf_backoff_show(
2274 area->spf_delay_ietf[level - 1], vty,
2275 " ");
2276 } else {
2277 vty_out(vty, " Using legacy backoff algo\n");
2278 }
2279 }
2280 }
2281 }
2282
2283 DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
2284 "show " PROTO_NAME " [vrf <NAME|all>] spf-delay-ietf",
2285 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2286 "All VRFs\n"
2287 "SPF delay IETF information\n")
2288 {
2289 struct listnode *node;
2290 struct isis *isis;
2291 int idx_vrf = 0;
2292 const char *vrf_name = VRF_DEFAULT_NAME;
2293 bool all_vrf = false;
2294
2295 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
2296
2297 if (!im) {
2298 vty_out(vty, "ISIS is not running\n");
2299 return CMD_SUCCESS;
2300 }
2301
2302 if (vrf_name) {
2303 if (all_vrf) {
2304 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2305 isis_spf_ietf_common(vty, isis);
2306
2307 return CMD_SUCCESS;
2308 }
2309 isis = isis_lookup_by_vrfname(vrf_name);
2310 if (isis != NULL)
2311 isis_spf_ietf_common(vty, isis);
2312 }
2313
2314 return CMD_SUCCESS;
2315 }
2316
2317
2318 static const char *pdu_counter_index_to_name_json(enum pdu_counter_index index)
2319 {
2320 switch (index) {
2321 case L1_LAN_HELLO_INDEX:
2322 return "l1-iih";
2323 case L2_LAN_HELLO_INDEX:
2324 return "l2-iih";
2325 case P2P_HELLO_INDEX:
2326 return "p2p-iih";
2327 case L1_LINK_STATE_INDEX:
2328 return "l1-lsp";
2329 case L2_LINK_STATE_INDEX:
2330 return "l2-lsp";
2331 case FS_LINK_STATE_INDEX:
2332 return "fs-lsp";
2333 case L1_COMPLETE_SEQ_NUM_INDEX:
2334 return "l1-csnp";
2335 case L2_COMPLETE_SEQ_NUM_INDEX:
2336 return "l2-csnp";
2337 case L1_PARTIAL_SEQ_NUM_INDEX:
2338 return "l1-psnp";
2339 case L2_PARTIAL_SEQ_NUM_INDEX:
2340 return "l2-psnp";
2341 case PDU_COUNTER_SIZE:
2342 return "???????";
2343 }
2344
2345 assert(!"Reached end of function where we are not expecting to");
2346 }
2347
2348 static void common_isis_summary_json(struct json_object *json,
2349 struct isis *isis)
2350 {
2351 int level;
2352 json_object *areas_json, *area_json, *tx_pdu_json, *rx_pdu_json,
2353 *levels_json, *level_json;
2354 struct listnode *node, *node2;
2355 struct isis_area *area;
2356 time_t cur;
2357 char uptime[MONOTIME_STRLEN];
2358 char stier[5];
2359
2360 json_object_string_add(json, "vrf", isis->name);
2361 json_object_int_add(json, "process-id", isis->process_id);
2362 if (isis->sysid_set)
2363 json_object_string_addf(json, "system-id", "%pSY", isis->sysid);
2364
2365 cur = time(NULL);
2366 cur -= isis->uptime;
2367 frrtime_to_interval(cur, uptime, sizeof(uptime));
2368 json_object_string_add(json, "up-time", uptime);
2369 if (isis->area_list)
2370 json_object_int_add(json, "number-areas",
2371 isis->area_list->count);
2372 areas_json = json_object_new_array();
2373 json_object_object_add(json, "areas", areas_json);
2374 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2375 area_json = json_object_new_object();
2376 json_object_string_add(area_json, "area",
2377 area->area_tag ? area->area_tag
2378 : "null");
2379
2380
2381 if (fabricd) {
2382 uint8_t tier = fabricd_tier(area);
2383 snprintfrr(stier, sizeof(stier), "%s", &tier);
2384 json_object_string_add(area_json, "tier",
2385 tier == ISIS_TIER_UNDEFINED
2386 ? "undefined"
2387 : stier);
2388 }
2389
2390 if (listcount(area->area_addrs) > 0) {
2391 struct iso_address *area_addr;
2392 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
2393 area_addr))
2394 json_object_string_addf(area_json, "net",
2395 "%pISl", area_addr);
2396 }
2397
2398 tx_pdu_json = json_object_new_object();
2399 json_object_object_add(area_json, "tx-pdu-type", tx_pdu_json);
2400 for (int i = 0; i < PDU_COUNTER_SIZE; i++) {
2401 if (!area->pdu_tx_counters[i])
2402 continue;
2403 json_object_int_add(tx_pdu_json,
2404 pdu_counter_index_to_name_json(i),
2405 area->pdu_tx_counters[i]);
2406 }
2407 json_object_int_add(tx_pdu_json, "lsp-rxmt",
2408 area->lsp_rxmt_count);
2409
2410 rx_pdu_json = json_object_new_object();
2411 json_object_object_add(area_json, "rx-pdu-type", rx_pdu_json);
2412 for (int i = 0; i < PDU_COUNTER_SIZE; i++) {
2413 if (!area->pdu_rx_counters[i])
2414 continue;
2415 json_object_int_add(rx_pdu_json,
2416 pdu_counter_index_to_name_json(i),
2417 area->pdu_rx_counters[i]);
2418 }
2419
2420 levels_json = json_object_new_array();
2421 json_object_object_add(area_json, "levels", levels_json);
2422 for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
2423 if ((area->is_type & level) == 0)
2424 continue;
2425 level_json = json_object_new_object();
2426 json_object_int_add(level_json, "id", level);
2427 json_object_int_add(level_json, "lsp0-regenerated",
2428 area->lsp_gen_count[level - 1]);
2429 json_object_int_add(level_json, "lsp-purged",
2430 area->lsp_purge_count[level - 1]);
2431 if (area->spf_timer[level - 1])
2432 json_object_string_add(level_json, "spf",
2433 "pending");
2434 else
2435 json_object_string_add(level_json, "spf",
2436 "no pending");
2437 json_object_int_add(level_json, "minimum-interval",
2438 area->min_spf_interval[level - 1]);
2439 if (area->spf_delay_ietf[level - 1])
2440 json_object_string_add(
2441 level_json, "ietf-spf-delay-activated",
2442 "not used");
2443 if (area->ip_circuits) {
2444 isis_spf_print_json(
2445 area->spftree[SPFTREE_IPV4][level - 1],
2446 level_json);
2447 }
2448 if (area->ipv6_circuits) {
2449 isis_spf_print_json(
2450 area->spftree[SPFTREE_IPV6][level - 1],
2451 level_json);
2452 }
2453 json_object_array_add(levels_json, level_json);
2454 }
2455 json_object_array_add(areas_json, area_json);
2456 }
2457 }
2458
2459 static void common_isis_summary_vty(struct vty *vty, struct isis *isis)
2460 {
2461 struct listnode *node, *node2;
2462 struct isis_area *area;
2463 int level;
2464
2465 vty_out(vty, "vrf : %s\n", isis->name);
2466 vty_out(vty, "Process Id : %ld\n", isis->process_id);
2467 if (isis->sysid_set)
2468 vty_out(vty, "System Id : %pSY\n", isis->sysid);
2469
2470 vty_out(vty, "Up time : ");
2471 vty_out_timestr(vty, isis->uptime);
2472 vty_out(vty, "\n");
2473
2474 if (isis->area_list)
2475 vty_out(vty, "Number of areas : %d\n", isis->area_list->count);
2476
2477 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2478 vty_out(vty, "Area %s:\n",
2479 area->area_tag ? area->area_tag : "null");
2480
2481 if (fabricd) {
2482 uint8_t tier = fabricd_tier(area);
2483 if (tier == ISIS_TIER_UNDEFINED)
2484 vty_out(vty, " Tier: undefined\n");
2485 else
2486 vty_out(vty, " Tier: %hhu\n", tier);
2487 }
2488
2489 if (listcount(area->area_addrs) > 0) {
2490 struct iso_address *area_addr;
2491 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
2492 area_addr))
2493 vty_out(vty, " Net: %pISl\n", area_addr);
2494 }
2495
2496 vty_out(vty, " TX counters per PDU type:\n");
2497 pdu_counter_print(vty, " ", area->pdu_tx_counters);
2498 vty_out(vty, " LSP RXMT: %" PRIu64 "\n",
2499 area->lsp_rxmt_count);
2500 vty_out(vty, " RX counters per PDU type:\n");
2501 pdu_counter_print(vty, " ", area->pdu_rx_counters);
2502
2503 vty_out(vty, " Drop counters per PDU type:\n");
2504 pdu_counter_print(vty, " ", area->pdu_drop_counters);
2505
2506 vty_out(vty, " Advertise high metrics: %s\n",
2507 area->advertise_high_metrics ? "Enabled" : "Disabled");
2508
2509 for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
2510 if ((area->is_type & level) == 0)
2511 continue;
2512
2513 vty_out(vty, " Level-%d:\n", level);
2514
2515 vty_out(vty, " LSP0 regenerated: %" PRIu64 "\n",
2516 area->lsp_gen_count[level - 1]);
2517
2518 vty_out(vty, " LSPs purged: %" PRIu64 "\n",
2519 area->lsp_purge_count[level - 1]);
2520
2521 if (area->spf_timer[level - 1])
2522 vty_out(vty, " SPF: (pending)\n");
2523 else
2524 vty_out(vty, " SPF:\n");
2525
2526 vty_out(vty, " minimum interval : %d",
2527 area->min_spf_interval[level - 1]);
2528 if (area->spf_delay_ietf[level - 1])
2529 vty_out(vty,
2530 " (not used, IETF SPF delay activated)");
2531 vty_out(vty, "\n");
2532
2533 if (area->ip_circuits) {
2534 vty_out(vty, " IPv4 route computation:\n");
2535 isis_spf_print(
2536 area->spftree[SPFTREE_IPV4][level - 1],
2537 vty);
2538 }
2539
2540 if (area->ipv6_circuits) {
2541 vty_out(vty, " IPv6 route computation:\n");
2542 isis_spf_print(
2543 area->spftree[SPFTREE_IPV6][level - 1],
2544 vty);
2545 }
2546
2547 if (area->ipv6_circuits
2548 && isis_area_ipv6_dstsrc_enabled(area)) {
2549 vty_out(vty,
2550 " IPv6 dst-src route computation:\n");
2551 isis_spf_print(area->spftree[SPFTREE_DSTSRC]
2552 [level - 1],
2553 vty);
2554 }
2555 }
2556 }
2557 }
2558
2559 static void common_isis_summary(struct vty *vty, struct json_object *json,
2560 struct isis *isis)
2561 {
2562 if (json) {
2563 common_isis_summary_json(json, isis);
2564 } else {
2565 common_isis_summary_vty(vty, isis);
2566 }
2567 }
2568
2569 DEFUN(show_isis_summary, show_isis_summary_cmd,
2570 "show " PROTO_NAME " [vrf <NAME|all>] summary [json]",
2571 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2572 "All VRFs\n"
2573 "json output\n"
2574 "summary\n")
2575 {
2576 struct listnode *node;
2577 int idx_vrf = 0;
2578 struct isis *isis;
2579 const char *vrf_name = VRF_DEFAULT_NAME;
2580 bool all_vrf = false;
2581 bool uj = use_json(argc, argv);
2582 json_object *json = NULL;
2583
2584 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
2585 if (!im) {
2586 vty_out(vty, PROTO_NAME " is not running\n");
2587 return CMD_SUCCESS;
2588 }
2589 if (uj)
2590 json = json_object_new_object();
2591 if (vrf_name) {
2592 if (all_vrf) {
2593 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2594 common_isis_summary(vty, json, isis);
2595
2596 return CMD_SUCCESS;
2597 }
2598 isis = isis_lookup_by_vrfname(vrf_name);
2599 if (isis != NULL)
2600 common_isis_summary(vty, json, isis);
2601 }
2602
2603 if (uj)
2604 vty_json(vty, json);
2605
2606 return CMD_SUCCESS;
2607 }
2608
2609 struct isis_lsp *lsp_for_sysid(struct lspdb_head *head, const char *sysid_str,
2610 struct isis *isis)
2611 {
2612 char sysid[255] = {0};
2613 uint8_t number[3] = {0};
2614 const char *pos;
2615 uint8_t lspid[ISIS_SYS_ID_LEN + 2] = {0};
2616 struct isis_dynhn *dynhn;
2617 struct isis_lsp *lsp = NULL;
2618
2619 if (!sysid_str)
2620 return NULL;
2621
2622 /*
2623 * extract fragment and pseudo id from the string sysid_str
2624 * in the forms:
2625 * (a) <systemid/hostname>.<pseudo-id>-<framenent> or
2626 * (b) <systemid/hostname>.<pseudo-id> or
2627 * (c) <systemid/hostname> or
2628 * Where systemid is in the form:
2629 * xxxx.xxxx.xxxx
2630 */
2631 strlcpy(sysid, sysid_str, sizeof(sysid));
2632
2633 if (strlen(sysid_str) > 3) {
2634 pos = sysid_str + strlen(sysid_str) - 3;
2635 if (strncmp(pos, "-", 1) == 0) {
2636 memcpy(number, ++pos, 2);
2637 lspid[ISIS_SYS_ID_LEN + 1] =
2638 (uint8_t)strtol((char *)number, NULL, 16);
2639 pos -= 4;
2640 if (strncmp(pos, ".", 1) != 0)
2641 return NULL;
2642 }
2643 if (strncmp(pos, ".", 1) == 0) {
2644 memcpy(number, ++pos, 2);
2645 lspid[ISIS_SYS_ID_LEN] =
2646 (uint8_t)strtol((char *)number, NULL, 16);
2647 sysid[pos - sysid_str - 1] = '\0';
2648 }
2649 }
2650
2651 /*
2652 * Try to find the lsp-id if the sysid_str
2653 * is in the form
2654 * hostname.<pseudo-id>-<fragment>
2655 */
2656 if (sysid2buff(lspid, sysid)) {
2657 lsp = lsp_search(head, lspid);
2658 } else if ((dynhn = dynhn_find_by_name(isis, sysid))) {
2659 memcpy(lspid, dynhn->id, ISIS_SYS_ID_LEN);
2660 lsp = lsp_search(head, lspid);
2661 } else if (strncmp(cmd_hostname_get(), sysid, 15) == 0) {
2662 memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
2663 lsp = lsp_search(head, lspid);
2664 }
2665
2666 return lsp;
2667 }
2668
2669 void show_isis_database_lspdb_json(struct json_object *json,
2670 struct isis_area *area, int level,
2671 struct lspdb_head *lspdb,
2672 const char *sysid_str, int ui_level)
2673 {
2674 struct isis_lsp *lsp;
2675 int lsp_count;
2676
2677 if (lspdb_count(lspdb) > 0) {
2678 lsp = lsp_for_sysid(lspdb, sysid_str, area->isis);
2679
2680 if (lsp != NULL || sysid_str == NULL) {
2681 json_object_int_add(json, "id", level + 1);
2682 }
2683
2684 if (lsp) {
2685 if (ui_level == ISIS_UI_LEVEL_DETAIL)
2686 lsp_print_detail(lsp, NULL, json,
2687 area->dynhostname, area->isis);
2688 else
2689 lsp_print_json(lsp, json, area->dynhostname,
2690 area->isis);
2691 } else if (sysid_str == NULL) {
2692 lsp_count =
2693 lsp_print_all(NULL, json, lspdb, ui_level,
2694 area->dynhostname, area->isis);
2695
2696 json_object_int_add(json, "count", lsp_count);
2697 }
2698 }
2699 }
2700 void show_isis_database_lspdb_vty(struct vty *vty, struct isis_area *area,
2701 int level, struct lspdb_head *lspdb,
2702 const char *sysid_str, int ui_level)
2703 {
2704 struct isis_lsp *lsp;
2705 int lsp_count;
2706
2707 if (lspdb_count(lspdb) > 0) {
2708 lsp = lsp_for_sysid(lspdb, sysid_str, area->isis);
2709
2710 if (lsp != NULL || sysid_str == NULL) {
2711 vty_out(vty, "IS-IS Level-%d link-state database:\n",
2712 level + 1);
2713
2714 /* print the title in all cases */
2715 vty_out(vty,
2716 "LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
2717 }
2718
2719 if (lsp) {
2720 if (ui_level == ISIS_UI_LEVEL_DETAIL)
2721 lsp_print_detail(lsp, vty, NULL,
2722 area->dynhostname, area->isis);
2723 else
2724 lsp_print_vty(lsp, vty, area->dynhostname,
2725 area->isis);
2726 } else if (sysid_str == NULL) {
2727 lsp_count =
2728 lsp_print_all(vty, NULL, lspdb, ui_level,
2729 area->dynhostname, area->isis);
2730
2731 vty_out(vty, " %u LSPs\n\n", lsp_count);
2732 }
2733 }
2734 }
2735
2736 static void show_isis_database_json(struct json_object *json, const char *sysid_str,
2737 int ui_level, struct isis *isis)
2738 {
2739 struct listnode *node;
2740 struct isis_area *area;
2741 int level;
2742 struct json_object *tag_area_json,*area_json, *lsp_json, *area_arr_json, *arr_json;
2743
2744 if (isis->area_list->count == 0)
2745 return;
2746
2747 area_arr_json = json_object_new_array();
2748 json_object_object_add(json, "areas", area_arr_json);
2749 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2750 area_json = json_object_new_object();
2751 tag_area_json = json_object_new_object();
2752 json_object_string_add(tag_area_json, "name",
2753 area->area_tag ? area->area_tag
2754 : "null");
2755
2756 arr_json = json_object_new_array();
2757 json_object_object_add(area_json,"area",tag_area_json);
2758 json_object_object_add(area_json,"levels",arr_json);
2759 for (level = 0; level < ISIS_LEVELS; level++) {
2760 lsp_json = json_object_new_object();
2761 show_isis_database_lspdb_json(lsp_json, area, level,
2762 &area->lspdb[level],
2763 sysid_str, ui_level);
2764 json_object_array_add(arr_json, lsp_json);
2765 }
2766 json_object_array_add(area_arr_json, area_json);
2767 }
2768 }
2769
2770 static void show_isis_database_vty(struct vty *vty, const char *sysid_str,
2771 int ui_level, struct isis *isis)
2772 {
2773 struct listnode *node;
2774 struct isis_area *area;
2775 int level;
2776
2777 if (isis->area_list->count == 0)
2778 return;
2779
2780 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2781 vty_out(vty, "Area %s:\n",
2782 area->area_tag ? area->area_tag : "null");
2783
2784 for (level = 0; level < ISIS_LEVELS; level++)
2785 show_isis_database_lspdb_vty(vty, area, level,
2786 &area->lspdb[level], sysid_str,
2787 ui_level);
2788 }
2789 }
2790
2791 static void show_isis_database_common(struct vty *vty, struct json_object *json, const char *sysid_str,
2792 int ui_level, struct isis *isis)
2793 {
2794 if (json) {
2795 show_isis_database_json(json, sysid_str, ui_level, isis);
2796 } else {
2797 show_isis_database_vty(vty, sysid_str, ui_level, isis);
2798 }
2799 }
2800
2801 /*
2802 * This function supports following display options:
2803 * [ show isis database [detail] ]
2804 * [ show isis database <sysid> [detail] ]
2805 * [ show isis database <hostname> [detail] ]
2806 * [ show isis database <sysid>.<pseudo-id> [detail] ]
2807 * [ show isis database <hostname>.<pseudo-id> [detail] ]
2808 * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
2809 * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
2810 * [ show isis database detail <sysid> ]
2811 * [ show isis database detail <hostname> ]
2812 * [ show isis database detail <sysid>.<pseudo-id> ]
2813 * [ show isis database detail <hostname>.<pseudo-id> ]
2814 * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
2815 * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
2816 */
2817 static int show_isis_database(struct vty *vty, struct json_object *json, const char *sysid_str,
2818 int ui_level, const char *vrf_name, bool all_vrf)
2819 {
2820 struct listnode *node;
2821 struct isis *isis;
2822
2823 if (vrf_name) {
2824 if (all_vrf) {
2825 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2826 show_isis_database_common(vty, json, sysid_str,
2827 ui_level, isis);
2828
2829 return CMD_SUCCESS;
2830 }
2831 isis = isis_lookup_by_vrfname(vrf_name);
2832 if (isis)
2833 show_isis_database_common(vty, json, sysid_str,
2834 ui_level, isis);
2835 }
2836
2837 return CMD_SUCCESS;
2838 }
2839
2840 DEFUN(show_database, show_database_cmd,
2841 "show " PROTO_NAME " [vrf <NAME|all>] database [detail] [WORD] [json]",
2842 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2843 "All VRFs\n"
2844 "Link state database\n"
2845 "Detailed information\n"
2846 "LSP ID\n"
2847 "json output\n")
2848 {
2849 int res = CMD_SUCCESS;
2850 int idx = 0;
2851 int idx_vrf = 0;
2852 const char *vrf_name = VRF_DEFAULT_NAME;
2853 bool all_vrf = false;
2854 int uilevel = argv_find(argv, argc, "detail", &idx)
2855 ? ISIS_UI_LEVEL_DETAIL
2856 : ISIS_UI_LEVEL_BRIEF;
2857 char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
2858 bool uj = use_json(argc, argv);
2859 json_object *json = NULL;
2860
2861 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
2862 if (uj)
2863 json = json_object_new_object();
2864
2865 res = show_isis_database(vty, json, id, uilevel, vrf_name, all_vrf);
2866 if (uj)
2867 vty_json(vty, json);
2868 return res;
2869 }
2870
2871 #ifdef FABRICD
2872 /*
2873 * 'router openfabric' command
2874 */
2875 DEFUN_NOSH (router_openfabric,
2876 router_openfabric_cmd,
2877 "router openfabric WORD",
2878 ROUTER_STR
2879 PROTO_HELP
2880 "ISO Routing area tag\n")
2881 {
2882 int idx_word = 2;
2883 return isis_area_get(vty, argv[idx_word]->arg);
2884 }
2885
2886 /*
2887 *'no router openfabric' command
2888 */
2889 DEFUN (no_router_openfabric,
2890 no_router_openfabric_cmd,
2891 "no router openfabric WORD",
2892 NO_STR
2893 ROUTER_STR
2894 PROTO_HELP
2895 "ISO Routing area tag\n")
2896 {
2897 struct isis_area *area;
2898 const char *area_tag;
2899 int idx_word = 3;
2900
2901 area_tag = argv[idx_word]->arg;
2902 area = isis_area_lookup(area_tag, VRF_DEFAULT);
2903 if (area == NULL) {
2904 zlog_warn("%s: could not find area with area-tag %s",
2905 __func__, area_tag);
2906 return CMD_ERR_NO_MATCH;
2907 }
2908
2909 isis_area_destroy(area);
2910 return CMD_SUCCESS;
2911 }
2912 #endif /* ifdef FABRICD */
2913 #ifdef FABRICD
2914 /*
2915 * 'net' command
2916 */
2917 DEFUN (net,
2918 net_cmd,
2919 "net WORD",
2920 "A Network Entity Title for this process (OSI only)\n"
2921 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
2922 {
2923 int idx_word = 1;
2924 return area_net_title(vty, argv[idx_word]->arg);
2925 }
2926
2927 /*
2928 * 'no net' command
2929 */
2930 DEFUN (no_net,
2931 no_net_cmd,
2932 "no net WORD",
2933 NO_STR
2934 "A Network Entity Title for this process (OSI only)\n"
2935 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
2936 {
2937 int idx_word = 2;
2938 return area_clear_net_title(vty, argv[idx_word]->arg);
2939 }
2940 #endif /* ifdef FABRICD */
2941 #ifdef FABRICD
2942 DEFUN (isis_topology,
2943 isis_topology_cmd,
2944 "topology " ISIS_MT_NAMES " [overload]",
2945 "Configure IS-IS topologies\n"
2946 ISIS_MT_DESCRIPTIONS
2947 "Set overload bit for topology\n")
2948 {
2949 VTY_DECLVAR_CONTEXT(isis_area, area);
2950
2951 const char *arg = argv[1]->arg;
2952 uint16_t mtid = isis_str2mtid(arg);
2953
2954 if (area->oldmetric) {
2955 vty_out(vty,
2956 "Multi topology IS-IS can only be used with wide metrics\n");
2957 return CMD_WARNING_CONFIG_FAILED;
2958 }
2959
2960 if (mtid == (uint16_t)-1) {
2961 vty_out(vty, "Don't know topology '%s'\n", arg);
2962 return CMD_WARNING_CONFIG_FAILED;
2963 }
2964 if (mtid == ISIS_MT_IPV4_UNICAST) {
2965 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
2966 return CMD_WARNING_CONFIG_FAILED;
2967 }
2968
2969 area_set_mt_enabled(area, mtid, true);
2970 area_set_mt_overload(area, mtid, (argc == 3));
2971 return CMD_SUCCESS;
2972 }
2973
2974 DEFUN (no_isis_topology,
2975 no_isis_topology_cmd,
2976 "no topology " ISIS_MT_NAMES " [overload]",
2977 NO_STR
2978 "Configure IS-IS topologies\n"
2979 ISIS_MT_DESCRIPTIONS
2980 "Set overload bit for topology\n")
2981 {
2982 VTY_DECLVAR_CONTEXT(isis_area, area);
2983
2984 const char *arg = argv[2]->arg;
2985 uint16_t mtid = isis_str2mtid(arg);
2986
2987 if (area->oldmetric) {
2988 vty_out(vty,
2989 "Multi topology IS-IS can only be used with wide metrics\n");
2990 return CMD_WARNING_CONFIG_FAILED;
2991 }
2992
2993 if (mtid == (uint16_t)-1) {
2994 vty_out(vty, "Don't know topology '%s'\n", arg);
2995 return CMD_WARNING_CONFIG_FAILED;
2996 }
2997 if (mtid == ISIS_MT_IPV4_UNICAST) {
2998 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
2999 return CMD_WARNING_CONFIG_FAILED;
3000 }
3001
3002 area_set_mt_enabled(area, mtid, false);
3003 area_set_mt_overload(area, mtid, false);
3004 return CMD_SUCCESS;
3005 }
3006 #endif /* ifdef FABRICD */
3007
3008 void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
3009 {
3010 area->lsp_mtu = lsp_mtu;
3011 lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1);
3012 }
3013
3014 static int isis_area_passwd_set(struct isis_area *area, int level,
3015 uint8_t passwd_type, const char *passwd,
3016 uint8_t snp_auth)
3017 {
3018 struct isis_passwd *dest;
3019 struct isis_passwd modified;
3020 int len;
3021
3022 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
3023 dest = (level == IS_LEVEL_1) ? &area->area_passwd
3024 : &area->domain_passwd;
3025 memset(&modified, 0, sizeof(modified));
3026
3027 if (passwd_type != ISIS_PASSWD_TYPE_UNUSED) {
3028 if (!passwd)
3029 return -1;
3030
3031 len = strlen(passwd);
3032 if (len > 254)
3033 return -1;
3034
3035 modified.len = len;
3036 strlcpy((char *)modified.passwd, passwd,
3037 sizeof(modified.passwd));
3038 modified.type = passwd_type;
3039 modified.snp_auth = snp_auth;
3040 }
3041
3042 if (memcmp(&modified, dest, sizeof(modified))) {
3043 memcpy(dest, &modified, sizeof(modified));
3044 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
3045 }
3046
3047 return 0;
3048 }
3049
3050 int isis_area_passwd_unset(struct isis_area *area, int level)
3051 {
3052 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_UNUSED, NULL,
3053 0);
3054 }
3055
3056 int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
3057 const char *passwd, uint8_t snp_auth)
3058 {
3059 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_CLEARTXT,
3060 passwd, snp_auth);
3061 }
3062
3063 int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
3064 const char *passwd, uint8_t snp_auth)
3065 {
3066 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_HMAC_MD5,
3067 passwd, snp_auth);
3068 }
3069
3070 void isis_area_invalidate_routes(struct isis_area *area, int levels)
3071 {
3072 #ifndef FABRICD
3073 struct flex_algo *fa;
3074 struct listnode *node;
3075 struct isis_flex_algo_data *data;
3076 #endif /* ifndef FABRICD */
3077
3078 for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
3079 if (!(level & levels))
3080 continue;
3081 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
3082 isis_spf_invalidate_routes(
3083 area->spftree[tree][level - 1]);
3084
3085 #ifndef FABRICD
3086 for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos,
3087 node, fa)) {
3088 data = fa->data;
3089 isis_spf_invalidate_routes(
3090 data->spftree[tree][level - 1]);
3091 }
3092 #endif /* ifndef FABRICD */
3093 }
3094 }
3095 }
3096
3097 void isis_area_verify_routes(struct isis_area *area)
3098 {
3099 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++)
3100 isis_spf_verify_routes(area, area->spftree[tree], tree);
3101 }
3102
3103 void isis_area_switchover_routes(struct isis_area *area, int family,
3104 union g_addr *nexthop_ip, ifindex_t ifindex,
3105 int level)
3106 {
3107 int tree;
3108
3109 /* TODO SPFTREE_DSTSRC */
3110 if (family == AF_INET)
3111 tree = SPFTREE_IPV4;
3112 else if (family == AF_INET6)
3113 tree = SPFTREE_IPV6;
3114 else
3115 return;
3116
3117 isis_spf_switchover_routes(area, area->spftree[tree], family,
3118 nexthop_ip, ifindex, level);
3119 }
3120
3121
3122 static void area_resign_level(struct isis_area *area, int level)
3123 {
3124 #ifndef FABRICD
3125 struct flex_algo *fa;
3126 struct listnode *node;
3127 struct isis_flex_algo_data *data;
3128 #endif /* ifndef FABRICD */
3129
3130 isis_area_invalidate_routes(area, level);
3131 isis_area_verify_routes(area);
3132
3133 lsp_db_fini(&area->lspdb[level - 1]);
3134
3135 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
3136 if (area->spftree[tree][level - 1]) {
3137 isis_spftree_del(area->spftree[tree][level - 1]);
3138 area->spftree[tree][level - 1] = NULL;
3139 }
3140 }
3141
3142 #ifndef FABRICD
3143 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
3144 for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos, node,
3145 fa)) {
3146 data = fa->data;
3147 if (data->spftree[tree][level - 1]) {
3148 isis_spftree_del(
3149 data->spftree[tree][level - 1]);
3150 data->spftree[tree][level - 1] = NULL;
3151 }
3152 }
3153 }
3154 #endif /* ifndef FABRICD */
3155
3156 if (area->spf_timer[level - 1])
3157 isis_spf_timer_free(EVENT_ARG(area->spf_timer[level - 1]));
3158
3159 EVENT_OFF(area->spf_timer[level - 1]);
3160
3161 sched_debug(
3162 "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
3163 area->area_tag, level);
3164 EVENT_OFF(area->t_lsp_refresh[level - 1]);
3165 area->lsp_regenerate_pending[level - 1] = 0;
3166 }
3167
3168 void isis_area_is_type_set(struct isis_area *area, int is_type)
3169 {
3170 struct listnode *node;
3171 struct isis_circuit *circuit;
3172
3173 if (IS_DEBUG_EVENTS)
3174 zlog_debug("ISIS-Evt (%s) system type change %s -> %s",
3175 area->area_tag, circuit_t2string(area->is_type),
3176 circuit_t2string(is_type));
3177
3178 if (area->is_type == is_type)
3179 return; /* No change */
3180
3181 switch (area->is_type) {
3182 case IS_LEVEL_1:
3183 if (is_type == IS_LEVEL_2)
3184 area_resign_level(area, IS_LEVEL_1);
3185
3186 lsp_db_init(&area->lspdb[1]);
3187 break;
3188
3189 case IS_LEVEL_1_AND_2:
3190 if (is_type == IS_LEVEL_1)
3191 area_resign_level(area, IS_LEVEL_2);
3192 else
3193 area_resign_level(area, IS_LEVEL_1);
3194 break;
3195
3196 case IS_LEVEL_2:
3197 if (is_type == IS_LEVEL_1)
3198 area_resign_level(area, IS_LEVEL_2);
3199
3200 lsp_db_init(&area->lspdb[0]);
3201 break;
3202
3203 default:
3204 break;
3205 }
3206
3207 area->is_type = is_type;
3208
3209 /*
3210 * If area's IS type is strict Level-1 or Level-2, override circuit's
3211 * IS type. Otherwise use circuit's configured IS type.
3212 */
3213 if (area->is_type != IS_LEVEL_1_AND_2) {
3214 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
3215 isis_circuit_is_type_set(circuit, is_type);
3216 } else {
3217 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
3218 isis_circuit_is_type_set(circuit, circuit->is_type_config);
3219 }
3220
3221 spftree_area_init(area);
3222
3223 if (listcount(area->area_addrs) > 0) {
3224 if (is_type & IS_LEVEL_1)
3225 lsp_generate(area, IS_LEVEL_1);
3226 if (is_type & IS_LEVEL_2)
3227 lsp_generate(area, IS_LEVEL_2);
3228 }
3229 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
3230
3231 return;
3232 }
3233
3234 void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
3235 bool new_metric)
3236 {
3237 area->oldmetric = old_metric;
3238 area->newmetric = new_metric;
3239 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
3240 }
3241
3242 void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
3243 {
3244 char new_overload_bit = overload_bit ? LSPBIT_OL : 0;
3245
3246 if (new_overload_bit != area->overload_bit) {
3247 area->overload_bit = new_overload_bit;
3248 if (new_overload_bit) {
3249 area->overload_counter++;
3250 } else {
3251 /* Cancel overload on startup timer if it's running */
3252 if (area->t_overload_on_startup_timer) {
3253 EVENT_OFF(area->t_overload_on_startup_timer);
3254 area->t_overload_on_startup_timer = NULL;
3255 }
3256 }
3257
3258 #ifndef FABRICD
3259 hook_call(isis_hook_db_overload, area);
3260 #endif /* ifndef FABRICD */
3261
3262 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
3263 }
3264 #ifndef FABRICD
3265 isis_notif_db_overload(area, overload_bit);
3266 #endif /* ifndef FABRICD */
3267 }
3268
3269 void isis_area_overload_on_startup_set(struct isis_area *area,
3270 uint32_t startup_time)
3271 {
3272 if (area->overload_on_startup_time != startup_time) {
3273 area->overload_on_startup_time = startup_time;
3274 isis_restart_write_overload_time(area, startup_time);
3275 }
3276 }
3277
3278 void config_end_lsp_generate(struct isis_area *area)
3279 {
3280 if (listcount(area->area_addrs) > 0) {
3281 if (CHECK_FLAG(area->is_type, IS_LEVEL_1))
3282 lsp_generate(area, IS_LEVEL_1);
3283 if (CHECK_FLAG(area->is_type, IS_LEVEL_2))
3284 lsp_generate(area, IS_LEVEL_2);
3285 }
3286 }
3287
3288 void isis_area_advertise_high_metrics_set(struct isis_area *area,
3289 bool advertise_high_metrics)
3290 {
3291 struct listnode *node;
3292 struct isis_circuit *circuit;
3293 int max_metric;
3294 char xpath[XPATH_MAXLEN];
3295 struct lyd_node *dnode;
3296 int configured_metric_l1;
3297 int configured_metric_l2;
3298
3299 if (area->advertise_high_metrics == advertise_high_metrics)
3300 return;
3301
3302 if (advertise_high_metrics) {
3303 if (area->oldmetric && area->newmetric)
3304 max_metric = ISIS_NARROW_METRIC_INFINITY;
3305 else if (area->newmetric)
3306 max_metric = MAX_WIDE_LINK_METRIC;
3307 else
3308 max_metric = MAX_NARROW_LINK_METRIC;
3309
3310 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
3311 isis_circuit_metric_set(circuit, IS_LEVEL_1,
3312 max_metric);
3313 isis_circuit_metric_set(circuit, IS_LEVEL_2,
3314 max_metric);
3315 }
3316
3317 area->advertise_high_metrics = true;
3318 } else {
3319 area->advertise_high_metrics = false;
3320 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
3321 /* Get configured metric */
3322 snprintf(xpath, XPATH_MAXLEN,
3323 "/frr-interface:lib/interface[name='%s']",
3324 circuit->interface->name);
3325 dnode = yang_dnode_get(running_config->dnode, xpath);
3326
3327 configured_metric_l1 = yang_dnode_get_uint32(
3328 dnode, "./frr-isisd:isis/metric/level-1");
3329 configured_metric_l2 = yang_dnode_get_uint32(
3330 dnode, "./frr-isisd:isis/metric/level-2");
3331
3332 isis_circuit_metric_set(circuit, IS_LEVEL_1,
3333 configured_metric_l1);
3334 isis_circuit_metric_set(circuit, IS_LEVEL_2,
3335 configured_metric_l2);
3336 }
3337 }
3338 }
3339
3340 /*
3341 * Returns the path of the file (non-volatile memory) that contains restart
3342 * information.
3343 */
3344 char *isis_restart_filepath(void)
3345 {
3346 static char filepath[MAXPATHLEN];
3347 snprintf(filepath, sizeof(filepath), ISISD_RESTART, "");
3348 return filepath;
3349 }
3350
3351 /*
3352 * Record in non-volatile memory the overload on startup time.
3353 */
3354 void isis_restart_write_overload_time(struct isis_area *isis_area,
3355 uint32_t overload_time)
3356 {
3357 char *filepath;
3358 const char *area_name;
3359 json_object *json;
3360 json_object *json_areas;
3361 json_object *json_area;
3362
3363 filepath = isis_restart_filepath();
3364 area_name = isis_area->area_tag;
3365
3366 json = json_object_from_file(filepath);
3367 if (json == NULL)
3368 json = json_object_new_object();
3369
3370 json_object_object_get_ex(json, "areas", &json_areas);
3371 if (!json_areas) {
3372 json_areas = json_object_new_object();
3373 json_object_object_add(json, "areas", json_areas);
3374 }
3375
3376 json_object_object_get_ex(json_areas, area_name, &json_area);
3377 if (!json_area) {
3378 json_area = json_object_new_object();
3379 json_object_object_add(json_areas, area_name, json_area);
3380 }
3381
3382 json_object_int_add(json_area, "overload_time",
3383 isis_area->overload_on_startup_time);
3384 json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
3385 json_object_free(json);
3386 }
3387
3388 /*
3389 * Fetch from non-volatile memory the overload on startup time.
3390 */
3391 uint32_t isis_restart_read_overload_time(struct isis_area *isis_area)
3392 {
3393 char *filepath;
3394 const char *area_name;
3395 json_object *json;
3396 json_object *json_areas;
3397 json_object *json_area;
3398 json_object *json_overload_time;
3399 uint32_t overload_time = 0;
3400
3401 filepath = isis_restart_filepath();
3402 area_name = isis_area->area_tag;
3403
3404 json = json_object_from_file(filepath);
3405 if (json == NULL)
3406 json = json_object_new_object();
3407
3408 json_object_object_get_ex(json, "areas", &json_areas);
3409 if (!json_areas) {
3410 json_areas = json_object_new_object();
3411 json_object_object_add(json, "areas", json_areas);
3412 }
3413
3414 json_object_object_get_ex(json_areas, area_name, &json_area);
3415 if (!json_area) {
3416 json_area = json_object_new_object();
3417 json_object_object_add(json_areas, area_name, json_area);
3418 }
3419
3420 json_object_object_get_ex(json_area, "overload_time",
3421 &json_overload_time);
3422 if (json_overload_time) {
3423 overload_time = json_object_get_int(json_overload_time);
3424 }
3425
3426 json_object_object_del(json_areas, area_name);
3427
3428 json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
3429 json_object_free(json);
3430
3431 return overload_time;
3432 }
3433
3434 void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit)
3435 {
3436
3437 if (attached_bit != area->attached_bit_send) {
3438 area->attached_bit_send = attached_bit;
3439 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
3440 }
3441 }
3442
3443 void isis_area_attached_bit_receive_set(struct isis_area *area,
3444 bool attached_bit)
3445 {
3446
3447 if (attached_bit != area->attached_bit_rcv_ignore) {
3448 area->attached_bit_rcv_ignore = attached_bit;
3449 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
3450 }
3451 }
3452
3453 void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname)
3454 {
3455 if (area->dynhostname != dynhostname) {
3456 area->dynhostname = dynhostname;
3457 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
3458 }
3459 }
3460
3461 void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level,
3462 uint16_t max_lsp_lifetime)
3463 {
3464 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
3465
3466 if (area->max_lsp_lifetime[level - 1] == max_lsp_lifetime)
3467 return;
3468
3469 area->max_lsp_lifetime[level - 1] = max_lsp_lifetime;
3470 lsp_regenerate_schedule(area, level, 1);
3471 }
3472
3473 void isis_area_lsp_refresh_set(struct isis_area *area, int level,
3474 uint16_t lsp_refresh)
3475 {
3476 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
3477
3478 if (area->lsp_refresh[level - 1] == lsp_refresh)
3479 return;
3480
3481 area->lsp_refresh[level - 1] = lsp_refresh;
3482 lsp_regenerate_schedule(area, level, 1);
3483 }
3484
3485 #ifdef FABRICD
3486 DEFUN (log_adj_changes,
3487 log_adj_changes_cmd,
3488 "log-adjacency-changes",
3489 "Log changes in adjacency state\n")
3490 {
3491 VTY_DECLVAR_CONTEXT(isis_area, area);
3492
3493 area->log_adj_changes = 1;
3494
3495 return CMD_SUCCESS;
3496 }
3497
3498 DEFUN (no_log_adj_changes,
3499 no_log_adj_changes_cmd,
3500 "no log-adjacency-changes",
3501 NO_STR
3502 "Stop logging changes in adjacency state\n")
3503 {
3504 VTY_DECLVAR_CONTEXT(isis_area, area);
3505
3506 area->log_adj_changes = 0;
3507
3508 return CMD_SUCCESS;
3509 }
3510 #endif /* ifdef FABRICD */
3511 #ifdef FABRICD
3512 /* IS-IS configuration write function */
3513 static int isis_config_write(struct vty *vty)
3514 {
3515 int write = 0;
3516 struct isis_area *area;
3517 struct listnode *node, *node2, *inode;
3518 struct isis *isis;
3519
3520 if (!im) {
3521 vty_out(vty, "IS-IS Routing Process not enabled\n");
3522 return CMD_SUCCESS;
3523 }
3524
3525 for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
3526 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
3527 /* ISIS - Area name */
3528 vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
3529 write++;
3530 /* ISIS - Net */
3531 if (listcount(area->area_addrs) > 0) {
3532 struct iso_address *area_addr;
3533 for (ALL_LIST_ELEMENTS_RO(area->area_addrs,
3534 node2, area_addr)) {
3535 vty_out(vty, " net %pISl\n", area_addr);
3536 write++;
3537 }
3538 }
3539 /* ISIS - Dynamic hostname - Defaults to true so only
3540 * display if
3541 * false. */
3542 if (!area->dynhostname) {
3543 vty_out(vty, " no hostname dynamic\n");
3544 write++;
3545 }
3546 /* ISIS - Metric-Style - when true displays wide */
3547 if (!fabricd) {
3548 if (area->newmetric) {
3549 if (!area->oldmetric)
3550 vty_out(vty, " metric-style wide\n");
3551 else
3552 vty_out(vty,
3553 " metric-style transition\n");
3554 write++;
3555 } else {
3556 vty_out(vty, " metric-style narrow\n");
3557 write++;
3558 }
3559 }
3560 /* ISIS - overload-bit */
3561 if (area->overload_bit) {
3562 vty_out(vty, " set-overload-bit\n");
3563 write++;
3564 }
3565 /* ISIS - Area is-type (level-1-2 is default) */
3566 if (!fabricd) {
3567 if (area->is_type == IS_LEVEL_1) {
3568 vty_out(vty, " is-type level-1\n");
3569 write++;
3570 } else if (area->is_type == IS_LEVEL_2) {
3571 vty_out(vty, " is-type level-2-only\n");
3572 write++;
3573 }
3574 }
3575 write += isis_redist_config_write(vty, area, AF_INET);
3576 write += isis_redist_config_write(vty, area, AF_INET6);
3577 /* ISIS - Lsp generation interval */
3578 if (area->lsp_gen_interval[0]
3579 == area->lsp_gen_interval[1]) {
3580 if (area->lsp_gen_interval[0]
3581 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
3582 vty_out(vty, " lsp-gen-interval %d\n",
3583 area->lsp_gen_interval[0]);
3584 write++;
3585 }
3586 } else {
3587 if (area->lsp_gen_interval[0]
3588 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
3589 vty_out(vty,
3590 " lsp-gen-interval level-1 %d\n",
3591 area->lsp_gen_interval[0]);
3592 write++;
3593 }
3594 if (area->lsp_gen_interval[1]
3595 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
3596 vty_out(vty,
3597 " lsp-gen-interval level-2 %d\n",
3598 area->lsp_gen_interval[1]);
3599 write++;
3600 }
3601 }
3602 /* ISIS - LSP lifetime */
3603 if (area->max_lsp_lifetime[0]
3604 == area->max_lsp_lifetime[1]) {
3605 if (area->max_lsp_lifetime[0]
3606 != DEFAULT_LSP_LIFETIME) {
3607 vty_out(vty, " max-lsp-lifetime %u\n",
3608 area->max_lsp_lifetime[0]);
3609 write++;
3610 }
3611 } else {
3612 if (area->max_lsp_lifetime[0]
3613 != DEFAULT_LSP_LIFETIME) {
3614 vty_out(vty,
3615 " max-lsp-lifetime level-1 %u\n",
3616 area->max_lsp_lifetime[0]);
3617 write++;
3618 }
3619 if (area->max_lsp_lifetime[1]
3620 != DEFAULT_LSP_LIFETIME) {
3621 vty_out(vty,
3622 " max-lsp-lifetime level-2 %u\n",
3623 area->max_lsp_lifetime[1]);
3624 write++;
3625 }
3626 }
3627 /* ISIS - LSP refresh interval */
3628 if (area->lsp_refresh[0] == area->lsp_refresh[1]) {
3629 if (area->lsp_refresh[0]
3630 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
3631 vty_out(vty,
3632 " lsp-refresh-interval %u\n",
3633 area->lsp_refresh[0]);
3634 write++;
3635 }
3636 } else {
3637 if (area->lsp_refresh[0]
3638 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
3639 vty_out(vty,
3640 " lsp-refresh-interval level-1 %u\n",
3641 area->lsp_refresh[0]);
3642 write++;
3643 }
3644 if (area->lsp_refresh[1]
3645 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
3646 vty_out(vty,
3647 " lsp-refresh-interval level-2 %u\n",
3648 area->lsp_refresh[1]);
3649 write++;
3650 }
3651 }
3652 if (area->lsp_mtu != DEFAULT_LSP_MTU) {
3653 vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu);
3654 write++;
3655 }
3656 if (area->purge_originator) {
3657 vty_out(vty, " purge-originator\n");
3658 write++;
3659 }
3660
3661 /* Minimum SPF interval. */
3662 if (area->min_spf_interval[0]
3663 == area->min_spf_interval[1]) {
3664 if (area->min_spf_interval[0]
3665 != MINIMUM_SPF_INTERVAL) {
3666 vty_out(vty, " spf-interval %d\n",
3667 area->min_spf_interval[0]);
3668 write++;
3669 }
3670 } else {
3671 if (area->min_spf_interval[0]
3672 != MINIMUM_SPF_INTERVAL) {
3673 vty_out(vty,
3674 " spf-interval level-1 %d\n",
3675 area->min_spf_interval[0]);
3676 write++;
3677 }
3678 if (area->min_spf_interval[1]
3679 != MINIMUM_SPF_INTERVAL) {
3680 vty_out(vty,
3681 " spf-interval level-2 %d\n",
3682 area->min_spf_interval[1]);
3683 write++;
3684 }
3685 }
3686
3687 /* IETF SPF interval */
3688 if (area->spf_delay_ietf[0]) {
3689 vty_out(vty,
3690 " spf-delay-ietf init-delay %ld short-delay %ld long-delay %ld holddown %ld time-to-learn %ld\n",
3691 spf_backoff_init_delay(
3692 area->spf_delay_ietf[0]),
3693 spf_backoff_short_delay(
3694 area->spf_delay_ietf[0]),
3695 spf_backoff_long_delay(
3696 area->spf_delay_ietf[0]),
3697 spf_backoff_holddown(
3698 area->spf_delay_ietf[0]),
3699 spf_backoff_timetolearn(
3700 area->spf_delay_ietf[0]));
3701 write++;
3702 }
3703
3704 /* Authentication passwords. */
3705 if (area->area_passwd.type
3706 == ISIS_PASSWD_TYPE_HMAC_MD5) {
3707 vty_out(vty, " area-password md5 %s",
3708 area->area_passwd.passwd);
3709 if (CHECK_FLAG(area->area_passwd.snp_auth,
3710 SNP_AUTH_SEND)) {
3711 vty_out(vty, " authenticate snp ");
3712 if (CHECK_FLAG(
3713 area->area_passwd.snp_auth,
3714 SNP_AUTH_RECV))
3715 vty_out(vty, "validate");
3716 else
3717 vty_out(vty, "send-only");
3718 }
3719 vty_out(vty, "\n");
3720 write++;
3721 } else if (area->area_passwd.type
3722 == ISIS_PASSWD_TYPE_CLEARTXT) {
3723 vty_out(vty, " area-password clear %s",
3724 area->area_passwd.passwd);
3725 if (CHECK_FLAG(area->area_passwd.snp_auth,
3726 SNP_AUTH_SEND)) {
3727 vty_out(vty, " authenticate snp ");
3728 if (CHECK_FLAG(
3729 area->area_passwd.snp_auth,
3730 SNP_AUTH_RECV))
3731 vty_out(vty, "validate");
3732 else
3733 vty_out(vty, "send-only");
3734 }
3735 vty_out(vty, "\n");
3736 write++;
3737 }
3738 if (area->domain_passwd.type
3739 == ISIS_PASSWD_TYPE_HMAC_MD5) {
3740 vty_out(vty, " domain-password md5 %s",
3741 area->domain_passwd.passwd);
3742 if (CHECK_FLAG(area->domain_passwd.snp_auth,
3743 SNP_AUTH_SEND)) {
3744 vty_out(vty, " authenticate snp ");
3745 if (CHECK_FLAG(area->domain_passwd
3746 .snp_auth,
3747 SNP_AUTH_RECV))
3748 vty_out(vty, "validate");
3749 else
3750 vty_out(vty, "send-only");
3751 }
3752 vty_out(vty, "\n");
3753 write++;
3754 } else if (area->domain_passwd.type
3755 == ISIS_PASSWD_TYPE_CLEARTXT) {
3756 vty_out(vty, " domain-password clear %s",
3757 area->domain_passwd.passwd);
3758 if (CHECK_FLAG(area->domain_passwd.snp_auth,
3759 SNP_AUTH_SEND)) {
3760 vty_out(vty, " authenticate snp ");
3761 if (CHECK_FLAG(area->domain_passwd
3762 .snp_auth,
3763 SNP_AUTH_RECV))
3764 vty_out(vty, "validate");
3765 else
3766 vty_out(vty, "send-only");
3767 }
3768 vty_out(vty, "\n");
3769 write++;
3770 }
3771
3772 if (area->log_adj_changes) {
3773 vty_out(vty, " log-adjacency-changes\n");
3774 write++;
3775 }
3776
3777 write += area_write_mt_settings(area, vty);
3778 write += fabricd_write_settings(area, vty);
3779
3780 vty_out(vty, "exit\n");
3781 }
3782 }
3783
3784 return write;
3785 }
3786
3787 struct cmd_node router_node = {
3788 .name = "openfabric",
3789 .node = OPENFABRIC_NODE,
3790 .parent_node = CONFIG_NODE,
3791 .prompt = "%s(config-router)# ",
3792 .config_write = isis_config_write,
3793 };
3794 #endif /* ifdef FABRICD */
3795 #ifndef FABRICD
3796 /* IS-IS configuration write function */
3797 static int isis_config_write(struct vty *vty)
3798 {
3799 int write = 0;
3800 struct lyd_node *dnode;
3801
3802 dnode = yang_dnode_get(running_config->dnode, "/frr-isisd:isis");
3803 if (dnode) {
3804 nb_cli_show_dnode_cmds(vty, dnode, false);
3805 write++;
3806 }
3807
3808 return write;
3809 }
3810
3811 struct cmd_node router_node = {
3812 .name = "isis",
3813 .node = ISIS_NODE,
3814 .parent_node = CONFIG_NODE,
3815 .prompt = "%s(config-router)# ",
3816 .config_write = isis_config_write,
3817 };
3818
3819 struct cmd_node isis_flex_algo_node = {
3820 .name = "isis-flex-algo",
3821 .node = ISIS_FLEX_ALGO_NODE,
3822 .parent_node = ISIS_NODE,
3823 .prompt = "%s(config-router-flex-algo)# ",
3824 };
3825 #endif /* ifdnef FABRICD */
3826
3827 void isis_init(void)
3828 {
3829 /* Install IS-IS top node */
3830 install_node(&router_node);
3831
3832 install_element(VIEW_NODE, &show_isis_summary_cmd);
3833
3834 install_element(VIEW_NODE, &show_isis_spf_ietf_cmd);
3835
3836 install_element(VIEW_NODE, &show_isis_interface_cmd);
3837 install_element(VIEW_NODE, &show_isis_interface_detail_cmd);
3838 install_element(VIEW_NODE, &show_isis_interface_arg_cmd);
3839
3840 install_element(VIEW_NODE, &show_isis_neighbor_cmd);
3841 install_element(VIEW_NODE, &show_isis_neighbor_detail_cmd);
3842 install_element(VIEW_NODE, &show_isis_neighbor_arg_cmd);
3843 install_element(ENABLE_NODE, &clear_isis_neighbor_cmd);
3844 install_element(ENABLE_NODE, &clear_isis_neighbor_arg_cmd);
3845
3846 install_element(VIEW_NODE, &show_hostname_cmd);
3847 install_element(VIEW_NODE, &show_database_cmd);
3848
3849 install_element(ENABLE_NODE, &show_debugging_isis_cmd);
3850
3851 install_node(&debug_node);
3852
3853 install_element(ENABLE_NODE, &debug_isis_adj_cmd);
3854 install_element(ENABLE_NODE, &no_debug_isis_adj_cmd);
3855 install_element(ENABLE_NODE, &debug_isis_tx_queue_cmd);
3856 install_element(ENABLE_NODE, &no_debug_isis_tx_queue_cmd);
3857 install_element(ENABLE_NODE, &debug_isis_flooding_cmd);
3858 install_element(ENABLE_NODE, &no_debug_isis_flooding_cmd);
3859 install_element(ENABLE_NODE, &debug_isis_snp_cmd);
3860 install_element(ENABLE_NODE, &no_debug_isis_snp_cmd);
3861 install_element(ENABLE_NODE, &debug_isis_upd_cmd);
3862 install_element(ENABLE_NODE, &no_debug_isis_upd_cmd);
3863 install_element(ENABLE_NODE, &debug_isis_spfevents_cmd);
3864 install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd);
3865 install_element(ENABLE_NODE, &debug_isis_srevents_cmd);
3866 install_element(ENABLE_NODE, &no_debug_isis_srevents_cmd);
3867 install_element(ENABLE_NODE, &debug_isis_teevents_cmd);
3868 install_element(ENABLE_NODE, &no_debug_isis_teevents_cmd);
3869 install_element(ENABLE_NODE, &debug_isis_lfa_cmd);
3870 install_element(ENABLE_NODE, &no_debug_isis_lfa_cmd);
3871 install_element(ENABLE_NODE, &debug_isis_rtevents_cmd);
3872 install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd);
3873 install_element(ENABLE_NODE, &debug_isis_events_cmd);
3874 install_element(ENABLE_NODE, &no_debug_isis_events_cmd);
3875 install_element(ENABLE_NODE, &debug_isis_packet_dump_cmd);
3876 install_element(ENABLE_NODE, &no_debug_isis_packet_dump_cmd);
3877 install_element(ENABLE_NODE, &debug_isis_lsp_gen_cmd);
3878 install_element(ENABLE_NODE, &no_debug_isis_lsp_gen_cmd);
3879 install_element(ENABLE_NODE, &debug_isis_lsp_sched_cmd);
3880 install_element(ENABLE_NODE, &no_debug_isis_lsp_sched_cmd);
3881 install_element(ENABLE_NODE, &debug_isis_bfd_cmd);
3882 install_element(ENABLE_NODE, &no_debug_isis_bfd_cmd);
3883 install_element(ENABLE_NODE, &debug_isis_ldp_sync_cmd);
3884 install_element(ENABLE_NODE, &no_debug_isis_ldp_sync_cmd);
3885
3886 install_element(CONFIG_NODE, &debug_isis_adj_cmd);
3887 install_element(CONFIG_NODE, &no_debug_isis_adj_cmd);
3888 install_element(CONFIG_NODE, &debug_isis_tx_queue_cmd);
3889 install_element(CONFIG_NODE, &no_debug_isis_tx_queue_cmd);
3890 install_element(CONFIG_NODE, &debug_isis_flooding_cmd);
3891 install_element(CONFIG_NODE, &no_debug_isis_flooding_cmd);
3892 install_element(CONFIG_NODE, &debug_isis_snp_cmd);
3893 install_element(CONFIG_NODE, &no_debug_isis_snp_cmd);
3894 install_element(CONFIG_NODE, &debug_isis_upd_cmd);
3895 install_element(CONFIG_NODE, &no_debug_isis_upd_cmd);
3896 install_element(CONFIG_NODE, &debug_isis_spfevents_cmd);
3897 install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd);
3898 install_element(CONFIG_NODE, &debug_isis_srevents_cmd);
3899 install_element(CONFIG_NODE, &no_debug_isis_srevents_cmd);
3900 install_element(CONFIG_NODE, &debug_isis_teevents_cmd);
3901 install_element(CONFIG_NODE, &no_debug_isis_teevents_cmd);
3902 install_element(CONFIG_NODE, &debug_isis_lfa_cmd);
3903 install_element(CONFIG_NODE, &no_debug_isis_lfa_cmd);
3904 install_element(CONFIG_NODE, &debug_isis_rtevents_cmd);
3905 install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd);
3906 install_element(CONFIG_NODE, &debug_isis_events_cmd);
3907 install_element(CONFIG_NODE, &no_debug_isis_events_cmd);
3908 install_element(CONFIG_NODE, &debug_isis_packet_dump_cmd);
3909 install_element(CONFIG_NODE, &no_debug_isis_packet_dump_cmd);
3910 install_element(CONFIG_NODE, &debug_isis_lsp_gen_cmd);
3911 install_element(CONFIG_NODE, &no_debug_isis_lsp_gen_cmd);
3912 install_element(CONFIG_NODE, &debug_isis_lsp_sched_cmd);
3913 install_element(CONFIG_NODE, &no_debug_isis_lsp_sched_cmd);
3914 install_element(CONFIG_NODE, &debug_isis_bfd_cmd);
3915 install_element(CONFIG_NODE, &no_debug_isis_bfd_cmd);
3916 install_element(CONFIG_NODE, &debug_isis_ldp_sync_cmd);
3917 install_element(CONFIG_NODE, &no_debug_isis_ldp_sync_cmd);
3918
3919 install_default(ROUTER_NODE);
3920
3921 #ifdef FABRICD
3922 install_element(CONFIG_NODE, &router_openfabric_cmd);
3923 install_element(CONFIG_NODE, &no_router_openfabric_cmd);
3924
3925 install_element(ROUTER_NODE, &net_cmd);
3926 install_element(ROUTER_NODE, &no_net_cmd);
3927
3928 install_element(ROUTER_NODE, &isis_topology_cmd);
3929 install_element(ROUTER_NODE, &no_isis_topology_cmd);
3930
3931 install_element(ROUTER_NODE, &log_adj_changes_cmd);
3932 install_element(ROUTER_NODE, &no_log_adj_changes_cmd);
3933 #endif /* ifdef FABRICD */
3934 #ifndef FABRICD
3935 install_node(&isis_flex_algo_node);
3936 install_default(ISIS_FLEX_ALGO_NODE);
3937 #endif /* ifdnef FABRICD */
3938
3939 spf_backoff_cmd_init();
3940 }