]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_vty_fabricd.c
isisd: retrofit the 'max-lsp-lifetime' 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"
92ed0cde
CF
34
35DEFUN (fabric_tier,
36 fabric_tier_cmd,
37 "fabric-tier (0-14)",
38 "Statically configure the tier to advertise\n"
39 "Tier to advertise\n")
40{
41 VTY_DECLVAR_CONTEXT(isis_area, area);
42
43 uint8_t tier = atoi(argv[1]->arg);
44
45 fabricd_configure_tier(area, tier);
46 return CMD_SUCCESS;
47}
48
49DEFUN (no_fabric_tier,
50 no_fabric_tier_cmd,
51 "no fabric-tier [(0-14)]",
52 NO_STR
53 "Statically configure the tier to advertise\n"
54 "Tier to advertise\n")
55{
56 VTY_DECLVAR_CONTEXT(isis_area, area);
57
58 fabricd_configure_tier(area, ISIS_TIER_UNDEFINED);
59 return CMD_SUCCESS;
60}
ef020087 61
e923107c
CF
62DEFUN (triggered_csnp,
63 triggered_csnp_cmd,
64 "triggered-csnp-delay (100-10000) [always]",
65 "Configure the delay for triggered CSNPs\n"
66 "Delay in milliseconds\n"
67 "Trigger CSNP for all LSPs, not only circuit-scoped\n")
68{
69 VTY_DECLVAR_CONTEXT(isis_area, area);
70
71 int csnp_delay = atoi(argv[1]->arg);
72 bool always_send_csnp = (argc == 3);
73
74 fabricd_configure_triggered_csnp(area, csnp_delay, always_send_csnp);
75 return CMD_SUCCESS;
76}
77
78DEFUN (no_triggered_csnp,
79 no_triggered_csnp_cmd,
80 "no triggered-csnp-delay [(100-10000) [always]]",
81 NO_STR
82 "Configure the delay for triggered CSNPs\n"
83 "Delay in milliseconds\n"
84 "Trigger CSNP for all LSPs, not only circuit-scoped\n")
85{
86 VTY_DECLVAR_CONTEXT(isis_area, area);
87
88 fabricd_configure_triggered_csnp(area, FABRICD_DEFAULT_CSNP_DELAY,
89 false);
90 return CMD_SUCCESS;
91}
92
1eb7c3a1
CF
93static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp)
94{
95 char lspid[255];
96
97 lspid_print(lsp->hdr.lsp_id, lspid, true, true);
98 vty_out(vty, "Flooding information for %s\n", lspid);
99
100 if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) {
a6b60da9 101 vty_out(vty, " Never received.\n");
1eb7c3a1
CF
102 return;
103 }
104
a6b60da9 105 vty_out(vty, " Last received on: %s (",
1eb7c3a1
CF
106 lsp->flooding_interface ?
107 lsp->flooding_interface : "(null)");
108
a6b60da9
CF
109 time_t uptime = time(NULL) - lsp->flooding_time;
110 struct tm *tm = gmtime(&uptime);
111
112 if (uptime < ONE_DAY_SECOND)
113 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
114 tm->tm_sec);
115 else if (uptime < ONE_WEEK_SECOND)
116 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
117 tm->tm_min);
118 else
119 vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
120 tm->tm_yday - ((tm->tm_yday / 7) * 7),
121 tm->tm_hour);
122 vty_out(vty, " ago)\n");
123
124 if (lsp->flooding_circuit_scoped) {
89cdc4df
RM
125 vty_out(vty, " Received as circuit-scoped LSP, so not "
126 "flooded.\n");
a6b60da9
CF
127 return;
128 }
129
1eb7c3a1
CF
130 for (enum isis_tx_type type = TX_LSP_NORMAL;
131 type <= TX_LSP_CIRCUIT_SCOPED; type++) {
132 struct listnode *node;
133 uint8_t *neighbor_id;
134
135 vty_out(vty, " %s:\n",
136 (type == TX_LSP_NORMAL) ? "RF" : "DNR");
137 for (ALL_LIST_ELEMENTS_RO(lsp->flooding_neighbors[type],
138 node, neighbor_id)) {
139 vty_out(vty, " %s\n",
140 print_sys_hostname(neighbor_id));
141 }
142 }
143}
144
145DEFUN (show_lsp_flooding,
146 show_lsp_flooding_cmd,
147 "show openfabric flooding [WORD]",
148 SHOW_STR
149 PROTO_HELP
150 "Flooding information\n"
151 "LSP ID\n")
152{
153 const char *lspid = NULL;
154
89cdc4df 155 if (argc == 4)
1eb7c3a1 156 lspid = argv[3]->arg;
1eb7c3a1
CF
157
158 struct listnode *node;
159 struct isis_area *area;
160
161 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
162 dict_t *lspdb = area->lspdb[ISIS_LEVEL2 - 1];
163
164 vty_out(vty, "Area %s:\n", area->area_tag ?
165 area->area_tag : "null");
166
167 if (lspid) {
168 struct isis_lsp *lsp = lsp_for_arg(lspid, lspdb);
169
170 if (lsp)
171 lsp_print_flooding(vty, lsp);
172
173 continue;
174 }
175
176 for (dnode_t *dnode = dict_first(lspdb); dnode;
177 dnode = dict_next(lspdb, dnode)) {
178 lsp_print_flooding(vty, dnode_get(dnode));
179 vty_out(vty, "\n");
180 }
181 }
182
183 return CMD_SUCCESS;
184}
185
aaf2fd21
EDP
186DEFUN (ip_router_isis,
187 ip_router_isis_cmd,
188 "ip router " PROTO_NAME " WORD",
189 "Interface Internet Protocol config commands\n"
190 "IP router interface commands\n"
191 PROTO_HELP
192 "Routing process tag\n")
193{
194 int idx_afi = 0;
195 int idx_word = 3;
196 VTY_DECLVAR_CONTEXT(interface, ifp);
197 struct isis_circuit *circuit;
198 struct isis_area *area;
199 const char *af = argv[idx_afi]->arg;
200 const char *area_tag = argv[idx_word]->arg;
201
202 /* Prevent more than one area per circuit */
203 circuit = circuit_scan_by_ifp(ifp);
204 if (circuit && circuit->area) {
205 if (strcmp(circuit->area->area_tag, area_tag)) {
206 vty_out(vty, "ISIS circuit is already defined on %s\n",
207 circuit->area->area_tag);
208 return CMD_ERR_NOTHING_TODO;
209 }
210 }
211
212 area = isis_area_lookup(area_tag);
213 if (!area)
214 area = isis_area_create(area_tag);
215
216 if (!circuit || !circuit->area) {
217 circuit = isis_circuit_create(area, ifp);
218
219 if (circuit->state != C_STATE_CONF
220 && circuit->state != C_STATE_UP) {
221 vty_out(vty,
222 "Couldn't bring up interface, please check log.\n");
223 return CMD_WARNING_CONFIG_FAILED;
224 }
225 }
226
227 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
228 if (af[2] != '\0')
229 ipv6 = true;
230 else
231 ip = true;
232
233 isis_circuit_af_set(circuit, ip, ipv6);
234 return CMD_SUCCESS;
235}
236
237DEFUN (ip6_router_isis,
238 ip6_router_isis_cmd,
239 "ipv6 router " PROTO_NAME " WORD",
240 "Interface Internet Protocol config commands\n"
241 "IP router interface commands\n"
242 PROTO_HELP
243 "Routing process tag\n")
244{
245 return ip_router_isis(self, vty, argc, argv);
246}
247
248DEFUN (no_ip_router_isis,
249 no_ip_router_isis_cmd,
250 "no <ip|ipv6> router " PROTO_NAME " WORD",
251 NO_STR
252 "Interface Internet Protocol config commands\n"
253 "IP router interface commands\n"
254 "IP router interface commands\n"
255 PROTO_HELP
256 "Routing process tag\n")
257{
258 int idx_afi = 1;
259 int idx_word = 4;
260 VTY_DECLVAR_CONTEXT(interface, ifp);
261 struct isis_area *area;
262 struct isis_circuit *circuit;
263 const char *af = argv[idx_afi]->arg;
264 const char *area_tag = argv[idx_word]->arg;
265
266 area = isis_area_lookup(area_tag);
267 if (!area) {
268 vty_out(vty, "Can't find ISIS instance %s\n",
269 area_tag);
270 return CMD_ERR_NO_MATCH;
271 }
272
273 circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
274 if (!circuit) {
275 vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
276 return CMD_ERR_NO_MATCH;
277 }
278
279 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
280 if (af[2] != '\0')
281 ipv6 = false;
282 else
283 ip = false;
284
285 isis_circuit_af_set(circuit, ip, ipv6);
286 return CMD_SUCCESS;
287}
288
05a3f9f0
EDP
289DEFUN (set_overload_bit,
290 set_overload_bit_cmd,
291 "set-overload-bit",
292 "Set overload bit to avoid any transit traffic\n")
293{
294 VTY_DECLVAR_CONTEXT(isis_area, area);
295
296 isis_area_overload_bit_set(area, true);
297 return CMD_SUCCESS;
298}
299
300DEFUN (no_set_overload_bit,
301 no_set_overload_bit_cmd,
302 "no set-overload-bit",
303 "Reset overload bit to accept transit traffic\n"
304 "Reset overload bit\n")
305{
306 VTY_DECLVAR_CONTEXT(isis_area, area);
307
308 isis_area_overload_bit_set(area, false);
309 return CMD_SUCCESS;
310}
311
933536e3
EDP
312static int isis_vty_password_set(struct vty *vty, int argc,
313 struct cmd_token *argv[], int level)
314{
315 VTY_DECLVAR_CONTEXT(isis_area, area);
316
317 int idx_algo = 1;
318 int idx_password = 2;
319 int idx_snp_auth = 5;
320 uint8_t snp_auth = 0;
321
322 const char *passwd = argv[idx_password]->arg;
323 if (strlen(passwd) > 254) {
324 vty_out(vty, "Too long area password (>254)\n");
325 return CMD_WARNING_CONFIG_FAILED;
326 }
327
328 if (argc > idx_snp_auth) {
329 snp_auth = SNP_AUTH_SEND;
330 if (strmatch(argv[idx_snp_auth]->text, "validate"))
331 snp_auth |= SNP_AUTH_RECV;
332 }
333
334 if (strmatch(argv[idx_algo]->text, "clear")) {
335 return isis_area_passwd_cleartext_set(area, level,
336 passwd, snp_auth);
337 } else if (strmatch(argv[idx_algo]->text, "md5")) {
338 return isis_area_passwd_hmac_md5_set(area, level,
339 passwd, snp_auth);
340 }
341
342 return CMD_WARNING_CONFIG_FAILED;
343}
344
345DEFUN (domain_passwd,
346 domain_passwd_cmd,
347 "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
348 "Set the authentication password for a routing domain\n"
349 "Authentication type\n"
350 "Authentication type\n"
351 "Level-wide password\n"
352 "Authentication\n"
353 "SNP PDUs\n"
354 "Send but do not check PDUs on receiving\n"
355 "Send and check PDUs on receiving\n")
356{
357 return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2);
358}
359
360DEFUN (no_domain_passwd,
361 no_domain_passwd_cmd,
362 "no domain-password",
363 NO_STR
364 "Set the authentication password for a routing domain\n")
365{
366 VTY_DECLVAR_CONTEXT(isis_area, area);
367
368 return isis_area_passwd_unset(area, IS_LEVEL_2);
369}
370
1d6fe72e
EDP
371static int
372isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval)
373{
374 VTY_DECLVAR_CONTEXT(isis_area, area);
375 int lvl;
376
377 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
378 if (!(lvl & level))
379 continue;
380
381 if (interval >= area->lsp_refresh[lvl - 1]) {
382 vty_out(vty,
383 "LSP gen interval %us must be less than "
384 "the LSP refresh interval %us\n",
385 interval, area->lsp_refresh[lvl - 1]);
386 return CMD_WARNING_CONFIG_FAILED;
387 }
388 }
389
390 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
391 if (!(lvl & level))
392 continue;
393 area->lsp_gen_interval[lvl - 1] = interval;
394 }
395
396 return CMD_SUCCESS;
397}
398
399DEFUN (lsp_gen_interval,
400 lsp_gen_interval_cmd,
401 "lsp-gen-interval (1-120)",
402 "Minimum interval between regenerating same LSP\n"
403 "Minimum interval in seconds\n")
404{
405 uint16_t interval = atoi(argv[1]->arg);
406
407 return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval);
408}
409
410DEFUN (no_lsp_gen_interval,
411 no_lsp_gen_interval_cmd,
412 "no lsp-gen-interval [(1-120)]",
413 NO_STR
414 "Minimum interval between regenerating same LSP\n"
415 "Minimum interval in seconds\n")
416{
417 VTY_DECLVAR_CONTEXT(isis_area, area);
418
419 return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2,
420 DEFAULT_MIN_LSP_GEN_INTERVAL);
421}
7e869004
EDP
422
423static int
424isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval)
425{
426 VTY_DECLVAR_CONTEXT(isis_area, area);
427 int lvl;
428
429 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
430 if (!(lvl & level))
431 continue;
432 if (interval <= area->lsp_gen_interval[lvl - 1]) {
433 vty_out(vty,
434 "LSP refresh interval %us must be greater than "
435 "the configured LSP gen interval %us\n",
436 interval, area->lsp_gen_interval[lvl - 1]);
437 return CMD_WARNING_CONFIG_FAILED;
438 }
439 if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) {
440 vty_out(vty,
441 "LSP refresh interval %us must be less than "
442 "the configured LSP lifetime %us less 300\n",
443 interval, area->max_lsp_lifetime[lvl - 1]);
444 return CMD_WARNING_CONFIG_FAILED;
445 }
446 }
447
448 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
449 if (!(lvl & level))
450 continue;
451 isis_area_lsp_refresh_set(area, lvl, interval);
452 }
453
454 return CMD_SUCCESS;
455}
456
457DEFUN (lsp_refresh_interval,
458 lsp_refresh_interval_cmd,
459 "lsp-refresh-interval (1-65235)",
460 "LSP refresh interval\n"
461 "LSP refresh interval in seconds\n")
462{
463 unsigned int interval = atoi(argv[1]->arg);
464 return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval);
465}
466
467DEFUN (no_lsp_refresh_interval,
468 no_lsp_refresh_interval_cmd,
469 "no lsp-refresh-interval [(1-65235)]",
470 NO_STR
471 "LSP refresh interval\n"
472 "LSP refresh interval in seconds\n")
473{
474 return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2,
475 DEFAULT_MAX_LSP_GEN_INTERVAL);
476}
477
ea120aa0
EDP
478static int
479isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval)
480{
481 VTY_DECLVAR_CONTEXT(isis_area, area);
482 int lvl;
483 uint16_t refresh_interval = interval - 300;
484 int set_refresh_interval[ISIS_LEVELS] = {0, 0};
485
486 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
487 if (!(lvl & level))
488 continue;
489
490 if (refresh_interval < area->lsp_refresh[lvl - 1]) {
491 vty_out(vty,
492 "Level %d Max LSP lifetime %us must be 300s greater than "
493 "the configured LSP refresh interval %us\n",
494 lvl, interval, area->lsp_refresh[lvl - 1]);
495 vty_out(vty,
496 "Automatically reducing level %d LSP refresh interval "
497 "to %us\n",
498 lvl, refresh_interval);
499 set_refresh_interval[lvl - 1] = 1;
500
501 if (refresh_interval
502 <= area->lsp_gen_interval[lvl - 1]) {
503 vty_out(vty,
504 "LSP refresh interval %us must be greater than "
505 "the configured LSP gen interval %us\n",
506 refresh_interval,
507 area->lsp_gen_interval[lvl - 1]);
508 return CMD_WARNING_CONFIG_FAILED;
509 }
510 }
511 }
512
513 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
514 if (!(lvl & level))
515 continue;
516 isis_area_max_lsp_lifetime_set(area, lvl, interval);
517 if (set_refresh_interval[lvl - 1])
518 isis_area_lsp_refresh_set(area, lvl, refresh_interval);
519 }
520
521 return CMD_SUCCESS;
522}
523
524DEFUN (max_lsp_lifetime,
525 max_lsp_lifetime_cmd,
526 "max-lsp-lifetime (350-65535)",
527 "Maximum LSP lifetime\n"
528 "LSP lifetime in seconds\n")
529{
530 int lifetime = atoi(argv[1]->arg);
531
532 return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime);
533}
534
535
536DEFUN (no_max_lsp_lifetime,
537 no_max_lsp_lifetime_cmd,
538 "no max-lsp-lifetime [(350-65535)]",
539 NO_STR
540 "Maximum LSP lifetime\n"
541 "LSP lifetime in seconds\n")
542{
543 return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2,
544 DEFAULT_LSP_LIFETIME);
545}
546
ef020087
CF
547void isis_vty_daemon_init(void)
548{
92ed0cde
CF
549 install_element(ROUTER_NODE, &fabric_tier_cmd);
550 install_element(ROUTER_NODE, &no_fabric_tier_cmd);
e923107c
CF
551 install_element(ROUTER_NODE, &triggered_csnp_cmd);
552 install_element(ROUTER_NODE, &no_triggered_csnp_cmd);
1eb7c3a1
CF
553
554 install_element(ENABLE_NODE, &show_lsp_flooding_cmd);
aaf2fd21
EDP
555
556 install_element(INTERFACE_NODE, &ip_router_isis_cmd);
557 install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
558 install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
05a3f9f0
EDP
559
560 install_element(ROUTER_NODE, &set_overload_bit_cmd);
561 install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
933536e3
EDP
562
563 install_element(ROUTER_NODE, &domain_passwd_cmd);
564 install_element(ROUTER_NODE, &no_domain_passwd_cmd);
1d6fe72e
EDP
565
566 install_element(ROUTER_NODE, &lsp_gen_interval_cmd);
567 install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd);
7e869004
EDP
568
569 install_element(ROUTER_NODE, &lsp_refresh_interval_cmd);
570 install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd);
ea120aa0
EDP
571
572 install_element(ROUTER_NODE, &max_lsp_lifetime_cmd);
573 install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd);
ef020087 574}