]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isisd.c
Merge pull request #4539 from opensourcerouting/7.1/watchfrr-sd-timeout
[mirror_frr.git] / isisd / isisd.c
1 /*
2 * IS-IS Rout(e)ing protocol - isisd.c
3 *
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
7 *
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)
11 * any later version.
12 *
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
16 * more details.
17 *
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
21 */
22
23 #include <zebra.h>
24
25 #include "thread.h"
26 #include "vty.h"
27 #include "command.h"
28 #include "log.h"
29 #include "memory.h"
30 #include "time.h"
31 #include "linklist.h"
32 #include "if.h"
33 #include "hash.h"
34 #include "stream.h"
35 #include "prefix.h"
36 #include "table.h"
37 #include "qobj.h"
38 #include "spf_backoff.h"
39 #include "lib/northbound_cli.h"
40
41 #include "isisd/isis_constants.h"
42 #include "isisd/isis_common.h"
43 #include "isisd/isis_flags.h"
44 #include "isisd/isis_circuit.h"
45 #include "isisd/isis_csm.h"
46 #include "isisd/isisd.h"
47 #include "isisd/isis_dynhn.h"
48 #include "isisd/isis_adjacency.h"
49 #include "isisd/isis_pdu.h"
50 #include "isisd/isis_misc.h"
51 #include "isisd/isis_constants.h"
52 #include "isisd/isis_lsp.h"
53 #include "isisd/isis_spf.h"
54 #include "isisd/isis_route.h"
55 #include "isisd/isis_zebra.h"
56 #include "isisd/isis_events.h"
57 #include "isisd/isis_te.h"
58 #include "isisd/isis_mt.h"
59 #include "isisd/fabricd.h"
60
61 struct isis *isis = NULL;
62
63 DEFINE_QOBJ_TYPE(isis)
64 DEFINE_QOBJ_TYPE(isis_area)
65
66 /*
67 * Prototypes.
68 */
69 int isis_area_get(struct vty *, const char *);
70 int area_net_title(struct vty *, const char *);
71 int area_clear_net_title(struct vty *, const char *);
72 int show_isis_interface_common(struct vty *, const char *ifname, char);
73 int show_isis_neighbor_common(struct vty *, const char *id, char);
74 int clear_isis_neighbor_common(struct vty *, const char *id);
75 int isis_config_write(struct vty *);
76
77
78 void isis_new(unsigned long process_id)
79 {
80 isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
81 /*
82 * Default values
83 */
84 isis->max_area_addrs = 3;
85 isis->process_id = process_id;
86 isis->router_id = 0;
87 isis->area_list = list_new();
88 isis->init_circ_list = list_new();
89 isis->uptime = time(NULL);
90 isis->nexthops = list_new();
91 isis->nexthops6 = list_new();
92 dyn_cache_init();
93 /*
94 * uncomment the next line for full debugs
95 */
96 /* isis->debugs = 0xFFFF; */
97
98 QOBJ_REG(isis, isis);
99 }
100
101 struct isis_area *isis_area_create(const char *area_tag)
102 {
103 struct isis_area *area;
104
105 area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
106
107 /*
108 * Fabricd runs only as level-2.
109 * For IS-IS, the first instance is level-1-2 rest are level-1,
110 * unless otherwise configured
111 */
112 if (fabricd) {
113 area->is_type = IS_LEVEL_2;
114 } else if (listcount(isis->area_list) == 0)
115 area->is_type = IS_LEVEL_1_AND_2;
116 else
117 area->is_type = yang_get_default_enum(
118 "/frr-isisd:isis/instance/is-type");
119
120 /*
121 * intialize the databases
122 */
123 if (area->is_type & IS_LEVEL_1)
124 lsp_db_init(&area->lspdb[0]);
125 if (area->is_type & IS_LEVEL_2)
126 lsp_db_init(&area->lspdb[1]);
127
128 spftree_area_init(area);
129
130 area->circuit_list = list_new();
131 area->area_addrs = list_new();
132 thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
133 flags_initialize(&area->flags);
134
135 /*
136 * Default values
137 */
138 #ifndef FABRICD
139 enum isis_metric_style default_style;
140
141 area->max_lsp_lifetime[0] = yang_get_default_uint16(
142 "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1");
143 area->max_lsp_lifetime[1] = yang_get_default_uint16(
144 "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2");
145 area->lsp_refresh[0] = yang_get_default_uint16(
146 "/frr-isisd:isis/instance/lsp/refresh-interval/level-1");
147 area->lsp_refresh[1] = yang_get_default_uint16(
148 "/frr-isisd:isis/instance/lsp/refresh-interval/level-2");
149 area->lsp_gen_interval[0] = yang_get_default_uint16(
150 "/frr-isisd:isis/instance/lsp/generation-interval/level-1");
151 area->lsp_gen_interval[1] = yang_get_default_uint16(
152 "/frr-isisd:isis/instance/lsp/generation-interval/level-2");
153 area->min_spf_interval[0] = yang_get_default_uint16(
154 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
155 area->min_spf_interval[1] = yang_get_default_uint16(
156 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
157 area->dynhostname = yang_get_default_bool(
158 "/frr-isisd:isis/instance/dynamic-hostname");
159 default_style =
160 yang_get_default_enum("/frr-isisd:isis/instance/metric-style");
161 area->oldmetric = default_style == ISIS_WIDE_METRIC ? 0 : 1;
162 area->newmetric = default_style == ISIS_NARROW_METRIC ? 0 : 1;
163 area->lsp_frag_threshold = 90; /* not currently configurable */
164 area->lsp_mtu =
165 yang_get_default_uint16("/frr-isisd:isis/instance/lsp/mtu");
166 #else
167 area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */
168 area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */
169 area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
170 area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
171 area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL;
172 area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL;
173 area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
174 area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
175 area->dynhostname = 1;
176 area->oldmetric = 0;
177 area->newmetric = 1;
178 area->lsp_frag_threshold = 90;
179 area->lsp_mtu = DEFAULT_LSP_MTU;
180 #endif /* ifndef FABRICD */
181
182 area_mt_init(area);
183
184 area->area_tag = strdup(area_tag);
185 listnode_add(isis->area_list, area);
186 area->isis = isis;
187
188 if (fabricd)
189 area->fabricd = fabricd_new(area);
190
191 area->lsp_refresh_arg[0].area = area;
192 area->lsp_refresh_arg[0].level = IS_LEVEL_1;
193 area->lsp_refresh_arg[1].area = area;
194 area->lsp_refresh_arg[1].level = IS_LEVEL_2;
195
196
197 QOBJ_REG(area, isis_area);
198
199 return area;
200 }
201
202 struct isis_area *isis_area_lookup(const char *area_tag)
203 {
204 struct isis_area *area;
205 struct listnode *node;
206
207 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
208 if ((area->area_tag == NULL && area_tag == NULL)
209 || (area->area_tag && area_tag
210 && strcmp(area->area_tag, area_tag) == 0))
211 return area;
212
213 return NULL;
214 }
215
216 int isis_area_get(struct vty *vty, const char *area_tag)
217 {
218 struct isis_area *area;
219
220 area = isis_area_lookup(area_tag);
221
222 if (area) {
223 VTY_PUSH_CONTEXT(ROUTER_NODE, area);
224 return CMD_SUCCESS;
225 }
226
227 area = isis_area_create(area_tag);
228
229 if (isis->debugs & DEBUG_EVENTS)
230 zlog_debug("New IS-IS area instance %s", area->area_tag);
231
232 VTY_PUSH_CONTEXT(ROUTER_NODE, area);
233
234 return CMD_SUCCESS;
235 }
236
237 int isis_area_destroy(const char *area_tag)
238 {
239 struct isis_area *area;
240 struct listnode *node, *nnode;
241 struct isis_circuit *circuit;
242 struct area_addr *addr;
243
244 area = isis_area_lookup(area_tag);
245
246 if (area == NULL) {
247 zlog_warn("%s: could not find area with area-tag %s",
248 __func__, area_tag);
249 return CMD_ERR_NO_MATCH;
250 }
251
252 QOBJ_UNREG(area);
253
254 if (fabricd)
255 fabricd_finish(area->fabricd);
256
257 /* Disable MPLS if necessary before flooding LSP */
258 if (IS_MPLS_TE(area->mta))
259 area->mta->status = disable;
260
261 if (area->circuit_list) {
262 for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
263 circuit)) {
264 circuit->ip_router = 0;
265 circuit->ipv6_router = 0;
266 isis_csm_state_change(ISIS_DISABLE, circuit, area);
267 }
268 list_delete(&area->circuit_list);
269 }
270
271 lsp_db_fini(&area->lspdb[0]);
272 lsp_db_fini(&area->lspdb[1]);
273
274 /* invalidate and verify to delete all routes from zebra */
275 isis_area_invalidate_routes(area, area->is_type);
276 isis_area_verify_routes(area);
277
278 spftree_area_del(area);
279
280 THREAD_TIMER_OFF(area->spf_timer[0]);
281 THREAD_TIMER_OFF(area->spf_timer[1]);
282
283 spf_backoff_free(area->spf_delay_ietf[0]);
284 spf_backoff_free(area->spf_delay_ietf[1]);
285
286 isis_redist_area_finish(area);
287
288 for (ALL_LIST_ELEMENTS(area->area_addrs, node, nnode, addr)) {
289 list_delete_node(area->area_addrs, node);
290 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
291 }
292 area->area_addrs = NULL;
293
294 THREAD_TIMER_OFF(area->t_tick);
295 THREAD_TIMER_OFF(area->t_lsp_refresh[0]);
296 THREAD_TIMER_OFF(area->t_lsp_refresh[1]);
297
298 thread_cancel_event(master, area);
299
300 listnode_delete(isis->area_list, area);
301
302 free(area->area_tag);
303
304 area_mt_finish(area);
305
306 XFREE(MTYPE_ISIS_AREA, area);
307
308 if (listcount(isis->area_list) == 0) {
309 memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
310 isis->sysid_set = 0;
311 }
312
313 return CMD_SUCCESS;
314 }
315
316 #ifdef FABRICD
317 static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid,
318 bool enabled)
319 {
320 struct isis_area_mt_setting *setting;
321
322 setting = area_get_mt_setting(area, mtid);
323 if (setting->enabled != enabled) {
324 setting->enabled = enabled;
325 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
326 }
327 }
328
329 static void area_set_mt_overload(struct isis_area *area, uint16_t mtid,
330 bool overload)
331 {
332 struct isis_area_mt_setting *setting;
333
334 setting = area_get_mt_setting(area, mtid);
335 if (setting->overload != overload) {
336 setting->overload = overload;
337 if (setting->enabled)
338 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2,
339 0);
340 }
341 }
342 #endif /* ifdef FABRICD */
343
344 int area_net_title(struct vty *vty, const char *net_title)
345 {
346 VTY_DECLVAR_CONTEXT(isis_area, area);
347 struct area_addr *addr;
348 struct area_addr *addrp;
349 struct listnode *node;
350
351 uint8_t buff[255];
352
353 /* We check that we are not over the maximal number of addresses */
354 if (listcount(area->area_addrs) >= isis->max_area_addrs) {
355 vty_out(vty,
356 "Maximum of area addresses (%d) already reached \n",
357 isis->max_area_addrs);
358 return CMD_ERR_NOTHING_TODO;
359 }
360
361 addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
362 addr->addr_len = dotformat2buff(buff, net_title);
363 memcpy(addr->area_addr, buff, addr->addr_len);
364 #ifdef EXTREME_DEBUG
365 zlog_debug("added area address %s for area %s (address length %d)",
366 net_title, area->area_tag, addr->addr_len);
367 #endif /* EXTREME_DEBUG */
368 if (addr->addr_len < 8 || addr->addr_len > 20) {
369 vty_out(vty,
370 "area address must be at least 8..20 octets long (%d)\n",
371 addr->addr_len);
372 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
373 return CMD_WARNING_CONFIG_FAILED;
374 }
375
376 if (addr->area_addr[addr->addr_len - 1] != 0) {
377 vty_out(vty,
378 "nsel byte (last byte) in area address must be 0\n");
379 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
380 return CMD_WARNING_CONFIG_FAILED;
381 }
382
383 if (isis->sysid_set == 0) {
384 /*
385 * First area address - get the SystemID for this router
386 */
387 memcpy(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
388 isis->sysid_set = 1;
389 if (isis->debugs & DEBUG_EVENTS)
390 zlog_debug("Router has SystemID %s",
391 sysid_print(isis->sysid));
392 } else {
393 /*
394 * Check that the SystemID portions match
395 */
396 if (memcmp(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN)) {
397 vty_out(vty,
398 "System ID must not change when defining additional area addresses\n");
399 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
400 return CMD_WARNING_CONFIG_FAILED;
401 }
402
403 /* now we see that we don't already have this address */
404 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
405 if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN)
406 != (addr->addr_len))
407 continue;
408 if (!memcmp(addrp->area_addr, addr->area_addr,
409 addr->addr_len)) {
410 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
411 return CMD_SUCCESS; /* silent fail */
412 }
413 }
414 }
415
416 /*
417 * Forget the systemID part of the address
418 */
419 addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
420 listnode_add(area->area_addrs, addr);
421
422 /* only now we can safely generate our LSPs for this area */
423 if (listcount(area->area_addrs) > 0) {
424 if (area->is_type & IS_LEVEL_1)
425 lsp_generate(area, IS_LEVEL_1);
426 if (area->is_type & IS_LEVEL_2)
427 lsp_generate(area, IS_LEVEL_2);
428 }
429
430 return CMD_SUCCESS;
431 }
432
433 int area_clear_net_title(struct vty *vty, const char *net_title)
434 {
435 VTY_DECLVAR_CONTEXT(isis_area, area);
436 struct area_addr addr, *addrp = NULL;
437 struct listnode *node;
438 uint8_t buff[255];
439
440 addr.addr_len = dotformat2buff(buff, net_title);
441 if (addr.addr_len < 8 || addr.addr_len > 20) {
442 vty_out(vty,
443 "Unsupported area address length %d, should be 8...20 \n",
444 addr.addr_len);
445 return CMD_WARNING_CONFIG_FAILED;
446 }
447
448 memcpy(addr.area_addr, buff, (int)addr.addr_len);
449
450 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp))
451 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
452 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
453 break;
454
455 if (!addrp) {
456 vty_out(vty, "No area address %s for area %s \n", net_title,
457 area->area_tag);
458 return CMD_ERR_NO_MATCH;
459 }
460
461 listnode_delete(area->area_addrs, addrp);
462 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
463
464 /*
465 * Last area address - reset the SystemID for this router
466 */
467 if (listcount(area->area_addrs) == 0) {
468 memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
469 isis->sysid_set = 0;
470 if (isis->debugs & DEBUG_EVENTS)
471 zlog_debug("Router has no SystemID");
472 }
473
474 return CMD_SUCCESS;
475 }
476
477 /*
478 * 'show isis interface' command
479 */
480
481 int show_isis_interface_common(struct vty *vty, const char *ifname, char detail)
482 {
483 struct listnode *anode, *cnode;
484 struct isis_area *area;
485 struct isis_circuit *circuit;
486
487 if (!isis) {
488 vty_out(vty, "IS-IS Routing Process not enabled\n");
489 return CMD_SUCCESS;
490 }
491
492 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
493 vty_out(vty, "Area %s:\n", area->area_tag);
494
495 if (detail == ISIS_UI_LEVEL_BRIEF)
496 vty_out(vty,
497 " Interface CircId State Type Level\n");
498
499 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
500 if (!ifname)
501 isis_circuit_print_vty(circuit, vty, detail);
502 else if (strcmp(circuit->interface->name, ifname) == 0)
503 isis_circuit_print_vty(circuit, vty, detail);
504 }
505
506 return CMD_SUCCESS;
507 }
508
509 DEFUN (show_isis_interface,
510 show_isis_interface_cmd,
511 "show " PROTO_NAME " interface",
512 SHOW_STR
513 PROTO_HELP
514 "ISIS interface\n")
515 {
516 return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
517 }
518
519 DEFUN (show_isis_interface_detail,
520 show_isis_interface_detail_cmd,
521 "show " PROTO_NAME " interface detail",
522 SHOW_STR
523 PROTO_HELP
524 "ISIS interface\n"
525 "show detailed information\n")
526 {
527 return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL);
528 }
529
530 DEFUN (show_isis_interface_arg,
531 show_isis_interface_arg_cmd,
532 "show " PROTO_NAME " interface WORD",
533 SHOW_STR
534 PROTO_HELP
535 "ISIS interface\n"
536 "ISIS interface name\n")
537 {
538 int idx_word = 3;
539 return show_isis_interface_common(vty, argv[idx_word]->arg,
540 ISIS_UI_LEVEL_DETAIL);
541 }
542
543 /*
544 * 'show isis neighbor' command
545 */
546
547 int show_isis_neighbor_common(struct vty *vty, const char *id, char detail)
548 {
549 struct listnode *anode, *cnode, *node;
550 struct isis_area *area;
551 struct isis_circuit *circuit;
552 struct list *adjdb;
553 struct isis_adjacency *adj;
554 struct isis_dynhn *dynhn;
555 uint8_t sysid[ISIS_SYS_ID_LEN];
556 int i;
557
558 if (!isis) {
559 vty_out(vty, "IS-IS Routing Process not enabled\n");
560 return CMD_SUCCESS;
561 }
562
563 memset(sysid, 0, ISIS_SYS_ID_LEN);
564 if (id) {
565 if (sysid2buff(sysid, id) == 0) {
566 dynhn = dynhn_find_by_name(id);
567 if (dynhn == NULL) {
568 vty_out(vty, "Invalid system id %s\n", id);
569 return CMD_SUCCESS;
570 }
571 memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
572 }
573 }
574
575 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
576 vty_out(vty, "Area %s:\n", area->area_tag);
577
578 if (detail == ISIS_UI_LEVEL_BRIEF)
579 vty_out(vty,
580 " System Id Interface L State Holdtime SNPA\n");
581
582 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
583 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
584 for (i = 0; i < 2; i++) {
585 adjdb = circuit->u.bc.adjdb[i];
586 if (adjdb && adjdb->count) {
587 for (ALL_LIST_ELEMENTS_RO(
588 adjdb, node, adj))
589 if (!id
590 || !memcmp(adj->sysid,
591 sysid,
592 ISIS_SYS_ID_LEN))
593 isis_adj_print_vty(
594 adj,
595 vty,
596 detail);
597 }
598 }
599 } else if (circuit->circ_type == CIRCUIT_T_P2P
600 && circuit->u.p2p.neighbor) {
601 adj = circuit->u.p2p.neighbor;
602 if (!id
603 || !memcmp(adj->sysid, sysid,
604 ISIS_SYS_ID_LEN))
605 isis_adj_print_vty(adj, vty, detail);
606 }
607 }
608 }
609
610 return CMD_SUCCESS;
611 }
612
613 /*
614 * 'clear isis neighbor' command
615 */
616 int clear_isis_neighbor_common(struct vty *vty, const char *id)
617 {
618 struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
619 struct isis_area *area;
620 struct isis_circuit *circuit;
621 struct list *adjdb;
622 struct isis_adjacency *adj;
623 struct isis_dynhn *dynhn;
624 uint8_t sysid[ISIS_SYS_ID_LEN];
625 int i;
626
627 if (!isis) {
628 vty_out(vty, "IS-IS Routing Process not enabled\n");
629 return CMD_SUCCESS;
630 }
631
632 memset(sysid, 0, ISIS_SYS_ID_LEN);
633 if (id) {
634 if (sysid2buff(sysid, id) == 0) {
635 dynhn = dynhn_find_by_name(id);
636 if (dynhn == NULL) {
637 vty_out(vty, "Invalid system id %s\n", id);
638 return CMD_SUCCESS;
639 }
640 memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
641 }
642 }
643
644 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
645 for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode,
646 circuit)) {
647 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
648 for (i = 0; i < 2; i++) {
649 adjdb = circuit->u.bc.adjdb[i];
650 if (adjdb && adjdb->count) {
651 for (ALL_LIST_ELEMENTS(
652 adjdb, node, nnode,
653 adj))
654 if (!id
655 || !memcmp(adj->sysid,
656 sysid,
657 ISIS_SYS_ID_LEN))
658 isis_adj_state_change(
659 adj,
660 ISIS_ADJ_DOWN,
661 "clear user request");
662 }
663 }
664 } else if (circuit->circ_type == CIRCUIT_T_P2P
665 && circuit->u.p2p.neighbor) {
666 adj = circuit->u.p2p.neighbor;
667 if (!id
668 || !memcmp(adj->sysid, sysid,
669 ISIS_SYS_ID_LEN))
670 isis_adj_state_change(
671 adj, ISIS_ADJ_DOWN,
672 "clear user request");
673 }
674 }
675 }
676
677 return CMD_SUCCESS;
678 }
679
680 DEFUN (show_isis_neighbor,
681 show_isis_neighbor_cmd,
682 "show " PROTO_NAME " neighbor",
683 SHOW_STR
684 PROTO_HELP
685 "ISIS neighbor adjacencies\n")
686 {
687 return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
688 }
689
690 DEFUN (show_isis_neighbor_detail,
691 show_isis_neighbor_detail_cmd,
692 "show " PROTO_NAME " neighbor detail",
693 SHOW_STR
694 PROTO_HELP
695 "ISIS neighbor adjacencies\n"
696 "show detailed information\n")
697 {
698 return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL);
699 }
700
701 DEFUN (show_isis_neighbor_arg,
702 show_isis_neighbor_arg_cmd,
703 "show " PROTO_NAME " neighbor WORD",
704 SHOW_STR
705 PROTO_HELP
706 "ISIS neighbor adjacencies\n"
707 "System id\n")
708 {
709 int idx_word = 3;
710 return show_isis_neighbor_common(vty, argv[idx_word]->arg,
711 ISIS_UI_LEVEL_DETAIL);
712 }
713
714 DEFUN (clear_isis_neighbor,
715 clear_isis_neighbor_cmd,
716 "clear " PROTO_NAME " neighbor",
717 CLEAR_STR
718 PROTO_HELP
719 "ISIS neighbor adjacencies\n")
720 {
721 return clear_isis_neighbor_common(vty, NULL);
722 }
723
724 DEFUN (clear_isis_neighbor_arg,
725 clear_isis_neighbor_arg_cmd,
726 "clear " PROTO_NAME " neighbor WORD",
727 CLEAR_STR
728 PROTO_HELP
729 "ISIS neighbor adjacencies\n"
730 "System id\n")
731 {
732 int idx_word = 3;
733 return clear_isis_neighbor_common(vty, argv[idx_word]->arg);
734 }
735
736 /*
737 * 'isis debug', 'show debugging'
738 */
739 void print_debug(struct vty *vty, int flags, int onoff)
740 {
741 char onoffs[4];
742 if (onoff)
743 strcpy(onoffs, "on");
744 else
745 strcpy(onoffs, "off");
746
747 if (flags & DEBUG_ADJ_PACKETS)
748 vty_out(vty,
749 "IS-IS Adjacency related packets debugging is %s\n",
750 onoffs);
751 if (flags & DEBUG_TX_QUEUE)
752 vty_out(vty, "IS-IS TX queue debugging is %s\n",
753 onoffs);
754 if (flags & DEBUG_SNP_PACKETS)
755 vty_out(vty, "IS-IS CSNP/PSNP packets debugging is %s\n",
756 onoffs);
757 if (flags & DEBUG_SPF_EVENTS)
758 vty_out(vty, "IS-IS SPF events debugging is %s\n", onoffs);
759 if (flags & DEBUG_UPDATE_PACKETS)
760 vty_out(vty, "IS-IS Update related packet debugging is %s\n",
761 onoffs);
762 if (flags & DEBUG_RTE_EVENTS)
763 vty_out(vty, "IS-IS Route related debuggin is %s\n", onoffs);
764 if (flags & DEBUG_EVENTS)
765 vty_out(vty, "IS-IS Event debugging is %s\n", onoffs);
766 if (flags & DEBUG_PACKET_DUMP)
767 vty_out(vty, "IS-IS Packet dump debugging is %s\n", onoffs);
768 if (flags & DEBUG_LSP_GEN)
769 vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs);
770 if (flags & DEBUG_LSP_SCHED)
771 vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs);
772 if (flags & DEBUG_FLOODING)
773 vty_out(vty, "IS-IS Flooding debugging is %s\n", onoffs);
774 if (flags & DEBUG_BFD)
775 vty_out(vty, "IS-IS BFD debugging is %s\n", onoffs);
776 }
777
778 DEFUN_NOSH (show_debugging,
779 show_debugging_isis_cmd,
780 "show debugging [" PROTO_NAME "]",
781 SHOW_STR
782 "State of each debugging option\n"
783 PROTO_HELP)
784 {
785 vty_out(vty, PROTO_NAME " debugging status:\n");
786
787 if (isis->debugs)
788 print_debug(vty, isis->debugs, 1);
789
790 return CMD_SUCCESS;
791 }
792
793 /* Debug node. */
794 static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
795
796 static int config_write_debug(struct vty *vty)
797 {
798 int write = 0;
799 int flags = isis->debugs;
800
801 if (flags & DEBUG_ADJ_PACKETS) {
802 vty_out(vty, "debug " PROTO_NAME " adj-packets\n");
803 write++;
804 }
805 if (flags & DEBUG_TX_QUEUE) {
806 vty_out(vty, "debug " PROTO_NAME " tx-queue\n");
807 write++;
808 }
809 if (flags & DEBUG_SNP_PACKETS) {
810 vty_out(vty, "debug " PROTO_NAME " snp-packets\n");
811 write++;
812 }
813 if (flags & DEBUG_SPF_EVENTS) {
814 vty_out(vty, "debug " PROTO_NAME " spf-events\n");
815 write++;
816 }
817 if (flags & DEBUG_UPDATE_PACKETS) {
818 vty_out(vty, "debug " PROTO_NAME " update-packets\n");
819 write++;
820 }
821 if (flags & DEBUG_RTE_EVENTS) {
822 vty_out(vty, "debug " PROTO_NAME " route-events\n");
823 write++;
824 }
825 if (flags & DEBUG_EVENTS) {
826 vty_out(vty, "debug " PROTO_NAME " events\n");
827 write++;
828 }
829 if (flags & DEBUG_PACKET_DUMP) {
830 vty_out(vty, "debug " PROTO_NAME " packet-dump\n");
831 write++;
832 }
833 if (flags & DEBUG_LSP_GEN) {
834 vty_out(vty, "debug " PROTO_NAME " lsp-gen\n");
835 write++;
836 }
837 if (flags & DEBUG_LSP_SCHED) {
838 vty_out(vty, "debug " PROTO_NAME " lsp-sched\n");
839 write++;
840 }
841 if (flags & DEBUG_FLOODING) {
842 vty_out(vty, "debug " PROTO_NAME " flooding\n");
843 write++;
844 }
845 if (flags & DEBUG_BFD) {
846 vty_out(vty, "debug " PROTO_NAME " bfd\n");
847 write++;
848 }
849 write += spf_backoff_write_config(vty);
850
851 return write;
852 }
853
854 DEFUN (debug_isis_adj,
855 debug_isis_adj_cmd,
856 "debug " PROTO_NAME " adj-packets",
857 DEBUG_STR
858 PROTO_HELP
859 "IS-IS Adjacency related packets\n")
860 {
861 isis->debugs |= DEBUG_ADJ_PACKETS;
862 print_debug(vty, DEBUG_ADJ_PACKETS, 1);
863
864 return CMD_SUCCESS;
865 }
866
867 DEFUN (no_debug_isis_adj,
868 no_debug_isis_adj_cmd,
869 "no debug " PROTO_NAME " adj-packets",
870 NO_STR
871 UNDEBUG_STR
872 PROTO_HELP
873 "IS-IS Adjacency related packets\n")
874 {
875 isis->debugs &= ~DEBUG_ADJ_PACKETS;
876 print_debug(vty, DEBUG_ADJ_PACKETS, 0);
877
878 return CMD_SUCCESS;
879 }
880
881 DEFUN (debug_isis_tx_queue,
882 debug_isis_tx_queue_cmd,
883 "debug " PROTO_NAME " tx-queue",
884 DEBUG_STR
885 PROTO_HELP
886 "IS-IS TX queues\n")
887 {
888 isis->debugs |= DEBUG_TX_QUEUE;
889 print_debug(vty, DEBUG_TX_QUEUE, 1);
890
891 return CMD_SUCCESS;
892 }
893
894 DEFUN (no_debug_isis_tx_queue,
895 no_debug_isis_tx_queue_cmd,
896 "no debug " PROTO_NAME " tx-queue",
897 NO_STR
898 UNDEBUG_STR
899 PROTO_HELP
900 "IS-IS TX queues\n")
901 {
902 isis->debugs &= ~DEBUG_TX_QUEUE;
903 print_debug(vty, DEBUG_TX_QUEUE, 0);
904
905 return CMD_SUCCESS;
906 }
907
908 DEFUN (debug_isis_flooding,
909 debug_isis_flooding_cmd,
910 "debug " PROTO_NAME " flooding",
911 DEBUG_STR
912 PROTO_HELP
913 "Flooding algorithm\n")
914 {
915 isis->debugs |= DEBUG_FLOODING;
916 print_debug(vty, DEBUG_FLOODING, 1);
917
918 return CMD_SUCCESS;
919 }
920
921 DEFUN (no_debug_isis_flooding,
922 no_debug_isis_flooding_cmd,
923 "no debug " PROTO_NAME " flooding",
924 NO_STR
925 UNDEBUG_STR
926 PROTO_HELP
927 "Flooding algorithm\n")
928 {
929 isis->debugs &= ~DEBUG_FLOODING;
930 print_debug(vty, DEBUG_FLOODING, 0);
931
932 return CMD_SUCCESS;
933 }
934
935 DEFUN (debug_isis_snp,
936 debug_isis_snp_cmd,
937 "debug " PROTO_NAME " snp-packets",
938 DEBUG_STR
939 PROTO_HELP
940 "IS-IS CSNP/PSNP packets\n")
941 {
942 isis->debugs |= DEBUG_SNP_PACKETS;
943 print_debug(vty, DEBUG_SNP_PACKETS, 1);
944
945 return CMD_SUCCESS;
946 }
947
948 DEFUN (no_debug_isis_snp,
949 no_debug_isis_snp_cmd,
950 "no debug " PROTO_NAME " snp-packets",
951 NO_STR
952 UNDEBUG_STR
953 PROTO_HELP
954 "IS-IS CSNP/PSNP packets\n")
955 {
956 isis->debugs &= ~DEBUG_SNP_PACKETS;
957 print_debug(vty, DEBUG_SNP_PACKETS, 0);
958
959 return CMD_SUCCESS;
960 }
961
962 DEFUN (debug_isis_upd,
963 debug_isis_upd_cmd,
964 "debug " PROTO_NAME " update-packets",
965 DEBUG_STR
966 PROTO_HELP
967 "IS-IS Update related packets\n")
968 {
969 isis->debugs |= DEBUG_UPDATE_PACKETS;
970 print_debug(vty, DEBUG_UPDATE_PACKETS, 1);
971
972 return CMD_SUCCESS;
973 }
974
975 DEFUN (no_debug_isis_upd,
976 no_debug_isis_upd_cmd,
977 "no debug " PROTO_NAME " update-packets",
978 NO_STR
979 UNDEBUG_STR
980 PROTO_HELP
981 "IS-IS Update related packets\n")
982 {
983 isis->debugs &= ~DEBUG_UPDATE_PACKETS;
984 print_debug(vty, DEBUG_UPDATE_PACKETS, 0);
985
986 return CMD_SUCCESS;
987 }
988
989 DEFUN (debug_isis_spfevents,
990 debug_isis_spfevents_cmd,
991 "debug " PROTO_NAME " spf-events",
992 DEBUG_STR
993 PROTO_HELP
994 "IS-IS Shortest Path First Events\n")
995 {
996 isis->debugs |= DEBUG_SPF_EVENTS;
997 print_debug(vty, DEBUG_SPF_EVENTS, 1);
998
999 return CMD_SUCCESS;
1000 }
1001
1002 DEFUN (no_debug_isis_spfevents,
1003 no_debug_isis_spfevents_cmd,
1004 "no debug " PROTO_NAME " spf-events",
1005 NO_STR
1006 UNDEBUG_STR
1007 PROTO_HELP
1008 "IS-IS Shortest Path First Events\n")
1009 {
1010 isis->debugs &= ~DEBUG_SPF_EVENTS;
1011 print_debug(vty, DEBUG_SPF_EVENTS, 0);
1012
1013 return CMD_SUCCESS;
1014 }
1015
1016 DEFUN (debug_isis_rtevents,
1017 debug_isis_rtevents_cmd,
1018 "debug " PROTO_NAME " route-events",
1019 DEBUG_STR
1020 PROTO_HELP
1021 "IS-IS Route related events\n")
1022 {
1023 isis->debugs |= DEBUG_RTE_EVENTS;
1024 print_debug(vty, DEBUG_RTE_EVENTS, 1);
1025
1026 return CMD_SUCCESS;
1027 }
1028
1029 DEFUN (no_debug_isis_rtevents,
1030 no_debug_isis_rtevents_cmd,
1031 "no debug " PROTO_NAME " route-events",
1032 NO_STR
1033 UNDEBUG_STR
1034 PROTO_HELP
1035 "IS-IS Route related events\n")
1036 {
1037 isis->debugs &= ~DEBUG_RTE_EVENTS;
1038 print_debug(vty, DEBUG_RTE_EVENTS, 0);
1039
1040 return CMD_SUCCESS;
1041 }
1042
1043 DEFUN (debug_isis_events,
1044 debug_isis_events_cmd,
1045 "debug " PROTO_NAME " events",
1046 DEBUG_STR
1047 PROTO_HELP
1048 "IS-IS Events\n")
1049 {
1050 isis->debugs |= DEBUG_EVENTS;
1051 print_debug(vty, DEBUG_EVENTS, 1);
1052
1053 return CMD_SUCCESS;
1054 }
1055
1056 DEFUN (no_debug_isis_events,
1057 no_debug_isis_events_cmd,
1058 "no debug " PROTO_NAME " events",
1059 NO_STR
1060 UNDEBUG_STR
1061 PROTO_HELP
1062 "IS-IS Events\n")
1063 {
1064 isis->debugs &= ~DEBUG_EVENTS;
1065 print_debug(vty, DEBUG_EVENTS, 0);
1066
1067 return CMD_SUCCESS;
1068 }
1069
1070 DEFUN (debug_isis_packet_dump,
1071 debug_isis_packet_dump_cmd,
1072 "debug " PROTO_NAME " packet-dump",
1073 DEBUG_STR
1074 PROTO_HELP
1075 "IS-IS packet dump\n")
1076 {
1077 isis->debugs |= DEBUG_PACKET_DUMP;
1078 print_debug(vty, DEBUG_PACKET_DUMP, 1);
1079
1080 return CMD_SUCCESS;
1081 }
1082
1083 DEFUN (no_debug_isis_packet_dump,
1084 no_debug_isis_packet_dump_cmd,
1085 "no debug " PROTO_NAME " packet-dump",
1086 NO_STR
1087 UNDEBUG_STR
1088 PROTO_HELP
1089 "IS-IS packet dump\n")
1090 {
1091 isis->debugs &= ~DEBUG_PACKET_DUMP;
1092 print_debug(vty, DEBUG_PACKET_DUMP, 0);
1093
1094 return CMD_SUCCESS;
1095 }
1096
1097 DEFUN (debug_isis_lsp_gen,
1098 debug_isis_lsp_gen_cmd,
1099 "debug " PROTO_NAME " lsp-gen",
1100 DEBUG_STR
1101 PROTO_HELP
1102 "IS-IS generation of own LSPs\n")
1103 {
1104 isis->debugs |= DEBUG_LSP_GEN;
1105 print_debug(vty, DEBUG_LSP_GEN, 1);
1106
1107 return CMD_SUCCESS;
1108 }
1109
1110 DEFUN (no_debug_isis_lsp_gen,
1111 no_debug_isis_lsp_gen_cmd,
1112 "no debug " PROTO_NAME " lsp-gen",
1113 NO_STR
1114 UNDEBUG_STR
1115 PROTO_HELP
1116 "IS-IS generation of own LSPs\n")
1117 {
1118 isis->debugs &= ~DEBUG_LSP_GEN;
1119 print_debug(vty, DEBUG_LSP_GEN, 0);
1120
1121 return CMD_SUCCESS;
1122 }
1123
1124 DEFUN (debug_isis_lsp_sched,
1125 debug_isis_lsp_sched_cmd,
1126 "debug " PROTO_NAME " lsp-sched",
1127 DEBUG_STR
1128 PROTO_HELP
1129 "IS-IS scheduling of LSP generation\n")
1130 {
1131 isis->debugs |= DEBUG_LSP_SCHED;
1132 print_debug(vty, DEBUG_LSP_SCHED, 1);
1133
1134 return CMD_SUCCESS;
1135 }
1136
1137 DEFUN (no_debug_isis_lsp_sched,
1138 no_debug_isis_lsp_sched_cmd,
1139 "no debug " PROTO_NAME " lsp-sched",
1140 NO_STR
1141 UNDEBUG_STR
1142 PROTO_HELP
1143 "IS-IS scheduling of LSP generation\n")
1144 {
1145 isis->debugs &= ~DEBUG_LSP_SCHED;
1146 print_debug(vty, DEBUG_LSP_SCHED, 0);
1147
1148 return CMD_SUCCESS;
1149 }
1150
1151 DEFUN (debug_isis_bfd,
1152 debug_isis_bfd_cmd,
1153 "debug " PROTO_NAME " bfd",
1154 DEBUG_STR
1155 PROTO_HELP
1156 PROTO_NAME " interaction with BFD\n")
1157 {
1158 isis->debugs |= DEBUG_BFD;
1159 print_debug(vty, DEBUG_BFD, 1);
1160
1161 return CMD_SUCCESS;
1162 }
1163
1164 DEFUN (no_debug_isis_bfd,
1165 no_debug_isis_bfd_cmd,
1166 "no debug " PROTO_NAME " bfd",
1167 NO_STR
1168 UNDEBUG_STR
1169 PROTO_HELP
1170 PROTO_NAME " interaction with BFD\n")
1171 {
1172 isis->debugs &= ~DEBUG_BFD;
1173 print_debug(vty, DEBUG_BFD, 0);
1174
1175 return CMD_SUCCESS;
1176 }
1177
1178 DEFUN (show_hostname,
1179 show_hostname_cmd,
1180 "show " PROTO_NAME " hostname",
1181 SHOW_STR
1182 PROTO_HELP
1183 "IS-IS Dynamic hostname mapping\n")
1184 {
1185 dynhn_print_all(vty);
1186
1187 return CMD_SUCCESS;
1188 }
1189
1190 DEFUN (show_isis_spf_ietf,
1191 show_isis_spf_ietf_cmd,
1192 "show " PROTO_NAME " spf-delay-ietf",
1193 SHOW_STR
1194 PROTO_HELP
1195 "SPF delay IETF information\n")
1196 {
1197 if (!isis) {
1198 vty_out(vty, "ISIS is not running\n");
1199 return CMD_SUCCESS;
1200 }
1201
1202 struct listnode *node;
1203 struct isis_area *area;
1204
1205 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
1206 vty_out(vty, "Area %s:\n",
1207 area->area_tag ? area->area_tag : "null");
1208
1209 for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
1210 if ((area->is_type & level) == 0)
1211 continue;
1212
1213 vty_out(vty, " Level-%d:\n", level);
1214 vty_out(vty, " SPF delay status: ");
1215 if (area->spf_timer[level - 1]) {
1216 struct timeval remain = thread_timer_remain(
1217 area->spf_timer[level - 1]);
1218 vty_out(vty, "Pending, due in %lld msec\n",
1219 (long long)remain.tv_sec * 1000
1220 + remain.tv_usec / 1000);
1221 } else {
1222 vty_out(vty, "Not scheduled\n");
1223 }
1224
1225 if (area->spf_delay_ietf[level - 1]) {
1226 vty_out(vty,
1227 " Using draft-ietf-rtgwg-backoff-algo-04\n");
1228 spf_backoff_show(
1229 area->spf_delay_ietf[level - 1], vty,
1230 " ");
1231 } else {
1232 vty_out(vty, " Using legacy backoff algo\n");
1233 }
1234 }
1235 }
1236 return CMD_SUCCESS;
1237 }
1238
1239 DEFUN (show_isis_summary,
1240 show_isis_summary_cmd,
1241 "show " PROTO_NAME " summary",
1242 SHOW_STR PROTO_HELP "summary\n")
1243 {
1244 struct listnode *node, *node2;
1245 struct isis_area *area;
1246 int level;
1247
1248 if (isis == NULL) {
1249 vty_out(vty, PROTO_NAME " is not running\n");
1250 return CMD_SUCCESS;
1251 }
1252
1253 vty_out(vty, "Process Id : %ld\n", isis->process_id);
1254 if (isis->sysid_set)
1255 vty_out(vty, "System Id : %s\n",
1256 sysid_print(isis->sysid));
1257
1258 vty_out(vty, "Up time : ");
1259 vty_out_timestr(vty, isis->uptime);
1260 vty_out(vty, "\n");
1261
1262 if (isis->area_list)
1263 vty_out(vty, "Number of areas : %d\n", isis->area_list->count);
1264
1265 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
1266 vty_out(vty, "Area %s:\n",
1267 area->area_tag ? area->area_tag : "null");
1268
1269 if (fabricd) {
1270 uint8_t tier = fabricd_tier(area);
1271 if (tier == ISIS_TIER_UNDEFINED)
1272 vty_out(vty, " Tier: undefined\n");
1273 else
1274 vty_out(vty, " Tier: %" PRIu8 "\n", tier);
1275 }
1276
1277 if (listcount(area->area_addrs) > 0) {
1278 struct area_addr *area_addr;
1279 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
1280 area_addr)) {
1281 vty_out(vty, " Net: %s\n",
1282 isonet_print(area_addr->area_addr,
1283 area_addr->addr_len
1284 + ISIS_SYS_ID_LEN
1285 + 1));
1286 }
1287 }
1288
1289 vty_out(vty, " TX counters per PDU type:\n");
1290 pdu_counter_print(vty, " ", area->pdu_tx_counters);
1291 vty_out(vty, " LSP RXMT: %" PRIu64 "\n",
1292 area->lsp_rxmt_count);
1293 vty_out(vty, " RX counters per PDU type:\n");
1294 pdu_counter_print(vty, " ", area->pdu_rx_counters);
1295
1296 for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
1297 if ((area->is_type & level) == 0)
1298 continue;
1299
1300 vty_out(vty, " Level-%d:\n", level);
1301
1302 vty_out(vty, " LSP0 regenerated: %" PRIu64 "\n",
1303 area->lsp_gen_count[level - 1]);
1304
1305 vty_out(vty, " LSPs purged: %" PRIu64 "\n",
1306 area->lsp_purge_count[level - 1]);
1307
1308 if (area->spf_timer[level - 1])
1309 vty_out(vty, " SPF: (pending)\n");
1310 else
1311 vty_out(vty, " SPF:\n");
1312
1313 vty_out(vty, " minimum interval : %d",
1314 area->min_spf_interval[level - 1]);
1315 if (area->spf_delay_ietf[level - 1])
1316 vty_out(vty,
1317 " (not used, IETF SPF delay activated)");
1318 vty_out(vty, "\n");
1319
1320 vty_out(vty, " IPv4 route computation:\n");
1321 isis_spf_print(area->spftree[SPFTREE_IPV4][level - 1],
1322 vty);
1323
1324 vty_out(vty, " IPv6 route computation:\n");
1325 isis_spf_print(area->spftree[SPFTREE_IPV6][level - 1],
1326 vty);
1327
1328 vty_out(vty, " IPv6 dst-src route computation:\n");
1329 isis_spf_print(area->spftree[SPFTREE_DSTSRC][level-1],
1330 vty);
1331 }
1332 }
1333 vty_out(vty, "\n");
1334
1335 return CMD_SUCCESS;
1336 }
1337
1338 struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv)
1339 {
1340 char sysid[255] = {0};
1341 uint8_t number[3];
1342 const char *pos;
1343 uint8_t lspid[ISIS_SYS_ID_LEN + 2] = {0};
1344 struct isis_dynhn *dynhn;
1345 struct isis_lsp *lsp = NULL;
1346
1347 if (!argv)
1348 return NULL;
1349
1350 /*
1351 * extract fragment and pseudo id from the string argv
1352 * in the forms:
1353 * (a) <systemid/hostname>.<pseudo-id>-<framenent> or
1354 * (b) <systemid/hostname>.<pseudo-id> or
1355 * (c) <systemid/hostname> or
1356 * Where systemid is in the form:
1357 * xxxx.xxxx.xxxx
1358 */
1359 if (argv)
1360 strlcpy(sysid, argv, sizeof(sysid));
1361 if (argv && strlen(argv) > 3) {
1362 pos = argv + strlen(argv) - 3;
1363 if (strncmp(pos, "-", 1) == 0) {
1364 memcpy(number, ++pos, 2);
1365 lspid[ISIS_SYS_ID_LEN + 1] =
1366 (uint8_t)strtol((char *)number, NULL, 16);
1367 pos -= 4;
1368 if (strncmp(pos, ".", 1) != 0)
1369 return NULL;
1370 }
1371 if (strncmp(pos, ".", 1) == 0) {
1372 memcpy(number, ++pos, 2);
1373 lspid[ISIS_SYS_ID_LEN] =
1374 (uint8_t)strtol((char *)number, NULL, 16);
1375 sysid[pos - argv - 1] = '\0';
1376 }
1377 }
1378
1379 /*
1380 * Try to find the lsp-id if the argv
1381 * string is in
1382 * the form
1383 * hostname.<pseudo-id>-<fragment>
1384 */
1385 if (sysid2buff(lspid, sysid)) {
1386 lsp = lsp_search(head, lspid);
1387 } else if ((dynhn = dynhn_find_by_name(sysid))) {
1388 memcpy(lspid, dynhn->id, ISIS_SYS_ID_LEN);
1389 lsp = lsp_search(head, lspid);
1390 } else if (strncmp(cmd_hostname_get(), sysid, 15) == 0) {
1391 memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
1392 lsp = lsp_search(head, lspid);
1393 }
1394
1395 return lsp;
1396 }
1397
1398 /*
1399 * This function supports following display options:
1400 * [ show isis database [detail] ]
1401 * [ show isis database <sysid> [detail] ]
1402 * [ show isis database <hostname> [detail] ]
1403 * [ show isis database <sysid>.<pseudo-id> [detail] ]
1404 * [ show isis database <hostname>.<pseudo-id> [detail] ]
1405 * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
1406 * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
1407 * [ show isis database detail <sysid> ]
1408 * [ show isis database detail <hostname> ]
1409 * [ show isis database detail <sysid>.<pseudo-id> ]
1410 * [ show isis database detail <hostname>.<pseudo-id> ]
1411 * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
1412 * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
1413 */
1414 static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
1415 {
1416 struct listnode *node;
1417 struct isis_area *area;
1418 struct isis_lsp *lsp;
1419 int level, lsp_count;
1420
1421 if (isis->area_list->count == 0)
1422 return CMD_SUCCESS;
1423
1424 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
1425 vty_out(vty, "Area %s:\n",
1426 area->area_tag ? area->area_tag : "null");
1427
1428 for (level = 0; level < ISIS_LEVELS; level++) {
1429 if (lspdb_count(&area->lspdb[level]) > 0) {
1430 lsp = lsp_for_arg(&area->lspdb[level], argv);
1431
1432 if (lsp != NULL || argv == NULL) {
1433 vty_out(vty,
1434 "IS-IS Level-%d link-state database:\n",
1435 level + 1);
1436
1437 /* print the title in all cases */
1438 vty_out(vty,
1439 "LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
1440 }
1441
1442 if (lsp) {
1443 if (ui_level == ISIS_UI_LEVEL_DETAIL)
1444 lsp_print_detail(
1445 lsp, vty,
1446 area->dynhostname);
1447 else
1448 lsp_print(lsp, vty,
1449 area->dynhostname);
1450 } else if (argv == NULL) {
1451 lsp_count = lsp_print_all(
1452 vty, &area->lspdb[level],
1453 ui_level, area->dynhostname);
1454
1455 vty_out(vty, " %u LSPs\n\n",
1456 lsp_count);
1457 }
1458 }
1459 }
1460 }
1461
1462 return CMD_SUCCESS;
1463 }
1464
1465 DEFUN (show_database,
1466 show_database_cmd,
1467 "show " PROTO_NAME " database [detail] [WORD]",
1468 SHOW_STR
1469 PROTO_HELP
1470 "Link state database\n"
1471 "Detailed information\n"
1472 "LSP ID\n")
1473 {
1474 int idx = 0;
1475 int uilevel = argv_find(argv, argc, "detail", &idx)
1476 ? ISIS_UI_LEVEL_DETAIL
1477 : ISIS_UI_LEVEL_BRIEF;
1478 char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
1479 return show_isis_database(vty, id, uilevel);
1480 }
1481
1482 #ifdef FABRICD
1483 /*
1484 * 'router openfabric' command
1485 */
1486 DEFUN_NOSH (router_openfabric,
1487 router_openfabric_cmd,
1488 "router openfabric WORD",
1489 ROUTER_STR
1490 PROTO_HELP
1491 "ISO Routing area tag\n")
1492 {
1493 int idx_word = 2;
1494 return isis_area_get(vty, argv[idx_word]->arg);
1495 }
1496
1497 /*
1498 *'no router openfabric' command
1499 */
1500 DEFUN (no_router_openfabric,
1501 no_router_openfabric_cmd,
1502 "no router openfabric WORD",
1503 NO_STR
1504 ROUTER_STR
1505 PROTO_HELP
1506 "ISO Routing area tag\n")
1507 {
1508 int idx_word = 3;
1509 return isis_area_destroy(argv[idx_word]->arg);
1510 }
1511 #endif /* ifdef FABRICD */
1512 #ifdef FABRICD
1513 /*
1514 * 'net' command
1515 */
1516 DEFUN (net,
1517 net_cmd,
1518 "net WORD",
1519 "A Network Entity Title for this process (OSI only)\n"
1520 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
1521 {
1522 int idx_word = 1;
1523 return area_net_title(vty, argv[idx_word]->arg);
1524 }
1525
1526 /*
1527 * 'no net' command
1528 */
1529 DEFUN (no_net,
1530 no_net_cmd,
1531 "no net WORD",
1532 NO_STR
1533 "A Network Entity Title for this process (OSI only)\n"
1534 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
1535 {
1536 int idx_word = 2;
1537 return area_clear_net_title(vty, argv[idx_word]->arg);
1538 }
1539 #endif /* ifdef FABRICD */
1540 #ifdef FABRICD
1541 DEFUN (isis_topology,
1542 isis_topology_cmd,
1543 "topology " ISIS_MT_NAMES " [overload]",
1544 "Configure IS-IS topologies\n"
1545 ISIS_MT_DESCRIPTIONS
1546 "Set overload bit for topology\n")
1547 {
1548 VTY_DECLVAR_CONTEXT(isis_area, area);
1549
1550 const char *arg = argv[1]->arg;
1551 uint16_t mtid = isis_str2mtid(arg);
1552
1553 if (area->oldmetric) {
1554 vty_out(vty,
1555 "Multi topology IS-IS can only be used with wide metrics\n");
1556 return CMD_WARNING_CONFIG_FAILED;
1557 }
1558
1559 if (mtid == (uint16_t)-1) {
1560 vty_out(vty, "Don't know topology '%s'\n", arg);
1561 return CMD_WARNING_CONFIG_FAILED;
1562 }
1563 if (mtid == ISIS_MT_IPV4_UNICAST) {
1564 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
1565 return CMD_WARNING_CONFIG_FAILED;
1566 }
1567
1568 area_set_mt_enabled(area, mtid, true);
1569 area_set_mt_overload(area, mtid, (argc == 3));
1570 return CMD_SUCCESS;
1571 }
1572
1573 DEFUN (no_isis_topology,
1574 no_isis_topology_cmd,
1575 "no topology " ISIS_MT_NAMES " [overload]",
1576 NO_STR
1577 "Configure IS-IS topologies\n"
1578 ISIS_MT_DESCRIPTIONS
1579 "Set overload bit for topology\n")
1580 {
1581 VTY_DECLVAR_CONTEXT(isis_area, area);
1582
1583 const char *arg = argv[2]->arg;
1584 uint16_t mtid = isis_str2mtid(arg);
1585
1586 if (area->oldmetric) {
1587 vty_out(vty,
1588 "Multi topology IS-IS can only be used with wide metrics\n");
1589 return CMD_WARNING_CONFIG_FAILED;
1590 }
1591
1592 if (mtid == (uint16_t)-1) {
1593 vty_out(vty, "Don't know topology '%s'\n", arg);
1594 return CMD_WARNING_CONFIG_FAILED;
1595 }
1596 if (mtid == ISIS_MT_IPV4_UNICAST) {
1597 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
1598 return CMD_WARNING_CONFIG_FAILED;
1599 }
1600
1601 area_set_mt_enabled(area, mtid, false);
1602 area_set_mt_overload(area, mtid, false);
1603 return CMD_SUCCESS;
1604 }
1605 #endif /* ifdef FABRICD */
1606
1607 void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
1608 {
1609 area->lsp_mtu = lsp_mtu;
1610 lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1);
1611 }
1612
1613 static int isis_area_passwd_set(struct isis_area *area, int level,
1614 uint8_t passwd_type, const char *passwd,
1615 uint8_t snp_auth)
1616 {
1617 struct isis_passwd *dest;
1618 struct isis_passwd modified;
1619 int len;
1620
1621 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
1622 dest = (level == IS_LEVEL_1) ? &area->area_passwd
1623 : &area->domain_passwd;
1624 memset(&modified, 0, sizeof(modified));
1625
1626 if (passwd_type != ISIS_PASSWD_TYPE_UNUSED) {
1627 if (!passwd)
1628 return -1;
1629
1630 len = strlen(passwd);
1631 if (len > 254)
1632 return -1;
1633
1634 modified.len = len;
1635 strlcpy((char *)modified.passwd, passwd,
1636 sizeof(modified.passwd));
1637 modified.type = passwd_type;
1638 modified.snp_auth = snp_auth;
1639 }
1640
1641 if (memcmp(&modified, dest, sizeof(modified))) {
1642 memcpy(dest, &modified, sizeof(modified));
1643 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1644 }
1645
1646 return 0;
1647 }
1648
1649 int isis_area_passwd_unset(struct isis_area *area, int level)
1650 {
1651 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_UNUSED, NULL,
1652 0);
1653 }
1654
1655 int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
1656 const char *passwd, uint8_t snp_auth)
1657 {
1658 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_CLEARTXT,
1659 passwd, snp_auth);
1660 }
1661
1662 int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
1663 const char *passwd, uint8_t snp_auth)
1664 {
1665 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_HMAC_MD5,
1666 passwd, snp_auth);
1667 }
1668
1669 void isis_area_invalidate_routes(struct isis_area *area, int levels)
1670 {
1671 for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
1672 if (!(level & levels))
1673 continue;
1674 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
1675 isis_spf_invalidate_routes(
1676 area->spftree[tree][level - 1]);
1677 }
1678 }
1679 }
1680
1681 void isis_area_verify_routes(struct isis_area *area)
1682 {
1683 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++)
1684 isis_spf_verify_routes(area, area->spftree[tree]);
1685 }
1686
1687 static void area_resign_level(struct isis_area *area, int level)
1688 {
1689 isis_area_invalidate_routes(area, level);
1690 isis_area_verify_routes(area);
1691
1692 lsp_db_fini(&area->lspdb[level - 1]);
1693
1694 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
1695 if (area->spftree[tree][level - 1]) {
1696 isis_spftree_del(area->spftree[tree][level - 1]);
1697 area->spftree[tree][level - 1] = NULL;
1698 }
1699 }
1700
1701 THREAD_TIMER_OFF(area->spf_timer[level - 1]);
1702
1703 sched_debug(
1704 "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
1705 area->area_tag, level);
1706 THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]);
1707 area->lsp_regenerate_pending[level - 1] = 0;
1708 }
1709
1710 void isis_area_is_type_set(struct isis_area *area, int is_type)
1711 {
1712 struct listnode *node;
1713 struct isis_circuit *circuit;
1714
1715 if (isis->debugs & DEBUG_EVENTS)
1716 zlog_debug("ISIS-Evt (%s) system type change %s -> %s",
1717 area->area_tag, circuit_t2string(area->is_type),
1718 circuit_t2string(is_type));
1719
1720 if (area->is_type == is_type)
1721 return; /* No change */
1722
1723 switch (area->is_type) {
1724 case IS_LEVEL_1:
1725 if (is_type == IS_LEVEL_2)
1726 area_resign_level(area, IS_LEVEL_1);
1727
1728 lsp_db_init(&area->lspdb[1]);
1729 break;
1730
1731 case IS_LEVEL_1_AND_2:
1732 if (is_type == IS_LEVEL_1)
1733 area_resign_level(area, IS_LEVEL_2);
1734 else
1735 area_resign_level(area, IS_LEVEL_1);
1736 break;
1737
1738 case IS_LEVEL_2:
1739 if (is_type == IS_LEVEL_1)
1740 area_resign_level(area, IS_LEVEL_2);
1741
1742 lsp_db_init(&area->lspdb[0]);
1743 break;
1744
1745 default:
1746 break;
1747 }
1748
1749 area->is_type = is_type;
1750
1751 /* override circuit's is_type */
1752 if (area->is_type != IS_LEVEL_1_AND_2) {
1753 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
1754 isis_circuit_is_type_set(circuit, is_type);
1755 }
1756
1757 spftree_area_init(area);
1758
1759 if (listcount(area->area_addrs) > 0) {
1760 if (is_type & IS_LEVEL_1)
1761 lsp_generate(area, IS_LEVEL_1);
1762 if (is_type & IS_LEVEL_2)
1763 lsp_generate(area, IS_LEVEL_2);
1764 }
1765 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1766
1767 return;
1768 }
1769
1770 void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
1771 bool new_metric)
1772 {
1773 area->oldmetric = old_metric;
1774 area->newmetric = new_metric;
1775 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1776 }
1777
1778 void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
1779 {
1780 char new_overload_bit = overload_bit ? LSPBIT_OL : 0;
1781
1782 if (new_overload_bit != area->overload_bit) {
1783 area->overload_bit = new_overload_bit;
1784 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1785 }
1786 #ifndef FABRICD
1787 isis_notif_db_overload(area, overload_bit);
1788 #endif /* ifndef FABRICD */
1789 }
1790
1791 void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit)
1792 {
1793 char new_attached_bit = attached_bit ? LSPBIT_ATT : 0;
1794
1795 if (new_attached_bit != area->attached_bit) {
1796 area->attached_bit = new_attached_bit;
1797 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
1798 }
1799 }
1800
1801 void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname)
1802 {
1803 if (area->dynhostname != dynhostname) {
1804 area->dynhostname = dynhostname;
1805 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1806 }
1807 }
1808
1809 void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level,
1810 uint16_t max_lsp_lifetime)
1811 {
1812 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
1813
1814 if (area->max_lsp_lifetime[level - 1] == max_lsp_lifetime)
1815 return;
1816
1817 area->max_lsp_lifetime[level - 1] = max_lsp_lifetime;
1818 lsp_regenerate_schedule(area, level, 1);
1819 }
1820
1821 void isis_area_lsp_refresh_set(struct isis_area *area, int level,
1822 uint16_t lsp_refresh)
1823 {
1824 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
1825
1826 if (area->lsp_refresh[level - 1] == lsp_refresh)
1827 return;
1828
1829 area->lsp_refresh[level - 1] = lsp_refresh;
1830 lsp_regenerate_schedule(area, level, 1);
1831 }
1832
1833 #ifdef FABRICD
1834 DEFUN (log_adj_changes,
1835 log_adj_changes_cmd,
1836 "log-adjacency-changes",
1837 "Log changes in adjacency state\n")
1838 {
1839 VTY_DECLVAR_CONTEXT(isis_area, area);
1840
1841 area->log_adj_changes = 1;
1842
1843 return CMD_SUCCESS;
1844 }
1845
1846 DEFUN (no_log_adj_changes,
1847 no_log_adj_changes_cmd,
1848 "no log-adjacency-changes",
1849 NO_STR
1850 "Stop logging changes in adjacency state\n")
1851 {
1852 VTY_DECLVAR_CONTEXT(isis_area, area);
1853
1854 area->log_adj_changes = 0;
1855
1856 return CMD_SUCCESS;
1857 }
1858 #endif /* ifdef FABRICD */
1859 #ifdef FABRICD
1860 /* IS-IS configuration write function */
1861 int isis_config_write(struct vty *vty)
1862 {
1863 int write = 0;
1864
1865 if (isis != NULL) {
1866 struct isis_area *area;
1867 struct listnode *node, *node2;
1868
1869 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
1870 /* ISIS - Area name */
1871 vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
1872 write++;
1873 /* ISIS - Net */
1874 if (listcount(area->area_addrs) > 0) {
1875 struct area_addr *area_addr;
1876 for (ALL_LIST_ELEMENTS_RO(area->area_addrs,
1877 node2, area_addr)) {
1878 vty_out(vty, " net %s\n",
1879 isonet_print(
1880 area_addr->area_addr,
1881 area_addr->addr_len
1882 + ISIS_SYS_ID_LEN
1883 + 1));
1884 write++;
1885 }
1886 }
1887 /* ISIS - Dynamic hostname - Defaults to true so only
1888 * display if
1889 * false. */
1890 if (!area->dynhostname) {
1891 vty_out(vty, " no hostname dynamic\n");
1892 write++;
1893 }
1894 /* ISIS - Metric-Style - when true displays wide */
1895 if (!fabricd) {
1896 if (area->newmetric) {
1897 if (!area->oldmetric)
1898 vty_out(vty, " metric-style wide\n");
1899 else
1900 vty_out(vty,
1901 " metric-style transition\n");
1902 write++;
1903 } else {
1904 vty_out(vty, " metric-style narrow\n");
1905 write++;
1906 }
1907 }
1908 /* ISIS - overload-bit */
1909 if (area->overload_bit) {
1910 vty_out(vty, " set-overload-bit\n");
1911 write++;
1912 }
1913 /* ISIS - Area is-type (level-1-2 is default) */
1914 if (!fabricd) {
1915 if (area->is_type == IS_LEVEL_1) {
1916 vty_out(vty, " is-type level-1\n");
1917 write++;
1918 } else if (area->is_type == IS_LEVEL_2) {
1919 vty_out(vty, " is-type level-2-only\n");
1920 write++;
1921 }
1922 }
1923 write += isis_redist_config_write(vty, area, AF_INET);
1924 write += isis_redist_config_write(vty, area, AF_INET6);
1925 /* ISIS - Lsp generation interval */
1926 if (area->lsp_gen_interval[0]
1927 == area->lsp_gen_interval[1]) {
1928 if (area->lsp_gen_interval[0]
1929 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
1930 vty_out(vty, " lsp-gen-interval %d\n",
1931 area->lsp_gen_interval[0]);
1932 write++;
1933 }
1934 } else {
1935 if (area->lsp_gen_interval[0]
1936 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
1937 vty_out(vty,
1938 " lsp-gen-interval level-1 %d\n",
1939 area->lsp_gen_interval[0]);
1940 write++;
1941 }
1942 if (area->lsp_gen_interval[1]
1943 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
1944 vty_out(vty,
1945 " lsp-gen-interval level-2 %d\n",
1946 area->lsp_gen_interval[1]);
1947 write++;
1948 }
1949 }
1950 /* ISIS - LSP lifetime */
1951 if (area->max_lsp_lifetime[0]
1952 == area->max_lsp_lifetime[1]) {
1953 if (area->max_lsp_lifetime[0]
1954 != DEFAULT_LSP_LIFETIME) {
1955 vty_out(vty, " max-lsp-lifetime %u\n",
1956 area->max_lsp_lifetime[0]);
1957 write++;
1958 }
1959 } else {
1960 if (area->max_lsp_lifetime[0]
1961 != DEFAULT_LSP_LIFETIME) {
1962 vty_out(vty,
1963 " max-lsp-lifetime level-1 %u\n",
1964 area->max_lsp_lifetime[0]);
1965 write++;
1966 }
1967 if (area->max_lsp_lifetime[1]
1968 != DEFAULT_LSP_LIFETIME) {
1969 vty_out(vty,
1970 " max-lsp-lifetime level-2 %u\n",
1971 area->max_lsp_lifetime[1]);
1972 write++;
1973 }
1974 }
1975 /* ISIS - LSP refresh interval */
1976 if (area->lsp_refresh[0] == area->lsp_refresh[1]) {
1977 if (area->lsp_refresh[0]
1978 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
1979 vty_out(vty,
1980 " lsp-refresh-interval %u\n",
1981 area->lsp_refresh[0]);
1982 write++;
1983 }
1984 } else {
1985 if (area->lsp_refresh[0]
1986 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
1987 vty_out(vty,
1988 " lsp-refresh-interval level-1 %u\n",
1989 area->lsp_refresh[0]);
1990 write++;
1991 }
1992 if (area->lsp_refresh[1]
1993 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
1994 vty_out(vty,
1995 " lsp-refresh-interval level-2 %u\n",
1996 area->lsp_refresh[1]);
1997 write++;
1998 }
1999 }
2000 if (area->lsp_mtu != DEFAULT_LSP_MTU) {
2001 vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu);
2002 write++;
2003 }
2004 if (area->purge_originator) {
2005 vty_out(vty, " purge-originator\n");
2006 write++;
2007 }
2008
2009 /* Minimum SPF interval. */
2010 if (area->min_spf_interval[0]
2011 == area->min_spf_interval[1]) {
2012 if (area->min_spf_interval[0]
2013 != MINIMUM_SPF_INTERVAL) {
2014 vty_out(vty, " spf-interval %d\n",
2015 area->min_spf_interval[0]);
2016 write++;
2017 }
2018 } else {
2019 if (area->min_spf_interval[0]
2020 != MINIMUM_SPF_INTERVAL) {
2021 vty_out(vty,
2022 " spf-interval level-1 %d\n",
2023 area->min_spf_interval[0]);
2024 write++;
2025 }
2026 if (area->min_spf_interval[1]
2027 != MINIMUM_SPF_INTERVAL) {
2028 vty_out(vty,
2029 " spf-interval level-2 %d\n",
2030 area->min_spf_interval[1]);
2031 write++;
2032 }
2033 }
2034
2035 /* IETF SPF interval */
2036 if (area->spf_delay_ietf[0]) {
2037 vty_out(vty,
2038 " spf-delay-ietf init-delay %ld short-delay %ld long-delay %ld holddown %ld time-to-learn %ld\n",
2039 spf_backoff_init_delay(
2040 area->spf_delay_ietf[0]),
2041 spf_backoff_short_delay(
2042 area->spf_delay_ietf[0]),
2043 spf_backoff_long_delay(
2044 area->spf_delay_ietf[0]),
2045 spf_backoff_holddown(
2046 area->spf_delay_ietf[0]),
2047 spf_backoff_timetolearn(
2048 area->spf_delay_ietf[0]));
2049 write++;
2050 }
2051
2052 /* Authentication passwords. */
2053 if (area->area_passwd.type
2054 == ISIS_PASSWD_TYPE_HMAC_MD5) {
2055 vty_out(vty, " area-password md5 %s",
2056 area->area_passwd.passwd);
2057 if (CHECK_FLAG(area->area_passwd.snp_auth,
2058 SNP_AUTH_SEND)) {
2059 vty_out(vty, " authenticate snp ");
2060 if (CHECK_FLAG(
2061 area->area_passwd.snp_auth,
2062 SNP_AUTH_RECV))
2063 vty_out(vty, "validate");
2064 else
2065 vty_out(vty, "send-only");
2066 }
2067 vty_out(vty, "\n");
2068 write++;
2069 } else if (area->area_passwd.type
2070 == ISIS_PASSWD_TYPE_CLEARTXT) {
2071 vty_out(vty, " area-password clear %s",
2072 area->area_passwd.passwd);
2073 if (CHECK_FLAG(area->area_passwd.snp_auth,
2074 SNP_AUTH_SEND)) {
2075 vty_out(vty, " authenticate snp ");
2076 if (CHECK_FLAG(
2077 area->area_passwd.snp_auth,
2078 SNP_AUTH_RECV))
2079 vty_out(vty, "validate");
2080 else
2081 vty_out(vty, "send-only");
2082 }
2083 vty_out(vty, "\n");
2084 write++;
2085 }
2086 if (area->domain_passwd.type
2087 == ISIS_PASSWD_TYPE_HMAC_MD5) {
2088 vty_out(vty, " domain-password md5 %s",
2089 area->domain_passwd.passwd);
2090 if (CHECK_FLAG(area->domain_passwd.snp_auth,
2091 SNP_AUTH_SEND)) {
2092 vty_out(vty, " authenticate snp ");
2093 if (CHECK_FLAG(area->domain_passwd
2094 .snp_auth,
2095 SNP_AUTH_RECV))
2096 vty_out(vty, "validate");
2097 else
2098 vty_out(vty, "send-only");
2099 }
2100 vty_out(vty, "\n");
2101 write++;
2102 } else if (area->domain_passwd.type
2103 == ISIS_PASSWD_TYPE_CLEARTXT) {
2104 vty_out(vty, " domain-password clear %s",
2105 area->domain_passwd.passwd);
2106 if (CHECK_FLAG(area->domain_passwd.snp_auth,
2107 SNP_AUTH_SEND)) {
2108 vty_out(vty, " authenticate snp ");
2109 if (CHECK_FLAG(area->domain_passwd
2110 .snp_auth,
2111 SNP_AUTH_RECV))
2112 vty_out(vty, "validate");
2113 else
2114 vty_out(vty, "send-only");
2115 }
2116 vty_out(vty, "\n");
2117 write++;
2118 }
2119
2120 if (area->log_adj_changes) {
2121 vty_out(vty, " log-adjacency-changes\n");
2122 write++;
2123 }
2124
2125 write += area_write_mt_settings(area, vty);
2126 write += fabricd_write_settings(area, vty);
2127 }
2128 }
2129
2130 return write;
2131 }
2132
2133 #else
2134 /* IS-IS configuration write function */
2135 int isis_config_write(struct vty *vty)
2136 {
2137 int write = 0;
2138 struct lyd_node *dnode;
2139
2140 dnode = yang_dnode_get(running_config->dnode, "/frr-isisd:isis");
2141 if (dnode) {
2142 nb_cli_show_dnode_cmds(vty, dnode, false);
2143 write++;
2144 }
2145
2146 return write;
2147 }
2148 #endif /* ifdef FABRICD */
2149
2150 struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1};
2151
2152 void isis_init(void)
2153 {
2154 /* Install IS-IS top node */
2155 install_node(&router_node, isis_config_write);
2156
2157 install_element(VIEW_NODE, &show_isis_summary_cmd);
2158
2159 install_element(VIEW_NODE, &show_isis_spf_ietf_cmd);
2160
2161 install_element(VIEW_NODE, &show_isis_interface_cmd);
2162 install_element(VIEW_NODE, &show_isis_interface_detail_cmd);
2163 install_element(VIEW_NODE, &show_isis_interface_arg_cmd);
2164
2165 install_element(VIEW_NODE, &show_isis_neighbor_cmd);
2166 install_element(VIEW_NODE, &show_isis_neighbor_detail_cmd);
2167 install_element(VIEW_NODE, &show_isis_neighbor_arg_cmd);
2168 install_element(VIEW_NODE, &clear_isis_neighbor_cmd);
2169 install_element(VIEW_NODE, &clear_isis_neighbor_arg_cmd);
2170
2171 install_element(VIEW_NODE, &show_hostname_cmd);
2172 install_element(VIEW_NODE, &show_database_cmd);
2173
2174 install_element(ENABLE_NODE, &show_debugging_isis_cmd);
2175
2176 install_node(&debug_node, config_write_debug);
2177
2178 install_element(ENABLE_NODE, &debug_isis_adj_cmd);
2179 install_element(ENABLE_NODE, &no_debug_isis_adj_cmd);
2180 install_element(ENABLE_NODE, &debug_isis_tx_queue_cmd);
2181 install_element(ENABLE_NODE, &no_debug_isis_tx_queue_cmd);
2182 install_element(ENABLE_NODE, &debug_isis_flooding_cmd);
2183 install_element(ENABLE_NODE, &no_debug_isis_flooding_cmd);
2184 install_element(ENABLE_NODE, &debug_isis_snp_cmd);
2185 install_element(ENABLE_NODE, &no_debug_isis_snp_cmd);
2186 install_element(ENABLE_NODE, &debug_isis_upd_cmd);
2187 install_element(ENABLE_NODE, &no_debug_isis_upd_cmd);
2188 install_element(ENABLE_NODE, &debug_isis_spfevents_cmd);
2189 install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd);
2190 install_element(ENABLE_NODE, &debug_isis_rtevents_cmd);
2191 install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd);
2192 install_element(ENABLE_NODE, &debug_isis_events_cmd);
2193 install_element(ENABLE_NODE, &no_debug_isis_events_cmd);
2194 install_element(ENABLE_NODE, &debug_isis_packet_dump_cmd);
2195 install_element(ENABLE_NODE, &no_debug_isis_packet_dump_cmd);
2196 install_element(ENABLE_NODE, &debug_isis_lsp_gen_cmd);
2197 install_element(ENABLE_NODE, &no_debug_isis_lsp_gen_cmd);
2198 install_element(ENABLE_NODE, &debug_isis_lsp_sched_cmd);
2199 install_element(ENABLE_NODE, &no_debug_isis_lsp_sched_cmd);
2200 install_element(ENABLE_NODE, &debug_isis_bfd_cmd);
2201 install_element(ENABLE_NODE, &no_debug_isis_bfd_cmd);
2202
2203 install_element(CONFIG_NODE, &debug_isis_adj_cmd);
2204 install_element(CONFIG_NODE, &no_debug_isis_adj_cmd);
2205 install_element(CONFIG_NODE, &debug_isis_tx_queue_cmd);
2206 install_element(CONFIG_NODE, &no_debug_isis_tx_queue_cmd);
2207 install_element(CONFIG_NODE, &debug_isis_flooding_cmd);
2208 install_element(CONFIG_NODE, &no_debug_isis_flooding_cmd);
2209 install_element(CONFIG_NODE, &debug_isis_snp_cmd);
2210 install_element(CONFIG_NODE, &no_debug_isis_snp_cmd);
2211 install_element(CONFIG_NODE, &debug_isis_upd_cmd);
2212 install_element(CONFIG_NODE, &no_debug_isis_upd_cmd);
2213 install_element(CONFIG_NODE, &debug_isis_spfevents_cmd);
2214 install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd);
2215 install_element(CONFIG_NODE, &debug_isis_rtevents_cmd);
2216 install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd);
2217 install_element(CONFIG_NODE, &debug_isis_events_cmd);
2218 install_element(CONFIG_NODE, &no_debug_isis_events_cmd);
2219 install_element(CONFIG_NODE, &debug_isis_packet_dump_cmd);
2220 install_element(CONFIG_NODE, &no_debug_isis_packet_dump_cmd);
2221 install_element(CONFIG_NODE, &debug_isis_lsp_gen_cmd);
2222 install_element(CONFIG_NODE, &no_debug_isis_lsp_gen_cmd);
2223 install_element(CONFIG_NODE, &debug_isis_lsp_sched_cmd);
2224 install_element(CONFIG_NODE, &no_debug_isis_lsp_sched_cmd);
2225 install_element(CONFIG_NODE, &debug_isis_bfd_cmd);
2226 install_element(CONFIG_NODE, &no_debug_isis_bfd_cmd);
2227
2228 install_default(ROUTER_NODE);
2229
2230 #ifdef FABRICD
2231 install_element(CONFIG_NODE, &router_openfabric_cmd);
2232 install_element(CONFIG_NODE, &no_router_openfabric_cmd);
2233
2234 install_element(ROUTER_NODE, &net_cmd);
2235 install_element(ROUTER_NODE, &no_net_cmd);
2236
2237 install_element(ROUTER_NODE, &isis_topology_cmd);
2238 install_element(ROUTER_NODE, &no_isis_topology_cmd);
2239
2240 install_element(ROUTER_NODE, &log_adj_changes_cmd);
2241 install_element(ROUTER_NODE, &no_log_adj_changes_cmd);
2242 #endif /* ifdef FABRICD */
2243
2244 spf_backoff_cmd_init();
2245 }