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