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