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