]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_cli.c
Merge pull request #4214 from donaldsharp/s_g_channel_deletion
[mirror_frr.git] / isisd / isis_cli.c
1 /*
2 * Copyright (C) 2001,2002 Sampo Saaristo
3 * Tampere University of Technology
4 * Institute of Communications Engineering
5 * Copyright (C) 2018 Volta Networks
6 * Emanuele Di Pascale
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as 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
23 #include <zebra.h>
24
25 #include "if.h"
26 #include "vrf.h"
27 #include "log.h"
28 #include "prefix.h"
29 #include "command.h"
30 #include "northbound_cli.h"
31 #include "libfrr.h"
32 #include "yang.h"
33 #include "lib/linklist.h"
34 #include "isisd/isisd.h"
35 #include "isisd/isis_cli.h"
36 #include "isisd/isis_misc.h"
37 #include "isisd/isis_circuit.h"
38 #include "isisd/isis_csm.h"
39
40 #ifndef VTYSH_EXTRACT_PL
41 #include "isisd/isis_cli_clippy.c"
42 #endif
43
44 #ifndef FABRICD
45
46 /*
47 * XPath: /frr-isisd:isis/instance
48 */
49 DEFPY_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag",
50 ROUTER_STR
51 "ISO IS-IS\n"
52 "ISO Routing area tag\n")
53 {
54 int ret;
55 char base_xpath[XPATH_MAXLEN];
56
57 snprintf(base_xpath, XPATH_MAXLEN,
58 "/frr-isisd:isis/instance[area-tag='%s']", tag);
59 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
60 /* default value in yang for is-type is level-1, but in FRR
61 * the first instance is assigned is-type level-1-2. We
62 * need to make sure to set it in the yang model so that it
63 * is consistent with what FRR sees.
64 */
65 if (listcount(isis->area_list) == 0)
66 nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
67 "level-1-2");
68 ret = nb_cli_apply_changes(vty, base_xpath);
69 if (ret == CMD_SUCCESS)
70 VTY_PUSH_XPATH(ISIS_NODE, base_xpath);
71
72 return ret;
73 }
74
75 DEFPY(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag",
76 NO_STR ROUTER_STR
77 "ISO IS-IS\n"
78 "ISO Routing area tag\n")
79 {
80 char temp_xpath[XPATH_MAXLEN];
81 struct listnode *node, *nnode;
82 struct isis_circuit *circuit = NULL;
83 struct isis_area *area = NULL;
84
85 if (!yang_dnode_exists(vty->candidate_config->dnode,
86 "/frr-isisd:isis/instance[area-tag='%s']",
87 tag)) {
88 vty_out(vty, "ISIS area %s not found.\n", tag);
89 return CMD_ERR_NOTHING_TODO;
90 }
91
92 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
93 area = isis_area_lookup(tag);
94 if (area && area->circuit_list && listcount(area->circuit_list)) {
95 for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
96 circuit)) {
97 /* add callbacks to delete each of the circuits listed
98 */
99 const char *vrf_name =
100 vrf_lookup_by_id(circuit->interface->vrf_id)
101 ->name;
102 snprintf(
103 temp_xpath, XPATH_MAXLEN,
104 "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
105 circuit->interface->name, vrf_name);
106 nb_cli_enqueue_change(vty, temp_xpath, NB_OP_DESTROY,
107 NULL);
108 }
109 }
110
111 return nb_cli_apply_changes(
112 vty, "/frr-isisd:isis/instance[area-tag='%s']", tag);
113 }
114
115 void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
116 bool show_defaults)
117 {
118 vty_out(vty, "!\n");
119 vty_out(vty, "router isis %s\n",
120 yang_dnode_get_string(dnode, "./area-tag"));
121 }
122
123 /*
124 * XPath: /frr-interface:lib/interface/frr-isisd:isis/
125 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
126 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
127 * XPath: /frr-isisd:isis/instance
128 */
129 DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
130 "Interface Internet Protocol config commands\n"
131 "IP router interface commands\n"
132 "IS-IS routing protocol\n"
133 "Routing process tag\n")
134 {
135 char temp_xpath[XPATH_MAXLEN];
136 const char *circ_type;
137 struct isis_area *area;
138 struct interface *ifp;
139
140 /* area will be created if it is not present. make sure the yang model
141 * is synced with FRR and call the appropriate NB cb.
142 */
143 area = isis_area_lookup(tag);
144 if (!area) {
145 snprintf(temp_xpath, XPATH_MAXLEN,
146 "/frr-isisd:isis/instance[area-tag='%s']", tag);
147 nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
148 snprintf(temp_xpath, XPATH_MAXLEN,
149 "/frr-isisd:isis/instance[area-tag='%s']/is-type",
150 tag);
151 nb_cli_enqueue_change(
152 vty, temp_xpath, NB_OP_MODIFY,
153 listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
154 nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
155 NULL);
156 nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
157 NB_OP_MODIFY, tag);
158 nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
159 NB_OP_MODIFY, "true");
160 nb_cli_enqueue_change(
161 vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
162 listcount(isis->area_list) == 0 ? "level-1-2"
163 : "level-1");
164 } else {
165 /* area exists, circuit type defaults to its area's is_type */
166 switch (area->is_type) {
167 case IS_LEVEL_1:
168 circ_type = "level-1";
169 break;
170 case IS_LEVEL_2:
171 circ_type = "level-2";
172 break;
173 case IS_LEVEL_1_AND_2:
174 circ_type = "level-1-2";
175 break;
176 default:
177 /* just to silence compiler warnings */
178 return CMD_WARNING_CONFIG_FAILED;
179 }
180 nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
181 NULL);
182 nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
183 NB_OP_MODIFY, tag);
184 nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
185 NB_OP_MODIFY, "true");
186 nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
187 NB_OP_MODIFY, circ_type);
188 }
189
190 /* check if the interface is a loopback and if so set it as passive */
191 pthread_rwlock_rdlock(&running_config->lock);
192 {
193 ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
194 if (ifp && if_is_loopback(ifp))
195 nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
196 NB_OP_MODIFY, "true");
197 }
198 pthread_rwlock_unlock(&running_config->lock);
199
200 return nb_cli_apply_changes(vty, NULL);
201 }
202
203 DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
204 "Interface Internet Protocol config commands\n"
205 "IP router interface commands\n"
206 "IS-IS routing protocol\n"
207 "Routing process tag\n")
208 {
209 char temp_xpath[XPATH_MAXLEN];
210 const char *circ_type;
211 struct isis_area *area;
212 struct interface *ifp;
213
214 /* area will be created if it is not present. make sure the yang model
215 * is synced with FRR and call the appropriate NB cb.
216 */
217 area = isis_area_lookup(tag);
218 if (!area) {
219 snprintf(temp_xpath, XPATH_MAXLEN,
220 "/frr-isisd:isis/instance[area-tag='%s']", tag);
221 nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
222 snprintf(temp_xpath, XPATH_MAXLEN,
223 "/frr-isisd:isis/instance[area-tag='%s']/is-type",
224 tag);
225 nb_cli_enqueue_change(
226 vty, temp_xpath, NB_OP_MODIFY,
227 listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
228 nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
229 NULL);
230 nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
231 NB_OP_MODIFY, tag);
232 nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
233 NB_OP_MODIFY, "true");
234 nb_cli_enqueue_change(
235 vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
236 listcount(isis->area_list) == 0 ? "level-1-2"
237 : "level-1");
238 } else {
239 /* area exists, circuit type defaults to its area's is_type */
240 switch (area->is_type) {
241 case IS_LEVEL_1:
242 circ_type = "level-1";
243 break;
244 case IS_LEVEL_2:
245 circ_type = "level-2";
246 break;
247 case IS_LEVEL_1_AND_2:
248 circ_type = "level-1-2";
249 break;
250 default:
251 /* just to silence compiler warnings */
252 return CMD_WARNING_CONFIG_FAILED;
253 }
254 nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
255 NULL);
256 nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
257 NB_OP_MODIFY, tag);
258 nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
259 NB_OP_MODIFY, "true");
260 nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
261 NB_OP_MODIFY, circ_type);
262 }
263
264 /* check if the interface is a loopback and if so set it as passive */
265 pthread_rwlock_rdlock(&running_config->lock);
266 {
267 ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
268 if (ifp && if_is_loopback(ifp))
269 nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
270 NB_OP_MODIFY, "true");
271 }
272 pthread_rwlock_unlock(&running_config->lock);
273
274 return nb_cli_apply_changes(vty, NULL);
275 }
276
277 DEFPY(no_ip_router_isis, no_ip_router_isis_cmd,
278 "no <ip|ipv6>$ip router isis [WORD]$tag",
279 NO_STR
280 "Interface Internet Protocol config commands\n"
281 "IP router interface commands\n"
282 "IP router interface commands\n"
283 "IS-IS routing protocol\n"
284 "Routing process tag\n")
285 {
286 const struct lyd_node *dnode;
287
288 dnode = yang_dnode_get(vty->candidate_config->dnode,
289 "%s/frr-isisd:isis", VTY_CURR_XPATH);
290 if (!dnode)
291 return CMD_SUCCESS;
292
293 /*
294 * If both ipv4 and ipv6 are off delete the interface isis container.
295 */
296 if (strmatch(ip, "ipv6")) {
297 if (!yang_dnode_get_bool(dnode, "./ipv4-routing"))
298 nb_cli_enqueue_change(vty, "./frr-isisd:isis",
299 NB_OP_DESTROY, NULL);
300 else
301 nb_cli_enqueue_change(vty,
302 "./frr-isisd:isis/ipv6-routing",
303 NB_OP_MODIFY, "false");
304 } else {
305 if (!yang_dnode_get_bool(dnode, "./ipv6-routing"))
306 nb_cli_enqueue_change(vty, "./frr-isisd:isis",
307 NB_OP_DESTROY, NULL);
308 else
309 nb_cli_enqueue_change(vty,
310 "./frr-isisd:isis/ipv4-routing",
311 NB_OP_MODIFY, "false");
312 }
313
314 return nb_cli_apply_changes(vty, NULL);
315 }
316
317 void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
318 bool show_defaults)
319 {
320 if (!yang_dnode_get_bool(dnode, NULL))
321 vty_out(vty, " no");
322 vty_out(vty, " ip router isis %s\n",
323 yang_dnode_get_string(dnode, "../area-tag"));
324 }
325
326 void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
327 bool show_defaults)
328 {
329 if (!yang_dnode_get_bool(dnode, NULL))
330 vty_out(vty, " no");
331 vty_out(vty, " ipv6 router isis %s\n",
332 yang_dnode_get_string(dnode, "../area-tag"));
333 }
334
335 /*
336 * XPath: /frr-isisd:isis/instance/area-address
337 */
338 DEFPY(net, net_cmd, "[no] net WORD",
339 "Remove an existing Network Entity Title for this process\n"
340 "A Network Entity Title for this process (OSI only)\n"
341 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
342 {
343 nb_cli_enqueue_change(vty, "./area-address",
344 no ? NB_OP_DESTROY : NB_OP_CREATE, net);
345
346 return nb_cli_apply_changes(vty, NULL);
347 }
348
349 void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode,
350 bool show_defaults)
351 {
352 vty_out(vty, " net %s\n", yang_dnode_get_string(dnode, NULL));
353 }
354
355 /*
356 * XPath: /frr-isisd:isis/instance/is-type
357 */
358 DEFPY(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level",
359 "IS Level for this routing process (OSI only)\n"
360 "Act as a station router only\n"
361 "Act as both a station router and an area router\n"
362 "Act as an area router only\n")
363 {
364 nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
365 strmatch(level, "level-2-only") ? "level-2"
366 : level);
367
368 return nb_cli_apply_changes(vty, NULL);
369 }
370
371 DEFPY(no_is_type, no_is_type_cmd,
372 "no is-type [<level-1|level-1-2|level-2-only>]",
373 NO_STR
374 "IS Level for this routing process (OSI only)\n"
375 "Act as a station router only\n"
376 "Act as both a station router and an area router\n"
377 "Act as an area router only\n")
378 {
379 const char *value;
380
381 pthread_rwlock_rdlock(&running_config->lock);
382 {
383 struct isis_area *area;
384
385 area = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
386
387 /*
388 * Put the is-type back to defaults:
389 * - level-1-2 on first area
390 * - level-1 for the rest
391 */
392 if (area && listgetdata(listhead(isis->area_list)) == area)
393 value = "level-1-2";
394 else
395 value = NULL;
396 }
397 pthread_rwlock_unlock(&running_config->lock);
398
399 nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, value);
400
401 return nb_cli_apply_changes(vty, NULL);
402 }
403
404 void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode,
405 bool show_defaults)
406 {
407 int is_type = yang_dnode_get_enum(dnode, NULL);
408
409 switch (is_type) {
410 case IS_LEVEL_1:
411 vty_out(vty, " is-type level-1\n");
412 break;
413 case IS_LEVEL_2:
414 vty_out(vty, " is-type level-2-only\n");
415 break;
416 case IS_LEVEL_1_AND_2:
417 vty_out(vty, " is-type level-1-2\n");
418 break;
419 }
420 }
421
422 /*
423 * XPath: /frr-isisd:isis/instance/dynamic-hostname
424 */
425 DEFPY(dynamic_hostname, dynamic_hostname_cmd, "[no] hostname dynamic",
426 NO_STR
427 "Dynamic hostname for IS-IS\n"
428 "Dynamic hostname\n")
429 {
430 nb_cli_enqueue_change(vty, "./dynamic-hostname", NB_OP_MODIFY,
431 no ? "false" : "true");
432
433 return nb_cli_apply_changes(vty, NULL);
434 }
435
436 void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode,
437 bool show_defaults)
438 {
439 if (!yang_dnode_get_bool(dnode, NULL))
440 vty_out(vty, " no");
441
442 vty_out(vty, " hostname dynamic\n");
443 }
444
445 /*
446 * XPath: /frr-isisd:isis/instance/overload
447 */
448 DEFPY(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit",
449 "Reset overload bit to accept transit traffic\n"
450 "Set overload bit to avoid any transit traffic\n")
451 {
452 nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY,
453 no ? "false" : "true");
454
455 return nb_cli_apply_changes(vty, NULL);
456 }
457
458 void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
459 bool show_defaults)
460 {
461 if (!yang_dnode_get_bool(dnode, NULL))
462 vty_out(vty, " no");
463 vty_out(vty, " set-overload-bit\n");
464 }
465
466 /*
467 * XPath: /frr-isisd:isis/instance/attached
468 */
469 DEFPY(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit",
470 "Reset attached bit\n"
471 "Set attached bit to identify as L1/L2 router for inter-area traffic\n")
472 {
473 nb_cli_enqueue_change(vty, "./attached", NB_OP_MODIFY,
474 no ? "false" : "true");
475
476 return nb_cli_apply_changes(vty, NULL);
477 }
478
479 void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
480 bool show_defaults)
481 {
482 if (!yang_dnode_get_bool(dnode, NULL))
483 vty_out(vty, " no");
484 vty_out(vty, " set-attached-bit\n");
485 }
486
487 /*
488 * XPath: /frr-isisd:isis/instance/metric-style
489 */
490 DEFPY(metric_style, metric_style_cmd,
491 "metric-style <narrow|transition|wide>$style",
492 "Use old-style (ISO 10589) or new-style packet formats\n"
493 "Use old style of TLVs with narrow metric\n"
494 "Send and accept both styles of TLVs during transition\n"
495 "Use new style of TLVs to carry wider metric\n")
496 {
497 nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, style);
498
499 return nb_cli_apply_changes(vty, NULL);
500 }
501
502 DEFPY(no_metric_style, no_metric_style_cmd,
503 "no metric-style [narrow|transition|wide]",
504 NO_STR
505 "Use old-style (ISO 10589) or new-style packet formats\n"
506 "Use old style of TLVs with narrow metric\n"
507 "Send and accept both styles of TLVs during transition\n"
508 "Use new style of TLVs to carry wider metric\n")
509 {
510 nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, "narrow");
511
512 return nb_cli_apply_changes(vty, NULL);
513 }
514
515 void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode,
516 bool show_defaults)
517 {
518 int metric = yang_dnode_get_enum(dnode, NULL);
519
520 switch (metric) {
521 case ISIS_NARROW_METRIC:
522 vty_out(vty, " metric-style narrow\n");
523 break;
524 case ISIS_WIDE_METRIC:
525 vty_out(vty, " metric-style wide\n");
526 break;
527 case ISIS_TRANSITION_METRIC:
528 vty_out(vty, " metric-style transition\n");
529 break;
530 }
531 }
532
533 /*
534 * XPath: /frr-isisd:isis/instance/area-password
535 */
536 DEFPY(area_passwd, area_passwd_cmd,
537 "area-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]",
538 "Configure the authentication password for an area\n"
539 "Clear-text authentication type\n"
540 "MD5 authentication type\n"
541 "Level-wide password\n"
542 "Authentication\n"
543 "SNP PDUs\n"
544 "Send but do not check PDUs on receiving\n"
545 "Send and check PDUs on receiving\n")
546 {
547 nb_cli_enqueue_change(vty, "./area-password", NB_OP_CREATE, NULL);
548 nb_cli_enqueue_change(vty, "./area-password/password", NB_OP_MODIFY,
549 pwd);
550 nb_cli_enqueue_change(vty, "./area-password/password-type",
551 NB_OP_MODIFY, pwd_type);
552 nb_cli_enqueue_change(vty, "./area-password/authenticate-snp",
553 NB_OP_MODIFY, snp ? snp : "none");
554
555 return nb_cli_apply_changes(vty, NULL);
556 }
557
558 void cli_show_isis_area_pwd(struct vty *vty, struct lyd_node *dnode,
559 bool show_defaults)
560 {
561 const char *snp;
562
563 vty_out(vty, " area-password %s %s",
564 yang_dnode_get_string(dnode, "./password-type"),
565 yang_dnode_get_string(dnode, "./password"));
566 snp = yang_dnode_get_string(dnode, "./authenticate-snp");
567 if (!strmatch("none", snp))
568 vty_out(vty, " authenticate snp %s", snp);
569 vty_out(vty, "\n");
570 }
571
572 /*
573 * XPath: /frr-isisd:isis/instance/domain-password
574 */
575 DEFPY(domain_passwd, domain_passwd_cmd,
576 "domain-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]",
577 "Set the authentication password for a routing domain\n"
578 "Clear-text authentication type\n"
579 "MD5 authentication type\n"
580 "Level-wide password\n"
581 "Authentication\n"
582 "SNP PDUs\n"
583 "Send but do not check PDUs on receiving\n"
584 "Send and check PDUs on receiving\n")
585 {
586 nb_cli_enqueue_change(vty, "./domain-password", NB_OP_CREATE, NULL);
587 nb_cli_enqueue_change(vty, "./domain-password/password", NB_OP_MODIFY,
588 pwd);
589 nb_cli_enqueue_change(vty, "./domain-password/password-type",
590 NB_OP_MODIFY, pwd_type);
591 nb_cli_enqueue_change(vty, "./domain-password/authenticate-snp",
592 NB_OP_MODIFY, snp ? snp : "none");
593
594 return nb_cli_apply_changes(vty, NULL);
595 }
596
597 DEFPY(no_area_passwd, no_area_passwd_cmd,
598 "no <area-password|domain-password>$cmd",
599 NO_STR
600 "Configure the authentication password for an area\n"
601 "Set the authentication password for a routing domain\n")
602 {
603 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
604
605 return nb_cli_apply_changes(vty, "./%s", cmd);
606 }
607
608 void cli_show_isis_domain_pwd(struct vty *vty, struct lyd_node *dnode,
609 bool show_defaults)
610 {
611 const char *snp;
612
613 vty_out(vty, " domain-password %s %s",
614 yang_dnode_get_string(dnode, "./password-type"),
615 yang_dnode_get_string(dnode, "./password"));
616 snp = yang_dnode_get_string(dnode, "./authenticate-snp");
617 if (!strmatch("none", snp))
618 vty_out(vty, " authenticate snp %s", snp);
619 vty_out(vty, "\n");
620 }
621
622 /*
623 * XPath: /frr-isisd:isis/instance/lsp/generation-interval
624 */
625 DEFPY(lsp_gen_interval, lsp_gen_interval_cmd,
626 "lsp-gen-interval [level-1|level-2]$level (1-120)$val",
627 "Minimum interval between regenerating same LSP\n"
628 "Set interval for level 1 only\n"
629 "Set interval for level 2 only\n"
630 "Minimum interval in seconds\n")
631 {
632 if (!level || strmatch(level, "level-1"))
633 nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-1",
634 NB_OP_MODIFY, val_str);
635 if (!level || strmatch(level, "level-2"))
636 nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-2",
637 NB_OP_MODIFY, val_str);
638
639 return nb_cli_apply_changes(vty, NULL);
640 }
641
642 DEFPY(no_lsp_gen_interval, no_lsp_gen_interval_cmd,
643 "no lsp-gen-interval [level-1|level-2]$level [(1-120)]",
644 NO_STR
645 "Minimum interval between regenerating same LSP\n"
646 "Set interval for level 1 only\n"
647 "Set interval for level 2 only\n"
648 "Minimum interval in seconds\n")
649 {
650 if (!level || strmatch(level, "level-1"))
651 nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-1",
652 NB_OP_MODIFY, NULL);
653 if (!level || strmatch(level, "level-2"))
654 nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-2",
655 NB_OP_MODIFY, NULL);
656
657 return nb_cli_apply_changes(vty, NULL);
658 }
659
660 void cli_show_isis_lsp_gen_interval(struct vty *vty, struct lyd_node *dnode,
661 bool show_defaults)
662 {
663 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
664 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
665
666 if (strmatch(l1, l2))
667 vty_out(vty, " lsp-gen-interval %s\n", l1);
668 else {
669 vty_out(vty, " lsp-gen-interval level-1 %s\n", l1);
670 vty_out(vty, " lsp-gen-interval level-2 %s\n", l2);
671 }
672 }
673
674 /*
675 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval
676 */
677 DEFPY(lsp_refresh_interval, lsp_refresh_interval_cmd,
678 "lsp-refresh-interval [level-1|level-2]$level (1-65235)$val",
679 "LSP refresh interval\n"
680 "LSP refresh interval for Level 1 only\n"
681 "LSP refresh interval for Level 2 only\n"
682 "LSP refresh interval in seconds\n")
683 {
684 if (!level || strmatch(level, "level-1"))
685 nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-1",
686 NB_OP_MODIFY, val_str);
687 if (!level || strmatch(level, "level-2"))
688 nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-2",
689 NB_OP_MODIFY, val_str);
690
691 return nb_cli_apply_changes(vty, NULL);
692 }
693
694 DEFPY(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd,
695 "no lsp-refresh-interval [level-1|level-2]$level [(1-65235)]",
696 NO_STR
697 "LSP refresh interval\n"
698 "LSP refresh interval for Level 1 only\n"
699 "LSP refresh interval for Level 2 only\n"
700 "LSP refresh interval in seconds\n")
701 {
702 if (!level || strmatch(level, "level-1"))
703 nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-1",
704 NB_OP_MODIFY, NULL);
705 if (!level || strmatch(level, "level-2"))
706 nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-2",
707 NB_OP_MODIFY, NULL);
708
709 return nb_cli_apply_changes(vty, NULL);
710 }
711
712 void cli_show_isis_lsp_ref_interval(struct vty *vty, struct lyd_node *dnode,
713 bool show_defaults)
714 {
715 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
716 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
717
718 if (strmatch(l1, l2))
719 vty_out(vty, " lsp-refresh-interval %s\n", l1);
720 else {
721 vty_out(vty, " lsp-refresh-interval level-1 %s\n", l1);
722 vty_out(vty, " lsp-refresh-interval level-2 %s\n", l2);
723 }
724 }
725
726 /*
727 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime
728 */
729 DEFPY(max_lsp_lifetime, max_lsp_lifetime_cmd,
730 "max-lsp-lifetime [level-1|level-2]$level (350-65535)$val",
731 "Maximum LSP lifetime\n"
732 "Maximum LSP lifetime for Level 1 only\n"
733 "Maximum LSP lifetime for Level 2 only\n"
734 "LSP lifetime in seconds\n")
735 {
736 if (!level || strmatch(level, "level-1"))
737 nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-1",
738 NB_OP_MODIFY, val_str);
739 if (!level || strmatch(level, "level-2"))
740 nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-2",
741 NB_OP_MODIFY, val_str);
742
743 return nb_cli_apply_changes(vty, NULL);
744 }
745
746 DEFPY(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd,
747 "no max-lsp-lifetime [level-1|level-2]$level [(350-65535)]",
748 NO_STR
749 "Maximum LSP lifetime\n"
750 "Maximum LSP lifetime for Level 1 only\n"
751 "Maximum LSP lifetime for Level 2 only\n"
752 "LSP lifetime in seconds\n")
753 {
754 if (!level || strmatch(level, "level-1"))
755 nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-1",
756 NB_OP_MODIFY, NULL);
757 if (!level || strmatch(level, "level-2"))
758 nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-2",
759 NB_OP_MODIFY, NULL);
760
761 return nb_cli_apply_changes(vty, NULL);
762 }
763
764 void cli_show_isis_lsp_max_lifetime(struct vty *vty, struct lyd_node *dnode,
765 bool show_defaults)
766 {
767 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
768 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
769
770 if (strmatch(l1, l2))
771 vty_out(vty, " max-lsp-lifetime %s\n", l1);
772 else {
773 vty_out(vty, " max-lsp-lifetime level-1 %s\n", l1);
774 vty_out(vty, " max-lsp-lifetime level-2 %s\n", l2);
775 }
776 }
777
778 /*
779 * XPath: /frr-isisd:isis/instance/lsp/mtu
780 */
781 DEFPY(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val",
782 "Configure the maximum size of generated LSPs\n"
783 "Maximum size of generated LSPs\n")
784 {
785 nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, val_str);
786
787 return nb_cli_apply_changes(vty, NULL);
788 }
789
790 DEFPY(no_area_lsp_mtu, no_area_lsp_mtu_cmd, "no lsp-mtu [(128-4352)]",
791 NO_STR
792 "Configure the maximum size of generated LSPs\n"
793 "Maximum size of generated LSPs\n")
794 {
795 nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, NULL);
796
797 return nb_cli_apply_changes(vty, NULL);
798 }
799
800 void cli_show_isis_lsp_mtu(struct vty *vty, struct lyd_node *dnode,
801 bool show_defaults)
802 {
803 vty_out(vty, " lsp-mtu %s\n", yang_dnode_get_string(dnode, NULL));
804 }
805
806 /*
807 * XPath: /frr-isisd:isis/instance/spf/minimum-interval
808 */
809 DEFPY(spf_interval, spf_interval_cmd,
810 "spf-interval [level-1|level-2]$level (1-120)$val",
811 "Minimum interval between SPF calculations\n"
812 "Set interval for level 1 only\n"
813 "Set interval for level 2 only\n"
814 "Minimum interval between consecutive SPFs in seconds\n")
815 {
816 if (!level || strmatch(level, "level-1"))
817 nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1",
818 NB_OP_MODIFY, val_str);
819 if (!level || strmatch(level, "level-2"))
820 nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2",
821 NB_OP_MODIFY, val_str);
822
823 return nb_cli_apply_changes(vty, NULL);
824 }
825
826 DEFPY(no_spf_interval, no_spf_interval_cmd,
827 "no spf-interval [level-1|level-2]$level [(1-120)]",
828 NO_STR
829 "Minimum interval between SPF calculations\n"
830 "Set interval for level 1 only\n"
831 "Set interval for level 2 only\n"
832 "Minimum interval between consecutive SPFs in seconds\n")
833 {
834 if (!level || strmatch(level, "level-1"))
835 nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1",
836 NB_OP_MODIFY, NULL);
837 if (!level || strmatch(level, "level-2"))
838 nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2",
839 NB_OP_MODIFY, NULL);
840
841 return nb_cli_apply_changes(vty, NULL);
842 }
843
844 void cli_show_isis_spf_min_interval(struct vty *vty, struct lyd_node *dnode,
845 bool show_defaults)
846 {
847 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
848 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
849
850 if (strmatch(l1, l2))
851 vty_out(vty, " spf-interval %s\n", l1);
852 else {
853 vty_out(vty, " spf-interval level-1 %s\n", l1);
854 vty_out(vty, " spf-interval level-2 %s\n", l2);
855 }
856 }
857
858 /*
859 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
860 */
861 DEFPY(spf_delay_ietf, spf_delay_ietf_cmd,
862 "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)",
863 "IETF SPF delay algorithm\n"
864 "Delay used while in QUIET state\n"
865 "Delay used while in QUIET state in milliseconds\n"
866 "Delay used while in SHORT_WAIT state\n"
867 "Delay used while in SHORT_WAIT state in milliseconds\n"
868 "Delay used while in LONG_WAIT\n"
869 "Delay used while in LONG_WAIT state in milliseconds\n"
870 "Time with no received IGP events before considering IGP stable\n"
871 "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
872 "Maximum duration needed to learn all the events related to a single failure\n"
873 "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
874 {
875 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_CREATE,
876 NULL);
877 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/init-delay",
878 NB_OP_MODIFY, init_delay_str);
879 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/short-delay",
880 NB_OP_MODIFY, short_delay_str);
881 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/long-delay",
882 NB_OP_MODIFY, long_delay_str);
883 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/hold-down",
884 NB_OP_MODIFY, holddown_str);
885 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/time-to-learn",
886 NB_OP_MODIFY, time_to_learn_str);
887
888 return nb_cli_apply_changes(vty, NULL);
889 }
890
891 DEFPY(no_spf_delay_ietf, no_spf_delay_ietf_cmd,
892 "no spf-delay-ietf [init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)]",
893 NO_STR
894 "IETF SPF delay algorithm\n"
895 "Delay used while in QUIET state\n"
896 "Delay used while in QUIET state in milliseconds\n"
897 "Delay used while in SHORT_WAIT state\n"
898 "Delay used while in SHORT_WAIT state in milliseconds\n"
899 "Delay used while in LONG_WAIT\n"
900 "Delay used while in LONG_WAIT state in milliseconds\n"
901 "Time with no received IGP events before considering IGP stable\n"
902 "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
903 "Maximum duration needed to learn all the events related to a single failure\n"
904 "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
905 {
906 nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_DESTROY,
907 NULL);
908
909 return nb_cli_apply_changes(vty, NULL);
910 }
911
912 void cli_show_isis_spf_ietf_backoff(struct vty *vty, struct lyd_node *dnode,
913 bool show_defaults)
914 {
915 vty_out(vty,
916 " spf-delay-ietf init-delay %s short-delay %s long-delay %s holddown %s time-to-learn %s\n",
917 yang_dnode_get_string(dnode, "./init-delay"),
918 yang_dnode_get_string(dnode, "./short-delay"),
919 yang_dnode_get_string(dnode, "./long-delay"),
920 yang_dnode_get_string(dnode, "./hold-down"),
921 yang_dnode_get_string(dnode, "./time-to-learn"));
922 }
923
924 /*
925 * XPath: /frr-isisd:isis/instance/purge-originator
926 */
927 DEFPY(area_purge_originator, area_purge_originator_cmd, "[no] purge-originator",
928 NO_STR "Use the RFC 6232 purge-originator\n")
929 {
930 nb_cli_enqueue_change(vty, "./purge-originator", NB_OP_MODIFY,
931 no ? "false" : "true");
932
933 return nb_cli_apply_changes(vty, NULL);
934 }
935
936 void cli_show_isis_purge_origin(struct vty *vty, struct lyd_node *dnode,
937 bool show_defaults)
938 {
939 if (!yang_dnode_get_bool(dnode, NULL))
940 vty_out(vty, " no");
941 vty_out(vty, " purge-originator\n");
942 }
943
944 /*
945 * XPath: /frr-isisd:isis/instance/mpls-te
946 */
947 DEFPY(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on",
948 MPLS_TE_STR "Enable the MPLS-TE functionality\n")
949 {
950 nb_cli_enqueue_change(vty, "./mpls-te", NB_OP_CREATE,
951 NULL);
952
953 return nb_cli_apply_changes(vty, NULL);
954 }
955
956 DEFPY(no_isis_mpls_te_on, no_isis_mpls_te_on_cmd, "no mpls-te [on]",
957 NO_STR
958 "Disable the MPLS-TE functionality\n"
959 "Disable the MPLS-TE functionality\n")
960 {
961 nb_cli_enqueue_change(vty, "./mpls-te", NB_OP_DESTROY,
962 NULL);
963
964 return nb_cli_apply_changes(vty, NULL);
965 }
966
967 void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode,
968 bool show_defaults)
969 {
970 vty_out(vty, " mpls-te on\n");
971 }
972
973 /*
974 * XPath: /frr-isisd:isis/instance/mpls-te/router-address
975 */
976 DEFPY(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd,
977 "mpls-te router-address A.B.C.D",
978 MPLS_TE_STR
979 "Stable IP address of the advertising router\n"
980 "MPLS-TE router address in IPv4 address format\n")
981 {
982 nb_cli_enqueue_change(vty, "./mpls-te/router-address",
983 NB_OP_MODIFY, router_address_str);
984
985 return nb_cli_apply_changes(vty, NULL);
986 }
987
988 DEFPY(no_isis_mpls_te_router_addr, no_isis_mpls_te_router_addr_cmd,
989 "no mpls-te router-address [A.B.C.D]",
990 NO_STR MPLS_TE_STR
991 "Delete IP address of the advertising router\n"
992 "MPLS-TE router address in IPv4 address format\n")
993 {
994 nb_cli_enqueue_change(vty, "./mpls-te/router-address",
995 NB_OP_DESTROY, NULL);
996
997 return nb_cli_apply_changes(vty, NULL);
998 }
999
1000 void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode,
1001 bool show_defaults)
1002 {
1003 vty_out(vty, " mpls-te router-address %s\n",
1004 yang_dnode_get_string(dnode, NULL));
1005 }
1006
1007 DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
1008 "[no] mpls-te inter-as [level-1|level-1-2|level-2-only]",
1009 NO_STR MPLS_TE_STR
1010 "Configure MPLS-TE Inter-AS support\n"
1011 "AREA native mode self originate INTER-AS LSP with L1 only flooding scope\n"
1012 "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope\n"
1013 "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n")
1014 {
1015 vty_out(vty, "MPLS-TE Inter-AS is not yet supported\n");
1016 return CMD_SUCCESS;
1017 }
1018
1019 /*
1020 * XPath: /frr-isisd:isis/instance/default-information-originate
1021 */
1022 DEFPY(isis_default_originate, isis_default_originate_cmd,
1023 "[no] default-information originate <ipv4|ipv6>$ip"
1024 " <level-1|level-2>$level [always]$always"
1025 " [{metric (0-16777215)$metric|route-map WORD$rmap}]",
1026 NO_STR
1027 "Control distribution of default information\n"
1028 "Distribute a default route\n"
1029 "Distribute default route for IPv4\n"
1030 "Distribute default route for IPv6\n"
1031 "Distribute default route into level-1\n"
1032 "Distribute default route into level-2\n"
1033 "Always advertise default route\n"
1034 "Metric for default route\n"
1035 "ISIS default metric\n"
1036 "Route map reference\n"
1037 "Pointer to route-map entries\n")
1038 {
1039 if (no)
1040 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
1041 else {
1042 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
1043 nb_cli_enqueue_change(vty, "./always", NB_OP_MODIFY,
1044 always ? "true" : "false");
1045 nb_cli_enqueue_change(vty, "./route-map",
1046 rmap ? NB_OP_MODIFY : NB_OP_DESTROY,
1047 rmap ? rmap : NULL);
1048 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
1049 metric_str ? metric_str : NULL);
1050 if (strmatch(ip, "ipv6") && !always) {
1051 vty_out(vty,
1052 "Zebra doesn't implement default-originate for IPv6 yet\n");
1053 vty_out(vty,
1054 "so use with care or use default-originate always.\n");
1055 }
1056 }
1057
1058 return nb_cli_apply_changes(
1059 vty, "./default-information-originate/%s[level='%s']", ip,
1060 level);
1061 }
1062
1063 static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode,
1064 const char *family, const char *level,
1065 bool show_defaults)
1066 {
1067 vty_out(vty, " default-information originate %s %s", family, level);
1068 if (yang_dnode_get_bool(dnode, "./always"))
1069 vty_out(vty, " always");
1070
1071 if (yang_dnode_exists(dnode, "./route-map"))
1072 vty_out(vty, " route-map %s",
1073 yang_dnode_get_string(dnode, "./route-map"));
1074 if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
1075 vty_out(vty, " metric %s",
1076 yang_dnode_get_string(dnode, "./metric"));
1077
1078 vty_out(vty, "\n");
1079 }
1080
1081 void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
1082 bool show_defaults)
1083 {
1084 const char *level = yang_dnode_get_string(dnode, "./level");
1085
1086 vty_print_def_origin(vty, dnode, "ipv4", level, show_defaults);
1087 }
1088
1089 void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
1090 bool show_defaults)
1091 {
1092 const char *level = yang_dnode_get_string(dnode, "./level");
1093
1094 vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults);
1095 }
1096
1097 /*
1098 * XPath: /frr-isisd:isis/instance/redistribute
1099 */
1100 DEFPY(isis_redistribute, isis_redistribute_cmd,
1101 "[no] redistribute <ipv4|ipv6>$ip " PROTO_REDIST_STR
1102 "$proto"
1103 " <level-1|level-2>$level"
1104 " [{metric (0-16777215)|route-map WORD}]",
1105 NO_STR REDIST_STR
1106 "Redistribute IPv4 routes\n"
1107 "Redistribute IPv6 routes\n" PROTO_REDIST_HELP
1108 "Redistribute into level-1\n"
1109 "Redistribute into level-2\n"
1110 "Metric for redistributed routes\n"
1111 "ISIS default metric\n"
1112 "Route map reference\n"
1113 "Pointer to route-map entries\n")
1114 {
1115 if (no)
1116 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
1117 else {
1118 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
1119 nb_cli_enqueue_change(vty, "./route-map",
1120 route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
1121 route_map ? route_map : NULL);
1122 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
1123 metric_str ? metric_str : NULL);
1124 }
1125
1126 return nb_cli_apply_changes(
1127 vty, "./redistribute/%s[protocol='%s'][level='%s']", ip, proto,
1128 level);
1129 }
1130
1131 static void vty_print_redistribute(struct vty *vty, struct lyd_node *dnode,
1132 bool show_defaults, const char *family)
1133 {
1134 const char *level = yang_dnode_get_string(dnode, "./level");
1135 const char *protocol = yang_dnode_get_string(dnode, "./protocol");
1136
1137 vty_out(vty, " redistribute %s %s %s", family, protocol, level);
1138 if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
1139 vty_out(vty, " metric %s",
1140 yang_dnode_get_string(dnode, "./metric"));
1141 if (yang_dnode_exists(dnode, "./route-map"))
1142 vty_out(vty, " route-map %s",
1143 yang_dnode_get_string(dnode, "./route-map"));
1144 vty_out(vty, "\n");
1145 }
1146
1147 void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode,
1148 bool show_defaults)
1149 {
1150 vty_print_redistribute(vty, dnode, show_defaults, "ipv4");
1151 }
1152 void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode,
1153 bool show_defaults)
1154 {
1155 vty_print_redistribute(vty, dnode, show_defaults, "ipv6");
1156 }
1157
1158 /*
1159 * XPath: /frr-isisd:isis/instance/multi-topology
1160 */
1161 DEFPY(isis_topology, isis_topology_cmd,
1162 "[no] topology "
1163 "<ipv4-unicast"
1164 "|ipv4-mgmt"
1165 "|ipv6-unicast"
1166 "|ipv4-multicast"
1167 "|ipv6-multicast"
1168 "|ipv6-mgmt"
1169 "|ipv6-dstsrc>$topology "
1170 "[overload]$overload",
1171 NO_STR
1172 "Configure IS-IS topologies\n"
1173 "IPv4 unicast topology\n"
1174 "IPv4 management topology\n"
1175 "IPv6 unicast topology\n"
1176 "IPv4 multicast topology\n"
1177 "IPv6 multicast topology\n"
1178 "IPv6 management topology\n"
1179 "IPv6 dst-src topology\n"
1180 "Set overload bit for topology\n")
1181 {
1182 char base_xpath[XPATH_MAXLEN];
1183
1184 /* Since IPv4-unicast is not configurable it is not present in the
1185 * YANG model, so we need to validate it here
1186 */
1187 if (strmatch(topology, "ipv4-unicast")) {
1188 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
1189 return CMD_WARNING_CONFIG_FAILED;
1190 }
1191
1192 if (strmatch(topology, "ipv4-mgmt"))
1193 snprintf(base_xpath, XPATH_MAXLEN,
1194 "./multi-topology/ipv4-management");
1195 else if (strmatch(topology, "ipv6-mgmt"))
1196 snprintf(base_xpath, XPATH_MAXLEN,
1197 "./multi-topology/ipv6-management");
1198 else
1199 snprintf(base_xpath, XPATH_MAXLEN, "./multi-topology/%s",
1200 topology);
1201
1202 if (no)
1203 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
1204 else {
1205 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
1206 nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY,
1207 overload ? "true" : "false");
1208 }
1209
1210 return nb_cli_apply_changes(vty, base_xpath);
1211 }
1212
1213 void cli_show_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode,
1214 bool show_defaults)
1215 {
1216 vty_out(vty, " topology ipv4-multicast");
1217 if (yang_dnode_get_bool(dnode, "./overload"))
1218 vty_out(vty, " overload");
1219 vty_out(vty, "\n");
1220 }
1221
1222 void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode,
1223 bool show_defaults)
1224 {
1225 vty_out(vty, " topology ipv4-mgmt");
1226 if (yang_dnode_get_bool(dnode, "./overload"))
1227 vty_out(vty, " overload");
1228 vty_out(vty, "\n");
1229 }
1230
1231 void cli_show_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode,
1232 bool show_defaults)
1233 {
1234 vty_out(vty, " topology ipv6-unicast");
1235 if (yang_dnode_get_bool(dnode, "./overload"))
1236 vty_out(vty, " overload");
1237 vty_out(vty, "\n");
1238 }
1239
1240 void cli_show_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode,
1241 bool show_defaults)
1242 {
1243 vty_out(vty, " topology ipv6-multicast");
1244 if (yang_dnode_get_bool(dnode, "./overload"))
1245 vty_out(vty, " overload");
1246 vty_out(vty, "\n");
1247 }
1248
1249 void cli_show_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
1250 bool show_defaults)
1251 {
1252 vty_out(vty, " topology ipv6-mgmt");
1253 if (yang_dnode_get_bool(dnode, "./overload"))
1254 vty_out(vty, " overload");
1255 vty_out(vty, "\n");
1256 }
1257
1258 void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
1259 bool show_defaults)
1260 {
1261 vty_out(vty, " topology ipv6-dstsrc");
1262 if (yang_dnode_get_bool(dnode, "./overload"))
1263 vty_out(vty, " overload");
1264 vty_out(vty, "\n");
1265 }
1266
1267 /*
1268 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
1269 */
1270 DEFPY(isis_passive, isis_passive_cmd, "[no] isis passive",
1271 NO_STR
1272 "IS-IS routing protocol\n"
1273 "Configure the passive mode for interface\n")
1274 {
1275 nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive", NB_OP_MODIFY,
1276 no ? "false" : "true");
1277
1278 return nb_cli_apply_changes(vty, NULL);
1279 }
1280
1281 void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode,
1282 bool show_defaults)
1283 {
1284 if (!yang_dnode_get_bool(dnode, NULL))
1285 vty_out(vty, " no");
1286 vty_out(vty, " isis passive\n");
1287 }
1288
1289 /*
1290 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
1291 */
1292
1293 DEFPY(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd",
1294 "IS-IS routing protocol\n"
1295 "Configure the authentication password for a circuit\n"
1296 "HMAC-MD5 authentication\n"
1297 "Cleartext password\n"
1298 "Circuit password\n")
1299 {
1300 nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_CREATE,
1301 NULL);
1302 nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password",
1303 NB_OP_MODIFY, pwd);
1304 nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password-type",
1305 NB_OP_MODIFY, type);
1306
1307 return nb_cli_apply_changes(vty, NULL);
1308 }
1309
1310 DEFPY(no_isis_passwd, no_isis_passwd_cmd, "no isis password [<md5|clear> WORD]",
1311 NO_STR
1312 "IS-IS routing protocol\n"
1313 "Configure the authentication password for a circuit\n"
1314 "HMAC-MD5 authentication\n"
1315 "Cleartext password\n"
1316 "Circuit password\n")
1317 {
1318 nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_DESTROY,
1319 NULL);
1320
1321 return nb_cli_apply_changes(vty, NULL);
1322 }
1323
1324 void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode,
1325 bool show_defaults)
1326 {
1327 vty_out(vty, " isis password %s %s\n",
1328 yang_dnode_get_string(dnode, "./password-type"),
1329 yang_dnode_get_string(dnode, "./password"));
1330 }
1331
1332 /*
1333 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric
1334 */
1335 DEFPY(isis_metric, isis_metric_cmd,
1336 "isis metric [level-1|level-2]$level (0-16777215)$met",
1337 "IS-IS routing protocol\n"
1338 "Set default metric for circuit\n"
1339 "Specify metric for level-1 routing\n"
1340 "Specify metric for level-2 routing\n"
1341 "Default metric value\n")
1342 {
1343 if (!level || strmatch(level, "level-1"))
1344 nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1",
1345 NB_OP_MODIFY, met_str);
1346 if (!level || strmatch(level, "level-2"))
1347 nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2",
1348 NB_OP_MODIFY, met_str);
1349
1350 return nb_cli_apply_changes(vty, NULL);
1351 }
1352
1353 DEFPY(no_isis_metric, no_isis_metric_cmd,
1354 "no isis metric [level-1|level-2]$level [(0-16777215)]",
1355 NO_STR
1356 "IS-IS routing protocol\n"
1357 "Set default metric for circuit\n"
1358 "Specify metric for level-1 routing\n"
1359 "Specify metric for level-2 routing\n"
1360 "Default metric value\n")
1361 {
1362 if (!level || strmatch(level, "level-1"))
1363 nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1",
1364 NB_OP_MODIFY, NULL);
1365 if (!level || strmatch(level, "level-2"))
1366 nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2",
1367 NB_OP_MODIFY, NULL);
1368
1369 return nb_cli_apply_changes(vty, NULL);
1370 }
1371
1372 void cli_show_ip_isis_metric(struct vty *vty, struct lyd_node *dnode,
1373 bool show_defaults)
1374 {
1375 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
1376 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
1377
1378 if (strmatch(l1, l2))
1379 vty_out(vty, " isis metric %s\n", l1);
1380 else {
1381 vty_out(vty, " isis metric %s level-1\n", l1);
1382 vty_out(vty, " isis metric %s level-2\n", l2);
1383 }
1384 }
1385
1386 /*
1387 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval
1388 */
1389 DEFPY(isis_hello_interval, isis_hello_interval_cmd,
1390 "isis hello-interval [level-1|level-2]$level (1-600)$intv",
1391 "IS-IS routing protocol\n"
1392 "Set Hello interval\n"
1393 "Specify hello-interval for level-1 IIHs\n"
1394 "Specify hello-interval for level-2 IIHs\n"
1395 "Holdtime 1 seconds, interval depends on multiplier\n")
1396 {
1397 if (!level || strmatch(level, "level-1"))
1398 nb_cli_enqueue_change(vty,
1399 "./frr-isisd:isis/hello/interval/level-1",
1400 NB_OP_MODIFY, intv_str);
1401 if (!level || strmatch(level, "level-2"))
1402 nb_cli_enqueue_change(vty,
1403 "./frr-isisd:isis/hello/interval/level-2",
1404 NB_OP_MODIFY, intv_str);
1405
1406 return nb_cli_apply_changes(vty, NULL);
1407 }
1408
1409 DEFPY(no_isis_hello_interval, no_isis_hello_interval_cmd,
1410 "no isis hello-interval [level-1|level-2]$level [(1-600)]",
1411 NO_STR
1412 "IS-IS routing protocol\n"
1413 "Set Hello interval\n"
1414 "Specify hello-interval for level-1 IIHs\n"
1415 "Specify hello-interval for level-2 IIHs\n"
1416 "Holdtime 1 second, interval depends on multiplier\n")
1417 {
1418 if (!level || strmatch(level, "level-1"))
1419 nb_cli_enqueue_change(vty,
1420 "./frr-isisd:isis/hello/interval/level-1",
1421 NB_OP_MODIFY, NULL);
1422 if (!level || strmatch(level, "level-2"))
1423 nb_cli_enqueue_change(vty,
1424 "./frr-isisd:isis/hello/interval/level-2",
1425 NB_OP_MODIFY, NULL);
1426
1427 return nb_cli_apply_changes(vty, NULL);
1428 }
1429
1430 void cli_show_ip_isis_hello_interval(struct vty *vty, struct lyd_node *dnode,
1431 bool show_defaults)
1432 {
1433 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
1434 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
1435
1436 if (strmatch(l1, l2))
1437 vty_out(vty, " isis hello-interval %s\n", l1);
1438 else {
1439 vty_out(vty, " isis hello-interval %s level-1\n", l1);
1440 vty_out(vty, " isis hello-interval %s level-2\n", l2);
1441 }
1442 }
1443
1444 /*
1445 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier
1446 */
1447 DEFPY(isis_hello_multiplier, isis_hello_multiplier_cmd,
1448 "isis hello-multiplier [level-1|level-2]$level (2-100)$mult",
1449 "IS-IS routing protocol\n"
1450 "Set multiplier for Hello holding time\n"
1451 "Specify hello multiplier for level-1 IIHs\n"
1452 "Specify hello multiplier for level-2 IIHs\n"
1453 "Hello multiplier value\n")
1454 {
1455 if (!level || strmatch(level, "level-1"))
1456 nb_cli_enqueue_change(
1457 vty, "./frr-isisd:isis/hello/multiplier/level-1",
1458 NB_OP_MODIFY, mult_str);
1459 if (!level || strmatch(level, "level-2"))
1460 nb_cli_enqueue_change(
1461 vty, "./frr-isisd:isis/hello/multiplier/level-2",
1462 NB_OP_MODIFY, mult_str);
1463
1464 return nb_cli_apply_changes(vty, NULL);
1465 }
1466
1467 DEFPY(no_isis_hello_multiplier, no_isis_hello_multiplier_cmd,
1468 "no isis hello-multiplier [level-1|level-2]$level [(2-100)]",
1469 NO_STR
1470 "IS-IS routing protocol\n"
1471 "Set multiplier for Hello holding time\n"
1472 "Specify hello multiplier for level-1 IIHs\n"
1473 "Specify hello multiplier for level-2 IIHs\n"
1474 "Hello multiplier value\n")
1475 {
1476 if (!level || strmatch(level, "level-1"))
1477 nb_cli_enqueue_change(
1478 vty, "./frr-isisd:isis/hello/multiplier/level-1",
1479 NB_OP_MODIFY, NULL);
1480 if (!level || strmatch(level, "level-2"))
1481 nb_cli_enqueue_change(
1482 vty, "./frr-isisd:isis/hello/multiplier/level-2",
1483 NB_OP_MODIFY, NULL);
1484
1485 return nb_cli_apply_changes(vty, NULL);
1486 }
1487
1488 void cli_show_ip_isis_hello_multi(struct vty *vty, struct lyd_node *dnode,
1489 bool show_defaults)
1490 {
1491 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
1492 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
1493
1494 if (strmatch(l1, l2))
1495 vty_out(vty, " isis hello-multiplier %s\n", l1);
1496 else {
1497 vty_out(vty, " isis hello-multiplier %s level-1\n", l1);
1498 vty_out(vty, " isis hello-multiplier %s level-2\n", l2);
1499 }
1500 }
1501
1502 /*
1503 * XPath:
1504 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
1505 */
1506 DEFPY(isis_threeway_adj, isis_threeway_adj_cmd, "[no] isis three-way-handshake",
1507 NO_STR
1508 "IS-IS commands\n"
1509 "Enable/Disable three-way handshake\n")
1510 {
1511 nb_cli_enqueue_change(vty,
1512 "./frr-isisd:isis/disable-three-way-handshake",
1513 NB_OP_MODIFY, no ? "true" : "false");
1514
1515 return nb_cli_apply_changes(vty, NULL);
1516 }
1517
1518 void cli_show_ip_isis_threeway_shake(struct vty *vty, struct lyd_node *dnode,
1519 bool show_defaults)
1520 {
1521 if (yang_dnode_get_bool(dnode, NULL))
1522 vty_out(vty, " no");
1523 vty_out(vty, " isis three-way-handshake\n");
1524 }
1525
1526 /*
1527 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1528 */
1529 DEFPY(isis_hello_padding, isis_hello_padding_cmd, "[no] isis hello padding",
1530 NO_STR
1531 "IS-IS routing protocol\n"
1532 "Add padding to IS-IS hello packets\n"
1533 "Pad hello packets\n")
1534 {
1535 nb_cli_enqueue_change(vty, "./frr-isisd:isis/hello/padding",
1536 NB_OP_MODIFY, no ? "false" : "true");
1537
1538 return nb_cli_apply_changes(vty, NULL);
1539 }
1540
1541 void cli_show_ip_isis_hello_padding(struct vty *vty, struct lyd_node *dnode,
1542 bool show_defaults)
1543 {
1544 if (!yang_dnode_get_bool(dnode, NULL))
1545 vty_out(vty, " no");
1546
1547 vty_out(vty, " isis hello padding\n");
1548 }
1549
1550 /*
1551 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval
1552 */
1553 DEFPY(csnp_interval, csnp_interval_cmd,
1554 "isis csnp-interval (1-600)$intv [level-1|level-2]$level",
1555 "IS-IS routing protocol\n"
1556 "Set CSNP interval in seconds\n"
1557 "CSNP interval value\n"
1558 "Specify interval for level-1 CSNPs\n"
1559 "Specify interval for level-2 CSNPs\n")
1560 {
1561 if (!level || strmatch(level, "level-1"))
1562 nb_cli_enqueue_change(vty,
1563 "./frr-isisd:isis/csnp-interval/level-1",
1564 NB_OP_MODIFY, intv_str);
1565 if (!level || strmatch(level, "level-2"))
1566 nb_cli_enqueue_change(vty,
1567 "./frr-isisd:isis/csnp-interval/level-2",
1568 NB_OP_MODIFY, intv_str);
1569
1570 return nb_cli_apply_changes(vty, NULL);
1571 }
1572
1573 DEFPY(no_csnp_interval, no_csnp_interval_cmd,
1574 "no isis csnp-interval [(1-600)] [level-1|level-2]$level",
1575 NO_STR
1576 "IS-IS routing protocol\n"
1577 "Set CSNP interval in seconds\n"
1578 "CSNP interval value\n"
1579 "Specify interval for level-1 CSNPs\n"
1580 "Specify interval for level-2 CSNPs\n")
1581 {
1582 if (!level || strmatch(level, "level-1"))
1583 nb_cli_enqueue_change(vty,
1584 "./frr-isisd:isis/csnp-interval/level-1",
1585 NB_OP_MODIFY, NULL);
1586 if (!level || strmatch(level, "level-2"))
1587 nb_cli_enqueue_change(vty,
1588 "./frr-isisd:isis/csnp-interval/level-2",
1589 NB_OP_MODIFY, NULL);
1590
1591 return nb_cli_apply_changes(vty, NULL);
1592 }
1593
1594 void cli_show_ip_isis_csnp_interval(struct vty *vty, struct lyd_node *dnode,
1595 bool show_defaults)
1596 {
1597 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
1598 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
1599
1600 if (strmatch(l1, l2))
1601 vty_out(vty, " isis csnp-interval %s\n", l1);
1602 else {
1603 vty_out(vty, " isis csnp-interval %s level-1\n", l1);
1604 vty_out(vty, " isis csnp-interval %s level-2\n", l2);
1605 }
1606 }
1607
1608 /*
1609 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval
1610 */
1611 DEFPY(psnp_interval, psnp_interval_cmd,
1612 "isis psnp-interval (1-120)$intv [level-1|level-2]$level",
1613 "IS-IS routing protocol\n"
1614 "Set PSNP interval in seconds\n"
1615 "PSNP interval value\n"
1616 "Specify interval for level-1 PSNPs\n"
1617 "Specify interval for level-2 PSNPs\n")
1618 {
1619 if (!level || strmatch(level, "level-1"))
1620 nb_cli_enqueue_change(vty,
1621 "./frr-isisd:isis/psnp-interval/level-1",
1622 NB_OP_MODIFY, intv_str);
1623 if (!level || strmatch(level, "level-2"))
1624 nb_cli_enqueue_change(vty,
1625 "./frr-isisd:isis/psnp-interval/level-2",
1626 NB_OP_MODIFY, intv_str);
1627
1628 return nb_cli_apply_changes(vty, NULL);
1629 }
1630
1631 DEFPY(no_psnp_interval, no_psnp_interval_cmd,
1632 "no isis psnp-interval [(1-120)] [level-1|level-2]$level",
1633 NO_STR
1634 "IS-IS routing protocol\n"
1635 "Set PSNP interval in seconds\n"
1636 "PSNP interval value\n"
1637 "Specify interval for level-1 PSNPs\n"
1638 "Specify interval for level-2 PSNPs\n")
1639 {
1640 if (!level || strmatch(level, "level-1"))
1641 nb_cli_enqueue_change(vty,
1642 "./frr-isisd:isis/psnp-interval/level-1",
1643 NB_OP_MODIFY, NULL);
1644 if (!level || strmatch(level, "level-2"))
1645 nb_cli_enqueue_change(vty,
1646 "./frr-isisd:isis/psnp-interval/level-2",
1647 NB_OP_MODIFY, NULL);
1648
1649 return nb_cli_apply_changes(vty, NULL);
1650 }
1651
1652 void cli_show_ip_isis_psnp_interval(struct vty *vty, struct lyd_node *dnode,
1653 bool show_defaults)
1654 {
1655 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
1656 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
1657
1658 if (strmatch(l1, l2))
1659 vty_out(vty, " isis psnp-interval %s\n", l1);
1660 else {
1661 vty_out(vty, " isis psnp-interval %s level-1\n", l1);
1662 vty_out(vty, " isis psnp-interval %s level-2\n", l2);
1663 }
1664 }
1665
1666 /*
1667 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology
1668 */
1669 DEFPY(circuit_topology, circuit_topology_cmd,
1670 "[no] isis topology"
1671 "<ipv4-unicast"
1672 "|ipv4-mgmt"
1673 "|ipv6-unicast"
1674 "|ipv4-multicast"
1675 "|ipv6-multicast"
1676 "|ipv6-mgmt"
1677 "|ipv6-dstsrc"
1678 ">$topology",
1679 NO_STR
1680 "IS-IS routing protocol\n"
1681 "Configure interface IS-IS topologies\n"
1682 "IPv4 unicast topology\n"
1683 "IPv4 management topology\n"
1684 "IPv6 unicast topology\n"
1685 "IPv4 multicast topology\n"
1686 "IPv6 multicast topology\n"
1687 "IPv6 management topology\n"
1688 "IPv6 dst-src topology\n")
1689 {
1690 nb_cli_enqueue_change(vty, ".", NB_OP_MODIFY, no ? "false" : "true");
1691
1692 if (strmatch(topology, "ipv4-mgmt"))
1693 return nb_cli_apply_changes(
1694 vty, "./frr-isisd:isis/multi-topology/ipv4-management");
1695 else if (strmatch(topology, "ipv6-mgmt"))
1696 return nb_cli_apply_changes(
1697 vty, "./frr-isisd:isis/multi-topology/ipv6-management");
1698 else
1699 return nb_cli_apply_changes(
1700 vty, "./frr-isisd:isis/multi-topology/%s", topology);
1701 }
1702
1703 void cli_show_ip_isis_mt_ipv4_unicast(struct vty *vty, struct lyd_node *dnode,
1704 bool show_defaults)
1705 {
1706 if (!yang_dnode_get_bool(dnode, NULL))
1707 vty_out(vty, " no");
1708 vty_out(vty, " isis topology ipv4-unicast\n");
1709 }
1710
1711 void cli_show_ip_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode,
1712 bool show_defaults)
1713 {
1714 if (!yang_dnode_get_bool(dnode, NULL))
1715 vty_out(vty, " no");
1716 vty_out(vty, " isis topology ipv4-multicast\n");
1717 }
1718
1719 void cli_show_ip_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode,
1720 bool show_defaults)
1721 {
1722 if (!yang_dnode_get_bool(dnode, NULL))
1723 vty_out(vty, " no");
1724 vty_out(vty, " isis topology ipv4-mgmt\n");
1725 }
1726
1727 void cli_show_ip_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode,
1728 bool show_defaults)
1729 {
1730 if (!yang_dnode_get_bool(dnode, NULL))
1731 vty_out(vty, " no");
1732 vty_out(vty, " isis topology ipv6-unicast\n");
1733 }
1734
1735 void cli_show_ip_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode,
1736 bool show_defaults)
1737 {
1738 if (!yang_dnode_get_bool(dnode, NULL))
1739 vty_out(vty, " no");
1740 vty_out(vty, " isis topology ipv6-multicast\n");
1741 }
1742
1743 void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
1744 bool show_defaults)
1745 {
1746 if (!yang_dnode_get_bool(dnode, NULL))
1747 vty_out(vty, " no");
1748 vty_out(vty, " isis topology ipv6-mgmt\n");
1749 }
1750
1751 void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
1752 bool show_defaults)
1753 {
1754 if (!yang_dnode_get_bool(dnode, NULL))
1755 vty_out(vty, " no");
1756 vty_out(vty, " isis topology ipv6-dstsrc\n");
1757 }
1758
1759 /*
1760 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1761 */
1762 DEFPY(isis_circuit_type, isis_circuit_type_cmd,
1763 "isis circuit-type <level-1|level-1-2|level-2-only>$type",
1764 "IS-IS routing protocol\n"
1765 "Configure circuit type for interface\n"
1766 "Level-1 only adjacencies are formed\n"
1767 "Level-1-2 adjacencies are formed\n"
1768 "Level-2 only adjacencies are formed\n")
1769 {
1770 nb_cli_enqueue_change(
1771 vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
1772 strmatch(type, "level-2-only") ? "level-2" : type);
1773
1774 return nb_cli_apply_changes(vty, NULL);
1775 }
1776
1777 DEFPY(no_isis_circuit_type, no_isis_circuit_type_cmd,
1778 "no isis circuit-type [level-1|level-1-2|level-2-only]",
1779 NO_STR
1780 "IS-IS routing protocol\n"
1781 "Configure circuit type for interface\n"
1782 "Level-1 only adjacencies are formed\n"
1783 "Level-1-2 adjacencies are formed\n"
1784 "Level-2 only adjacencies are formed\n")
1785 {
1786 const char *circ_type = NULL;
1787
1788 /*
1789 * Default value depends on whether the circuit is part of an area,
1790 * and the is-type of the area if there is one. So we need to do this
1791 * here.
1792 */
1793 pthread_rwlock_rdlock(&running_config->lock);
1794 {
1795 struct interface *ifp;
1796 struct isis_circuit *circuit;
1797
1798 ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
1799 if (!ifp)
1800 goto unlock;
1801
1802 circuit = circuit_scan_by_ifp(ifp);
1803 if (!circuit || circuit->state != C_STATE_UP)
1804 goto unlock;
1805
1806 switch (circuit->area->is_type) {
1807 case IS_LEVEL_1:
1808 circ_type = "level-1";
1809 break;
1810 case IS_LEVEL_2:
1811 circ_type = "level-2";
1812 break;
1813 case IS_LEVEL_1_AND_2:
1814 circ_type = "level-1-2";
1815 break;
1816 }
1817 }
1818 unlock:
1819 pthread_rwlock_unlock(&running_config->lock);
1820
1821 nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
1822 NB_OP_MODIFY, circ_type);
1823
1824 return nb_cli_apply_changes(vty, NULL);
1825 }
1826
1827 void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode,
1828 bool show_defaults)
1829 {
1830 int level = yang_dnode_get_enum(dnode, NULL);
1831
1832 switch (level) {
1833 case IS_LEVEL_1:
1834 vty_out(vty, " isis circuit-type level-1\n");
1835 break;
1836 case IS_LEVEL_2:
1837 vty_out(vty, " isis circuit-type level-2-only\n");
1838 break;
1839 case IS_LEVEL_1_AND_2:
1840 vty_out(vty, " isis circuit-type level-1-2\n");
1841 break;
1842 }
1843 }
1844
1845 /*
1846 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1847 */
1848 DEFPY(isis_network, isis_network_cmd, "[no] isis network point-to-point",
1849 NO_STR
1850 "IS-IS routing protocol\n"
1851 "Set network type\n"
1852 "point-to-point network type\n")
1853 {
1854 nb_cli_enqueue_change(vty, "./frr-isisd:isis/network-type",
1855 NB_OP_MODIFY,
1856 no ? "broadcast" : "point-to-point");
1857
1858 return nb_cli_apply_changes(vty, NULL);
1859 }
1860
1861 void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode,
1862 bool show_defaults)
1863 {
1864 if (yang_dnode_get_enum(dnode, NULL) != CIRCUIT_T_P2P)
1865 vty_out(vty, " no");
1866
1867 vty_out(vty, " isis network point-to-point\n");
1868 }
1869
1870 /*
1871 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority
1872 */
1873 DEFPY(isis_priority, isis_priority_cmd,
1874 "isis priority (0-127)$prio [level-1|level-2]$level",
1875 "IS-IS routing protocol\n"
1876 "Set priority for Designated Router election\n"
1877 "Priority value\n"
1878 "Specify priority for level-1 routing\n"
1879 "Specify priority for level-2 routing\n")
1880 {
1881 if (!level || strmatch(level, "level-1"))
1882 nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1",
1883 NB_OP_MODIFY, prio_str);
1884 if (!level || strmatch(level, "level-2"))
1885 nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2",
1886 NB_OP_MODIFY, prio_str);
1887
1888 return nb_cli_apply_changes(vty, NULL);
1889 }
1890
1891 DEFPY(no_isis_priority, no_isis_priority_cmd,
1892 "no isis priority [(0-127)] [level-1|level-2]$level",
1893 NO_STR
1894 "IS-IS routing protocol\n"
1895 "Set priority for Designated Router election\n"
1896 "Priority value\n"
1897 "Specify priority for level-1 routing\n"
1898 "Specify priority for level-2 routing\n")
1899 {
1900 if (!level || strmatch(level, "level-1"))
1901 nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1",
1902 NB_OP_MODIFY, NULL);
1903 if (!level || strmatch(level, "level-2"))
1904 nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2",
1905 NB_OP_MODIFY, NULL);
1906
1907 return nb_cli_apply_changes(vty, NULL);
1908 }
1909
1910 void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode,
1911 bool show_defaults)
1912 {
1913 const char *l1 = yang_dnode_get_string(dnode, "./level-1");
1914 const char *l2 = yang_dnode_get_string(dnode, "./level-2");
1915
1916 if (strmatch(l1, l2))
1917 vty_out(vty, " isis priority %s\n", l1);
1918 else {
1919 vty_out(vty, " isis priority %s level-1\n", l1);
1920 vty_out(vty, " isis priority %s level-2\n", l2);
1921 }
1922 }
1923
1924 /*
1925 * XPath: /frr-isisd:isis/instance/log-adjacency-changes
1926 */
1927 DEFPY(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes",
1928 NO_STR "Log changes in adjacency state\n")
1929 {
1930 nb_cli_enqueue_change(vty, "./log-adjacency-changes", NB_OP_MODIFY,
1931 no ? "false" : "true");
1932
1933 return nb_cli_apply_changes(vty, NULL);
1934 }
1935
1936 void cli_show_isis_log_adjacency(struct vty *vty, struct lyd_node *dnode,
1937 bool show_defaults)
1938 {
1939 if (!yang_dnode_get_bool(dnode, NULL))
1940 vty_out(vty, " no");
1941 vty_out(vty, " log-adjacency-changes\n");
1942 }
1943
1944 void isis_cli_init(void)
1945 {
1946 install_element(CONFIG_NODE, &router_isis_cmd);
1947 install_element(CONFIG_NODE, &no_router_isis_cmd);
1948
1949 install_element(INTERFACE_NODE, &ip_router_isis_cmd);
1950 install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
1951 install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
1952
1953 install_element(ISIS_NODE, &net_cmd);
1954
1955 install_element(ISIS_NODE, &is_type_cmd);
1956 install_element(ISIS_NODE, &no_is_type_cmd);
1957
1958 install_element(ISIS_NODE, &dynamic_hostname_cmd);
1959
1960 install_element(ISIS_NODE, &set_overload_bit_cmd);
1961 install_element(ISIS_NODE, &set_attached_bit_cmd);
1962
1963 install_element(ISIS_NODE, &metric_style_cmd);
1964 install_element(ISIS_NODE, &no_metric_style_cmd);
1965
1966 install_element(ISIS_NODE, &area_passwd_cmd);
1967 install_element(ISIS_NODE, &domain_passwd_cmd);
1968 install_element(ISIS_NODE, &no_area_passwd_cmd);
1969
1970 install_element(ISIS_NODE, &lsp_gen_interval_cmd);
1971 install_element(ISIS_NODE, &no_lsp_gen_interval_cmd);
1972 install_element(ISIS_NODE, &lsp_refresh_interval_cmd);
1973 install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd);
1974 install_element(ISIS_NODE, &max_lsp_lifetime_cmd);
1975 install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd);
1976 install_element(ISIS_NODE, &area_lsp_mtu_cmd);
1977 install_element(ISIS_NODE, &no_area_lsp_mtu_cmd);
1978
1979 install_element(ISIS_NODE, &spf_interval_cmd);
1980 install_element(ISIS_NODE, &no_spf_interval_cmd);
1981 install_element(ISIS_NODE, &spf_delay_ietf_cmd);
1982 install_element(ISIS_NODE, &no_spf_delay_ietf_cmd);
1983
1984 install_element(ISIS_NODE, &area_purge_originator_cmd);
1985
1986 install_element(ISIS_NODE, &isis_mpls_te_on_cmd);
1987 install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd);
1988 install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd);
1989 install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_cmd);
1990 install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
1991
1992 install_element(ISIS_NODE, &isis_default_originate_cmd);
1993 install_element(ISIS_NODE, &isis_redistribute_cmd);
1994
1995 install_element(ISIS_NODE, &isis_topology_cmd);
1996
1997 install_element(INTERFACE_NODE, &isis_passive_cmd);
1998
1999 install_element(INTERFACE_NODE, &isis_passwd_cmd);
2000 install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
2001
2002 install_element(INTERFACE_NODE, &isis_metric_cmd);
2003 install_element(INTERFACE_NODE, &no_isis_metric_cmd);
2004
2005 install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
2006 install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
2007
2008 install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
2009 install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
2010
2011 install_element(INTERFACE_NODE, &isis_threeway_adj_cmd);
2012
2013 install_element(INTERFACE_NODE, &isis_hello_padding_cmd);
2014
2015 install_element(INTERFACE_NODE, &csnp_interval_cmd);
2016 install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
2017
2018 install_element(INTERFACE_NODE, &psnp_interval_cmd);
2019 install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
2020
2021 install_element(INTERFACE_NODE, &circuit_topology_cmd);
2022
2023 install_element(INTERFACE_NODE, &isis_circuit_type_cmd);
2024 install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd);
2025
2026 install_element(INTERFACE_NODE, &isis_network_cmd);
2027
2028 install_element(INTERFACE_NODE, &isis_priority_cmd);
2029 install_element(INTERFACE_NODE, &no_isis_priority_cmd);
2030
2031 install_element(ISIS_NODE, &log_adj_changes_cmd);
2032 }
2033
2034 #endif /* ifndef FABRICD */