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