2 * IS-IS Rout(e)ing protocol - isisd.c
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
42 #include "spf_backoff.h"
43 #include "lib/northbound_cli.h"
46 #include "isisd/isis_constants.h"
47 #include "isisd/isis_common.h"
48 #include "isisd/isis_flags.h"
49 #include "isisd/isis_circuit.h"
50 #include "isisd/isis_csm.h"
51 #include "isisd/isisd.h"
52 #include "isisd/isis_dynhn.h"
53 #include "isisd/isis_adjacency.h"
54 #include "isisd/isis_pdu.h"
55 #include "isisd/isis_misc.h"
56 #include "isisd/isis_constants.h"
57 #include "isisd/isis_lsp.h"
58 #include "isisd/isis_spf.h"
59 #include "isisd/isis_route.h"
60 #include "isisd/isis_zebra.h"
61 #include "isisd/isis_events.h"
62 #include "isisd/isis_te.h"
63 #include "isisd/isis_mt.h"
64 #include "isisd/isis_sr.h"
65 #include "isisd/fabricd.h"
66 #include "isisd/isis_nb.h"
68 /* For debug statement. */
69 unsigned long debug_adj_pkt
;
70 unsigned long debug_snp_pkt
;
71 unsigned long debug_update_pkt
;
72 unsigned long debug_spf_events
;
73 unsigned long debug_rte_events
;
74 unsigned long debug_events
;
75 unsigned long debug_pkt_dump
;
76 unsigned long debug_lsp_gen
;
77 unsigned long debug_lsp_sched
;
78 unsigned long debug_flooding
;
79 unsigned long debug_bfd
;
80 unsigned long debug_tx_queue
;
81 unsigned long debug_sr
;
82 unsigned long debug_ldp_sync
;
83 unsigned long debug_lfa
;
84 unsigned long debug_te
;
86 DEFINE_MGROUP(ISISD
, "isisd");
88 DEFINE_MTYPE_STATIC(ISISD
, ISIS
, "ISIS process");
89 DEFINE_MTYPE_STATIC(ISISD
, ISIS_NAME
, "ISIS process name");
90 DEFINE_MTYPE_STATIC(ISISD
, ISIS_AREA
, "ISIS area");
91 DEFINE_MTYPE(ISISD
, ISIS_AREA_ADDR
, "ISIS area address");
92 DEFINE_MTYPE(ISISD
, ISIS_ACL_NAME
, "ISIS access-list name");
94 DEFINE_QOBJ_TYPE(isis_area
);
96 /* ISIS process wide configuration. */
97 static struct isis_master isis_master
;
99 /* ISIS process wide configuration pointer to export. */
100 struct isis_master
*im
;
103 DEFINE_HOOK(isis_hook_db_overload
, (const struct isis_area
*area
), (area
));
104 #endif /* ifndef FABRICD */
109 int isis_area_get(struct vty
*, const char *);
110 int area_net_title(struct vty
*, const char *);
111 int area_clear_net_title(struct vty
*, const char *);
112 int show_isis_interface_common(struct vty
*, struct json_object
*json
,
113 const char *ifname
, char, const char *vrf_name
,
115 int show_isis_interface_common_vty(struct vty
*, const char *ifname
, char,
116 const char *vrf_name
, bool all_vrf
);
117 int show_isis_interface_common_json(struct json_object
*json
,
118 const char *ifname
, char,
119 const char *vrf_name
, bool all_vrf
);
120 int show_isis_neighbor_common(struct vty
*, struct json_object
*json
,
121 const char *id
, char, const char *vrf_name
,
123 int clear_isis_neighbor_common(struct vty
*, const char *id
,
124 const char *vrf_name
, bool all_vrf
);
126 /* Link ISIS instance to VRF. */
127 void isis_vrf_link(struct isis
*isis
, struct vrf
*vrf
)
129 isis
->vrf_id
= vrf
->vrf_id
;
130 if (vrf
->info
!= (void *)isis
)
131 vrf
->info
= (void *)isis
;
134 /* Unlink ISIS instance to VRF. */
135 void isis_vrf_unlink(struct isis
*isis
, struct vrf
*vrf
)
137 if (vrf
->info
== (void *)isis
)
139 isis
->vrf_id
= VRF_UNKNOWN
;
142 struct isis
*isis_lookup_by_vrfid(vrf_id_t vrf_id
)
145 struct listnode
*node
;
147 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
148 if (isis
->vrf_id
== vrf_id
)
154 struct isis
*isis_lookup_by_vrfname(const char *vrfname
)
157 struct listnode
*node
;
159 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
160 if (isis
->name
&& vrfname
&& strcmp(isis
->name
, vrfname
) == 0)
166 struct isis
*isis_lookup_by_sysid(const uint8_t *sysid
)
169 struct listnode
*node
;
171 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
172 if (!memcmp(isis
->sysid
, sysid
, ISIS_SYS_ID_LEN
))
178 void isis_master_init(struct thread_master
*master
)
180 memset(&isis_master
, 0, sizeof(isis_master
));
182 im
->isis
= list_new();
186 struct isis
*isis_new(const char *vrf_name
)
191 isis
= XCALLOC(MTYPE_ISIS
, sizeof(struct isis
));
193 isis
->name
= XSTRDUP(MTYPE_ISIS_NAME
, vrf_name
);
195 vrf
= vrf_lookup_by_name(vrf_name
);
198 isis_vrf_link(isis
, vrf
);
200 isis
->vrf_id
= VRF_UNKNOWN
;
202 isis_zebra_vrf_register(isis
);
206 "%s: Create new isis instance with vrf_name %s vrf_id %u",
207 __func__
, isis
->name
, isis
->vrf_id
);
212 isis
->max_area_addrs
= ISIS_DEFAULT_MAX_AREA_ADDRESSES
;
213 isis
->process_id
= getpid();
215 isis
->area_list
= list_new();
216 isis
->uptime
= time(NULL
);
217 isis
->snmp_notifications
= 1;
218 dyn_cache_init(isis
);
220 listnode_add(im
->isis
, isis
);
225 void isis_finish(struct isis
*isis
)
227 struct vrf
*vrf
= NULL
;
229 listnode_delete(im
->isis
, isis
);
231 isis_zebra_vrf_deregister(isis
);
233 vrf
= vrf_lookup_by_name(isis
->name
);
235 isis_vrf_unlink(isis
, vrf
);
236 XFREE(MTYPE_ISIS_NAME
, isis
->name
);
238 isis_redist_free(isis
);
239 list_delete(&isis
->area_list
);
240 dyn_cache_finish(isis
);
241 XFREE(MTYPE_ISIS
, isis
);
244 void isis_area_add_circuit(struct isis_area
*area
, struct isis_circuit
*circuit
)
246 isis_csm_state_change(ISIS_ENABLE
, circuit
, area
);
248 area
->ip_circuits
+= circuit
->ip_router
;
249 area
->ipv6_circuits
+= circuit
->ipv6_router
;
251 area
->lfa_protected_links
[0] += circuit
->lfa_protection
[0];
252 area
->rlfa_protected_links
[0] += circuit
->rlfa_protection
[0];
253 area
->tilfa_protected_links
[0] += circuit
->tilfa_protection
[0];
255 area
->lfa_protected_links
[1] += circuit
->lfa_protection
[1];
256 area
->rlfa_protected_links
[1] += circuit
->rlfa_protection
[1];
257 area
->tilfa_protected_links
[1] += circuit
->tilfa_protection
[1];
260 void isis_area_del_circuit(struct isis_area
*area
, struct isis_circuit
*circuit
)
262 area
->ip_circuits
-= circuit
->ip_router
;
263 area
->ipv6_circuits
-= circuit
->ipv6_router
;
265 area
->lfa_protected_links
[0] -= circuit
->lfa_protection
[0];
266 area
->rlfa_protected_links
[0] -= circuit
->rlfa_protection
[0];
267 area
->tilfa_protected_links
[0] -= circuit
->tilfa_protection
[0];
269 area
->lfa_protected_links
[1] -= circuit
->lfa_protection
[1];
270 area
->rlfa_protected_links
[1] -= circuit
->rlfa_protection
[1];
271 area
->tilfa_protected_links
[1] -= circuit
->tilfa_protection
[1];
273 isis_csm_state_change(ISIS_DISABLE
, circuit
, area
);
276 struct isis_area
*isis_area_create(const char *area_tag
, const char *vrf_name
)
278 struct isis_area
*area
;
279 struct isis
*isis
= NULL
;
280 struct vrf
*vrf
= NULL
;
281 struct interface
*ifp
;
282 struct isis_circuit
*circuit
;
284 area
= XCALLOC(MTYPE_ISIS_AREA
, sizeof(struct isis_area
));
287 vrf_name
= VRF_DEFAULT_NAME
;
289 vrf
= vrf_lookup_by_name(vrf_name
);
290 isis
= isis_lookup_by_vrfname(vrf_name
);
293 isis
= isis_new(vrf_name
);
295 listnode_add(isis
->area_list
, area
);
299 * Fabricd runs only as level-2.
300 * For IS-IS, the default is level-1-2
303 area
->is_type
= IS_LEVEL_2
;
305 area
->is_type
= yang_get_default_enum(
306 "/frr-isisd:isis/instance/is-type");
309 * intialize the databases
311 if (area
->is_type
& IS_LEVEL_1
)
312 lsp_db_init(&area
->lspdb
[0]);
313 if (area
->is_type
& IS_LEVEL_2
)
314 lsp_db_init(&area
->lspdb
[1]);
316 spftree_area_init(area
);
318 area
->circuit_list
= list_new();
319 area
->adjacency_list
= list_new();
320 area
->area_addrs
= list_new();
321 if (!CHECK_FLAG(im
->options
, F_ISIS_UNIT_TEST
))
322 thread_add_timer(master
, lsp_tick
, area
, 1, &area
->t_tick
);
323 flags_initialize(&area
->flags
);
325 isis_sr_area_init(area
);
331 enum isis_metric_style default_style
;
333 area
->max_lsp_lifetime
[0] = yang_get_default_uint16(
334 "/frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime");
335 area
->max_lsp_lifetime
[1] = yang_get_default_uint16(
336 "/frr-isisd:isis/instance/lsp/timers/level-2/maximum-lifetime");
337 area
->lsp_refresh
[0] = yang_get_default_uint16(
338 "/frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval");
339 area
->lsp_refresh
[1] = yang_get_default_uint16(
340 "/frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval");
341 area
->lsp_gen_interval
[0] = yang_get_default_uint16(
342 "/frr-isisd:isis/instance/lsp/timers/level-1/generation-interval");
343 area
->lsp_gen_interval
[1] = yang_get_default_uint16(
344 "/frr-isisd:isis/instance/lsp/timers/level-2/generation-interval");
345 area
->min_spf_interval
[0] = yang_get_default_uint16(
346 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
347 area
->min_spf_interval
[1] = yang_get_default_uint16(
348 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
349 area
->dynhostname
= yang_get_default_bool(
350 "/frr-isisd:isis/instance/dynamic-hostname");
352 yang_get_default_enum("/frr-isisd:isis/instance/metric-style");
353 area
->oldmetric
= default_style
== ISIS_WIDE_METRIC
? 0 : 1;
354 area
->newmetric
= default_style
== ISIS_NARROW_METRIC
? 0 : 1;
355 area
->lsp_frag_threshold
= 90; /* not currently configurable */
357 yang_get_default_uint16("/frr-isisd:isis/instance/lsp/mtu");
358 area
->lfa_load_sharing
[0] = yang_get_default_bool(
359 "/frr-isisd:isis/instance/fast-reroute/level-1/lfa/load-sharing");
360 area
->lfa_load_sharing
[1] = yang_get_default_bool(
361 "/frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing");
362 area
->attached_bit_send
=
363 yang_get_default_bool("/frr-isisd:isis/instance/attach-send");
364 area
->attached_bit_rcv_ignore
= yang_get_default_bool(
365 "/frr-isisd:isis/instance/attach-receive-ignore");
368 area
->max_lsp_lifetime
[0] = DEFAULT_LSP_LIFETIME
; /* 1200 */
369 area
->max_lsp_lifetime
[1] = DEFAULT_LSP_LIFETIME
; /* 1200 */
370 area
->lsp_refresh
[0] = DEFAULT_MAX_LSP_GEN_INTERVAL
; /* 900 */
371 area
->lsp_refresh
[1] = DEFAULT_MAX_LSP_GEN_INTERVAL
; /* 900 */
372 area
->lsp_gen_interval
[0] = DEFAULT_MIN_LSP_GEN_INTERVAL
;
373 area
->lsp_gen_interval
[1] = DEFAULT_MIN_LSP_GEN_INTERVAL
;
374 area
->min_spf_interval
[0] = MINIMUM_SPF_INTERVAL
;
375 area
->min_spf_interval
[1] = MINIMUM_SPF_INTERVAL
;
376 area
->dynhostname
= 1;
379 area
->lsp_frag_threshold
= 90;
380 area
->lsp_mtu
= DEFAULT_LSP_MTU
;
381 area
->lfa_load_sharing
[0] = true;
382 area
->lfa_load_sharing
[1] = true;
383 area
->attached_bit_send
= true;
384 area
->attached_bit_rcv_ignore
= false;
385 #endif /* ifndef FABRICD */
386 area
->lfa_priority_limit
[0] = SPF_PREFIX_PRIO_LOW
;
387 area
->lfa_priority_limit
[1] = SPF_PREFIX_PRIO_LOW
;
388 isis_lfa_tiebreakers_init(area
, ISIS_LEVEL1
);
389 isis_lfa_tiebreakers_init(area
, ISIS_LEVEL2
);
393 area
->area_tag
= strdup(area_tag
);
396 area
->fabricd
= fabricd_new(area
);
398 area
->lsp_refresh_arg
[0].area
= area
;
399 area
->lsp_refresh_arg
[0].level
= IS_LEVEL_1
;
400 area
->lsp_refresh_arg
[1].area
= area
;
401 area
->lsp_refresh_arg
[1].level
= IS_LEVEL_2
;
403 area
->bfd_signalled_down
= false;
404 area
->bfd_force_spf_refresh
= false;
406 QOBJ_REG(area
, isis_area
);
409 FOR_ALL_INTERFACES (vrf
, ifp
) {
410 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
414 if (circuit
&& strmatch(circuit
->tag
, area
->area_tag
))
415 isis_area_add_circuit(area
, circuit
);
422 struct isis_area
*isis_area_lookup_by_vrf(const char *area_tag
,
423 const char *vrf_name
)
425 struct isis_area
*area
;
426 struct listnode
*node
;
427 struct isis
*isis
= NULL
;
429 isis
= isis_lookup_by_vrfname(vrf_name
);
433 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
))
434 if (strcmp(area
->area_tag
, area_tag
) == 0)
440 struct isis_area
*isis_area_lookup(const char *area_tag
, vrf_id_t vrf_id
)
442 struct isis_area
*area
;
443 struct listnode
*node
;
446 isis
= isis_lookup_by_vrfid(vrf_id
);
450 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
))
451 if ((area
->area_tag
== NULL
&& area_tag
== NULL
)
452 || (area
->area_tag
&& area_tag
453 && strcmp(area
->area_tag
, area_tag
) == 0))
459 int isis_area_get(struct vty
*vty
, const char *area_tag
)
461 struct isis_area
*area
;
463 area
= isis_area_lookup(area_tag
, VRF_DEFAULT
);
466 VTY_PUSH_CONTEXT(ROUTER_NODE
, area
);
470 area
= isis_area_create(area_tag
, VRF_DEFAULT_NAME
);
473 zlog_debug("New IS-IS area instance %s", area
->area_tag
);
475 VTY_PUSH_CONTEXT(ROUTER_NODE
, area
);
480 void isis_area_destroy(struct isis_area
*area
)
482 struct listnode
*node
, *nnode
;
483 struct isis_circuit
*circuit
;
484 struct area_addr
*addr
;
489 fabricd_finish(area
->fabricd
);
491 /* Disable MPLS if necessary before flooding LSP */
492 if (IS_MPLS_TE(area
->mta
))
493 area
->mta
->status
= disable
;
495 if (area
->circuit_list
) {
496 for (ALL_LIST_ELEMENTS(area
->circuit_list
, node
, nnode
,
498 isis_area_del_circuit(area
, circuit
);
500 list_delete(&area
->circuit_list
);
502 list_delete(&area
->adjacency_list
);
504 lsp_db_fini(&area
->lspdb
[0]);
505 lsp_db_fini(&area
->lspdb
[1]);
507 /* invalidate and verify to delete all routes from zebra */
508 isis_area_invalidate_routes(area
, area
->is_type
);
509 isis_area_verify_routes(area
);
511 isis_sr_area_term(area
);
513 spftree_area_del(area
);
515 if (area
->spf_timer
[0])
516 isis_spf_timer_free(THREAD_ARG(area
->spf_timer
[0]));
517 thread_cancel(&area
->spf_timer
[0]);
518 if (area
->spf_timer
[1])
519 isis_spf_timer_free(THREAD_ARG(area
->spf_timer
[1]));
520 thread_cancel(&area
->spf_timer
[1]);
522 spf_backoff_free(area
->spf_delay_ietf
[0]);
523 spf_backoff_free(area
->spf_delay_ietf
[1]);
525 if (!CHECK_FLAG(im
->options
, F_ISIS_UNIT_TEST
))
526 isis_redist_area_finish(area
);
528 for (ALL_LIST_ELEMENTS(area
->area_addrs
, node
, nnode
, addr
)) {
529 list_delete_node(area
->area_addrs
, node
);
530 XFREE(MTYPE_ISIS_AREA_ADDR
, addr
);
532 area
->area_addrs
= NULL
;
534 for (int i
= SPF_PREFIX_PRIO_CRITICAL
; i
<= SPF_PREFIX_PRIO_MEDIUM
;
536 struct spf_prefix_priority_acl
*ppa
;
538 ppa
= &area
->spf_prefix_priorities
[i
];
539 XFREE(MTYPE_ISIS_ACL_NAME
, ppa
->name
);
541 isis_lfa_tiebreakers_clear(area
, ISIS_LEVEL1
);
542 isis_lfa_tiebreakers_clear(area
, ISIS_LEVEL2
);
544 thread_cancel(&area
->t_tick
);
545 thread_cancel(&area
->t_lsp_refresh
[0]);
546 thread_cancel(&area
->t_lsp_refresh
[1]);
547 thread_cancel(&area
->t_rlfa_rib_update
);
549 thread_cancel_event(master
, area
);
551 listnode_delete(area
->isis
->area_list
, area
);
553 free(area
->area_tag
);
555 area_mt_finish(area
);
557 if (listcount(area
->isis
->area_list
) == 0) {
558 isis_finish(area
->isis
);
561 XFREE(MTYPE_ISIS_AREA
, area
);
565 /* This is hook function for vrf create called as part of vrf_init */
566 static int isis_vrf_new(struct vrf
*vrf
)
569 zlog_debug("%s: VRF Created: %s(%u)", __func__
, vrf
->name
,
575 /* This is hook function for vrf delete call as part of vrf_init */
576 static int isis_vrf_delete(struct vrf
*vrf
)
579 zlog_debug("%s: VRF Deletion: %s(%u)", __func__
, vrf
->name
,
585 static void isis_set_redist_vrf_bitmaps(struct isis
*isis
, bool set
)
587 struct listnode
*node
;
588 struct isis_area
*area
;
593 char do_subscribe
[REDIST_PROTOCOL_COUNT
][ZEBRA_ROUTE_MAX
+ 1];
595 memset(do_subscribe
, 0, sizeof(do_subscribe
));
597 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
))
598 for (protocol
= 0; protocol
< REDIST_PROTOCOL_COUNT
; protocol
++)
599 for (type
= 0; type
< ZEBRA_ROUTE_MAX
+ 1; type
++)
600 for (level
= 0; level
< ISIS_LEVELS
; level
++)
601 if (area
->redist_settings
[protocol
]
605 do_subscribe
[protocol
][type
] =
608 for (protocol
= 0; protocol
< REDIST_PROTOCOL_COUNT
; protocol
++)
609 for (type
= 0; type
< ZEBRA_ROUTE_MAX
+ 1; type
++) {
610 /* This field is actually controlling transmission of
612 * routes to Zebra and has nothing to do with
615 if (type
== PROTO_TYPE
)
618 if (!do_subscribe
[protocol
][type
])
621 afi_t afi
= afi_for_redist_protocol(protocol
);
623 if (type
== DEFAULT_ROUTE
) {
626 zclient
->default_information
631 zclient
->default_information
637 zclient
->redist
[afi
][type
],
641 zclient
->redist
[afi
][type
],
647 static int isis_vrf_enable(struct vrf
*vrf
)
653 zlog_debug("%s: VRF %s id %u enabled", __func__
, vrf
->name
,
656 isis
= isis_lookup_by_vrfname(vrf
->name
);
657 if (isis
&& isis
->vrf_id
!= vrf
->vrf_id
) {
658 old_vrf_id
= isis
->vrf_id
;
659 /* We have instance configured, link to VRF and make it "up". */
660 isis_vrf_link(isis
, vrf
);
663 "%s: isis linked to vrf %s vrf_id %u (old id %u)",
664 __func__
, vrf
->name
, isis
->vrf_id
, old_vrf_id
);
665 /* start zebra redist to us for new vrf */
666 isis_set_redist_vrf_bitmaps(isis
, true);
668 isis_zebra_vrf_register(isis
);
674 static int isis_vrf_disable(struct vrf
*vrf
)
677 vrf_id_t old_vrf_id
= VRF_UNKNOWN
;
679 if (vrf
->vrf_id
== VRF_DEFAULT
)
683 zlog_debug("%s: VRF %s id %d disabled.", __func__
, vrf
->name
,
685 isis
= isis_lookup_by_vrfname(vrf
->name
);
687 old_vrf_id
= isis
->vrf_id
;
689 isis_zebra_vrf_deregister(isis
);
691 isis_set_redist_vrf_bitmaps(isis
, false);
693 /* We have instance configured, unlink
694 * from VRF and make it "down".
696 isis_vrf_unlink(isis
, vrf
);
698 zlog_debug("%s: isis old_vrf_id %d unlinked", __func__
,
705 void isis_vrf_init(void)
707 vrf_init(isis_vrf_new
, isis_vrf_enable
, isis_vrf_disable
,
713 void isis_terminate()
716 struct listnode
*node
, *nnode
;
718 bfd_protocol_integration_set_shutdown(true);
720 if (listcount(im
->isis
) == 0)
723 for (ALL_LIST_ELEMENTS(im
->isis
, node
, nnode
, isis
))
727 void isis_filter_update(struct access_list
*access
)
730 struct isis_area
*area
;
731 struct listnode
*node
, *anode
;
733 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
)) {
734 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
, area
)) {
735 for (int i
= SPF_PREFIX_PRIO_CRITICAL
;
736 i
<= SPF_PREFIX_PRIO_MEDIUM
; i
++) {
737 struct spf_prefix_priority_acl
*ppa
;
739 ppa
= &area
->spf_prefix_priorities
[i
];
741 access_list_lookup(AFI_IP
, ppa
->name
);
743 access_list_lookup(AFI_IP6
, ppa
->name
);
745 lsp_regenerate_schedule(area
, area
->is_type
, 0);
750 void isis_prefix_list_update(struct prefix_list
*plist
)
753 struct isis_area
*area
;
754 struct listnode
*node
, *anode
;
756 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
)) {
757 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
, area
)) {
758 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
;
760 const char *plist_name
=
761 prefix_list_name(plist
);
763 if (!area
->rlfa_plist_name
[level
- 1])
766 if (!strmatch(area
->rlfa_plist_name
[level
- 1],
770 area
->rlfa_plist
[level
- 1] =
771 prefix_list_lookup(AFI_IP
, plist_name
);
772 lsp_regenerate_schedule(area
, area
->is_type
, 0);
779 static void area_set_mt_enabled(struct isis_area
*area
, uint16_t mtid
,
782 struct isis_area_mt_setting
*setting
;
784 setting
= area_get_mt_setting(area
, mtid
);
785 if (setting
->enabled
!= enabled
) {
786 setting
->enabled
= enabled
;
787 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 0);
791 static void area_set_mt_overload(struct isis_area
*area
, uint16_t mtid
,
794 struct isis_area_mt_setting
*setting
;
796 setting
= area_get_mt_setting(area
, mtid
);
797 if (setting
->overload
!= overload
) {
798 setting
->overload
= overload
;
799 if (setting
->enabled
)
800 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
,
804 #endif /* ifdef FABRICD */
806 int area_net_title(struct vty
*vty
, const char *net_title
)
808 VTY_DECLVAR_CONTEXT(isis_area
, area
);
809 struct area_addr
*addr
;
810 struct area_addr
*addrp
;
811 struct listnode
*node
;
815 /* We check that we are not over the maximal number of addresses */
816 if (listcount(area
->area_addrs
) >= area
->isis
->max_area_addrs
) {
818 "Maximum of area addresses (%d) already reached \n",
819 area
->isis
->max_area_addrs
);
820 return CMD_ERR_NOTHING_TODO
;
823 addr
= XMALLOC(MTYPE_ISIS_AREA_ADDR
, sizeof(struct area_addr
));
824 addr
->addr_len
= dotformat2buff(buff
, net_title
);
825 memcpy(addr
->area_addr
, buff
, addr
->addr_len
);
827 zlog_debug("added area address %s for area %s (address length %d)",
828 net_title
, area
->area_tag
, addr
->addr_len
);
829 #endif /* EXTREME_DEBUG */
830 if (addr
->addr_len
< 8 || addr
->addr_len
> 20) {
832 "area address must be at least 8..20 octets long (%d)\n",
834 XFREE(MTYPE_ISIS_AREA_ADDR
, addr
);
835 return CMD_WARNING_CONFIG_FAILED
;
838 if (addr
->area_addr
[addr
->addr_len
- 1] != 0) {
840 "nsel byte (last byte) in area address must be 0\n");
841 XFREE(MTYPE_ISIS_AREA_ADDR
, addr
);
842 return CMD_WARNING_CONFIG_FAILED
;
845 if (area
->isis
->sysid_set
== 0) {
847 * First area address - get the SystemID for this router
849 memcpy(area
->isis
->sysid
, GETSYSID(addr
), ISIS_SYS_ID_LEN
);
850 area
->isis
->sysid_set
= 1;
852 zlog_debug("Router has SystemID %s",
853 sysid_print(area
->isis
->sysid
));
856 * Check that the SystemID portions match
858 if (memcmp(area
->isis
->sysid
, GETSYSID(addr
),
861 "System ID must not change when defining additional area addresses\n");
862 XFREE(MTYPE_ISIS_AREA_ADDR
, addr
);
863 return CMD_WARNING_CONFIG_FAILED
;
866 /* now we see that we don't already have this address */
867 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, node
, addrp
)) {
868 if ((addrp
->addr_len
+ ISIS_SYS_ID_LEN
+ ISIS_NSEL_LEN
)
871 if (!memcmp(addrp
->area_addr
, addr
->area_addr
,
873 XFREE(MTYPE_ISIS_AREA_ADDR
, addr
);
874 return CMD_SUCCESS
; /* silent fail */
880 * Forget the systemID part of the address
882 addr
->addr_len
-= (ISIS_SYS_ID_LEN
+ ISIS_NSEL_LEN
);
883 listnode_add(area
->area_addrs
, addr
);
885 /* only now we can safely generate our LSPs for this area */
886 if (listcount(area
->area_addrs
) > 0) {
887 if (area
->is_type
& IS_LEVEL_1
)
888 lsp_generate(area
, IS_LEVEL_1
);
889 if (area
->is_type
& IS_LEVEL_2
)
890 lsp_generate(area
, IS_LEVEL_2
);
896 int area_clear_net_title(struct vty
*vty
, const char *net_title
)
898 VTY_DECLVAR_CONTEXT(isis_area
, area
);
899 struct area_addr addr
, *addrp
= NULL
;
900 struct listnode
*node
;
903 addr
.addr_len
= dotformat2buff(buff
, net_title
);
904 if (addr
.addr_len
< 8 || addr
.addr_len
> 20) {
906 "Unsupported area address length %d, should be 8...20 \n",
908 return CMD_WARNING_CONFIG_FAILED
;
911 memcpy(addr
.area_addr
, buff
, (int)addr
.addr_len
);
913 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, node
, addrp
))
914 if ((addrp
->addr_len
+ ISIS_SYS_ID_LEN
+ 1) == addr
.addr_len
915 && !memcmp(addrp
->area_addr
, addr
.area_addr
, addr
.addr_len
))
919 vty_out(vty
, "No area address %s for area %s \n", net_title
,
921 return CMD_ERR_NO_MATCH
;
924 listnode_delete(area
->area_addrs
, addrp
);
925 XFREE(MTYPE_ISIS_AREA_ADDR
, addrp
);
928 * Last area address - reset the SystemID for this router
930 if (listcount(area
->area_addrs
) == 0) {
931 memset(area
->isis
->sysid
, 0, ISIS_SYS_ID_LEN
);
932 area
->isis
->sysid_set
= 0;
934 zlog_debug("Router has no SystemID");
941 * 'show isis interface' command
943 int show_isis_interface_common(struct vty
*vty
, struct json_object
*json
,
944 const char *ifname
, char detail
,
945 const char *vrf_name
, bool all_vrf
)
948 return show_isis_interface_common_json(json
, ifname
, detail
,
951 return show_isis_interface_common_vty(vty
, ifname
, detail
,
956 int show_isis_interface_common_json(struct json_object
*json
,
957 const char *ifname
, char detail
,
958 const char *vrf_name
, bool all_vrf
)
960 struct listnode
*anode
, *cnode
, *inode
;
961 struct isis_area
*area
;
962 struct isis_circuit
*circuit
;
964 struct json_object
*areas_json
, *area_json
;
965 struct json_object
*circuits_json
, *circuit_json
;
967 // IS-IS Routing Process not enabled
968 json_object_string_add(json
, "is-is-routing-process-enabled",
974 for (ALL_LIST_ELEMENTS_RO(im
->isis
, inode
, isis
)) {
975 areas_json
= json_object_new_array();
976 json_object_object_add(json
, "areas",
978 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
,
980 area_json
= json_object_new_object();
981 json_object_string_add(
983 area
->area_tag
? area
->area_tag
985 circuits_json
= json_object_new_array();
986 json_object_object_add(area_json
,
989 for (ALL_LIST_ELEMENTS_RO(
990 area
->circuit_list
, cnode
,
993 json_object_new_object();
995 circuit_json
, "circuit",
996 circuit
->circuit_id
);
998 isis_circuit_print_json(
1002 else if (strcmp(circuit
->interface
->name
, ifname
) == 0)
1003 isis_circuit_print_json(
1007 json_object_array_add(
1011 json_object_array_add(areas_json
,
1017 isis
= isis_lookup_by_vrfname(vrf_name
);
1019 areas_json
= json_object_new_array();
1020 json_object_object_add(json
, "areas", areas_json
);
1021 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
,
1023 area_json
= json_object_new_object();
1024 json_object_string_add(area_json
, "area",
1029 circuits_json
= json_object_new_array();
1030 json_object_object_add(area_json
, "circuits",
1032 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
,
1034 circuit_json
= json_object_new_object();
1035 json_object_int_add(
1036 circuit_json
, "circuit",
1037 circuit
->circuit_id
);
1039 isis_circuit_print_json(
1040 circuit
, circuit_json
,
1043 strcmp(circuit
->interface
->name
,
1045 isis_circuit_print_json(
1046 circuit
, circuit_json
,
1048 json_object_array_add(circuits_json
,
1051 json_object_array_add(areas_json
, area_json
);
1058 int show_isis_interface_common_vty(struct vty
*vty
, const char *ifname
,
1059 char detail
, const char *vrf_name
,
1062 struct listnode
*anode
, *cnode
, *inode
;
1063 struct isis_area
*area
;
1064 struct isis_circuit
*circuit
;
1068 vty_out(vty
, "IS-IS Routing Process not enabled\n");
1073 for (ALL_LIST_ELEMENTS_RO(im
->isis
, inode
, isis
)) {
1074 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
,
1076 vty_out(vty
, "Area %s:\n",
1079 if (detail
== ISIS_UI_LEVEL_BRIEF
)
1081 " Interface CircId State Type Level\n");
1083 for (ALL_LIST_ELEMENTS_RO(
1084 area
->circuit_list
, cnode
,
1087 isis_circuit_print_vty(
1090 else if (strcmp(circuit
->interface
->name
, ifname
) == 0)
1091 isis_circuit_print_vty(
1098 isis
= isis_lookup_by_vrfname(vrf_name
);
1100 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
,
1102 vty_out(vty
, "Area %s:\n", area
->area_tag
);
1104 if (detail
== ISIS_UI_LEVEL_BRIEF
)
1106 " Interface CircId State Type Level\n");
1108 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
,
1111 isis_circuit_print_vty(
1112 circuit
, vty
, detail
);
1114 strcmp(circuit
->interface
->name
,
1116 isis_circuit_print_vty(
1117 circuit
, vty
, detail
);
1125 DEFUN(show_isis_interface
,
1126 show_isis_interface_cmd
,
1127 "show " PROTO_NAME
" [vrf <NAME|all>] interface [json]",
1133 "IS-IS interface\n")
1135 int res
= CMD_SUCCESS
;
1136 const char *vrf_name
= VRF_DEFAULT_NAME
;
1137 bool all_vrf
= false;
1139 bool uj
= use_json(argc
, argv
);
1140 json_object
*json
= NULL
;
1142 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1144 json
= json_object_new_object();
1145 res
= show_isis_interface_common(vty
, json
, NULL
, ISIS_UI_LEVEL_BRIEF
,
1148 vty_json(vty
, json
);
1152 DEFUN(show_isis_interface_detail
,
1153 show_isis_interface_detail_cmd
,
1154 "show " PROTO_NAME
" [vrf <NAME|all>] interface detail [json]",
1160 "show detailed information\n"
1163 int res
= CMD_SUCCESS
;
1164 const char *vrf_name
= VRF_DEFAULT_NAME
;
1165 bool all_vrf
= false;
1167 bool uj
= use_json(argc
, argv
);
1168 json_object
*json
= NULL
;
1170 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1172 json
= json_object_new_object();
1173 res
= show_isis_interface_common(vty
, json
, NULL
, ISIS_UI_LEVEL_DETAIL
,
1176 vty_json(vty
, json
);
1180 DEFUN(show_isis_interface_arg
,
1181 show_isis_interface_arg_cmd
,
1182 "show " PROTO_NAME
" [vrf <NAME|all>] interface WORD [json]",
1188 "IS-IS interface name\n"
1191 int res
= CMD_SUCCESS
;
1193 const char *vrf_name
= VRF_DEFAULT_NAME
;
1194 bool all_vrf
= false;
1196 bool uj
= use_json(argc
, argv
);
1197 json_object
*json
= NULL
;
1199 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1201 json
= json_object_new_object();
1203 char *ifname
= argv_find(argv
, argc
, "WORD", &idx_word
)
1204 ? argv
[idx_word
]->arg
1206 res
= show_isis_interface_common(
1207 vty
, json
, ifname
, ISIS_UI_LEVEL_DETAIL
, vrf_name
, all_vrf
);
1209 vty_json(vty
, json
);
1213 static int id_to_sysid(struct isis
*isis
, const char *id
, uint8_t *sysid
)
1215 struct isis_dynhn
*dynhn
;
1217 memset(sysid
, 0, ISIS_SYS_ID_LEN
);
1219 if (sysid2buff(sysid
, id
) == 0) {
1220 dynhn
= dynhn_find_by_name(isis
, id
);
1223 memcpy(sysid
, dynhn
->id
, ISIS_SYS_ID_LEN
);
1230 static void isis_neighbor_common_json(struct json_object
*json
, const char *id
,
1231 char detail
, struct isis
*isis
,
1234 struct listnode
*anode
, *cnode
, *node
;
1235 struct isis_area
*area
;
1236 struct isis_circuit
*circuit
;
1238 struct isis_adjacency
*adj
;
1239 struct json_object
*areas_json
, *area_json
;
1240 struct json_object
*circuits_json
, *circuit_json
;
1243 areas_json
= json_object_new_array();
1244 json_object_object_add(json
, "areas", areas_json
);
1245 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
, area
)) {
1246 area_json
= json_object_new_object();
1247 json_object_string_add(area_json
, "area",
1248 area
->area_tag
? area
->area_tag
1250 circuits_json
= json_object_new_array();
1251 json_object_object_add(area_json
, "circuits", circuits_json
);
1252 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, cnode
, circuit
)) {
1253 circuit_json
= json_object_new_object();
1254 json_object_int_add(circuit_json
, "circuit",
1255 circuit
->circuit_id
);
1256 if (circuit
->circ_type
== CIRCUIT_T_BROADCAST
) {
1257 for (i
= 0; i
< 2; i
++) {
1258 adjdb
= circuit
->u
.bc
.adjdb
[i
];
1259 if (adjdb
&& adjdb
->count
) {
1260 for (ALL_LIST_ELEMENTS_RO(
1266 isis_adj_print_json(
1272 } else if (circuit
->circ_type
== CIRCUIT_T_P2P
&&
1273 circuit
->u
.p2p
.neighbor
) {
1274 adj
= circuit
->u
.p2p
.neighbor
;
1276 !memcmp(adj
->sysid
, sysid
, ISIS_SYS_ID_LEN
))
1277 isis_adj_print_json(adj
, circuit_json
,
1280 json_object_array_add(circuits_json
, circuit_json
);
1282 json_object_array_add(areas_json
, area_json
);
1286 static void isis_neighbor_common_vty(struct vty
*vty
, const char *id
,
1287 char detail
, struct isis
*isis
,
1290 struct listnode
*anode
, *cnode
, *node
;
1291 struct isis_area
*area
;
1292 struct isis_circuit
*circuit
;
1294 struct isis_adjacency
*adj
;
1297 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
, area
)) {
1298 vty_out(vty
, "Area %s:\n", area
->area_tag
);
1300 if (detail
== ISIS_UI_LEVEL_BRIEF
)
1302 " System Id Interface L State Holdtime SNPA\n");
1304 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, cnode
, circuit
)) {
1305 if (circuit
->circ_type
== CIRCUIT_T_BROADCAST
) {
1306 for (i
= 0; i
< 2; i
++) {
1307 adjdb
= circuit
->u
.bc
.adjdb
[i
];
1308 if (adjdb
&& adjdb
->count
) {
1309 for (ALL_LIST_ELEMENTS_RO(
1321 } else if (circuit
->circ_type
== CIRCUIT_T_P2P
&&
1322 circuit
->u
.p2p
.neighbor
) {
1323 adj
= circuit
->u
.p2p
.neighbor
;
1325 !memcmp(adj
->sysid
, sysid
, ISIS_SYS_ID_LEN
))
1326 isis_adj_print_vty(adj
, vty
, detail
);
1332 static void isis_neighbor_common(struct vty
*vty
, struct json_object
*json
,
1333 const char *id
, char detail
, struct isis
*isis
,
1337 isis_neighbor_common_json(json
, id
, detail
,isis
,sysid
);
1339 isis_neighbor_common_vty(vty
, id
, detail
,isis
,sysid
);
1344 * 'show isis neighbor' command
1347 int show_isis_neighbor_common(struct vty
*vty
, struct json_object
*json
,
1348 const char *id
, char detail
, const char *vrf_name
,
1351 struct listnode
*node
;
1352 uint8_t sysid
[ISIS_SYS_ID_LEN
];
1356 vty_out(vty
, "IS-IS Routing Process not enabled\n");
1362 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
)) {
1363 if (id_to_sysid(isis
, id
, sysid
)) {
1364 vty_out(vty
, "Invalid system id %s\n",
1368 isis_neighbor_common(vty
, json
, id
, detail
,
1373 isis
= isis_lookup_by_vrfname(vrf_name
);
1375 if (id_to_sysid(isis
, id
, sysid
)) {
1376 vty_out(vty
, "Invalid system id %s\n", id
);
1379 isis_neighbor_common(vty
, json
, id
, detail
, isis
,
1387 static void isis_neighbor_common_clear(struct vty
*vty
, const char *id
,
1388 uint8_t *sysid
, struct isis
*isis
)
1390 struct listnode
*anode
, *cnode
, *node
, *nnode
;
1391 struct isis_area
*area
;
1392 struct isis_circuit
*circuit
;
1394 struct isis_adjacency
*adj
;
1397 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, anode
, area
)) {
1398 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, cnode
, circuit
)) {
1399 if (circuit
->circ_type
== CIRCUIT_T_BROADCAST
) {
1400 for (i
= 0; i
< 2; i
++) {
1401 adjdb
= circuit
->u
.bc
.adjdb
[i
];
1402 if (adjdb
&& adjdb
->count
) {
1403 for (ALL_LIST_ELEMENTS(
1411 isis_adj_state_change(
1414 "clear user request");
1417 } else if (circuit
->circ_type
== CIRCUIT_T_P2P
1418 && circuit
->u
.p2p
.neighbor
) {
1419 adj
= circuit
->u
.p2p
.neighbor
;
1421 || !memcmp(adj
->sysid
, sysid
,
1423 isis_adj_state_change(
1424 &adj
, ISIS_ADJ_DOWN
,
1425 "clear user request");
1431 * 'clear isis neighbor' command
1433 int clear_isis_neighbor_common(struct vty
*vty
, const char *id
, const char *vrf_name
,
1436 struct listnode
*node
;
1437 uint8_t sysid
[ISIS_SYS_ID_LEN
];
1441 vty_out(vty
, "IS-IS Routing Process not enabled\n");
1447 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
)) {
1448 if (id_to_sysid(isis
, id
, sysid
)) {
1449 vty_out(vty
, "Invalid system id %s\n",
1453 isis_neighbor_common_clear(vty
, id
, sysid
,
1458 isis
= isis_lookup_by_vrfname(vrf_name
);
1460 if (id_to_sysid(isis
, id
, sysid
)) {
1461 vty_out(vty
, "Invalid system id %s\n", id
);
1464 isis_neighbor_common_clear(vty
, id
, sysid
, isis
);
1471 DEFUN(show_isis_neighbor
,
1472 show_isis_neighbor_cmd
,
1473 "show " PROTO_NAME
" [vrf <NAME|all>] neighbor [json]",
1478 "IS-IS neighbor adjacencies\n"
1481 int res
= CMD_SUCCESS
;
1482 const char *vrf_name
= VRF_DEFAULT_NAME
;
1483 bool all_vrf
= false;
1485 bool uj
= use_json(argc
, argv
);
1486 json_object
*json
= NULL
;
1488 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1490 json
= json_object_new_object();
1491 res
= show_isis_neighbor_common(vty
, json
, NULL
, ISIS_UI_LEVEL_BRIEF
,
1494 vty_json(vty
, json
);
1498 DEFUN(show_isis_neighbor_detail
,
1499 show_isis_neighbor_detail_cmd
,
1500 "show " PROTO_NAME
" [vrf <NAME|all>] neighbor detail [json]",
1505 "IS-IS neighbor adjacencies\n"
1506 "show detailed information\n"
1509 int res
= CMD_SUCCESS
;
1510 const char *vrf_name
= VRF_DEFAULT_NAME
;
1511 bool all_vrf
= false;
1513 bool uj
= use_json(argc
, argv
);
1514 json_object
*json
= NULL
;
1516 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1518 json
= json_object_new_object();
1520 res
= show_isis_neighbor_common(vty
, json
, NULL
, ISIS_UI_LEVEL_DETAIL
,
1523 vty_json(vty
, json
);
1527 DEFUN(show_isis_neighbor_arg
,
1528 show_isis_neighbor_arg_cmd
,
1529 "show " PROTO_NAME
" [vrf <NAME|all>] neighbor WORD [json]",
1534 "IS-IS neighbor adjacencies\n"
1538 int res
= CMD_SUCCESS
;
1540 const char *vrf_name
= VRF_DEFAULT_NAME
;
1541 bool all_vrf
= false;
1543 bool uj
= use_json(argc
, argv
);
1544 json_object
*json
= NULL
;
1546 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1548 json
= json_object_new_object();
1549 char *id
= argv_find(argv
, argc
, "WORD", &idx_word
)
1550 ? argv
[idx_word
]->arg
1553 res
= show_isis_neighbor_common(vty
, json
, id
, ISIS_UI_LEVEL_DETAIL
,
1556 vty_json(vty
, json
);
1560 DEFUN(clear_isis_neighbor
,
1561 clear_isis_neighbor_cmd
,
1562 "clear " PROTO_NAME
" [vrf <NAME|all>] neighbor",
1567 "IS-IS neighbor adjacencies\n")
1569 const char *vrf_name
= VRF_DEFAULT_NAME
;
1570 bool all_vrf
= false;
1573 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1574 return clear_isis_neighbor_common(vty
, NULL
, vrf_name
, all_vrf
);
1577 DEFUN(clear_isis_neighbor_arg
,
1578 clear_isis_neighbor_arg_cmd
,
1579 "clear " PROTO_NAME
" [vrf <NAME|all>] neighbor WORD",
1584 "IS-IS neighbor adjacencies\n"
1588 const char *vrf_name
= VRF_DEFAULT_NAME
;
1589 bool all_vrf
= false;
1592 char *id
= argv_find(argv
, argc
, "WORD", &idx_word
)
1593 ? argv
[idx_word
]->arg
1595 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1596 return clear_isis_neighbor_common(vty
, id
, vrf_name
, all_vrf
);
1600 * 'isis debug', 'show debugging'
1602 void print_debug(struct vty
*vty
, int flags
, int onoff
)
1604 const char *onoffs
= onoff
? "on" : "off";
1606 if (flags
& DEBUG_ADJ_PACKETS
)
1608 "IS-IS Adjacency related packets debugging is %s\n",
1610 if (flags
& DEBUG_TX_QUEUE
)
1611 vty_out(vty
, "IS-IS TX queue debugging is %s\n",
1613 if (flags
& DEBUG_SNP_PACKETS
)
1614 vty_out(vty
, "IS-IS CSNP/PSNP packets debugging is %s\n",
1616 if (flags
& DEBUG_SPF_EVENTS
)
1617 vty_out(vty
, "IS-IS SPF events debugging is %s\n", onoffs
);
1618 if (flags
& DEBUG_SR
)
1619 vty_out(vty
, "IS-IS Segment Routing events debugging is %s\n",
1621 if (flags
& DEBUG_TE
)
1623 "IS-IS Traffic Engineering events debugging is %s\n",
1625 if (flags
& DEBUG_LFA
)
1626 vty_out(vty
, "IS-IS LFA events debugging is %s\n", onoffs
);
1627 if (flags
& DEBUG_UPDATE_PACKETS
)
1628 vty_out(vty
, "IS-IS Update related packet debugging is %s\n",
1630 if (flags
& DEBUG_RTE_EVENTS
)
1631 vty_out(vty
, "IS-IS Route related debugging is %s\n", onoffs
);
1632 if (flags
& DEBUG_EVENTS
)
1633 vty_out(vty
, "IS-IS Event debugging is %s\n", onoffs
);
1634 if (flags
& DEBUG_PACKET_DUMP
)
1635 vty_out(vty
, "IS-IS Packet dump debugging is %s\n", onoffs
);
1636 if (flags
& DEBUG_LSP_GEN
)
1637 vty_out(vty
, "IS-IS LSP generation debugging is %s\n", onoffs
);
1638 if (flags
& DEBUG_LSP_SCHED
)
1639 vty_out(vty
, "IS-IS LSP scheduling debugging is %s\n", onoffs
);
1640 if (flags
& DEBUG_FLOODING
)
1641 vty_out(vty
, "IS-IS Flooding debugging is %s\n", onoffs
);
1642 if (flags
& DEBUG_BFD
)
1643 vty_out(vty
, "IS-IS BFD debugging is %s\n", onoffs
);
1644 if (flags
& DEBUG_LDP_SYNC
)
1645 vty_out(vty
, "IS-IS ldp-sync debugging is %s\n", onoffs
);
1648 DEFUN_NOSH (show_debugging
,
1649 show_debugging_isis_cmd
,
1650 "show debugging [" PROTO_NAME
"]",
1652 "State of each debugging option\n"
1655 vty_out(vty
, PROTO_NAME
" debugging status:\n");
1657 if (IS_DEBUG_ADJ_PACKETS
)
1658 print_debug(vty
, DEBUG_ADJ_PACKETS
, 1);
1659 if (IS_DEBUG_TX_QUEUE
)
1660 print_debug(vty
, DEBUG_TX_QUEUE
, 1);
1661 if (IS_DEBUG_SNP_PACKETS
)
1662 print_debug(vty
, DEBUG_SNP_PACKETS
, 1);
1663 if (IS_DEBUG_SPF_EVENTS
)
1664 print_debug(vty
, DEBUG_SPF_EVENTS
, 1);
1666 print_debug(vty
, DEBUG_SR
, 1);
1668 print_debug(vty
, DEBUG_TE
, 1);
1669 if (IS_DEBUG_UPDATE_PACKETS
)
1670 print_debug(vty
, DEBUG_UPDATE_PACKETS
, 1);
1671 if (IS_DEBUG_RTE_EVENTS
)
1672 print_debug(vty
, DEBUG_RTE_EVENTS
, 1);
1673 if (IS_DEBUG_EVENTS
)
1674 print_debug(vty
, DEBUG_EVENTS
, 1);
1675 if (IS_DEBUG_PACKET_DUMP
)
1676 print_debug(vty
, DEBUG_PACKET_DUMP
, 1);
1677 if (IS_DEBUG_LSP_GEN
)
1678 print_debug(vty
, DEBUG_LSP_GEN
, 1);
1679 if (IS_DEBUG_LSP_SCHED
)
1680 print_debug(vty
, DEBUG_LSP_SCHED
, 1);
1681 if (IS_DEBUG_FLOODING
)
1682 print_debug(vty
, DEBUG_FLOODING
, 1);
1684 print_debug(vty
, DEBUG_BFD
, 1);
1685 if (IS_DEBUG_LDP_SYNC
)
1686 print_debug(vty
, DEBUG_LDP_SYNC
, 1);
1688 print_debug(vty
, DEBUG_LFA
, 1);
1693 static int config_write_debug(struct vty
*vty
);
1695 static struct cmd_node debug_node
= {
1699 .config_write
= config_write_debug
,
1702 static int config_write_debug(struct vty
*vty
)
1706 if (IS_DEBUG_ADJ_PACKETS
) {
1707 vty_out(vty
, "debug " PROTO_NAME
" adj-packets\n");
1710 if (IS_DEBUG_TX_QUEUE
) {
1711 vty_out(vty
, "debug " PROTO_NAME
" tx-queue\n");
1714 if (IS_DEBUG_SNP_PACKETS
) {
1715 vty_out(vty
, "debug " PROTO_NAME
" snp-packets\n");
1718 if (IS_DEBUG_SPF_EVENTS
) {
1719 vty_out(vty
, "debug " PROTO_NAME
" spf-events\n");
1723 vty_out(vty
, "debug " PROTO_NAME
" sr-events\n");
1727 vty_out(vty
, "debug " PROTO_NAME
" te-events\n");
1731 vty_out(vty
, "debug " PROTO_NAME
" lfa\n");
1734 if (IS_DEBUG_UPDATE_PACKETS
) {
1735 vty_out(vty
, "debug " PROTO_NAME
" update-packets\n");
1738 if (IS_DEBUG_RTE_EVENTS
) {
1739 vty_out(vty
, "debug " PROTO_NAME
" route-events\n");
1742 if (IS_DEBUG_EVENTS
) {
1743 vty_out(vty
, "debug " PROTO_NAME
" events\n");
1746 if (IS_DEBUG_PACKET_DUMP
) {
1747 vty_out(vty
, "debug " PROTO_NAME
" packet-dump\n");
1750 if (IS_DEBUG_LSP_GEN
) {
1751 vty_out(vty
, "debug " PROTO_NAME
" lsp-gen\n");
1754 if (IS_DEBUG_LSP_SCHED
) {
1755 vty_out(vty
, "debug " PROTO_NAME
" lsp-sched\n");
1758 if (IS_DEBUG_FLOODING
) {
1759 vty_out(vty
, "debug " PROTO_NAME
" flooding\n");
1763 vty_out(vty
, "debug " PROTO_NAME
" bfd\n");
1766 if (IS_DEBUG_LDP_SYNC
) {
1767 vty_out(vty
, "debug " PROTO_NAME
" ldp-sync\n");
1770 write
+= spf_backoff_write_config(vty
);
1775 DEFUN (debug_isis_adj
,
1777 "debug " PROTO_NAME
" adj-packets",
1780 "IS-IS Adjacency related packets\n")
1782 debug_adj_pkt
|= DEBUG_ADJ_PACKETS
;
1783 print_debug(vty
, DEBUG_ADJ_PACKETS
, 1);
1788 DEFUN (no_debug_isis_adj
,
1789 no_debug_isis_adj_cmd
,
1790 "no debug " PROTO_NAME
" adj-packets",
1794 "IS-IS Adjacency related packets\n")
1796 debug_adj_pkt
&= ~DEBUG_ADJ_PACKETS
;
1797 print_debug(vty
, DEBUG_ADJ_PACKETS
, 0);
1802 DEFUN (debug_isis_tx_queue
,
1803 debug_isis_tx_queue_cmd
,
1804 "debug " PROTO_NAME
" tx-queue",
1807 "IS-IS TX queues\n")
1809 debug_tx_queue
|= DEBUG_TX_QUEUE
;
1810 print_debug(vty
, DEBUG_TX_QUEUE
, 1);
1815 DEFUN (no_debug_isis_tx_queue
,
1816 no_debug_isis_tx_queue_cmd
,
1817 "no debug " PROTO_NAME
" tx-queue",
1821 "IS-IS TX queues\n")
1823 debug_tx_queue
&= ~DEBUG_TX_QUEUE
;
1824 print_debug(vty
, DEBUG_TX_QUEUE
, 0);
1829 DEFUN (debug_isis_flooding
,
1830 debug_isis_flooding_cmd
,
1831 "debug " PROTO_NAME
" flooding",
1834 "Flooding algorithm\n")
1836 debug_flooding
|= DEBUG_FLOODING
;
1837 print_debug(vty
, DEBUG_FLOODING
, 1);
1842 DEFUN (no_debug_isis_flooding
,
1843 no_debug_isis_flooding_cmd
,
1844 "no debug " PROTO_NAME
" flooding",
1848 "Flooding algorithm\n")
1850 debug_flooding
&= ~DEBUG_FLOODING
;
1851 print_debug(vty
, DEBUG_FLOODING
, 0);
1856 DEFUN (debug_isis_snp
,
1858 "debug " PROTO_NAME
" snp-packets",
1861 "IS-IS CSNP/PSNP packets\n")
1863 debug_snp_pkt
|= DEBUG_SNP_PACKETS
;
1864 print_debug(vty
, DEBUG_SNP_PACKETS
, 1);
1869 DEFUN (no_debug_isis_snp
,
1870 no_debug_isis_snp_cmd
,
1871 "no debug " PROTO_NAME
" snp-packets",
1875 "IS-IS CSNP/PSNP packets\n")
1877 debug_snp_pkt
&= ~DEBUG_SNP_PACKETS
;
1878 print_debug(vty
, DEBUG_SNP_PACKETS
, 0);
1883 DEFUN (debug_isis_upd
,
1885 "debug " PROTO_NAME
" update-packets",
1888 "IS-IS Update related packets\n")
1890 debug_update_pkt
|= DEBUG_UPDATE_PACKETS
;
1891 print_debug(vty
, DEBUG_UPDATE_PACKETS
, 1);
1896 DEFUN (no_debug_isis_upd
,
1897 no_debug_isis_upd_cmd
,
1898 "no debug " PROTO_NAME
" update-packets",
1902 "IS-IS Update related packets\n")
1904 debug_update_pkt
&= ~DEBUG_UPDATE_PACKETS
;
1905 print_debug(vty
, DEBUG_UPDATE_PACKETS
, 0);
1910 DEFUN (debug_isis_spfevents
,
1911 debug_isis_spfevents_cmd
,
1912 "debug " PROTO_NAME
" spf-events",
1915 "IS-IS Shortest Path First Events\n")
1917 debug_spf_events
|= DEBUG_SPF_EVENTS
;
1918 print_debug(vty
, DEBUG_SPF_EVENTS
, 1);
1923 DEFUN (no_debug_isis_spfevents
,
1924 no_debug_isis_spfevents_cmd
,
1925 "no debug " PROTO_NAME
" spf-events",
1929 "IS-IS Shortest Path First Events\n")
1931 debug_spf_events
&= ~DEBUG_SPF_EVENTS
;
1932 print_debug(vty
, DEBUG_SPF_EVENTS
, 0);
1937 DEFUN (debug_isis_srevents
,
1938 debug_isis_srevents_cmd
,
1939 "debug " PROTO_NAME
" sr-events",
1942 "IS-IS Segment Routing Events\n")
1944 debug_sr
|= DEBUG_SR
;
1945 print_debug(vty
, DEBUG_SR
, 1);
1950 DEFUN (no_debug_isis_srevents
,
1951 no_debug_isis_srevents_cmd
,
1952 "no debug " PROTO_NAME
" sr-events",
1956 "IS-IS Segment Routing Events\n")
1958 debug_sr
&= ~DEBUG_SR
;
1959 print_debug(vty
, DEBUG_SR
, 0);
1964 DEFUN (debug_isis_teevents
,
1965 debug_isis_teevents_cmd
,
1966 "debug " PROTO_NAME
" te-events",
1969 "IS-IS Traffic Engineering Events\n")
1971 debug_te
|= DEBUG_TE
;
1972 print_debug(vty
, DEBUG_TE
, 1);
1977 DEFUN (no_debug_isis_teevents
,
1978 no_debug_isis_teevents_cmd
,
1979 "no debug " PROTO_NAME
" te-events",
1983 "IS-IS Traffic Engineering Events\n")
1985 debug_te
&= ~DEBUG_TE
;
1986 print_debug(vty
, DEBUG_TE
, 0);
1991 DEFUN (debug_isis_lfa
,
1993 "debug " PROTO_NAME
" lfa",
1996 "IS-IS LFA Events\n")
1998 debug_lfa
|= DEBUG_LFA
;
1999 print_debug(vty
, DEBUG_LFA
, 1);
2004 DEFUN (no_debug_isis_lfa
,
2005 no_debug_isis_lfa_cmd
,
2006 "no debug " PROTO_NAME
" lfa",
2010 "IS-IS LFA Events\n")
2012 debug_lfa
&= ~DEBUG_LFA
;
2013 print_debug(vty
, DEBUG_LFA
, 0);
2018 DEFUN (debug_isis_rtevents
,
2019 debug_isis_rtevents_cmd
,
2020 "debug " PROTO_NAME
" route-events",
2023 "IS-IS Route related events\n")
2025 debug_rte_events
|= DEBUG_RTE_EVENTS
;
2026 print_debug(vty
, DEBUG_RTE_EVENTS
, 1);
2031 DEFUN (no_debug_isis_rtevents
,
2032 no_debug_isis_rtevents_cmd
,
2033 "no debug " PROTO_NAME
" route-events",
2037 "IS-IS Route related events\n")
2039 debug_rte_events
&= ~DEBUG_RTE_EVENTS
;
2040 print_debug(vty
, DEBUG_RTE_EVENTS
, 0);
2045 DEFUN (debug_isis_events
,
2046 debug_isis_events_cmd
,
2047 "debug " PROTO_NAME
" events",
2052 debug_events
|= DEBUG_EVENTS
;
2053 print_debug(vty
, DEBUG_EVENTS
, 1);
2058 DEFUN (no_debug_isis_events
,
2059 no_debug_isis_events_cmd
,
2060 "no debug " PROTO_NAME
" events",
2066 debug_events
&= ~DEBUG_EVENTS
;
2067 print_debug(vty
, DEBUG_EVENTS
, 0);
2072 DEFUN (debug_isis_packet_dump
,
2073 debug_isis_packet_dump_cmd
,
2074 "debug " PROTO_NAME
" packet-dump",
2077 "IS-IS packet dump\n")
2079 debug_pkt_dump
|= DEBUG_PACKET_DUMP
;
2080 print_debug(vty
, DEBUG_PACKET_DUMP
, 1);
2085 DEFUN (no_debug_isis_packet_dump
,
2086 no_debug_isis_packet_dump_cmd
,
2087 "no debug " PROTO_NAME
" packet-dump",
2091 "IS-IS packet dump\n")
2093 debug_pkt_dump
&= ~DEBUG_PACKET_DUMP
;
2094 print_debug(vty
, DEBUG_PACKET_DUMP
, 0);
2099 DEFUN (debug_isis_lsp_gen
,
2100 debug_isis_lsp_gen_cmd
,
2101 "debug " PROTO_NAME
" lsp-gen",
2104 "IS-IS generation of own LSPs\n")
2106 debug_lsp_gen
|= DEBUG_LSP_GEN
;
2107 print_debug(vty
, DEBUG_LSP_GEN
, 1);
2112 DEFUN (no_debug_isis_lsp_gen
,
2113 no_debug_isis_lsp_gen_cmd
,
2114 "no debug " PROTO_NAME
" lsp-gen",
2118 "IS-IS generation of own LSPs\n")
2120 debug_lsp_gen
&= ~DEBUG_LSP_GEN
;
2121 print_debug(vty
, DEBUG_LSP_GEN
, 0);
2126 DEFUN (debug_isis_lsp_sched
,
2127 debug_isis_lsp_sched_cmd
,
2128 "debug " PROTO_NAME
" lsp-sched",
2131 "IS-IS scheduling of LSP generation\n")
2133 debug_lsp_sched
|= DEBUG_LSP_SCHED
;
2134 print_debug(vty
, DEBUG_LSP_SCHED
, 1);
2139 DEFUN (no_debug_isis_lsp_sched
,
2140 no_debug_isis_lsp_sched_cmd
,
2141 "no debug " PROTO_NAME
" lsp-sched",
2145 "IS-IS scheduling of LSP generation\n")
2147 debug_lsp_sched
&= ~DEBUG_LSP_SCHED
;
2148 print_debug(vty
, DEBUG_LSP_SCHED
, 0);
2153 DEFUN (debug_isis_bfd
,
2155 "debug " PROTO_NAME
" bfd",
2158 PROTO_NAME
" interaction with BFD\n")
2160 debug_bfd
|= DEBUG_BFD
;
2161 bfd_protocol_integration_set_debug(true);
2162 print_debug(vty
, DEBUG_BFD
, 1);
2167 DEFUN (no_debug_isis_bfd
,
2168 no_debug_isis_bfd_cmd
,
2169 "no debug " PROTO_NAME
" bfd",
2173 PROTO_NAME
" interaction with BFD\n")
2175 debug_bfd
&= ~DEBUG_BFD
;
2176 bfd_protocol_integration_set_debug(false);
2177 print_debug(vty
, DEBUG_BFD
, 0);
2182 DEFUN(debug_isis_ldp_sync
, debug_isis_ldp_sync_cmd
,
2183 "debug " PROTO_NAME
" ldp-sync",
2184 DEBUG_STR PROTO_HELP PROTO_NAME
" interaction with LDP-Sync\n")
2186 debug_ldp_sync
|= DEBUG_LDP_SYNC
;
2187 print_debug(vty
, DEBUG_LDP_SYNC
, 1);
2192 DEFUN(no_debug_isis_ldp_sync
, no_debug_isis_ldp_sync_cmd
,
2193 "no debug " PROTO_NAME
" ldp-sync",
2194 NO_STR UNDEBUG_STR PROTO_HELP PROTO_NAME
" interaction with LDP-Sync\n")
2196 debug_ldp_sync
&= ~DEBUG_LDP_SYNC
;
2197 print_debug(vty
, DEBUG_LDP_SYNC
, 0);
2202 DEFUN (show_hostname
,
2204 "show " PROTO_NAME
" [vrf <NAME|all>] hostname",
2205 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2207 "IS-IS Dynamic hostname mapping\n")
2209 struct listnode
*node
;
2210 const char *vrf_name
= VRF_DEFAULT_NAME
;
2211 bool all_vrf
= false;
2215 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
2218 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
2219 dynhn_print_all(vty
, isis
);
2223 isis
= isis_lookup_by_vrfname(vrf_name
);
2225 dynhn_print_all(vty
, isis
);
2231 static void isis_spf_ietf_common(struct vty
*vty
, struct isis
*isis
)
2233 struct listnode
*node
;
2234 struct isis_area
*area
;
2235 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
)) {
2237 vty_out(vty
, "vrf : %s\n", isis
->name
);
2238 vty_out(vty
, "Area %s:\n",
2239 area
->area_tag
? area
->area_tag
: "null");
2241 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
; level
++) {
2242 if ((area
->is_type
& level
) == 0)
2245 vty_out(vty
, " Level-%d:\n", level
);
2246 vty_out(vty
, " SPF delay status: ");
2247 if (area
->spf_timer
[level
- 1]) {
2248 struct timeval remain
= thread_timer_remain(
2249 area
->spf_timer
[level
- 1]);
2250 vty_out(vty
, "Pending, due in %lld msec\n",
2251 (long long)remain
.tv_sec
* 1000
2252 + remain
.tv_usec
/ 1000);
2254 vty_out(vty
, "Not scheduled\n");
2257 if (area
->spf_delay_ietf
[level
- 1]) {
2259 " Using draft-ietf-rtgwg-backoff-algo-04\n");
2261 area
->spf_delay_ietf
[level
- 1], vty
,
2264 vty_out(vty
, " Using legacy backoff algo\n");
2270 DEFUN(show_isis_spf_ietf
, show_isis_spf_ietf_cmd
,
2271 "show " PROTO_NAME
" [vrf <NAME|all>] spf-delay-ietf",
2272 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2274 "SPF delay IETF information\n")
2276 struct listnode
*node
;
2279 const char *vrf_name
= VRF_DEFAULT_NAME
;
2280 bool all_vrf
= false;
2282 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
)
2285 vty_out(vty
, "ISIS is not running\n");
2291 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
2292 isis_spf_ietf_common(vty
, isis
);
2296 isis
= isis_lookup_by_vrfname(vrf_name
);
2298 isis_spf_ietf_common(vty
, isis
);
2305 static const char *pdu_counter_index_to_name_json(enum pdu_counter_index index
)
2308 case L1_LAN_HELLO_INDEX
:
2310 case L2_LAN_HELLO_INDEX
:
2312 case P2P_HELLO_INDEX
:
2314 case L1_LINK_STATE_INDEX
:
2316 case L2_LINK_STATE_INDEX
:
2318 case FS_LINK_STATE_INDEX
:
2320 case L1_COMPLETE_SEQ_NUM_INDEX
:
2322 case L2_COMPLETE_SEQ_NUM_INDEX
:
2324 case L1_PARTIAL_SEQ_NUM_INDEX
:
2326 case L2_PARTIAL_SEQ_NUM_INDEX
:
2333 static void common_isis_summary_json(struct json_object
*json
,
2337 json_object
*areas_json
, *area_json
, *tx_pdu_json
, *rx_pdu_json
,
2338 *levels_json
, *level_json
;
2339 struct listnode
*node
, *node2
;
2340 struct isis_area
*area
;
2342 char uptime
[MONOTIME_STRLEN
];
2344 json_object_string_add(json
, "vrf", isis
->name
);
2345 json_object_int_add(json
, "process-id", isis
->process_id
);
2346 if (isis
->sysid_set
)
2347 json_object_string_add(json
, "system-id",
2348 sysid_print(isis
->sysid
));
2351 cur
-= isis
->uptime
;
2352 frrtime_to_interval(cur
, uptime
, sizeof(uptime
));
2353 json_object_string_add(json
, "up-time", uptime
);
2354 if (isis
->area_list
)
2355 json_object_int_add(json
, "number-areas",
2356 isis
->area_list
->count
);
2357 areas_json
= json_object_new_array();
2358 json_object_object_add(json
, "areas", areas_json
);
2359 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
)) {
2360 area_json
= json_object_new_object();
2361 json_object_string_add(area_json
, "area",
2362 area
->area_tag
? area
->area_tag
2367 uint8_t tier
= fabricd_tier(area
);
2368 snprintfrr(stier
, sizeof(stier
), "%s", &tier
);
2369 json_object_string_add(area_json
, "tier",
2370 tier
== ISIS_TIER_UNDEFINED
2375 if (listcount(area
->area_addrs
) > 0) {
2376 struct area_addr
*area_addr
;
2377 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, node2
,
2379 json_object_string_add(
2381 isonet_print(area_addr
->area_addr
,
2382 area_addr
->addr_len
+
2388 tx_pdu_json
= json_object_new_object();
2389 json_object_object_add(area_json
, "tx-pdu-type", tx_pdu_json
);
2390 for (int i
= 0; i
< PDU_COUNTER_SIZE
; i
++) {
2391 if (!area
->pdu_tx_counters
[i
])
2393 json_object_int_add(tx_pdu_json
,
2394 pdu_counter_index_to_name_json(i
),
2395 area
->pdu_tx_counters
[i
]);
2397 json_object_int_add(tx_pdu_json
, "lsp-rxmt",
2398 area
->lsp_rxmt_count
);
2400 rx_pdu_json
= json_object_new_object();
2401 json_object_object_add(area_json
, "rx-pdu-type", rx_pdu_json
);
2402 for (int i
= 0; i
< PDU_COUNTER_SIZE
; i
++) {
2403 if (!area
->pdu_rx_counters
[i
])
2405 json_object_int_add(rx_pdu_json
,
2406 pdu_counter_index_to_name_json(i
),
2407 area
->pdu_rx_counters
[i
]);
2410 levels_json
= json_object_new_array();
2411 json_object_object_add(area_json
, "levels", levels_json
);
2412 for (level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
; level
++) {
2413 if ((area
->is_type
& level
) == 0)
2415 level_json
= json_object_new_object();
2416 json_object_int_add(level_json
, "id", level
);
2417 json_object_int_add(level_json
, "lsp0-regenerated",
2418 area
->lsp_gen_count
[level
- 1]);
2419 json_object_int_add(level_json
, "lsp-purged",
2420 area
->lsp_purge_count
[level
- 1]);
2421 if (area
->spf_timer
[level
- 1])
2422 json_object_string_add(level_json
, "spf",
2425 json_object_string_add(level_json
, "spf",
2427 json_object_int_add(level_json
, "minimum-interval",
2428 area
->min_spf_interval
[level
- 1]);
2429 if (area
->spf_delay_ietf
[level
- 1])
2430 json_object_string_add(
2431 level_json
, "ietf-spf-delay-activated",
2433 if (area
->ip_circuits
) {
2434 isis_spf_print_json(
2435 area
->spftree
[SPFTREE_IPV4
][level
- 1],
2438 if (area
->ipv6_circuits
) {
2439 isis_spf_print_json(
2440 area
->spftree
[SPFTREE_IPV6
][level
- 1],
2443 json_object_array_add(levels_json
, level_json
);
2445 json_object_array_add(areas_json
, area_json
);
2449 static void common_isis_summary_vty(struct vty
*vty
, struct isis
*isis
)
2451 struct listnode
*node
, *node2
;
2452 struct isis_area
*area
;
2455 vty_out(vty
, "vrf : %s\n", isis
->name
);
2456 vty_out(vty
, "Process Id : %ld\n", isis
->process_id
);
2457 if (isis
->sysid_set
)
2458 vty_out(vty
, "System Id : %s\n",
2459 sysid_print(isis
->sysid
));
2461 vty_out(vty
, "Up time : ");
2462 vty_out_timestr(vty
, isis
->uptime
);
2465 if (isis
->area_list
)
2466 vty_out(vty
, "Number of areas : %d\n", isis
->area_list
->count
);
2468 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
)) {
2469 vty_out(vty
, "Area %s:\n",
2470 area
->area_tag
? area
->area_tag
: "null");
2473 uint8_t tier
= fabricd_tier(area
);
2474 if (tier
== ISIS_TIER_UNDEFINED
)
2475 vty_out(vty
, " Tier: undefined\n");
2477 vty_out(vty
, " Tier: %hhu\n", tier
);
2480 if (listcount(area
->area_addrs
) > 0) {
2481 struct area_addr
*area_addr
;
2482 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, node2
,
2484 vty_out(vty
, " Net: %s\n",
2485 isonet_print(area_addr
->area_addr
,
2492 vty_out(vty
, " TX counters per PDU type:\n");
2493 pdu_counter_print(vty
, " ", area
->pdu_tx_counters
);
2494 vty_out(vty
, " LSP RXMT: %" PRIu64
"\n",
2495 area
->lsp_rxmt_count
);
2496 vty_out(vty
, " RX counters per PDU type:\n");
2497 pdu_counter_print(vty
, " ", area
->pdu_rx_counters
);
2499 for (level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
; level
++) {
2500 if ((area
->is_type
& level
) == 0)
2503 vty_out(vty
, " Level-%d:\n", level
);
2505 vty_out(vty
, " LSP0 regenerated: %" PRIu64
"\n",
2506 area
->lsp_gen_count
[level
- 1]);
2508 vty_out(vty
, " LSPs purged: %" PRIu64
"\n",
2509 area
->lsp_purge_count
[level
- 1]);
2511 if (area
->spf_timer
[level
- 1])
2512 vty_out(vty
, " SPF: (pending)\n");
2514 vty_out(vty
, " SPF:\n");
2516 vty_out(vty
, " minimum interval : %d",
2517 area
->min_spf_interval
[level
- 1]);
2518 if (area
->spf_delay_ietf
[level
- 1])
2520 " (not used, IETF SPF delay activated)");
2523 if (area
->ip_circuits
) {
2524 vty_out(vty
, " IPv4 route computation:\n");
2526 area
->spftree
[SPFTREE_IPV4
][level
- 1],
2530 if (area
->ipv6_circuits
) {
2531 vty_out(vty
, " IPv6 route computation:\n");
2533 area
->spftree
[SPFTREE_IPV6
][level
- 1],
2537 if (area
->ipv6_circuits
2538 && isis_area_ipv6_dstsrc_enabled(area
)) {
2540 " IPv6 dst-src route computation:\n");
2541 isis_spf_print(area
->spftree
[SPFTREE_DSTSRC
]
2549 static void common_isis_summary(struct vty
*vty
, struct json_object
*json
,
2553 common_isis_summary_json(json
, isis
);
2555 common_isis_summary_vty(vty
, isis
);
2559 DEFUN(show_isis_summary
, show_isis_summary_cmd
,
2560 "show " PROTO_NAME
" [vrf <NAME|all>] summary [json]",
2561 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2566 struct listnode
*node
;
2569 const char *vrf_name
= VRF_DEFAULT_NAME
;
2570 bool all_vrf
= false;
2571 bool uj
= use_json(argc
, argv
);
2572 json_object
*json
= NULL
;
2574 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
)
2576 vty_out(vty
, PROTO_NAME
" is not running\n");
2580 json
= json_object_new_object();
2583 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
2584 common_isis_summary(vty
, json
, isis
);
2588 isis
= isis_lookup_by_vrfname(vrf_name
);
2590 common_isis_summary(vty
, json
, isis
);
2594 vty_json(vty
, json
);
2599 struct isis_lsp
*lsp_for_sysid(struct lspdb_head
*head
, const char *sysid_str
,
2602 char sysid
[255] = {0};
2603 uint8_t number
[3] = {0};
2605 uint8_t lspid
[ISIS_SYS_ID_LEN
+ 2] = {0};
2606 struct isis_dynhn
*dynhn
;
2607 struct isis_lsp
*lsp
= NULL
;
2613 * extract fragment and pseudo id from the string sysid_str
2615 * (a) <systemid/hostname>.<pseudo-id>-<framenent> or
2616 * (b) <systemid/hostname>.<pseudo-id> or
2617 * (c) <systemid/hostname> or
2618 * Where systemid is in the form:
2621 strlcpy(sysid
, sysid_str
, sizeof(sysid
));
2623 if (strlen(sysid_str
) > 3) {
2624 pos
= sysid_str
+ strlen(sysid_str
) - 3;
2625 if (strncmp(pos
, "-", 1) == 0) {
2626 memcpy(number
, ++pos
, 2);
2627 lspid
[ISIS_SYS_ID_LEN
+ 1] =
2628 (uint8_t)strtol((char *)number
, NULL
, 16);
2630 if (strncmp(pos
, ".", 1) != 0)
2633 if (strncmp(pos
, ".", 1) == 0) {
2634 memcpy(number
, ++pos
, 2);
2635 lspid
[ISIS_SYS_ID_LEN
] =
2636 (uint8_t)strtol((char *)number
, NULL
, 16);
2637 sysid
[pos
- sysid_str
- 1] = '\0';
2642 * Try to find the lsp-id if the sysid_str
2644 * hostname.<pseudo-id>-<fragment>
2646 if (sysid2buff(lspid
, sysid
)) {
2647 lsp
= lsp_search(head
, lspid
);
2648 } else if ((dynhn
= dynhn_find_by_name(isis
, sysid
))) {
2649 memcpy(lspid
, dynhn
->id
, ISIS_SYS_ID_LEN
);
2650 lsp
= lsp_search(head
, lspid
);
2651 } else if (strncmp(cmd_hostname_get(), sysid
, 15) == 0) {
2652 memcpy(lspid
, isis
->sysid
, ISIS_SYS_ID_LEN
);
2653 lsp
= lsp_search(head
, lspid
);
2659 void show_isis_database_lspdb_json(struct json_object
*json
,
2660 struct isis_area
*area
, int level
,
2661 struct lspdb_head
*lspdb
,
2662 const char *sysid_str
, int ui_level
)
2664 struct isis_lsp
*lsp
;
2667 if (lspdb_count(lspdb
) > 0) {
2668 lsp
= lsp_for_sysid(lspdb
, sysid_str
, area
->isis
);
2670 if (lsp
!= NULL
|| sysid_str
== NULL
) {
2671 json_object_int_add(json
, "id", level
+ 1);
2675 if (ui_level
== ISIS_UI_LEVEL_DETAIL
)
2676 lsp_print_detail(lsp
, NULL
, json
,
2677 area
->dynhostname
, area
->isis
);
2679 lsp_print_json(lsp
, json
, area
->dynhostname
,
2681 } else if (sysid_str
== NULL
) {
2683 lsp_print_all(NULL
, json
, lspdb
, ui_level
,
2684 area
->dynhostname
, area
->isis
);
2686 json_object_int_add(json
, "count", lsp_count
);
2690 void show_isis_database_lspdb_vty(struct vty
*vty
, struct isis_area
*area
,
2691 int level
, struct lspdb_head
*lspdb
,
2692 const char *sysid_str
, int ui_level
)
2694 struct isis_lsp
*lsp
;
2697 if (lspdb_count(lspdb
) > 0) {
2698 lsp
= lsp_for_sysid(lspdb
, sysid_str
, area
->isis
);
2700 if (lsp
!= NULL
|| sysid_str
== NULL
) {
2701 vty_out(vty
, "IS-IS Level-%d link-state database:\n",
2704 /* print the title in all cases */
2706 "LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
2710 if (ui_level
== ISIS_UI_LEVEL_DETAIL
)
2711 lsp_print_detail(lsp
, vty
, NULL
,
2712 area
->dynhostname
, area
->isis
);
2714 lsp_print_vty(lsp
, vty
, area
->dynhostname
,
2716 } else if (sysid_str
== NULL
) {
2718 lsp_print_all(vty
, NULL
, lspdb
, ui_level
,
2719 area
->dynhostname
, area
->isis
);
2721 vty_out(vty
, " %u LSPs\n\n", lsp_count
);
2726 static void show_isis_database_json(struct json_object
*json
, const char *sysid_str
,
2727 int ui_level
, struct isis
*isis
)
2729 struct listnode
*node
;
2730 struct isis_area
*area
;
2732 struct json_object
*tag_area_json
,*area_json
, *lsp_json
, *area_arr_json
, *arr_json
;
2733 uint8_t area_cnt
= 0;
2735 if (isis
->area_list
->count
== 0)
2738 area_arr_json
= json_object_new_array();
2739 json_object_object_add(json
, "areas", area_arr_json
);
2740 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
)) {
2741 area_json
= json_object_new_object();
2742 tag_area_json
= json_object_new_object();
2743 json_object_string_add(tag_area_json
, "name",
2744 area
->area_tag
? area
->area_tag
2747 arr_json
= json_object_new_array();
2748 json_object_object_add(area_json
,"area",tag_area_json
);
2749 json_object_object_add(area_json
,"levels",arr_json
);
2750 for (level
= 0; level
< ISIS_LEVELS
; level
++) {
2751 lsp_json
= json_object_new_object();
2752 show_isis_database_lspdb_json(lsp_json
, area
, level
,
2753 &area
->lspdb
[level
],
2754 sysid_str
, ui_level
);
2755 json_object_array_add(arr_json
, lsp_json
);
2757 json_object_array_add(area_arr_json
, area_json
);
2762 static void show_isis_database_vty(struct vty
*vty
, const char *sysid_str
,
2763 int ui_level
, struct isis
*isis
)
2765 struct listnode
*node
;
2766 struct isis_area
*area
;
2769 if (isis
->area_list
->count
== 0)
2772 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
)) {
2773 vty_out(vty
, "Area %s:\n",
2774 area
->area_tag
? area
->area_tag
: "null");
2776 for (level
= 0; level
< ISIS_LEVELS
; level
++)
2777 show_isis_database_lspdb_vty(vty
, area
, level
,
2778 &area
->lspdb
[level
], sysid_str
,
2783 static void show_isis_database_common(struct vty
*vty
, struct json_object
*json
, const char *sysid_str
,
2784 int ui_level
, struct isis
*isis
)
2787 show_isis_database_json(json
, sysid_str
, ui_level
, isis
);
2789 show_isis_database_vty(vty
, sysid_str
, ui_level
, isis
);
2794 * This function supports following display options:
2795 * [ show isis database [detail] ]
2796 * [ show isis database <sysid> [detail] ]
2797 * [ show isis database <hostname> [detail] ]
2798 * [ show isis database <sysid>.<pseudo-id> [detail] ]
2799 * [ show isis database <hostname>.<pseudo-id> [detail] ]
2800 * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
2801 * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
2802 * [ show isis database detail <sysid> ]
2803 * [ show isis database detail <hostname> ]
2804 * [ show isis database detail <sysid>.<pseudo-id> ]
2805 * [ show isis database detail <hostname>.<pseudo-id> ]
2806 * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
2807 * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
2809 static int show_isis_database(struct vty
*vty
, struct json_object
*json
, const char *sysid_str
,
2810 int ui_level
, const char *vrf_name
, bool all_vrf
)
2812 struct listnode
*node
;
2817 for (ALL_LIST_ELEMENTS_RO(im
->isis
, node
, isis
))
2818 show_isis_database_common(vty
, json
, sysid_str
,
2823 isis
= isis_lookup_by_vrfname(vrf_name
);
2825 show_isis_database_common(vty
, json
, sysid_str
,
2832 DEFUN(show_database
, show_database_cmd
,
2833 "show " PROTO_NAME
" [vrf <NAME|all>] database [detail] [WORD] [json]",
2834 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2836 "Link state database\n"
2837 "Detailed information\n"
2841 int res
= CMD_SUCCESS
;
2844 const char *vrf_name
= VRF_DEFAULT_NAME
;
2845 bool all_vrf
= false;
2846 int uilevel
= argv_find(argv
, argc
, "detail", &idx
)
2847 ? ISIS_UI_LEVEL_DETAIL
2848 : ISIS_UI_LEVEL_BRIEF
;
2849 char *id
= argv_find(argv
, argc
, "WORD", &idx
) ? argv
[idx
]->arg
: NULL
;
2850 bool uj
= use_json(argc
, argv
);
2851 json_object
*json
= NULL
;
2853 ISIS_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
2855 json
= json_object_new_object();
2857 res
= show_isis_database(vty
, json
, id
, uilevel
, vrf_name
, all_vrf
);
2859 vty_json(vty
, json
);
2865 * 'router openfabric' command
2867 DEFUN_NOSH (router_openfabric
,
2868 router_openfabric_cmd
,
2869 "router openfabric WORD",
2872 "ISO Routing area tag\n")
2875 return isis_area_get(vty
, argv
[idx_word
]->arg
);
2879 *'no router openfabric' command
2881 DEFUN (no_router_openfabric
,
2882 no_router_openfabric_cmd
,
2883 "no router openfabric WORD",
2887 "ISO Routing area tag\n")
2889 struct isis_area
*area
;
2890 const char *area_tag
;
2893 area_tag
= argv
[idx_word
]->arg
;
2894 area
= isis_area_lookup(area_tag
, VRF_DEFAULT
);
2896 zlog_warn("%s: could not find area with area-tag %s",
2897 __func__
, area_tag
);
2898 return CMD_ERR_NO_MATCH
;
2901 isis_area_destroy(area
);
2904 #endif /* ifdef FABRICD */
2912 "A Network Entity Title for this process (OSI only)\n"
2913 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
2916 return area_net_title(vty
, argv
[idx_word
]->arg
);
2926 "A Network Entity Title for this process (OSI only)\n"
2927 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
2930 return area_clear_net_title(vty
, argv
[idx_word
]->arg
);
2932 #endif /* ifdef FABRICD */
2934 DEFUN (isis_topology
,
2936 "topology " ISIS_MT_NAMES
" [overload]",
2937 "Configure IS-IS topologies\n"
2938 ISIS_MT_DESCRIPTIONS
2939 "Set overload bit for topology\n")
2941 VTY_DECLVAR_CONTEXT(isis_area
, area
);
2943 const char *arg
= argv
[1]->arg
;
2944 uint16_t mtid
= isis_str2mtid(arg
);
2946 if (area
->oldmetric
) {
2948 "Multi topology IS-IS can only be used with wide metrics\n");
2949 return CMD_WARNING_CONFIG_FAILED
;
2952 if (mtid
== (uint16_t)-1) {
2953 vty_out(vty
, "Don't know topology '%s'\n", arg
);
2954 return CMD_WARNING_CONFIG_FAILED
;
2956 if (mtid
== ISIS_MT_IPV4_UNICAST
) {
2957 vty_out(vty
, "Cannot configure IPv4 unicast topology\n");
2958 return CMD_WARNING_CONFIG_FAILED
;
2961 area_set_mt_enabled(area
, mtid
, true);
2962 area_set_mt_overload(area
, mtid
, (argc
== 3));
2966 DEFUN (no_isis_topology
,
2967 no_isis_topology_cmd
,
2968 "no topology " ISIS_MT_NAMES
" [overload]",
2970 "Configure IS-IS topologies\n"
2971 ISIS_MT_DESCRIPTIONS
2972 "Set overload bit for topology\n")
2974 VTY_DECLVAR_CONTEXT(isis_area
, area
);
2976 const char *arg
= argv
[2]->arg
;
2977 uint16_t mtid
= isis_str2mtid(arg
);
2979 if (area
->oldmetric
) {
2981 "Multi topology IS-IS can only be used with wide metrics\n");
2982 return CMD_WARNING_CONFIG_FAILED
;
2985 if (mtid
== (uint16_t)-1) {
2986 vty_out(vty
, "Don't know topology '%s'\n", arg
);
2987 return CMD_WARNING_CONFIG_FAILED
;
2989 if (mtid
== ISIS_MT_IPV4_UNICAST
) {
2990 vty_out(vty
, "Cannot configure IPv4 unicast topology\n");
2991 return CMD_WARNING_CONFIG_FAILED
;
2994 area_set_mt_enabled(area
, mtid
, false);
2995 area_set_mt_overload(area
, mtid
, false);
2998 #endif /* ifdef FABRICD */
3000 void isis_area_lsp_mtu_set(struct isis_area
*area
, unsigned int lsp_mtu
)
3002 area
->lsp_mtu
= lsp_mtu
;
3003 lsp_regenerate_schedule(area
, IS_LEVEL_1_AND_2
, 1);
3006 static int isis_area_passwd_set(struct isis_area
*area
, int level
,
3007 uint8_t passwd_type
, const char *passwd
,
3010 struct isis_passwd
*dest
;
3011 struct isis_passwd modified
;
3014 assert((level
== IS_LEVEL_1
) || (level
== IS_LEVEL_2
));
3015 dest
= (level
== IS_LEVEL_1
) ? &area
->area_passwd
3016 : &area
->domain_passwd
;
3017 memset(&modified
, 0, sizeof(modified
));
3019 if (passwd_type
!= ISIS_PASSWD_TYPE_UNUSED
) {
3023 len
= strlen(passwd
);
3028 strlcpy((char *)modified
.passwd
, passwd
,
3029 sizeof(modified
.passwd
));
3030 modified
.type
= passwd_type
;
3031 modified
.snp_auth
= snp_auth
;
3034 if (memcmp(&modified
, dest
, sizeof(modified
))) {
3035 memcpy(dest
, &modified
, sizeof(modified
));
3036 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 1);
3042 int isis_area_passwd_unset(struct isis_area
*area
, int level
)
3044 return isis_area_passwd_set(area
, level
, ISIS_PASSWD_TYPE_UNUSED
, NULL
,
3048 int isis_area_passwd_cleartext_set(struct isis_area
*area
, int level
,
3049 const char *passwd
, uint8_t snp_auth
)
3051 return isis_area_passwd_set(area
, level
, ISIS_PASSWD_TYPE_CLEARTXT
,
3055 int isis_area_passwd_hmac_md5_set(struct isis_area
*area
, int level
,
3056 const char *passwd
, uint8_t snp_auth
)
3058 return isis_area_passwd_set(area
, level
, ISIS_PASSWD_TYPE_HMAC_MD5
,
3062 void isis_area_invalidate_routes(struct isis_area
*area
, int levels
)
3064 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVEL2
; level
++) {
3065 if (!(level
& levels
))
3067 for (int tree
= SPFTREE_IPV4
; tree
< SPFTREE_COUNT
; tree
++) {
3068 isis_spf_invalidate_routes(
3069 area
->spftree
[tree
][level
- 1]);
3074 void isis_area_verify_routes(struct isis_area
*area
)
3076 for (int tree
= SPFTREE_IPV4
; tree
< SPFTREE_COUNT
; tree
++)
3077 isis_spf_verify_routes(area
, area
->spftree
[tree
]);
3080 static void area_resign_level(struct isis_area
*area
, int level
)
3082 isis_area_invalidate_routes(area
, level
);
3083 isis_area_verify_routes(area
);
3085 lsp_db_fini(&area
->lspdb
[level
- 1]);
3087 for (int tree
= SPFTREE_IPV4
; tree
< SPFTREE_COUNT
; tree
++) {
3088 if (area
->spftree
[tree
][level
- 1]) {
3089 isis_spftree_del(area
->spftree
[tree
][level
- 1]);
3090 area
->spftree
[tree
][level
- 1] = NULL
;
3094 if (area
->spf_timer
[level
- 1])
3095 isis_spf_timer_free(THREAD_ARG(area
->spf_timer
[level
- 1]));
3097 thread_cancel(&area
->spf_timer
[level
- 1]);
3100 "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
3101 area
->area_tag
, level
);
3102 thread_cancel(&area
->t_lsp_refresh
[level
- 1]);
3103 area
->lsp_regenerate_pending
[level
- 1] = 0;
3106 void isis_area_is_type_set(struct isis_area
*area
, int is_type
)
3108 struct listnode
*node
;
3109 struct isis_circuit
*circuit
;
3111 if (IS_DEBUG_EVENTS
)
3112 zlog_debug("ISIS-Evt (%s) system type change %s -> %s",
3113 area
->area_tag
, circuit_t2string(area
->is_type
),
3114 circuit_t2string(is_type
));
3116 if (area
->is_type
== is_type
)
3117 return; /* No change */
3119 switch (area
->is_type
) {
3121 if (is_type
== IS_LEVEL_2
)
3122 area_resign_level(area
, IS_LEVEL_1
);
3124 lsp_db_init(&area
->lspdb
[1]);
3127 case IS_LEVEL_1_AND_2
:
3128 if (is_type
== IS_LEVEL_1
)
3129 area_resign_level(area
, IS_LEVEL_2
);
3131 area_resign_level(area
, IS_LEVEL_1
);
3135 if (is_type
== IS_LEVEL_1
)
3136 area_resign_level(area
, IS_LEVEL_2
);
3138 lsp_db_init(&area
->lspdb
[0]);
3145 area
->is_type
= is_type
;
3148 * If area's IS type is strict Level-1 or Level-2, override circuit's
3149 * IS type. Otherwise use circuit's configured IS type.
3151 if (area
->is_type
!= IS_LEVEL_1_AND_2
) {
3152 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, node
, circuit
))
3153 isis_circuit_is_type_set(circuit
, is_type
);
3155 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, node
, circuit
))
3156 isis_circuit_is_type_set(circuit
, circuit
->is_type_config
);
3159 spftree_area_init(area
);
3161 if (listcount(area
->area_addrs
) > 0) {
3162 if (is_type
& IS_LEVEL_1
)
3163 lsp_generate(area
, IS_LEVEL_1
);
3164 if (is_type
& IS_LEVEL_2
)
3165 lsp_generate(area
, IS_LEVEL_2
);
3167 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 1);
3172 void isis_area_metricstyle_set(struct isis_area
*area
, bool old_metric
,
3175 area
->oldmetric
= old_metric
;
3176 area
->newmetric
= new_metric
;
3177 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 1);
3180 void isis_area_overload_bit_set(struct isis_area
*area
, bool overload_bit
)
3182 char new_overload_bit
= overload_bit
? LSPBIT_OL
: 0;
3184 if (new_overload_bit
!= area
->overload_bit
) {
3185 area
->overload_bit
= new_overload_bit
;
3187 if (new_overload_bit
)
3188 area
->overload_counter
++;
3191 hook_call(isis_hook_db_overload
, area
);
3192 #endif /* ifndef FABRICD */
3194 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 1);
3197 isis_notif_db_overload(area
, overload_bit
);
3198 #endif /* ifndef FABRICD */
3201 void isis_area_attached_bit_send_set(struct isis_area
*area
, bool attached_bit
)
3204 if (attached_bit
!= area
->attached_bit_send
) {
3205 area
->attached_bit_send
= attached_bit
;
3206 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 1);
3210 void isis_area_attached_bit_receive_set(struct isis_area
*area
,
3214 if (attached_bit
!= area
->attached_bit_rcv_ignore
) {
3215 area
->attached_bit_rcv_ignore
= attached_bit
;
3216 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 1);
3220 void isis_area_dynhostname_set(struct isis_area
*area
, bool dynhostname
)
3222 if (area
->dynhostname
!= dynhostname
) {
3223 area
->dynhostname
= dynhostname
;
3224 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 0);
3228 void isis_area_max_lsp_lifetime_set(struct isis_area
*area
, int level
,
3229 uint16_t max_lsp_lifetime
)
3231 assert((level
== IS_LEVEL_1
) || (level
== IS_LEVEL_2
));
3233 if (area
->max_lsp_lifetime
[level
- 1] == max_lsp_lifetime
)
3236 area
->max_lsp_lifetime
[level
- 1] = max_lsp_lifetime
;
3237 lsp_regenerate_schedule(area
, level
, 1);
3240 void isis_area_lsp_refresh_set(struct isis_area
*area
, int level
,
3241 uint16_t lsp_refresh
)
3243 assert((level
== IS_LEVEL_1
) || (level
== IS_LEVEL_2
));
3245 if (area
->lsp_refresh
[level
- 1] == lsp_refresh
)
3248 area
->lsp_refresh
[level
- 1] = lsp_refresh
;
3249 lsp_regenerate_schedule(area
, level
, 1);
3253 DEFUN (log_adj_changes
,
3254 log_adj_changes_cmd
,
3255 "log-adjacency-changes",
3256 "Log changes in adjacency state\n")
3258 VTY_DECLVAR_CONTEXT(isis_area
, area
);
3260 area
->log_adj_changes
= 1;
3265 DEFUN (no_log_adj_changes
,
3266 no_log_adj_changes_cmd
,
3267 "no log-adjacency-changes",
3269 "Stop logging changes in adjacency state\n")
3271 VTY_DECLVAR_CONTEXT(isis_area
, area
);
3273 area
->log_adj_changes
= 0;
3277 #endif /* ifdef FABRICD */
3279 /* IS-IS configuration write function */
3280 static int isis_config_write(struct vty
*vty
)
3283 struct isis_area
*area
;
3284 struct listnode
*node
, *node2
, *inode
;
3288 vty_out(vty
, "IS-IS Routing Process not enabled\n");
3292 for (ALL_LIST_ELEMENTS_RO(im
->isis
, inode
, isis
)) {
3293 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
)) {
3294 /* ISIS - Area name */
3295 vty_out(vty
, "router " PROTO_NAME
" %s\n", area
->area_tag
);
3298 if (listcount(area
->area_addrs
) > 0) {
3299 struct area_addr
*area_addr
;
3300 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
,
3301 node2
, area_addr
)) {
3302 vty_out(vty
, " net %s\n",
3304 area_addr
->area_addr
,
3311 /* ISIS - Dynamic hostname - Defaults to true so only
3314 if (!area
->dynhostname
) {
3315 vty_out(vty
, " no hostname dynamic\n");
3318 /* ISIS - Metric-Style - when true displays wide */
3320 if (area
->newmetric
) {
3321 if (!area
->oldmetric
)
3322 vty_out(vty
, " metric-style wide\n");
3325 " metric-style transition\n");
3328 vty_out(vty
, " metric-style narrow\n");
3332 /* ISIS - overload-bit */
3333 if (area
->overload_bit
) {
3334 vty_out(vty
, " set-overload-bit\n");
3337 /* ISIS - Area is-type (level-1-2 is default) */
3339 if (area
->is_type
== IS_LEVEL_1
) {
3340 vty_out(vty
, " is-type level-1\n");
3342 } else if (area
->is_type
== IS_LEVEL_2
) {
3343 vty_out(vty
, " is-type level-2-only\n");
3347 write
+= isis_redist_config_write(vty
, area
, AF_INET
);
3348 write
+= isis_redist_config_write(vty
, area
, AF_INET6
);
3349 /* ISIS - Lsp generation interval */
3350 if (area
->lsp_gen_interval
[0]
3351 == area
->lsp_gen_interval
[1]) {
3352 if (area
->lsp_gen_interval
[0]
3353 != DEFAULT_MIN_LSP_GEN_INTERVAL
) {
3354 vty_out(vty
, " lsp-gen-interval %d\n",
3355 area
->lsp_gen_interval
[0]);
3359 if (area
->lsp_gen_interval
[0]
3360 != DEFAULT_MIN_LSP_GEN_INTERVAL
) {
3362 " lsp-gen-interval level-1 %d\n",
3363 area
->lsp_gen_interval
[0]);
3366 if (area
->lsp_gen_interval
[1]
3367 != DEFAULT_MIN_LSP_GEN_INTERVAL
) {
3369 " lsp-gen-interval level-2 %d\n",
3370 area
->lsp_gen_interval
[1]);
3374 /* ISIS - LSP lifetime */
3375 if (area
->max_lsp_lifetime
[0]
3376 == area
->max_lsp_lifetime
[1]) {
3377 if (area
->max_lsp_lifetime
[0]
3378 != DEFAULT_LSP_LIFETIME
) {
3379 vty_out(vty
, " max-lsp-lifetime %u\n",
3380 area
->max_lsp_lifetime
[0]);
3384 if (area
->max_lsp_lifetime
[0]
3385 != DEFAULT_LSP_LIFETIME
) {
3387 " max-lsp-lifetime level-1 %u\n",
3388 area
->max_lsp_lifetime
[0]);
3391 if (area
->max_lsp_lifetime
[1]
3392 != DEFAULT_LSP_LIFETIME
) {
3394 " max-lsp-lifetime level-2 %u\n",
3395 area
->max_lsp_lifetime
[1]);
3399 /* ISIS - LSP refresh interval */
3400 if (area
->lsp_refresh
[0] == area
->lsp_refresh
[1]) {
3401 if (area
->lsp_refresh
[0]
3402 != DEFAULT_MAX_LSP_GEN_INTERVAL
) {
3404 " lsp-refresh-interval %u\n",
3405 area
->lsp_refresh
[0]);
3409 if (area
->lsp_refresh
[0]
3410 != DEFAULT_MAX_LSP_GEN_INTERVAL
) {
3412 " lsp-refresh-interval level-1 %u\n",
3413 area
->lsp_refresh
[0]);
3416 if (area
->lsp_refresh
[1]
3417 != DEFAULT_MAX_LSP_GEN_INTERVAL
) {
3419 " lsp-refresh-interval level-2 %u\n",
3420 area
->lsp_refresh
[1]);
3424 if (area
->lsp_mtu
!= DEFAULT_LSP_MTU
) {
3425 vty_out(vty
, " lsp-mtu %u\n", area
->lsp_mtu
);
3428 if (area
->purge_originator
) {
3429 vty_out(vty
, " purge-originator\n");
3433 /* Minimum SPF interval. */
3434 if (area
->min_spf_interval
[0]
3435 == area
->min_spf_interval
[1]) {
3436 if (area
->min_spf_interval
[0]
3437 != MINIMUM_SPF_INTERVAL
) {
3438 vty_out(vty
, " spf-interval %d\n",
3439 area
->min_spf_interval
[0]);
3443 if (area
->min_spf_interval
[0]
3444 != MINIMUM_SPF_INTERVAL
) {
3446 " spf-interval level-1 %d\n",
3447 area
->min_spf_interval
[0]);
3450 if (area
->min_spf_interval
[1]
3451 != MINIMUM_SPF_INTERVAL
) {
3453 " spf-interval level-2 %d\n",
3454 area
->min_spf_interval
[1]);
3459 /* IETF SPF interval */
3460 if (area
->spf_delay_ietf
[0]) {
3462 " spf-delay-ietf init-delay %ld short-delay %ld long-delay %ld holddown %ld time-to-learn %ld\n",
3463 spf_backoff_init_delay(
3464 area
->spf_delay_ietf
[0]),
3465 spf_backoff_short_delay(
3466 area
->spf_delay_ietf
[0]),
3467 spf_backoff_long_delay(
3468 area
->spf_delay_ietf
[0]),
3469 spf_backoff_holddown(
3470 area
->spf_delay_ietf
[0]),
3471 spf_backoff_timetolearn(
3472 area
->spf_delay_ietf
[0]));
3476 /* Authentication passwords. */
3477 if (area
->area_passwd
.type
3478 == ISIS_PASSWD_TYPE_HMAC_MD5
) {
3479 vty_out(vty
, " area-password md5 %s",
3480 area
->area_passwd
.passwd
);
3481 if (CHECK_FLAG(area
->area_passwd
.snp_auth
,
3483 vty_out(vty
, " authenticate snp ");
3485 area
->area_passwd
.snp_auth
,
3487 vty_out(vty
, "validate");
3489 vty_out(vty
, "send-only");
3493 } else if (area
->area_passwd
.type
3494 == ISIS_PASSWD_TYPE_CLEARTXT
) {
3495 vty_out(vty
, " area-password clear %s",
3496 area
->area_passwd
.passwd
);
3497 if (CHECK_FLAG(area
->area_passwd
.snp_auth
,
3499 vty_out(vty
, " authenticate snp ");
3501 area
->area_passwd
.snp_auth
,
3503 vty_out(vty
, "validate");
3505 vty_out(vty
, "send-only");
3510 if (area
->domain_passwd
.type
3511 == ISIS_PASSWD_TYPE_HMAC_MD5
) {
3512 vty_out(vty
, " domain-password md5 %s",
3513 area
->domain_passwd
.passwd
);
3514 if (CHECK_FLAG(area
->domain_passwd
.snp_auth
,
3516 vty_out(vty
, " authenticate snp ");
3517 if (CHECK_FLAG(area
->domain_passwd
3520 vty_out(vty
, "validate");
3522 vty_out(vty
, "send-only");
3526 } else if (area
->domain_passwd
.type
3527 == ISIS_PASSWD_TYPE_CLEARTXT
) {
3528 vty_out(vty
, " domain-password clear %s",
3529 area
->domain_passwd
.passwd
);
3530 if (CHECK_FLAG(area
->domain_passwd
.snp_auth
,
3532 vty_out(vty
, " authenticate snp ");
3533 if (CHECK_FLAG(area
->domain_passwd
3536 vty_out(vty
, "validate");
3538 vty_out(vty
, "send-only");
3544 if (area
->log_adj_changes
) {
3545 vty_out(vty
, " log-adjacency-changes\n");
3549 write
+= area_write_mt_settings(area
, vty
);
3550 write
+= fabricd_write_settings(area
, vty
);
3552 vty_out(vty
, "exit\n");
3559 struct cmd_node router_node
= {
3560 .name
= "openfabric",
3561 .node
= OPENFABRIC_NODE
,
3562 .parent_node
= CONFIG_NODE
,
3563 .prompt
= "%s(config-router)# ",
3564 .config_write
= isis_config_write
,
3567 /* IS-IS configuration write function */
3568 static int isis_config_write(struct vty
*vty
)
3571 struct lyd_node
*dnode
;
3573 dnode
= yang_dnode_get(running_config
->dnode
, "/frr-isisd:isis");
3575 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3582 struct cmd_node router_node
= {
3585 .parent_node
= CONFIG_NODE
,
3586 .prompt
= "%s(config-router)# ",
3587 .config_write
= isis_config_write
,
3589 #endif /* ifdef FABRICD */
3591 void isis_init(void)
3593 /* Install IS-IS top node */
3594 install_node(&router_node
);
3596 install_element(VIEW_NODE
, &show_isis_summary_cmd
);
3598 install_element(VIEW_NODE
, &show_isis_spf_ietf_cmd
);
3600 install_element(VIEW_NODE
, &show_isis_interface_cmd
);
3601 install_element(VIEW_NODE
, &show_isis_interface_detail_cmd
);
3602 install_element(VIEW_NODE
, &show_isis_interface_arg_cmd
);
3604 install_element(VIEW_NODE
, &show_isis_neighbor_cmd
);
3605 install_element(VIEW_NODE
, &show_isis_neighbor_detail_cmd
);
3606 install_element(VIEW_NODE
, &show_isis_neighbor_arg_cmd
);
3607 install_element(ENABLE_NODE
, &clear_isis_neighbor_cmd
);
3608 install_element(ENABLE_NODE
, &clear_isis_neighbor_arg_cmd
);
3610 install_element(VIEW_NODE
, &show_hostname_cmd
);
3611 install_element(VIEW_NODE
, &show_database_cmd
);
3613 install_element(ENABLE_NODE
, &show_debugging_isis_cmd
);
3615 install_node(&debug_node
);
3617 install_element(ENABLE_NODE
, &debug_isis_adj_cmd
);
3618 install_element(ENABLE_NODE
, &no_debug_isis_adj_cmd
);
3619 install_element(ENABLE_NODE
, &debug_isis_tx_queue_cmd
);
3620 install_element(ENABLE_NODE
, &no_debug_isis_tx_queue_cmd
);
3621 install_element(ENABLE_NODE
, &debug_isis_flooding_cmd
);
3622 install_element(ENABLE_NODE
, &no_debug_isis_flooding_cmd
);
3623 install_element(ENABLE_NODE
, &debug_isis_snp_cmd
);
3624 install_element(ENABLE_NODE
, &no_debug_isis_snp_cmd
);
3625 install_element(ENABLE_NODE
, &debug_isis_upd_cmd
);
3626 install_element(ENABLE_NODE
, &no_debug_isis_upd_cmd
);
3627 install_element(ENABLE_NODE
, &debug_isis_spfevents_cmd
);
3628 install_element(ENABLE_NODE
, &no_debug_isis_spfevents_cmd
);
3629 install_element(ENABLE_NODE
, &debug_isis_srevents_cmd
);
3630 install_element(ENABLE_NODE
, &no_debug_isis_srevents_cmd
);
3631 install_element(ENABLE_NODE
, &debug_isis_teevents_cmd
);
3632 install_element(ENABLE_NODE
, &no_debug_isis_teevents_cmd
);
3633 install_element(ENABLE_NODE
, &debug_isis_lfa_cmd
);
3634 install_element(ENABLE_NODE
, &no_debug_isis_lfa_cmd
);
3635 install_element(ENABLE_NODE
, &debug_isis_rtevents_cmd
);
3636 install_element(ENABLE_NODE
, &no_debug_isis_rtevents_cmd
);
3637 install_element(ENABLE_NODE
, &debug_isis_events_cmd
);
3638 install_element(ENABLE_NODE
, &no_debug_isis_events_cmd
);
3639 install_element(ENABLE_NODE
, &debug_isis_packet_dump_cmd
);
3640 install_element(ENABLE_NODE
, &no_debug_isis_packet_dump_cmd
);
3641 install_element(ENABLE_NODE
, &debug_isis_lsp_gen_cmd
);
3642 install_element(ENABLE_NODE
, &no_debug_isis_lsp_gen_cmd
);
3643 install_element(ENABLE_NODE
, &debug_isis_lsp_sched_cmd
);
3644 install_element(ENABLE_NODE
, &no_debug_isis_lsp_sched_cmd
);
3645 install_element(ENABLE_NODE
, &debug_isis_bfd_cmd
);
3646 install_element(ENABLE_NODE
, &no_debug_isis_bfd_cmd
);
3647 install_element(ENABLE_NODE
, &debug_isis_ldp_sync_cmd
);
3648 install_element(ENABLE_NODE
, &no_debug_isis_ldp_sync_cmd
);
3650 install_element(CONFIG_NODE
, &debug_isis_adj_cmd
);
3651 install_element(CONFIG_NODE
, &no_debug_isis_adj_cmd
);
3652 install_element(CONFIG_NODE
, &debug_isis_tx_queue_cmd
);
3653 install_element(CONFIG_NODE
, &no_debug_isis_tx_queue_cmd
);
3654 install_element(CONFIG_NODE
, &debug_isis_flooding_cmd
);
3655 install_element(CONFIG_NODE
, &no_debug_isis_flooding_cmd
);
3656 install_element(CONFIG_NODE
, &debug_isis_snp_cmd
);
3657 install_element(CONFIG_NODE
, &no_debug_isis_snp_cmd
);
3658 install_element(CONFIG_NODE
, &debug_isis_upd_cmd
);
3659 install_element(CONFIG_NODE
, &no_debug_isis_upd_cmd
);
3660 install_element(CONFIG_NODE
, &debug_isis_spfevents_cmd
);
3661 install_element(CONFIG_NODE
, &no_debug_isis_spfevents_cmd
);
3662 install_element(CONFIG_NODE
, &debug_isis_srevents_cmd
);
3663 install_element(CONFIG_NODE
, &no_debug_isis_srevents_cmd
);
3664 install_element(CONFIG_NODE
, &debug_isis_teevents_cmd
);
3665 install_element(CONFIG_NODE
, &no_debug_isis_teevents_cmd
);
3666 install_element(CONFIG_NODE
, &debug_isis_lfa_cmd
);
3667 install_element(CONFIG_NODE
, &no_debug_isis_lfa_cmd
);
3668 install_element(CONFIG_NODE
, &debug_isis_rtevents_cmd
);
3669 install_element(CONFIG_NODE
, &no_debug_isis_rtevents_cmd
);
3670 install_element(CONFIG_NODE
, &debug_isis_events_cmd
);
3671 install_element(CONFIG_NODE
, &no_debug_isis_events_cmd
);
3672 install_element(CONFIG_NODE
, &debug_isis_packet_dump_cmd
);
3673 install_element(CONFIG_NODE
, &no_debug_isis_packet_dump_cmd
);
3674 install_element(CONFIG_NODE
, &debug_isis_lsp_gen_cmd
);
3675 install_element(CONFIG_NODE
, &no_debug_isis_lsp_gen_cmd
);
3676 install_element(CONFIG_NODE
, &debug_isis_lsp_sched_cmd
);
3677 install_element(CONFIG_NODE
, &no_debug_isis_lsp_sched_cmd
);
3678 install_element(CONFIG_NODE
, &debug_isis_bfd_cmd
);
3679 install_element(CONFIG_NODE
, &no_debug_isis_bfd_cmd
);
3680 install_element(CONFIG_NODE
, &debug_isis_ldp_sync_cmd
);
3681 install_element(CONFIG_NODE
, &no_debug_isis_ldp_sync_cmd
);
3683 install_default(ROUTER_NODE
);
3686 install_element(CONFIG_NODE
, &router_openfabric_cmd
);
3687 install_element(CONFIG_NODE
, &no_router_openfabric_cmd
);
3689 install_element(ROUTER_NODE
, &net_cmd
);
3690 install_element(ROUTER_NODE
, &no_net_cmd
);
3692 install_element(ROUTER_NODE
, &isis_topology_cmd
);
3693 install_element(ROUTER_NODE
, &no_isis_topology_cmd
);
3695 install_element(ROUTER_NODE
, &log_adj_changes_cmd
);
3696 install_element(ROUTER_NODE
, &no_log_adj_changes_cmd
);
3697 #endif /* ifdef FABRICD */
3699 spf_backoff_cmd_init();