]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_vty_common.c
Merge pull request #3137 from opensourcerouting/feature/isis-bfd
[mirror_frr.git] / isisd / isis_vty_common.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_vty_common.c
3 *
4 * This file contains the CLI that is shared between OpenFabric and IS-IS
5 *
6 * Copyright (C) 2001,2002 Sampo Saaristo
7 * Tampere University of Technology
8 * Institute of Communications Engineering
9 * Copyright (C) 2016 David Lamparter, for NetDEF, Inc.
10 * Copyright (C) 2018 Christian Franke, for NetDEF, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public Licenseas published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; see the file COPYING; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #include <zebra.h>
28
29 #include "command.h"
30 #include "spf_backoff.h"
31 #include "bfd.h"
32
33 #include "isis_circuit.h"
34 #include "isis_csm.h"
35 #include "isis_misc.h"
36 #include "isis_mt.h"
37 #include "isisd.h"
38 #include "isis_bfd.h"
39 #include "isis_vty_common.h"
40
41 struct isis_circuit *isis_circuit_lookup(struct vty *vty)
42 {
43 struct interface *ifp = VTY_GET_CONTEXT(interface);
44 struct isis_circuit *circuit;
45
46 if (!ifp) {
47 vty_out(vty, "Invalid interface \n");
48 return NULL;
49 }
50
51 circuit = circuit_scan_by_ifp(ifp);
52 if (!circuit) {
53 vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
54 return NULL;
55 }
56
57 return circuit;
58 }
59
60 DEFUN (ip_router_isis,
61 ip_router_isis_cmd,
62 "ip router " PROTO_NAME " WORD",
63 "Interface Internet Protocol config commands\n"
64 "IP router interface commands\n"
65 PROTO_HELP
66 "Routing process tag\n")
67 {
68 int idx_afi = 0;
69 int idx_word = 3;
70 VTY_DECLVAR_CONTEXT(interface, ifp);
71 struct isis_circuit *circuit;
72 struct isis_area *area;
73 const char *af = argv[idx_afi]->arg;
74 const char *area_tag = argv[idx_word]->arg;
75
76 /* Prevent more than one area per circuit */
77 circuit = circuit_scan_by_ifp(ifp);
78 if (circuit && circuit->area) {
79 if (strcmp(circuit->area->area_tag, area_tag)) {
80 vty_out(vty, "ISIS circuit is already defined on %s\n",
81 circuit->area->area_tag);
82 return CMD_ERR_NOTHING_TODO;
83 }
84 }
85
86 area = isis_area_lookup(area_tag);
87 if (!area)
88 area = isis_area_create(area_tag);
89
90 if (!circuit || !circuit->area) {
91 circuit = isis_circuit_create(area, ifp);
92
93 if (circuit->state != C_STATE_CONF
94 && circuit->state != C_STATE_UP) {
95 vty_out(vty,
96 "Couldn't bring up interface, please check log.\n");
97 return CMD_WARNING_CONFIG_FAILED;
98 }
99 }
100
101 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
102 if (af[2] != '\0')
103 ipv6 = true;
104 else
105 ip = true;
106
107 isis_circuit_af_set(circuit, ip, ipv6);
108 return CMD_SUCCESS;
109 }
110
111 DEFUN (ip6_router_isis,
112 ip6_router_isis_cmd,
113 "ipv6 router " PROTO_NAME " WORD",
114 "Interface Internet Protocol config commands\n"
115 "IP router interface commands\n"
116 PROTO_HELP
117 "Routing process tag\n")
118 {
119 return ip_router_isis(self, vty, argc, argv);
120 }
121
122 DEFUN (no_ip_router_isis,
123 no_ip_router_isis_cmd,
124 "no <ip|ipv6> router " PROTO_NAME " WORD",
125 NO_STR
126 "Interface Internet Protocol config commands\n"
127 "IP router interface commands\n"
128 "IP router interface commands\n"
129 PROTO_HELP
130 "Routing process tag\n")
131 {
132 int idx_afi = 1;
133 int idx_word = 4;
134 VTY_DECLVAR_CONTEXT(interface, ifp);
135 struct isis_area *area;
136 struct isis_circuit *circuit;
137 const char *af = argv[idx_afi]->arg;
138 const char *area_tag = argv[idx_word]->arg;
139
140 area = isis_area_lookup(area_tag);
141 if (!area) {
142 vty_out(vty, "Can't find ISIS instance %s\n",
143 area_tag);
144 return CMD_ERR_NO_MATCH;
145 }
146
147 circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
148 if (!circuit) {
149 vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
150 return CMD_ERR_NO_MATCH;
151 }
152
153 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
154 if (af[2] != '\0')
155 ipv6 = false;
156 else
157 ip = false;
158
159 isis_circuit_af_set(circuit, ip, ipv6);
160 return CMD_SUCCESS;
161 }
162
163 DEFUN (isis_passive,
164 isis_passive_cmd,
165 PROTO_NAME " passive",
166 PROTO_HELP
167 "Configure the passive mode for interface\n")
168 {
169 struct isis_circuit *circuit = isis_circuit_lookup(vty);
170 if (!circuit)
171 return CMD_ERR_NO_MATCH;
172
173 CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1),
174 "Cannot set passive: $ERR");
175 return CMD_SUCCESS;
176 }
177
178 DEFUN (no_isis_passive,
179 no_isis_passive_cmd,
180 "no " PROTO_NAME " passive",
181 NO_STR
182 PROTO_HELP
183 "Configure the passive mode for interface\n")
184 {
185 struct isis_circuit *circuit = isis_circuit_lookup(vty);
186 if (!circuit)
187 return CMD_ERR_NO_MATCH;
188
189 CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0),
190 "Cannot set no passive: $ERR");
191 return CMD_SUCCESS;
192 }
193
194 DEFUN (isis_passwd,
195 isis_passwd_cmd,
196 PROTO_NAME " password <md5|clear> WORD",
197 PROTO_HELP
198 "Configure the authentication password for a circuit\n"
199 "HMAC-MD5 authentication\n"
200 "Cleartext password\n"
201 "Circuit password\n")
202 {
203 int idx_encryption = 2;
204 int idx_word = 3;
205 struct isis_circuit *circuit = isis_circuit_lookup(vty);
206 ferr_r rv;
207
208 if (!circuit)
209 return CMD_ERR_NO_MATCH;
210
211 if (argv[idx_encryption]->arg[0] == 'm')
212 rv = isis_circuit_passwd_hmac_md5_set(circuit,
213 argv[idx_word]->arg);
214 else
215 rv = isis_circuit_passwd_cleartext_set(circuit,
216 argv[idx_word]->arg);
217
218 CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR");
219 return CMD_SUCCESS;
220 }
221
222 DEFUN (no_isis_passwd,
223 no_isis_passwd_cmd,
224 "no " PROTO_NAME " password [<md5|clear> WORD]",
225 NO_STR
226 PROTO_HELP
227 "Configure the authentication password for a circuit\n"
228 "HMAC-MD5 authentication\n"
229 "Cleartext password\n"
230 "Circuit password\n")
231 {
232 struct isis_circuit *circuit = isis_circuit_lookup(vty);
233 if (!circuit)
234 return CMD_ERR_NO_MATCH;
235
236 CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit),
237 "Failed to unset circuit password: $ERR");
238 return CMD_SUCCESS;
239 }
240
241 DEFUN (isis_metric,
242 isis_metric_cmd,
243 PROTO_NAME " metric (0-16777215)",
244 PROTO_HELP
245 "Set default metric for circuit\n"
246 "Default metric value\n")
247 {
248 int idx_number = 2;
249 int met;
250 struct isis_circuit *circuit = isis_circuit_lookup(vty);
251 if (!circuit)
252 return CMD_ERR_NO_MATCH;
253
254 met = atoi(argv[idx_number]->arg);
255
256 /* RFC3787 section 5.1 */
257 if (circuit->area && circuit->area->oldmetric == 1
258 && met > MAX_NARROW_LINK_METRIC) {
259 vty_out(vty,
260 "Invalid metric %d - should be <0-63> "
261 "when narrow metric type enabled\n",
262 met);
263 return CMD_WARNING_CONFIG_FAILED;
264 }
265
266 /* RFC4444 */
267 if (circuit->area && circuit->area->newmetric == 1
268 && met > MAX_WIDE_LINK_METRIC) {
269 vty_out(vty,
270 "Invalid metric %d - should be <0-16777215> "
271 "when wide metric type enabled\n",
272 met);
273 return CMD_WARNING_CONFIG_FAILED;
274 }
275
276 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met),
277 "Failed to set L1 metric: $ERR");
278 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met),
279 "Failed to set L2 metric: $ERR");
280 return CMD_SUCCESS;
281 }
282
283 DEFUN (no_isis_metric,
284 no_isis_metric_cmd,
285 "no " PROTO_NAME " metric [(0-16777215)]",
286 NO_STR
287 PROTO_HELP
288 "Set default metric for circuit\n"
289 "Default metric value\n")
290 {
291 struct isis_circuit *circuit = isis_circuit_lookup(vty);
292 if (!circuit)
293 return CMD_ERR_NO_MATCH;
294
295 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1,
296 DEFAULT_CIRCUIT_METRIC),
297 "Failed to set L1 metric: $ERR");
298 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2,
299 DEFAULT_CIRCUIT_METRIC),
300 "Failed to set L2 metric: $ERR");
301 return CMD_SUCCESS;
302 }
303
304 DEFUN (isis_hello_interval,
305 isis_hello_interval_cmd,
306 PROTO_NAME " hello-interval (1-600)",
307 PROTO_HELP
308 "Set Hello interval\n"
309 "Holdtime 1 seconds, interval depends on multiplier\n")
310 {
311 uint32_t interval = atoi(argv[2]->arg);
312 struct isis_circuit *circuit = isis_circuit_lookup(vty);
313 if (!circuit)
314 return CMD_ERR_NO_MATCH;
315
316 circuit->hello_interval[0] = interval;
317 circuit->hello_interval[1] = interval;
318
319 return CMD_SUCCESS;
320 }
321
322 DEFUN (no_isis_hello_interval,
323 no_isis_hello_interval_cmd,
324 "no " PROTO_NAME " hello-interval [(1-600)]",
325 NO_STR
326 PROTO_HELP
327 "Set Hello interval\n"
328 "Holdtime 1 second, interval depends on multiplier\n")
329 {
330 struct isis_circuit *circuit = isis_circuit_lookup(vty);
331 if (!circuit)
332 return CMD_ERR_NO_MATCH;
333
334 circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
335 circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
336
337 return CMD_SUCCESS;
338 }
339
340 DEFUN (isis_hello_multiplier,
341 isis_hello_multiplier_cmd,
342 PROTO_NAME " hello-multiplier (2-100)",
343 PROTO_HELP
344 "Set multiplier for Hello holding time\n"
345 "Hello multiplier value\n")
346 {
347 uint16_t mult = atoi(argv[2]->arg);
348 struct isis_circuit *circuit = isis_circuit_lookup(vty);
349 if (!circuit)
350 return CMD_ERR_NO_MATCH;
351
352 circuit->hello_multiplier[0] = mult;
353 circuit->hello_multiplier[1] = mult;
354
355 return CMD_SUCCESS;
356 }
357
358 DEFUN (no_isis_hello_multiplier,
359 no_isis_hello_multiplier_cmd,
360 "no " PROTO_NAME " hello-multiplier [(2-100)]",
361 NO_STR
362 PROTO_HELP
363 "Set multiplier for Hello holding time\n"
364 "Hello multiplier value\n")
365 {
366 struct isis_circuit *circuit = isis_circuit_lookup(vty);
367 if (!circuit)
368 return CMD_ERR_NO_MATCH;
369
370 circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
371 circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
372
373 return CMD_SUCCESS;
374 }
375
376 DEFUN (csnp_interval,
377 csnp_interval_cmd,
378 PROTO_NAME " csnp-interval (1-600)",
379 PROTO_HELP
380 "Set CSNP interval in seconds\n"
381 "CSNP interval value\n")
382 {
383 uint16_t interval = atoi(argv[2]->arg);
384 struct isis_circuit *circuit = isis_circuit_lookup(vty);
385 if (!circuit)
386 return CMD_ERR_NO_MATCH;
387
388 circuit->csnp_interval[0] = interval;
389 circuit->csnp_interval[1] = interval;
390
391 return CMD_SUCCESS;
392 }
393
394 DEFUN (no_csnp_interval,
395 no_csnp_interval_cmd,
396 "no " PROTO_NAME " csnp-interval [(1-600)]",
397 NO_STR
398 PROTO_HELP
399 "Set CSNP interval in seconds\n"
400 "CSNP interval value\n")
401 {
402 struct isis_circuit *circuit = isis_circuit_lookup(vty);
403 if (!circuit)
404 return CMD_ERR_NO_MATCH;
405
406 circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
407 circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
408
409 return CMD_SUCCESS;
410 }
411
412 DEFUN (psnp_interval,
413 psnp_interval_cmd,
414 PROTO_NAME " psnp-interval (1-120)",
415 PROTO_HELP
416 "Set PSNP interval in seconds\n"
417 "PSNP interval value\n")
418 {
419 uint16_t interval = atoi(argv[2]->arg);
420 struct isis_circuit *circuit = isis_circuit_lookup(vty);
421 if (!circuit)
422 return CMD_ERR_NO_MATCH;
423
424 circuit->psnp_interval[0] = interval;
425 circuit->psnp_interval[1] = interval;
426
427 return CMD_SUCCESS;
428 }
429
430 DEFUN (no_psnp_interval,
431 no_psnp_interval_cmd,
432 "no " PROTO_NAME " psnp-interval [(1-120)]",
433 NO_STR
434 PROTO_HELP
435 "Set PSNP interval in seconds\n"
436 "PSNP interval value\n")
437 {
438 struct isis_circuit *circuit = isis_circuit_lookup(vty);
439 if (!circuit)
440 return CMD_ERR_NO_MATCH;
441
442 circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
443 circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
444
445 return CMD_SUCCESS;
446 }
447
448 DEFUN (circuit_topology,
449 circuit_topology_cmd,
450 PROTO_NAME " topology " ISIS_MT_NAMES,
451 PROTO_HELP
452 "Configure interface IS-IS topologies\n"
453 ISIS_MT_DESCRIPTIONS)
454 {
455 struct isis_circuit *circuit = isis_circuit_lookup(vty);
456 if (!circuit)
457 return CMD_ERR_NO_MATCH;
458 const char *arg = argv[2]->arg;
459 uint16_t mtid = isis_str2mtid(arg);
460
461 if (circuit->area && circuit->area->oldmetric) {
462 vty_out(vty,
463 "Multi topology IS-IS can only be used with wide metrics\n");
464 return CMD_WARNING_CONFIG_FAILED;
465 }
466
467 if (mtid == (uint16_t)-1) {
468 vty_out(vty, "Don't know topology '%s'\n", arg);
469 return CMD_WARNING_CONFIG_FAILED;
470 }
471
472 return isis_circuit_mt_enabled_set(circuit, mtid, true);
473 }
474
475 DEFUN (no_circuit_topology,
476 no_circuit_topology_cmd,
477 "no " PROTO_NAME " topology " ISIS_MT_NAMES,
478 NO_STR
479 PROTO_HELP
480 "Configure interface IS-IS topologies\n"
481 ISIS_MT_DESCRIPTIONS)
482 {
483 struct isis_circuit *circuit = isis_circuit_lookup(vty);
484 if (!circuit)
485 return CMD_ERR_NO_MATCH;
486 const char *arg = argv[3]->arg;
487 uint16_t mtid = isis_str2mtid(arg);
488
489 if (circuit->area && circuit->area->oldmetric) {
490 vty_out(vty,
491 "Multi topology IS-IS can only be used with wide metrics\n");
492 return CMD_WARNING_CONFIG_FAILED;
493 }
494
495 if (mtid == (uint16_t)-1) {
496 vty_out(vty, "Don't know topology '%s'\n", arg);
497 return CMD_WARNING_CONFIG_FAILED;
498 }
499
500 return isis_circuit_mt_enabled_set(circuit, mtid, false);
501 }
502
503 DEFUN (isis_bfd,
504 isis_bfd_cmd,
505 PROTO_NAME " bfd",
506 PROTO_HELP
507 "Enable BFD support\n")
508 {
509 struct isis_circuit *circuit = isis_circuit_lookup(vty);
510
511 if (!circuit)
512 return CMD_ERR_NO_MATCH;
513
514 if (circuit->bfd_info
515 && CHECK_FLAG(circuit->bfd_info->flags, BFD_FLAG_PARAM_CFG)) {
516 return CMD_SUCCESS;
517 }
518
519 isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX,
520 BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, true);
521
522 return CMD_SUCCESS;
523 }
524
525 DEFUN (no_isis_bfd,
526 no_isis_bfd_cmd,
527 "no " PROTO_NAME " bfd",
528 NO_STR
529 PROTO_HELP
530 "Disables BFD support\n"
531 )
532 {
533 struct isis_circuit *circuit = isis_circuit_lookup(vty);
534
535 if (!circuit)
536 return CMD_ERR_NO_MATCH;
537
538 if (!circuit->bfd_info)
539 return CMD_SUCCESS;
540
541 isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER);
542 bfd_info_free(&circuit->bfd_info);
543 return CMD_SUCCESS;
544 }
545
546 DEFUN (set_overload_bit,
547 set_overload_bit_cmd,
548 "set-overload-bit",
549 "Set overload bit to avoid any transit traffic\n")
550 {
551 VTY_DECLVAR_CONTEXT(isis_area, area);
552
553 isis_area_overload_bit_set(area, true);
554 return CMD_SUCCESS;
555 }
556
557 DEFUN (no_set_overload_bit,
558 no_set_overload_bit_cmd,
559 "no set-overload-bit",
560 "Reset overload bit to accept transit traffic\n"
561 "Reset overload bit\n")
562 {
563 VTY_DECLVAR_CONTEXT(isis_area, area);
564
565 isis_area_overload_bit_set(area, false);
566 return CMD_SUCCESS;
567 }
568
569 static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu)
570 {
571 VTY_DECLVAR_CONTEXT(isis_area, area);
572 struct listnode *node;
573 struct isis_circuit *circuit;
574
575 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
576 if (circuit->state != C_STATE_INIT
577 && circuit->state != C_STATE_UP)
578 continue;
579 if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
580 vty_out(vty,
581 "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n",
582 circuit->interface->name,
583 isis_circuit_pdu_size(circuit));
584 return CMD_WARNING_CONFIG_FAILED;
585 }
586 }
587
588 isis_area_lsp_mtu_set(area, lsp_mtu);
589 return CMD_SUCCESS;
590 }
591
592 DEFUN (area_lsp_mtu,
593 area_lsp_mtu_cmd,
594 "lsp-mtu (128-4352)",
595 "Configure the maximum size of generated LSPs\n"
596 "Maximum size of generated LSPs\n")
597 {
598 int idx_number = 1;
599 unsigned int lsp_mtu;
600
601 lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10);
602
603 return isis_vty_lsp_mtu_set(vty, lsp_mtu);
604 }
605
606 DEFUN (no_area_lsp_mtu,
607 no_area_lsp_mtu_cmd,
608 "no lsp-mtu [(128-4352)]",
609 NO_STR
610 "Configure the maximum size of generated LSPs\n"
611 "Maximum size of generated LSPs\n")
612 {
613 return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
614 }
615
616 DEFUN (area_purge_originator,
617 area_purge_originator_cmd,
618 "[no] purge-originator",
619 NO_STR
620 "Use the RFC 6232 purge-originator\n")
621 {
622 VTY_DECLVAR_CONTEXT(isis_area, area);
623
624 area->purge_originator = !!strcmp(argv[0]->text, "no");
625 return CMD_SUCCESS;
626 }
627
628 int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval)
629 {
630 VTY_DECLVAR_CONTEXT(isis_area, area);
631 int lvl;
632
633 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
634 if (!(lvl & level))
635 continue;
636
637 if (interval >= area->lsp_refresh[lvl - 1]) {
638 vty_out(vty,
639 "LSP gen interval %us must be less than "
640 "the LSP refresh interval %us\n",
641 interval, area->lsp_refresh[lvl - 1]);
642 return CMD_WARNING_CONFIG_FAILED;
643 }
644 }
645
646 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
647 if (!(lvl & level))
648 continue;
649 area->lsp_gen_interval[lvl - 1] = interval;
650 }
651
652 return CMD_SUCCESS;
653 }
654
655 DEFUN (lsp_gen_interval,
656 lsp_gen_interval_cmd,
657 "lsp-gen-interval (1-120)",
658 "Minimum interval between regenerating same LSP\n"
659 "Minimum interval in seconds\n")
660 {
661 uint16_t interval = atoi(argv[1]->arg);
662
663 return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval);
664 }
665
666 DEFUN (no_lsp_gen_interval,
667 no_lsp_gen_interval_cmd,
668 "no lsp-gen-interval [(1-120)]",
669 NO_STR
670 "Minimum interval between regenerating same LSP\n"
671 "Minimum interval in seconds\n")
672 {
673 VTY_DECLVAR_CONTEXT(isis_area, area);
674
675 return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2,
676 DEFAULT_MIN_LSP_GEN_INTERVAL);
677 }
678
679 DEFUN (spf_interval,
680 spf_interval_cmd,
681 "spf-interval (1-120)",
682 "Minimum interval between SPF calculations\n"
683 "Minimum interval between consecutive SPFs in seconds\n")
684 {
685 VTY_DECLVAR_CONTEXT(isis_area, area);
686 uint16_t interval = atoi(argv[1]->arg);
687
688 area->min_spf_interval[0] = interval;
689 area->min_spf_interval[1] = interval;
690
691 return CMD_SUCCESS;
692 }
693
694 DEFUN (no_spf_interval,
695 no_spf_interval_cmd,
696 "no spf-interval [(1-120)]",
697 NO_STR
698 "Minimum interval between SPF calculations\n"
699 "Minimum interval between consecutive SPFs in seconds\n")
700 {
701 VTY_DECLVAR_CONTEXT(isis_area, area);
702
703 area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
704 area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
705
706 return CMD_SUCCESS;
707 }
708
709 DEFUN (no_spf_delay_ietf,
710 no_spf_delay_ietf_cmd,
711 "no spf-delay-ietf",
712 NO_STR
713 "IETF SPF delay algorithm\n")
714 {
715 VTY_DECLVAR_CONTEXT(isis_area, area);
716
717 spf_backoff_free(area->spf_delay_ietf[0]);
718 spf_backoff_free(area->spf_delay_ietf[1]);
719 area->spf_delay_ietf[0] = NULL;
720 area->spf_delay_ietf[1] = NULL;
721
722 return CMD_SUCCESS;
723 }
724
725 DEFUN (spf_delay_ietf,
726 spf_delay_ietf_cmd,
727 "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)",
728 "IETF SPF delay algorithm\n"
729 "Delay used while in QUIET state\n"
730 "Delay used while in QUIET state in milliseconds\n"
731 "Delay used while in SHORT_WAIT state\n"
732 "Delay used while in SHORT_WAIT state in milliseconds\n"
733 "Delay used while in LONG_WAIT\n"
734 "Delay used while in LONG_WAIT state in milliseconds\n"
735 "Time with no received IGP events before considering IGP stable\n"
736 "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
737 "Maximum duration needed to learn all the events related to a single failure\n"
738 "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
739 {
740 VTY_DECLVAR_CONTEXT(isis_area, area);
741
742 long init_delay = atol(argv[2]->arg);
743 long short_delay = atol(argv[4]->arg);
744 long long_delay = atol(argv[6]->arg);
745 long holddown = atol(argv[8]->arg);
746 long timetolearn = atol(argv[10]->arg);
747
748 size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx");
749 char *buf = XCALLOC(MTYPE_TMP, bufsiz);
750
751 snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
752 spf_backoff_free(area->spf_delay_ietf[0]);
753 area->spf_delay_ietf[0] =
754 spf_backoff_new(master, buf, init_delay, short_delay,
755 long_delay, holddown, timetolearn);
756
757 snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
758 spf_backoff_free(area->spf_delay_ietf[1]);
759 area->spf_delay_ietf[1] =
760 spf_backoff_new(master, buf, init_delay, short_delay,
761 long_delay, holddown, timetolearn);
762
763 XFREE(MTYPE_TMP, buf);
764 return CMD_SUCCESS;
765 }
766
767 int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval)
768 {
769 VTY_DECLVAR_CONTEXT(isis_area, area);
770 int lvl;
771 uint16_t refresh_interval = interval - 300;
772 int set_refresh_interval[ISIS_LEVELS] = {0, 0};
773
774 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
775 if (!(lvl & level))
776 continue;
777
778 if (refresh_interval < area->lsp_refresh[lvl - 1]) {
779 vty_out(vty,
780 "Level %d Max LSP lifetime %us must be 300s greater than "
781 "the configured LSP refresh interval %us\n",
782 lvl, interval, area->lsp_refresh[lvl - 1]);
783 vty_out(vty,
784 "Automatically reducing level %d LSP refresh interval "
785 "to %us\n",
786 lvl, refresh_interval);
787 set_refresh_interval[lvl - 1] = 1;
788
789 if (refresh_interval
790 <= area->lsp_gen_interval[lvl - 1]) {
791 vty_out(vty,
792 "LSP refresh interval %us must be greater than "
793 "the configured LSP gen interval %us\n",
794 refresh_interval,
795 area->lsp_gen_interval[lvl - 1]);
796 return CMD_WARNING_CONFIG_FAILED;
797 }
798 }
799 }
800
801 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
802 if (!(lvl & level))
803 continue;
804 isis_area_max_lsp_lifetime_set(area, lvl, interval);
805 if (set_refresh_interval[lvl - 1])
806 isis_area_lsp_refresh_set(area, lvl, refresh_interval);
807 }
808
809 return CMD_SUCCESS;
810 }
811
812 DEFUN (max_lsp_lifetime,
813 max_lsp_lifetime_cmd,
814 "max-lsp-lifetime (350-65535)",
815 "Maximum LSP lifetime\n"
816 "LSP lifetime in seconds\n")
817 {
818 int lifetime = atoi(argv[1]->arg);
819
820 return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime);
821 }
822
823
824 DEFUN (no_max_lsp_lifetime,
825 no_max_lsp_lifetime_cmd,
826 "no max-lsp-lifetime [(350-65535)]",
827 NO_STR
828 "Maximum LSP lifetime\n"
829 "LSP lifetime in seconds\n")
830 {
831 return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2,
832 DEFAULT_LSP_LIFETIME);
833 }
834
835 int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval)
836 {
837 VTY_DECLVAR_CONTEXT(isis_area, area);
838 int lvl;
839
840 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
841 if (!(lvl & level))
842 continue;
843 if (interval <= area->lsp_gen_interval[lvl - 1]) {
844 vty_out(vty,
845 "LSP refresh interval %us must be greater than "
846 "the configured LSP gen interval %us\n",
847 interval, area->lsp_gen_interval[lvl - 1]);
848 return CMD_WARNING_CONFIG_FAILED;
849 }
850 if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) {
851 vty_out(vty,
852 "LSP refresh interval %us must be less than "
853 "the configured LSP lifetime %us less 300\n",
854 interval, area->max_lsp_lifetime[lvl - 1]);
855 return CMD_WARNING_CONFIG_FAILED;
856 }
857 }
858
859 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
860 if (!(lvl & level))
861 continue;
862 isis_area_lsp_refresh_set(area, lvl, interval);
863 }
864
865 return CMD_SUCCESS;
866 }
867
868 DEFUN (lsp_refresh_interval,
869 lsp_refresh_interval_cmd,
870 "lsp-refresh-interval (1-65235)",
871 "LSP refresh interval\n"
872 "LSP refresh interval in seconds\n")
873 {
874 unsigned int interval = atoi(argv[1]->arg);
875 return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval);
876 }
877
878 DEFUN (no_lsp_refresh_interval,
879 no_lsp_refresh_interval_cmd,
880 "no lsp-refresh-interval [(1-65235)]",
881 NO_STR
882 "LSP refresh interval\n"
883 "LSP refresh interval in seconds\n")
884 {
885 return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2,
886 DEFAULT_MAX_LSP_GEN_INTERVAL);
887 }
888
889 int isis_vty_password_set(struct vty *vty, int argc,
890 struct cmd_token *argv[], int level)
891 {
892 VTY_DECLVAR_CONTEXT(isis_area, area);
893
894 int idx_algo = 1;
895 int idx_password = 2;
896 int idx_snp_auth = 5;
897 uint8_t snp_auth = 0;
898
899 const char *passwd = argv[idx_password]->arg;
900 if (strlen(passwd) > 254) {
901 vty_out(vty, "Too long area password (>254)\n");
902 return CMD_WARNING_CONFIG_FAILED;
903 }
904
905 if (argc > idx_snp_auth) {
906 snp_auth = SNP_AUTH_SEND;
907 if (strmatch(argv[idx_snp_auth]->text, "validate"))
908 snp_auth |= SNP_AUTH_RECV;
909 }
910
911 if (strmatch(argv[idx_algo]->text, "clear")) {
912 return isis_area_passwd_cleartext_set(area, level,
913 passwd, snp_auth);
914 } else if (strmatch(argv[idx_algo]->text, "md5")) {
915 return isis_area_passwd_hmac_md5_set(area, level,
916 passwd, snp_auth);
917 }
918
919 return CMD_WARNING_CONFIG_FAILED;
920 }
921
922 DEFUN (domain_passwd,
923 domain_passwd_cmd,
924 "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
925 "Set the authentication password for a routing domain\n"
926 "Authentication type\n"
927 "Authentication type\n"
928 "Level-wide password\n"
929 "Authentication\n"
930 "SNP PDUs\n"
931 "Send but do not check PDUs on receiving\n"
932 "Send and check PDUs on receiving\n")
933 {
934 return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2);
935 }
936
937 DEFUN (no_domain_passwd,
938 no_domain_passwd_cmd,
939 "no domain-password",
940 NO_STR
941 "Set the authentication password for a routing domain\n")
942 {
943 VTY_DECLVAR_CONTEXT(isis_area, area);
944
945 return isis_area_passwd_unset(area, IS_LEVEL_2);
946 }
947
948 void isis_vty_init(void)
949 {
950 install_element(INTERFACE_NODE, &ip_router_isis_cmd);
951 install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
952 install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
953
954 install_element(INTERFACE_NODE, &isis_passive_cmd);
955 install_element(INTERFACE_NODE, &no_isis_passive_cmd);
956
957 install_element(INTERFACE_NODE, &isis_passwd_cmd);
958 install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
959
960 install_element(INTERFACE_NODE, &isis_metric_cmd);
961 install_element(INTERFACE_NODE, &no_isis_metric_cmd);
962
963 install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
964 install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
965
966 install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
967 install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
968
969 install_element(INTERFACE_NODE, &csnp_interval_cmd);
970 install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
971
972 install_element(INTERFACE_NODE, &psnp_interval_cmd);
973 install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
974
975 install_element(INTERFACE_NODE, &circuit_topology_cmd);
976 install_element(INTERFACE_NODE, &no_circuit_topology_cmd);
977
978 install_element(INTERFACE_NODE, &isis_bfd_cmd);
979 install_element(INTERFACE_NODE, &no_isis_bfd_cmd);
980
981 install_element(ROUTER_NODE, &set_overload_bit_cmd);
982 install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
983
984 install_element(ROUTER_NODE, &area_lsp_mtu_cmd);
985 install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd);
986
987 install_element(ROUTER_NODE, &area_purge_originator_cmd);
988
989 install_element(ROUTER_NODE, &lsp_gen_interval_cmd);
990 install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd);
991
992 install_element(ROUTER_NODE, &spf_interval_cmd);
993 install_element(ROUTER_NODE, &no_spf_interval_cmd);
994
995 install_element(ROUTER_NODE, &max_lsp_lifetime_cmd);
996 install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd);
997
998 install_element(ROUTER_NODE, &lsp_refresh_interval_cmd);
999 install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd);
1000
1001 install_element(ROUTER_NODE, &domain_passwd_cmd);
1002 install_element(ROUTER_NODE, &no_domain_passwd_cmd);
1003
1004 install_element(ROUTER_NODE, &spf_delay_ietf_cmd);
1005 install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd);
1006
1007 isis_vty_daemon_init();
1008 }