]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_vty_fabricd.c
isisd: allow arbitrary order of area/interface configuration
[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
f2971ce3
RZ
26#include "lib/bfd.h"
27#include "isisd/isis_bfd.h"
1eb7c3a1 28#include "isisd/isisd.h"
1eb7c3a1
CF
29#include "isisd/fabricd.h"
30#include "isisd/isis_tlvs.h"
31#include "isisd/isis_misc.h"
32#include "isisd/isis_lsp.h"
aaf2fd21 33#include "isisd/isis_csm.h"
f084ea55 34#include "isisd/isis_circuit.h"
5336ba30 35#include "lib/spf_backoff.h"
83d043f6 36#include "isisd/isis_mt.h"
92ed0cde 37
f2971ce3
RZ
38static 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
92ed0cde
CF
57DEFUN (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
71DEFUN (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}
ef020087 83
e923107c
CF
84DEFUN (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
100DEFUN (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
eab88f36
K
115static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp,
116 struct isis *isis)
1eb7c3a1
CF
117{
118 char lspid[255];
d0636ead 119 char buf[MONOTIME_STRLEN];
1eb7c3a1 120
7533cad7 121 lspid_print(lsp->hdr.lsp_id, lspid, sizeof(lspid), true, true, isis);
1eb7c3a1
CF
122 vty_out(vty, "Flooding information for %s\n", lspid);
123
124 if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) {
a6b60da9 125 vty_out(vty, " Never received.\n");
1eb7c3a1
CF
126 return;
127 }
128
a6b60da9 129 vty_out(vty, " Last received on: %s (",
1eb7c3a1
CF
130 lsp->flooding_interface ?
131 lsp->flooding_interface : "(null)");
132
a6b60da9 133 time_t uptime = time(NULL) - lsp->flooding_time;
d0636ead
MS
134
135 frrtime_to_interval(uptime, buf, sizeof(buf));
136
137 vty_out(vty, "%s ago)\n", buf);
a6b60da9
CF
138
139 if (lsp->flooding_circuit_scoped) {
3efd0893 140 vty_out(vty, " Received as circuit-scoped LSP, so not flooded.\n");
a6b60da9
CF
141 return;
142 }
143
1eb7c3a1
CF
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
159DEFUN (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
89cdc4df 169 if (argc == 4)
1eb7c3a1 170 lspid = argv[3]->arg;
1eb7c3a1
CF
171
172 struct listnode *node;
173 struct isis_area *area;
eab88f36
K
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 }
1eb7c3a1
CF
182
183 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
4bef0ec4
DL
184 struct lspdb_head *head = &area->lspdb[ISIS_LEVEL2 - 1];
185 struct isis_lsp *lsp;
1eb7c3a1 186
eab88f36
K
187 vty_out(vty, "Area %s:\n",
188 area->area_tag ? area->area_tag : "null");
1eb7c3a1 189 if (lspid) {
eab88f36 190 lsp = lsp_for_arg(head, lspid, isis);
1eb7c3a1 191 if (lsp)
eab88f36 192 lsp_print_flooding(vty, lsp, isis);
1eb7c3a1
CF
193 continue;
194 }
81fddbe7 195 frr_each (lspdb, head, lsp) {
eab88f36 196 lsp_print_flooding(vty, lsp, isis);
1eb7c3a1
CF
197 vty_out(vty, "\n");
198 }
199 }
200
201 return CMD_SUCCESS;
202}
203
aaf2fd21
EDP
204DEFUN (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
eab88f36 230 area = isis_area_lookup(area_tag, VRF_DEFAULT);
aaf2fd21 231 if (!area)
bcf22081 232 isis_area_create(area_tag, VRF_DEFAULT_NAME);
aaf2fd21 233
bcf22081
IR
234 if (!circuit) {
235 circuit = isis_circuit_new(ifp, area_tag);
aaf2fd21
EDP
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
255DEFUN (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
266DEFUN (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
eab88f36 284 area = isis_area_lookup(area_tag, VRF_DEFAULT);
aaf2fd21
EDP
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
bcf22081 291 circuit = circuit_scan_by_ifp(ifp);
aaf2fd21
EDP
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);
bcf22081
IR
304
305 if (!ip && !ipv6)
306 isis_circuit_del(circuit);
307
aaf2fd21
EDP
308 return CMD_SUCCESS;
309}
310
f2971ce3
RZ
311DEFUN (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_info
323 && CHECK_FLAG(circuit->bfd_info->flags, BFD_FLAG_PARAM_CFG)) {
324 return CMD_SUCCESS;
325 }
326
4affdba7
G
327 isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
328 BFD_DEF_DETECT_MULT, NULL, true);
f2971ce3
RZ
329
330 return CMD_SUCCESS;
331}
332
333DEFUN (no_isis_bfd,
334 no_isis_bfd_cmd,
335 "no " PROTO_NAME " bfd",
336 NO_STR
337 PROTO_HELP
338 "Disables BFD support\n"
339)
340{
341 struct isis_circuit *circuit = isis_circuit_lookup(vty);
342
343 if (!circuit)
344 return CMD_ERR_NO_MATCH;
345
346 if (!circuit->bfd_info)
347 return CMD_SUCCESS;
348
349 isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER);
350 bfd_info_free(&circuit->bfd_info);
351 return CMD_SUCCESS;
352}
353
05a3f9f0
EDP
354DEFUN (set_overload_bit,
355 set_overload_bit_cmd,
356 "set-overload-bit",
357 "Set overload bit to avoid any transit traffic\n")
358{
359 VTY_DECLVAR_CONTEXT(isis_area, area);
360
361 isis_area_overload_bit_set(area, true);
362 return CMD_SUCCESS;
363}
364
365DEFUN (no_set_overload_bit,
366 no_set_overload_bit_cmd,
367 "no set-overload-bit",
368 "Reset overload bit to accept transit traffic\n"
369 "Reset overload bit\n")
370{
371 VTY_DECLVAR_CONTEXT(isis_area, area);
372
373 isis_area_overload_bit_set(area, false);
374 return CMD_SUCCESS;
375}
376
933536e3
EDP
377static int isis_vty_password_set(struct vty *vty, int argc,
378 struct cmd_token *argv[], int level)
379{
380 VTY_DECLVAR_CONTEXT(isis_area, area);
381
382 int idx_algo = 1;
383 int idx_password = 2;
384 int idx_snp_auth = 5;
385 uint8_t snp_auth = 0;
386
387 const char *passwd = argv[idx_password]->arg;
388 if (strlen(passwd) > 254) {
389 vty_out(vty, "Too long area password (>254)\n");
390 return CMD_WARNING_CONFIG_FAILED;
391 }
392
393 if (argc > idx_snp_auth) {
394 snp_auth = SNP_AUTH_SEND;
395 if (strmatch(argv[idx_snp_auth]->text, "validate"))
396 snp_auth |= SNP_AUTH_RECV;
397 }
398
399 if (strmatch(argv[idx_algo]->text, "clear")) {
400 return isis_area_passwd_cleartext_set(area, level,
401 passwd, snp_auth);
402 } else if (strmatch(argv[idx_algo]->text, "md5")) {
403 return isis_area_passwd_hmac_md5_set(area, level,
404 passwd, snp_auth);
405 }
406
407 return CMD_WARNING_CONFIG_FAILED;
408}
409
410DEFUN (domain_passwd,
411 domain_passwd_cmd,
412 "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
413 "Set the authentication password for a routing domain\n"
414 "Authentication type\n"
415 "Authentication type\n"
416 "Level-wide password\n"
417 "Authentication\n"
418 "SNP PDUs\n"
419 "Send but do not check PDUs on receiving\n"
420 "Send and check PDUs on receiving\n")
421{
422 return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2);
423}
424
425DEFUN (no_domain_passwd,
426 no_domain_passwd_cmd,
427 "no domain-password",
428 NO_STR
429 "Set the authentication password for a routing domain\n")
430{
431 VTY_DECLVAR_CONTEXT(isis_area, area);
432
433 return isis_area_passwd_unset(area, IS_LEVEL_2);
434}
435
1d6fe72e
EDP
436static int
437isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval)
438{
439 VTY_DECLVAR_CONTEXT(isis_area, area);
440 int lvl;
441
442 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
443 if (!(lvl & level))
444 continue;
445
446 if (interval >= area->lsp_refresh[lvl - 1]) {
447 vty_out(vty,
3efd0893 448 "LSP gen interval %us must be less than the LSP refresh interval %us\n",
1d6fe72e
EDP
449 interval, area->lsp_refresh[lvl - 1]);
450 return CMD_WARNING_CONFIG_FAILED;
451 }
452 }
453
454 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
455 if (!(lvl & level))
456 continue;
457 area->lsp_gen_interval[lvl - 1] = interval;
458 }
459
460 return CMD_SUCCESS;
461}
462
463DEFUN (lsp_gen_interval,
464 lsp_gen_interval_cmd,
465 "lsp-gen-interval (1-120)",
466 "Minimum interval between regenerating same LSP\n"
467 "Minimum interval in seconds\n")
468{
469 uint16_t interval = atoi(argv[1]->arg);
470
471 return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval);
472}
473
474DEFUN (no_lsp_gen_interval,
475 no_lsp_gen_interval_cmd,
476 "no lsp-gen-interval [(1-120)]",
477 NO_STR
478 "Minimum interval between regenerating same LSP\n"
479 "Minimum interval in seconds\n")
480{
481 VTY_DECLVAR_CONTEXT(isis_area, area);
482
483 return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2,
484 DEFAULT_MIN_LSP_GEN_INTERVAL);
485}
7e869004
EDP
486
487static int
488isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval)
489{
490 VTY_DECLVAR_CONTEXT(isis_area, area);
491 int lvl;
492
493 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
494 if (!(lvl & level))
495 continue;
496 if (interval <= area->lsp_gen_interval[lvl - 1]) {
497 vty_out(vty,
3efd0893 498 "LSP refresh interval %us must be greater than the configured LSP gen interval %us\n",
7e869004
EDP
499 interval, area->lsp_gen_interval[lvl - 1]);
500 return CMD_WARNING_CONFIG_FAILED;
501 }
502 if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) {
503 vty_out(vty,
3efd0893 504 "LSP refresh interval %us must be less than the configured LSP lifetime %us less 300\n",
7e869004
EDP
505 interval, area->max_lsp_lifetime[lvl - 1]);
506 return CMD_WARNING_CONFIG_FAILED;
507 }
508 }
509
510 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
511 if (!(lvl & level))
512 continue;
513 isis_area_lsp_refresh_set(area, lvl, interval);
514 }
515
516 return CMD_SUCCESS;
517}
518
519DEFUN (lsp_refresh_interval,
520 lsp_refresh_interval_cmd,
521 "lsp-refresh-interval (1-65235)",
522 "LSP refresh interval\n"
523 "LSP refresh interval in seconds\n")
524{
525 unsigned int interval = atoi(argv[1]->arg);
526 return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval);
527}
528
529DEFUN (no_lsp_refresh_interval,
530 no_lsp_refresh_interval_cmd,
531 "no lsp-refresh-interval [(1-65235)]",
532 NO_STR
533 "LSP refresh interval\n"
534 "LSP refresh interval in seconds\n")
535{
536 return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2,
537 DEFAULT_MAX_LSP_GEN_INTERVAL);
538}
539
ea120aa0
EDP
540static int
541isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval)
542{
543 VTY_DECLVAR_CONTEXT(isis_area, area);
544 int lvl;
545 uint16_t refresh_interval = interval - 300;
546 int set_refresh_interval[ISIS_LEVELS] = {0, 0};
547
548 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
549 if (!(lvl & level))
550 continue;
551
552 if (refresh_interval < area->lsp_refresh[lvl - 1]) {
553 vty_out(vty,
3efd0893 554 "Level %d Max LSP lifetime %us must be 300s greater than the configured LSP refresh interval %us\n",
ea120aa0
EDP
555 lvl, interval, area->lsp_refresh[lvl - 1]);
556 vty_out(vty,
3efd0893 557 "Automatically reducing level %d LSP refresh interval to %us\n",
ea120aa0
EDP
558 lvl, refresh_interval);
559 set_refresh_interval[lvl - 1] = 1;
560
561 if (refresh_interval
562 <= area->lsp_gen_interval[lvl - 1]) {
563 vty_out(vty,
3efd0893 564 "LSP refresh interval %us must be greater than the configured LSP gen interval %us\n",
ea120aa0
EDP
565 refresh_interval,
566 area->lsp_gen_interval[lvl - 1]);
567 return CMD_WARNING_CONFIG_FAILED;
568 }
569 }
570 }
571
572 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
573 if (!(lvl & level))
574 continue;
575 isis_area_max_lsp_lifetime_set(area, lvl, interval);
576 if (set_refresh_interval[lvl - 1])
577 isis_area_lsp_refresh_set(area, lvl, refresh_interval);
578 }
579
580 return CMD_SUCCESS;
581}
582
583DEFUN (max_lsp_lifetime,
584 max_lsp_lifetime_cmd,
585 "max-lsp-lifetime (350-65535)",
586 "Maximum LSP lifetime\n"
587 "LSP lifetime in seconds\n")
588{
589 int lifetime = atoi(argv[1]->arg);
590
591 return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime);
592}
593
594
595DEFUN (no_max_lsp_lifetime,
596 no_max_lsp_lifetime_cmd,
597 "no max-lsp-lifetime [(350-65535)]",
598 NO_STR
599 "Maximum LSP lifetime\n"
600 "LSP lifetime in seconds\n")
601{
602 return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2,
603 DEFAULT_LSP_LIFETIME);
604}
605
dcb1dcd6
EDP
606DEFUN (spf_interval,
607 spf_interval_cmd,
608 "spf-interval (1-120)",
609 "Minimum interval between SPF calculations\n"
610 "Minimum interval between consecutive SPFs in seconds\n")
611{
612 VTY_DECLVAR_CONTEXT(isis_area, area);
613 uint16_t interval = atoi(argv[1]->arg);
614
615 area->min_spf_interval[0] = interval;
616 area->min_spf_interval[1] = interval;
617
618 return CMD_SUCCESS;
619}
620
621DEFUN (no_spf_interval,
622 no_spf_interval_cmd,
623 "no spf-interval [(1-120)]",
624 NO_STR
625 "Minimum interval between SPF calculations\n"
626 "Minimum interval between consecutive SPFs in seconds\n")
627{
628 VTY_DECLVAR_CONTEXT(isis_area, area);
629
630 area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
631 area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
632
633 return CMD_SUCCESS;
634}
27a45d16
EDP
635
636static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu)
637{
638 VTY_DECLVAR_CONTEXT(isis_area, area);
639 struct listnode *node;
640 struct isis_circuit *circuit;
641
642 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
643 if (circuit->state != C_STATE_INIT
644 && circuit->state != C_STATE_UP)
645 continue;
646 if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
647 vty_out(vty,
648 "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n",
649 circuit->interface->name,
650 isis_circuit_pdu_size(circuit));
651 return CMD_WARNING_CONFIG_FAILED;
652 }
653 }
654
655 isis_area_lsp_mtu_set(area, lsp_mtu);
656 return CMD_SUCCESS;
657}
658
659DEFUN (area_lsp_mtu,
660 area_lsp_mtu_cmd,
661 "lsp-mtu (128-4352)",
662 "Configure the maximum size of generated LSPs\n"
663 "Maximum size of generated LSPs\n")
664{
665 int idx_number = 1;
666 unsigned int lsp_mtu;
667
668 lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10);
669
670 return isis_vty_lsp_mtu_set(vty, lsp_mtu);
671}
672
673DEFUN (no_area_lsp_mtu,
674 no_area_lsp_mtu_cmd,
675 "no lsp-mtu [(128-4352)]",
676 NO_STR
677 "Configure the maximum size of generated LSPs\n"
678 "Maximum size of generated LSPs\n")
679{
680 return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
681}
682
5336ba30
EDP
683DEFUN (no_spf_delay_ietf,
684 no_spf_delay_ietf_cmd,
685 "no spf-delay-ietf",
686 NO_STR
687 "IETF SPF delay algorithm\n")
688{
689 VTY_DECLVAR_CONTEXT(isis_area, area);
690
691 spf_backoff_free(area->spf_delay_ietf[0]);
692 spf_backoff_free(area->spf_delay_ietf[1]);
693 area->spf_delay_ietf[0] = NULL;
694 area->spf_delay_ietf[1] = NULL;
695
696 return CMD_SUCCESS;
697}
698
699DEFUN (spf_delay_ietf,
700 spf_delay_ietf_cmd,
701 "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)",
702 "IETF SPF delay algorithm\n"
703 "Delay used while in QUIET state\n"
704 "Delay used while in QUIET state in milliseconds\n"
705 "Delay used while in SHORT_WAIT state\n"
706 "Delay used while in SHORT_WAIT state in milliseconds\n"
707 "Delay used while in LONG_WAIT\n"
708 "Delay used while in LONG_WAIT state in milliseconds\n"
709 "Time with no received IGP events before considering IGP stable\n"
710 "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
711 "Maximum duration needed to learn all the events related to a single failure\n"
712 "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
713{
714 VTY_DECLVAR_CONTEXT(isis_area, area);
715
716 long init_delay = atol(argv[2]->arg);
717 long short_delay = atol(argv[4]->arg);
718 long long_delay = atol(argv[6]->arg);
719 long holddown = atol(argv[8]->arg);
720 long timetolearn = atol(argv[10]->arg);
721
722 size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx");
723 char *buf = XCALLOC(MTYPE_TMP, bufsiz);
724
725 snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
726 spf_backoff_free(area->spf_delay_ietf[0]);
727 area->spf_delay_ietf[0] =
728 spf_backoff_new(master, buf, init_delay, short_delay,
729 long_delay, holddown, timetolearn);
730
731 snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
732 spf_backoff_free(area->spf_delay_ietf[1]);
733 area->spf_delay_ietf[1] =
734 spf_backoff_new(master, buf, init_delay, short_delay,
735 long_delay, holddown, timetolearn);
736
737 XFREE(MTYPE_TMP, buf);
738 return CMD_SUCCESS;
739}
740
66e45e10
EDP
741DEFUN (area_purge_originator,
742 area_purge_originator_cmd,
743 "[no] purge-originator",
744 NO_STR
745 "Use the RFC 6232 purge-originator\n")
746{
747 VTY_DECLVAR_CONTEXT(isis_area, area);
748
749 area->purge_originator = !!strcmp(argv[0]->text, "no");
750 return CMD_SUCCESS;
751}
752
a6a36c41
EDP
753DEFUN (isis_passive,
754 isis_passive_cmd,
755 PROTO_NAME " passive",
756 PROTO_HELP
757 "Configure the passive mode for interface\n")
758{
759 struct isis_circuit *circuit = isis_circuit_lookup(vty);
760 if (!circuit)
761 return CMD_ERR_NO_MATCH;
762
763 CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1),
764 "Cannot set passive: $ERR");
765 return CMD_SUCCESS;
766}
767
768DEFUN (no_isis_passive,
769 no_isis_passive_cmd,
770 "no " PROTO_NAME " passive",
771 NO_STR
772 PROTO_HELP
773 "Configure the passive mode for interface\n")
774{
775 struct isis_circuit *circuit = isis_circuit_lookup(vty);
776 if (!circuit)
777 return CMD_ERR_NO_MATCH;
778
779 CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0),
780 "Cannot set no passive: $ERR");
781 return CMD_SUCCESS;
782}
783
3e20c83a
EDP
784DEFUN (isis_passwd,
785 isis_passwd_cmd,
786 PROTO_NAME " password <md5|clear> WORD",
787 PROTO_HELP
788 "Configure the authentication password for a circuit\n"
789 "HMAC-MD5 authentication\n"
790 "Cleartext password\n"
791 "Circuit password\n")
792{
793 int idx_encryption = 2;
794 int idx_word = 3;
795 struct isis_circuit *circuit = isis_circuit_lookup(vty);
796 ferr_r rv;
797
798 if (!circuit)
799 return CMD_ERR_NO_MATCH;
800
801 if (argv[idx_encryption]->arg[0] == 'm')
802 rv = isis_circuit_passwd_hmac_md5_set(circuit,
803 argv[idx_word]->arg);
804 else
805 rv = isis_circuit_passwd_cleartext_set(circuit,
806 argv[idx_word]->arg);
807
808 CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR");
809 return CMD_SUCCESS;
810}
811
812DEFUN (no_isis_passwd,
813 no_isis_passwd_cmd,
814 "no " PROTO_NAME " password [<md5|clear> WORD]",
815 NO_STR
816 PROTO_HELP
817 "Configure the authentication password for a circuit\n"
818 "HMAC-MD5 authentication\n"
819 "Cleartext password\n"
820 "Circuit password\n")
821{
822 struct isis_circuit *circuit = isis_circuit_lookup(vty);
823 if (!circuit)
824 return CMD_ERR_NO_MATCH;
825
826 CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit),
827 "Failed to unset circuit password: $ERR");
828 return CMD_SUCCESS;
829}
830
be49219c
EDP
831DEFUN (isis_metric,
832 isis_metric_cmd,
833 PROTO_NAME " metric (0-16777215)",
834 PROTO_HELP
835 "Set default metric for circuit\n"
836 "Default metric value\n")
837{
838 int idx_number = 2;
839 int met;
840 struct isis_circuit *circuit = isis_circuit_lookup(vty);
841 if (!circuit)
842 return CMD_ERR_NO_MATCH;
843
844 met = atoi(argv[idx_number]->arg);
845
846 /* RFC3787 section 5.1 */
847 if (circuit->area && circuit->area->oldmetric == 1
848 && met > MAX_NARROW_LINK_METRIC) {
849 vty_out(vty,
3efd0893 850 "Invalid metric %d - should be <0-63> when narrow metric type enabled\n",
be49219c
EDP
851 met);
852 return CMD_WARNING_CONFIG_FAILED;
853 }
854
855 /* RFC4444 */
856 if (circuit->area && circuit->area->newmetric == 1
857 && met > MAX_WIDE_LINK_METRIC) {
858 vty_out(vty,
3efd0893 859 "Invalid metric %d - should be <0-16777215> when wide metric type enabled\n",
be49219c
EDP
860 met);
861 return CMD_WARNING_CONFIG_FAILED;
862 }
863
864 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met),
865 "Failed to set L1 metric: $ERR");
866 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met),
867 "Failed to set L2 metric: $ERR");
868 return CMD_SUCCESS;
869}
870
871DEFUN (no_isis_metric,
872 no_isis_metric_cmd,
873 "no " PROTO_NAME " metric [(0-16777215)]",
874 NO_STR
875 PROTO_HELP
876 "Set default metric for circuit\n"
877 "Default metric value\n")
878{
879 struct isis_circuit *circuit = isis_circuit_lookup(vty);
880 if (!circuit)
881 return CMD_ERR_NO_MATCH;
882
883 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1,
884 DEFAULT_CIRCUIT_METRIC),
885 "Failed to set L1 metric: $ERR");
886 CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2,
887 DEFAULT_CIRCUIT_METRIC),
888 "Failed to set L2 metric: $ERR");
889 return CMD_SUCCESS;
890}
891
356a2e3c
EDP
892DEFUN (isis_hello_interval,
893 isis_hello_interval_cmd,
894 PROTO_NAME " hello-interval (1-600)",
895 PROTO_HELP
896 "Set Hello interval\n"
897 "Holdtime 1 seconds, interval depends on multiplier\n")
898{
899 uint32_t interval = atoi(argv[2]->arg);
900 struct isis_circuit *circuit = isis_circuit_lookup(vty);
901 if (!circuit)
902 return CMD_ERR_NO_MATCH;
903
904 circuit->hello_interval[0] = interval;
905 circuit->hello_interval[1] = interval;
906
907 return CMD_SUCCESS;
908}
909
910DEFUN (no_isis_hello_interval,
911 no_isis_hello_interval_cmd,
912 "no " PROTO_NAME " hello-interval [(1-600)]",
913 NO_STR
914 PROTO_HELP
915 "Set Hello interval\n"
916 "Holdtime 1 second, interval depends on multiplier\n")
917{
918 struct isis_circuit *circuit = isis_circuit_lookup(vty);
919 if (!circuit)
920 return CMD_ERR_NO_MATCH;
921
922 circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
923 circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
924
925 return CMD_SUCCESS;
926}
927
4e75a67d
EDP
928DEFUN (isis_hello_multiplier,
929 isis_hello_multiplier_cmd,
930 PROTO_NAME " hello-multiplier (2-100)",
931 PROTO_HELP
932 "Set multiplier for Hello holding time\n"
933 "Hello multiplier value\n")
934{
935 uint16_t mult = atoi(argv[2]->arg);
936 struct isis_circuit *circuit = isis_circuit_lookup(vty);
937 if (!circuit)
938 return CMD_ERR_NO_MATCH;
939
940 circuit->hello_multiplier[0] = mult;
941 circuit->hello_multiplier[1] = mult;
942
943 return CMD_SUCCESS;
944}
945
946DEFUN (no_isis_hello_multiplier,
947 no_isis_hello_multiplier_cmd,
948 "no " PROTO_NAME " hello-multiplier [(2-100)]",
949 NO_STR
950 PROTO_HELP
951 "Set multiplier for Hello holding time\n"
952 "Hello multiplier value\n")
953{
954 struct isis_circuit *circuit = isis_circuit_lookup(vty);
955 if (!circuit)
956 return CMD_ERR_NO_MATCH;
957
958 circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
959 circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
960
961 return CMD_SUCCESS;
962}
963
9ce808b9
EDP
964DEFUN (csnp_interval,
965 csnp_interval_cmd,
966 PROTO_NAME " csnp-interval (1-600)",
967 PROTO_HELP
968 "Set CSNP interval in seconds\n"
969 "CSNP interval value\n")
970{
971 uint16_t interval = atoi(argv[2]->arg);
972 struct isis_circuit *circuit = isis_circuit_lookup(vty);
973 if (!circuit)
974 return CMD_ERR_NO_MATCH;
975
976 circuit->csnp_interval[0] = interval;
977 circuit->csnp_interval[1] = interval;
978
979 return CMD_SUCCESS;
980}
981
982DEFUN (no_csnp_interval,
983 no_csnp_interval_cmd,
984 "no " PROTO_NAME " csnp-interval [(1-600)]",
985 NO_STR
986 PROTO_HELP
987 "Set CSNP interval in seconds\n"
988 "CSNP interval value\n")
989{
990 struct isis_circuit *circuit = isis_circuit_lookup(vty);
991 if (!circuit)
992 return CMD_ERR_NO_MATCH;
993
994 circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
995 circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
996
997 return CMD_SUCCESS;
998}
999
1000DEFUN (psnp_interval,
1001 psnp_interval_cmd,
1002 PROTO_NAME " psnp-interval (1-120)",
1003 PROTO_HELP
1004 "Set PSNP interval in seconds\n"
1005 "PSNP interval value\n")
1006{
1007 uint16_t interval = atoi(argv[2]->arg);
1008 struct isis_circuit *circuit = isis_circuit_lookup(vty);
1009 if (!circuit)
1010 return CMD_ERR_NO_MATCH;
1011
1012 circuit->psnp_interval[0] = interval;
1013 circuit->psnp_interval[1] = interval;
1014
1015 return CMD_SUCCESS;
1016}
1017
1018DEFUN (no_psnp_interval,
1019 no_psnp_interval_cmd,
1020 "no " PROTO_NAME " psnp-interval [(1-120)]",
1021 NO_STR
1022 PROTO_HELP
1023 "Set PSNP interval in seconds\n"
1024 "PSNP interval value\n")
1025{
1026 struct isis_circuit *circuit = isis_circuit_lookup(vty);
1027 if (!circuit)
1028 return CMD_ERR_NO_MATCH;
1029
1030 circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
1031 circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
1032
1033 return CMD_SUCCESS;
1034}
1035
83d043f6
EDP
1036DEFUN (circuit_topology,
1037 circuit_topology_cmd,
1038 PROTO_NAME " topology " ISIS_MT_NAMES,
1039 PROTO_HELP
1040 "Configure interface IS-IS topologies\n"
1041 ISIS_MT_DESCRIPTIONS)
1042{
1043 struct isis_circuit *circuit = isis_circuit_lookup(vty);
1044 if (!circuit)
1045 return CMD_ERR_NO_MATCH;
1046 const char *arg = argv[2]->arg;
1047 uint16_t mtid = isis_str2mtid(arg);
1048
1049 if (circuit->area && circuit->area->oldmetric) {
1050 vty_out(vty,
1051 "Multi topology IS-IS can only be used with wide metrics\n");
1052 return CMD_WARNING_CONFIG_FAILED;
1053 }
1054
1055 if (mtid == (uint16_t)-1) {
1056 vty_out(vty, "Don't know topology '%s'\n", arg);
1057 return CMD_WARNING_CONFIG_FAILED;
1058 }
1059
1060 return isis_circuit_mt_enabled_set(circuit, mtid, true);
1061}
1062
1063DEFUN (no_circuit_topology,
1064 no_circuit_topology_cmd,
1065 "no " PROTO_NAME " topology " ISIS_MT_NAMES,
1066 NO_STR
1067 PROTO_HELP
1068 "Configure interface IS-IS topologies\n"
1069 ISIS_MT_DESCRIPTIONS)
1070{
1071 struct isis_circuit *circuit = isis_circuit_lookup(vty);
1072 if (!circuit)
1073 return CMD_ERR_NO_MATCH;
1074 const char *arg = argv[3]->arg;
1075 uint16_t mtid = isis_str2mtid(arg);
1076
1077 if (circuit->area && circuit->area->oldmetric) {
1078 vty_out(vty,
1079 "Multi topology IS-IS can only be used with wide metrics\n");
1080 return CMD_WARNING_CONFIG_FAILED;
1081 }
1082
1083 if (mtid == (uint16_t)-1) {
1084 vty_out(vty, "Don't know topology '%s'\n", arg);
1085 return CMD_WARNING_CONFIG_FAILED;
1086 }
1087
1088 return isis_circuit_mt_enabled_set(circuit, mtid, false);
1089}
1090
ef020087
CF
1091void isis_vty_daemon_init(void)
1092{
92ed0cde
CF
1093 install_element(ROUTER_NODE, &fabric_tier_cmd);
1094 install_element(ROUTER_NODE, &no_fabric_tier_cmd);
e923107c
CF
1095 install_element(ROUTER_NODE, &triggered_csnp_cmd);
1096 install_element(ROUTER_NODE, &no_triggered_csnp_cmd);
1eb7c3a1
CF
1097
1098 install_element(ENABLE_NODE, &show_lsp_flooding_cmd);
aaf2fd21
EDP
1099
1100 install_element(INTERFACE_NODE, &ip_router_isis_cmd);
1101 install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
1102 install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
f2971ce3
RZ
1103 install_element(INTERFACE_NODE, &isis_bfd_cmd);
1104 install_element(INTERFACE_NODE, &no_isis_bfd_cmd);
05a3f9f0
EDP
1105
1106 install_element(ROUTER_NODE, &set_overload_bit_cmd);
1107 install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
933536e3
EDP
1108
1109 install_element(ROUTER_NODE, &domain_passwd_cmd);
1110 install_element(ROUTER_NODE, &no_domain_passwd_cmd);
1d6fe72e
EDP
1111
1112 install_element(ROUTER_NODE, &lsp_gen_interval_cmd);
1113 install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd);
7e869004
EDP
1114
1115 install_element(ROUTER_NODE, &lsp_refresh_interval_cmd);
1116 install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd);
ea120aa0
EDP
1117
1118 install_element(ROUTER_NODE, &max_lsp_lifetime_cmd);
1119 install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd);
27a45d16
EDP
1120
1121 install_element(ROUTER_NODE, &area_lsp_mtu_cmd);
1122 install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd);
dcb1dcd6
EDP
1123
1124 install_element(ROUTER_NODE, &spf_interval_cmd);
1125 install_element(ROUTER_NODE, &no_spf_interval_cmd);
5336ba30
EDP
1126
1127 install_element(ROUTER_NODE, &spf_delay_ietf_cmd);
1128 install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd);
66e45e10
EDP
1129
1130 install_element(ROUTER_NODE, &area_purge_originator_cmd);
a6a36c41
EDP
1131
1132 install_element(INTERFACE_NODE, &isis_passive_cmd);
1133 install_element(INTERFACE_NODE, &no_isis_passive_cmd);
3e20c83a
EDP
1134
1135 install_element(INTERFACE_NODE, &isis_passwd_cmd);
1136 install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
be49219c
EDP
1137
1138 install_element(INTERFACE_NODE, &isis_metric_cmd);
1139 install_element(INTERFACE_NODE, &no_isis_metric_cmd);
356a2e3c
EDP
1140
1141 install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
1142 install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
4e75a67d
EDP
1143
1144 install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
1145 install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
9ce808b9
EDP
1146
1147 install_element(INTERFACE_NODE, &csnp_interval_cmd);
1148 install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
1149
1150 install_element(INTERFACE_NODE, &psnp_interval_cmd);
1151 install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
83d043f6
EDP
1152
1153 install_element(INTERFACE_NODE, &circuit_topology_cmd);
1154 install_element(INTERFACE_NODE, &no_circuit_topology_cmd);
ef020087 1155}