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