]> git.proxmox.com Git - mirror_frr.git/blob - bfdd/bfdd_cli.c
Merge pull request #11517 from louis-6wind/advert-map
[mirror_frr.git] / bfdd / bfdd_cli.c
1 /*
2 * BFD daemon CLI implementation.
3 *
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
5 * Rafael Zalamena
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23 #include <zebra.h>
24
25 #include "lib/command.h"
26 #include "lib/log.h"
27 #include "lib/northbound_cli.h"
28
29 #ifndef VTYSH_EXTRACT_PL
30 #include "bfdd/bfdd_cli_clippy.c"
31 #endif /* VTYSH_EXTRACT_PL */
32
33 #include "bfd.h"
34 #include "bfdd_nb.h"
35
36 /*
37 * Definitions.
38 */
39 #define PEER_STR "Configure peer\n"
40 #define INTERFACE_NAME_STR "Configure interface name to use\n"
41 #define PEER_IPV4_STR "IPv4 peer address\n"
42 #define PEER_IPV6_STR "IPv6 peer address\n"
43 #define MHOP_STR "Configure multihop\n"
44 #define LOCAL_STR "Configure local address\n"
45 #define LOCAL_IPV4_STR "IPv4 local address\n"
46 #define LOCAL_IPV6_STR "IPv6 local address\n"
47 #define LOCAL_INTF_STR "Configure local interface name to use\n"
48 #define VRF_STR "Configure VRF\n"
49 #define VRF_NAME_STR "Configure VRF name\n"
50
51 /*
52 * Prototypes.
53 */
54 static bool
55 bfd_cli_is_single_hop(struct vty *vty)
56 {
57 return strstr(VTY_CURR_XPATH, "/single-hop") != NULL;
58 }
59
60 static bool
61 bfd_cli_is_profile(struct vty *vty)
62 {
63 return strstr(VTY_CURR_XPATH, "/bfd/profile") != NULL;
64 }
65
66 /*
67 * Functions.
68 */
69 DEFPY_YANG_NOSH(
70 bfd_enter, bfd_enter_cmd,
71 "bfd",
72 "Configure BFD peers\n")
73 {
74 int ret;
75
76 nb_cli_enqueue_change(vty, "/frr-bfdd:bfdd/bfd", NB_OP_CREATE, NULL);
77 ret = nb_cli_apply_changes(vty, NULL);
78 if (ret == CMD_SUCCESS)
79 VTY_PUSH_XPATH(BFD_NODE, "/frr-bfdd:bfdd/bfd");
80
81 return ret;
82 }
83
84 DEFUN_YANG(
85 bfd_config_reset, bfd_config_reset_cmd,
86 "no bfd",
87 NO_STR
88 "Configure BFD peers\n")
89 {
90 nb_cli_enqueue_change(vty, "/frr-bfdd:bfdd/bfd", NB_OP_DESTROY, NULL);
91 return nb_cli_apply_changes(vty, NULL);
92 }
93
94 void bfd_cli_show_header(struct vty *vty,
95 const struct lyd_node *dnode
96 __attribute__((__unused__)),
97 bool show_defaults __attribute__((__unused__)))
98 {
99 vty_out(vty, "!\nbfd\n");
100 }
101
102 void bfd_cli_show_header_end(struct vty *vty, const struct lyd_node *dnode
103 __attribute__((__unused__)))
104 {
105 vty_out(vty, "exit\n");
106 vty_out(vty, "!\n");
107 }
108
109 DEFPY_YANG_NOSH(
110 bfd_peer_enter, bfd_peer_enter_cmd,
111 "peer <A.B.C.D|X:X::X:X> [{multihop$multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME$ifname|vrf NAME}]",
112 PEER_STR
113 PEER_IPV4_STR
114 PEER_IPV6_STR
115 MHOP_STR
116 LOCAL_STR
117 LOCAL_IPV4_STR
118 LOCAL_IPV6_STR
119 INTERFACE_STR
120 LOCAL_INTF_STR
121 VRF_STR
122 VRF_NAME_STR)
123 {
124 int ret, slen;
125 char source_str[INET6_ADDRSTRLEN + 32];
126 char xpath[XPATH_MAXLEN], xpath_srcaddr[XPATH_MAXLEN + 32];
127
128 if (multihop) {
129 if (!local_address_str) {
130 vty_out(vty,
131 "%% local-address is required when using multihop\n");
132 return CMD_WARNING_CONFIG_FAILED;
133 }
134 if (ifname) {
135 vty_out(vty,
136 "%% interface is prohibited when using multihop\n");
137 return CMD_WARNING_CONFIG_FAILED;
138 }
139 snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
140 local_address_str);
141 } else
142 source_str[0] = 0;
143
144 slen = snprintf(xpath, sizeof(xpath),
145 "/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
146 multihop ? "multi-hop" : "single-hop", source_str,
147 peer_str);
148 if (ifname)
149 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
150 "[interface='%s']", ifname);
151 else if (!multihop)
152 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
153 "[interface='*']");
154 if (vrf)
155 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']", vrf);
156 else
157 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']",
158 VRF_DEFAULT_NAME);
159
160 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
161 if (multihop == NULL && local_address_str != NULL) {
162 snprintf(xpath_srcaddr, sizeof(xpath_srcaddr),
163 "%s/source-addr", xpath);
164 nb_cli_enqueue_change(vty, xpath_srcaddr, NB_OP_MODIFY,
165 local_address_str);
166 }
167
168 /* Apply settings immediately. */
169 ret = nb_cli_apply_changes(vty, NULL);
170 if (ret == CMD_SUCCESS)
171 VTY_PUSH_XPATH(BFD_PEER_NODE, xpath);
172
173 return ret;
174 }
175
176 DEFPY_YANG(
177 bfd_no_peer, bfd_no_peer_cmd,
178 "no peer <A.B.C.D|X:X::X:X> [{multihop$multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME$ifname|vrf NAME}]",
179 NO_STR
180 PEER_STR
181 PEER_IPV4_STR
182 PEER_IPV6_STR
183 MHOP_STR
184 LOCAL_STR
185 LOCAL_IPV4_STR
186 LOCAL_IPV6_STR
187 INTERFACE_STR
188 LOCAL_INTF_STR
189 VRF_STR
190 VRF_NAME_STR)
191 {
192 int slen;
193 char xpath[XPATH_MAXLEN];
194 char source_str[INET6_ADDRSTRLEN + 32];
195
196 if (multihop) {
197 if (!local_address_str) {
198 vty_out(vty,
199 "%% local-address is required when using multihop\n");
200 return CMD_WARNING_CONFIG_FAILED;
201 }
202 if (ifname) {
203 vty_out(vty,
204 "%% interface is prohibited when using multihop\n");
205 return CMD_WARNING_CONFIG_FAILED;
206 }
207 snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
208 local_address_str);
209 } else
210 source_str[0] = 0;
211
212 slen = snprintf(xpath, sizeof(xpath),
213 "/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
214 multihop ? "multi-hop" : "single-hop", source_str,
215 peer_str);
216 if (ifname)
217 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
218 "[interface='%s']", ifname);
219 else if (!multihop)
220 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
221 "[interface='*']");
222 if (vrf)
223 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']", vrf);
224 else
225 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']",
226 VRF_DEFAULT_NAME);
227
228 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
229
230 /* Apply settings immediatly. */
231 return nb_cli_apply_changes(vty, NULL);
232 }
233
234 static void _bfd_cli_show_peer(struct vty *vty, const struct lyd_node *dnode,
235 bool show_defaults __attribute__((__unused__)),
236 bool mhop)
237 {
238 const char *vrf = yang_dnode_get_string(dnode, "./vrf");
239
240 vty_out(vty, " peer %s",
241 yang_dnode_get_string(dnode, "./dest-addr"));
242
243 if (mhop)
244 vty_out(vty, " multihop");
245
246 if (yang_dnode_exists(dnode, "./source-addr"))
247 vty_out(vty, " local-address %s",
248 yang_dnode_get_string(dnode, "./source-addr"));
249
250 if (strcmp(vrf, VRF_DEFAULT_NAME))
251 vty_out(vty, " vrf %s", vrf);
252
253 if (!mhop) {
254 const char *ifname =
255 yang_dnode_get_string(dnode, "./interface");
256 if (strcmp(ifname, "*"))
257 vty_out(vty, " interface %s", ifname);
258 }
259
260 vty_out(vty, "\n");
261 }
262
263 void bfd_cli_show_single_hop_peer(struct vty *vty, const struct lyd_node *dnode,
264 bool show_defaults)
265 {
266 _bfd_cli_show_peer(vty, dnode, show_defaults, false);
267 }
268
269 void bfd_cli_show_multi_hop_peer(struct vty *vty, const struct lyd_node *dnode,
270 bool show_defaults)
271 {
272 _bfd_cli_show_peer(vty, dnode, show_defaults, true);
273 }
274
275 void bfd_cli_show_peer_end(struct vty *vty, const struct lyd_node *dnode
276 __attribute__((__unused__)))
277 {
278 vty_out(vty, " exit\n");
279 vty_out(vty, " !\n");
280 }
281
282 DEFPY_YANG(
283 bfd_peer_shutdown, bfd_peer_shutdown_cmd,
284 "[no] shutdown",
285 NO_STR
286 "Disable BFD peer\n")
287 {
288 nb_cli_enqueue_change(vty, "./administrative-down", NB_OP_MODIFY,
289 no ? "false" : "true");
290 return nb_cli_apply_changes(vty, NULL);
291 }
292
293 void bfd_cli_show_shutdown(struct vty *vty, const struct lyd_node *dnode,
294 bool show_defaults)
295 {
296 vty_out(vty, " %sshutdown\n",
297 yang_dnode_get_bool(dnode, NULL) ? "" : "no ");
298 }
299
300 DEFPY_YANG(
301 bfd_peer_passive, bfd_peer_passive_cmd,
302 "[no] passive-mode",
303 NO_STR
304 "Don't attempt to start sessions\n")
305 {
306 nb_cli_enqueue_change(vty, "./passive-mode", NB_OP_MODIFY,
307 no ? "false" : "true");
308 return nb_cli_apply_changes(vty, NULL);
309 }
310
311 void bfd_cli_show_passive(struct vty *vty, const struct lyd_node *dnode,
312 bool show_defaults)
313 {
314 vty_out(vty, " %spassive-mode\n",
315 yang_dnode_get_bool(dnode, NULL) ? "" : "no ");
316 }
317
318 DEFPY_YANG(
319 bfd_peer_minimum_ttl, bfd_peer_minimum_ttl_cmd,
320 "[no] minimum-ttl (1-254)$ttl",
321 NO_STR
322 "Expect packets with at least this TTL\n"
323 "Minimum TTL expected\n")
324 {
325 if (bfd_cli_is_single_hop(vty)) {
326 vty_out(vty, "%% Minimum TTL is only available for multi hop sessions.\n");
327 return CMD_WARNING_CONFIG_FAILED;
328 }
329
330 if (no)
331 nb_cli_enqueue_change(vty, "./minimum-ttl", NB_OP_DESTROY,
332 NULL);
333 else
334 nb_cli_enqueue_change(vty, "./minimum-ttl", NB_OP_MODIFY,
335 ttl_str);
336 return nb_cli_apply_changes(vty, NULL);
337 }
338
339 DEFPY_YANG(
340 no_bfd_peer_minimum_ttl, no_bfd_peer_minimum_ttl_cmd,
341 "no minimum-ttl",
342 NO_STR
343 "Expect packets with at least this TTL\n")
344 {
345 nb_cli_enqueue_change(vty, "./minimum-ttl", NB_OP_DESTROY, NULL);
346 return nb_cli_apply_changes(vty, NULL);
347 }
348
349 void bfd_cli_show_minimum_ttl(struct vty *vty, const struct lyd_node *dnode,
350 bool show_defaults)
351 {
352 vty_out(vty, " minimum-ttl %s\n", yang_dnode_get_string(dnode, NULL));
353 }
354
355 DEFPY_YANG(
356 bfd_peer_mult, bfd_peer_mult_cmd,
357 "detect-multiplier (2-255)$multiplier",
358 "Configure peer detection multiplier\n"
359 "Configure peer detection multiplier value\n")
360 {
361 nb_cli_enqueue_change(vty, "./detection-multiplier", NB_OP_MODIFY,
362 multiplier_str);
363 return nb_cli_apply_changes(vty, NULL);
364 }
365
366 void bfd_cli_show_mult(struct vty *vty, const struct lyd_node *dnode,
367 bool show_defaults)
368 {
369 vty_out(vty, " detect-multiplier %s\n",
370 yang_dnode_get_string(dnode, NULL));
371 }
372
373 DEFPY_YANG(
374 bfd_peer_rx, bfd_peer_rx_cmd,
375 "receive-interval (10-60000)$interval",
376 "Configure peer receive interval\n"
377 "Configure peer receive interval value in milliseconds\n")
378 {
379 char value[32];
380
381 snprintf(value, sizeof(value), "%ld", interval * 1000);
382 nb_cli_enqueue_change(vty, "./required-receive-interval", NB_OP_MODIFY,
383 value);
384
385 return nb_cli_apply_changes(vty, NULL);
386 }
387
388 void bfd_cli_show_rx(struct vty *vty, const struct lyd_node *dnode,
389 bool show_defaults)
390 {
391 uint32_t value = yang_dnode_get_uint32(dnode, NULL);
392
393 vty_out(vty, " receive-interval %u\n", value / 1000);
394 }
395
396 DEFPY_YANG(
397 bfd_peer_tx, bfd_peer_tx_cmd,
398 "transmit-interval (10-60000)$interval",
399 "Configure peer transmit interval\n"
400 "Configure peer transmit interval value in milliseconds\n")
401 {
402 char value[32];
403
404 snprintf(value, sizeof(value), "%ld", interval * 1000);
405 nb_cli_enqueue_change(vty, "./desired-transmission-interval",
406 NB_OP_MODIFY, value);
407
408 return nb_cli_apply_changes(vty, NULL);
409 }
410
411 void bfd_cli_show_tx(struct vty *vty, const struct lyd_node *dnode,
412 bool show_defaults)
413 {
414 uint32_t value = yang_dnode_get_uint32(dnode, NULL);
415
416 vty_out(vty, " transmit-interval %u\n", value / 1000);
417 }
418
419 DEFPY_YANG(
420 bfd_peer_echo, bfd_peer_echo_cmd,
421 "[no] echo-mode",
422 NO_STR
423 "Configure echo mode\n")
424 {
425 if (!bfd_cli_is_profile(vty) && !bfd_cli_is_single_hop(vty)) {
426 vty_out(vty,
427 "%% Echo mode is only available for single hop sessions.\n");
428 return CMD_WARNING_CONFIG_FAILED;
429 }
430
431 if (!no && !bglobal.bg_use_dplane) {
432 #ifdef BFD_LINUX
433 vty_out(vty,
434 "%% Echo mode works correctly for IPv4, but only works when the peer is also FRR for IPv6.\n");
435 #else
436 vty_out(vty,
437 "%% Current implementation of echo mode works only when the peer is also FRR.\n");
438 #endif /* BFD_LINUX */
439 }
440
441 nb_cli_enqueue_change(vty, "./echo-mode", NB_OP_MODIFY,
442 no ? "false" : "true");
443 return nb_cli_apply_changes(vty, NULL);
444 }
445
446 void bfd_cli_show_echo(struct vty *vty, const struct lyd_node *dnode,
447 bool show_defaults)
448 {
449 vty_out(vty, " %secho-mode\n",
450 yang_dnode_get_bool(dnode, NULL) ? "" : "no ");
451 }
452
453 DEFPY_YANG(
454 bfd_peer_echo_interval, bfd_peer_echo_interval_cmd,
455 "echo-interval (10-60000)$interval",
456 "Configure peer echo intervals\n"
457 "Configure peer echo rx/tx intervals value in milliseconds\n")
458 {
459 char value[32];
460
461 if (!bfd_cli_is_profile(vty) && !bfd_cli_is_single_hop(vty)) {
462 vty_out(vty, "%% Echo mode is only available for single hop sessions.\n");
463 return CMD_WARNING_CONFIG_FAILED;
464 }
465
466 snprintf(value, sizeof(value), "%ld", interval * 1000);
467 nb_cli_enqueue_change(vty, "./desired-echo-transmission-interval",
468 NB_OP_MODIFY, value);
469 nb_cli_enqueue_change(vty, "./required-echo-receive-interval",
470 NB_OP_MODIFY, value);
471
472 return nb_cli_apply_changes(vty, NULL);
473 }
474
475 DEFPY_YANG(
476 bfd_peer_echo_transmit_interval, bfd_peer_echo_transmit_interval_cmd,
477 "echo transmit-interval (10-60000)$interval",
478 "Configure peer echo intervals\n"
479 "Configure desired transmit interval\n"
480 "Configure interval value in milliseconds\n")
481 {
482 char value[32];
483
484 if (!bfd_cli_is_profile(vty) && !bfd_cli_is_single_hop(vty)) {
485 vty_out(vty, "%% Echo mode is only available for single hop sessions.\n");
486 return CMD_WARNING_CONFIG_FAILED;
487 }
488
489 snprintf(value, sizeof(value), "%ld", interval * 1000);
490 nb_cli_enqueue_change(vty, "./desired-echo-transmission-interval",
491 NB_OP_MODIFY, value);
492
493 return nb_cli_apply_changes(vty, NULL);
494 }
495
496 void bfd_cli_show_desired_echo_transmission_interval(
497 struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
498 {
499 uint32_t value = yang_dnode_get_uint32(dnode, NULL);
500
501 vty_out(vty, " echo transmit-interval %u\n", value / 1000);
502 }
503
504 DEFPY_YANG(
505 bfd_peer_echo_receive_interval, bfd_peer_echo_receive_interval_cmd,
506 "echo receive-interval <disabled$disabled|(10-60000)$interval>",
507 "Configure peer echo intervals\n"
508 "Configure required receive interval\n"
509 "Disable echo packets receive\n"
510 "Configure interval value in milliseconds\n")
511 {
512 char value[32];
513
514 if (!bfd_cli_is_profile(vty) && !bfd_cli_is_single_hop(vty)) {
515 vty_out(vty, "%% Echo mode is only available for single hop sessions.\n");
516 return CMD_WARNING_CONFIG_FAILED;
517 }
518
519 if (disabled)
520 snprintf(value, sizeof(value), "0");
521 else
522 snprintf(value, sizeof(value), "%ld", interval * 1000);
523
524 nb_cli_enqueue_change(vty, "./required-echo-receive-interval",
525 NB_OP_MODIFY, value);
526
527 return nb_cli_apply_changes(vty, NULL);
528 }
529
530 void bfd_cli_show_required_echo_receive_interval(struct vty *vty,
531 const struct lyd_node *dnode,
532 bool show_defaults)
533 {
534 uint32_t value = yang_dnode_get_uint32(dnode, NULL);
535
536 if (value)
537 vty_out(vty, " echo receive-interval %u\n", value / 1000);
538 else
539 vty_out(vty, " echo receive-interval disabled\n");
540 }
541
542 /*
543 * Profile commands.
544 */
545 DEFPY_YANG_NOSH(bfd_profile, bfd_profile_cmd,
546 "profile BFDPROF$name",
547 BFD_PROFILE_STR
548 BFD_PROFILE_NAME_STR)
549 {
550 char xpath[XPATH_MAXLEN];
551 int rv;
552
553 snprintf(xpath, sizeof(xpath), "/frr-bfdd:bfdd/bfd/profile[name='%s']",
554 name);
555
556 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
557
558 /* Apply settings immediately. */
559 rv = nb_cli_apply_changes(vty, NULL);
560 if (rv == CMD_SUCCESS)
561 VTY_PUSH_XPATH(BFD_PROFILE_NODE, xpath);
562
563 return CMD_SUCCESS;
564 }
565
566 DEFPY_YANG(no_bfd_profile, no_bfd_profile_cmd,
567 "no profile BFDPROF$name",
568 NO_STR
569 BFD_PROFILE_STR
570 BFD_PROFILE_NAME_STR)
571 {
572 char xpath[XPATH_MAXLEN];
573
574 snprintf(xpath, sizeof(xpath), "/frr-bfdd:bfdd/bfd/profile[name='%s']",
575 name);
576
577 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
578
579 /* Apply settings immediately. */
580 return nb_cli_apply_changes(vty, NULL);
581 }
582
583 void bfd_cli_show_profile(struct vty *vty, const struct lyd_node *dnode,
584 bool show_defaults)
585 {
586 vty_out(vty, " profile %s\n", yang_dnode_get_string(dnode, "./name"));
587 }
588
589 ALIAS_YANG(bfd_peer_mult, bfd_profile_mult_cmd,
590 "detect-multiplier (2-255)$multiplier",
591 "Configure peer detection multiplier\n"
592 "Configure peer detection multiplier value\n")
593
594 ALIAS_YANG(bfd_peer_tx, bfd_profile_tx_cmd,
595 "transmit-interval (10-60000)$interval",
596 "Configure peer transmit interval\n"
597 "Configure peer transmit interval value in milliseconds\n")
598
599 ALIAS_YANG(bfd_peer_rx, bfd_profile_rx_cmd,
600 "receive-interval (10-60000)$interval",
601 "Configure peer receive interval\n"
602 "Configure peer receive interval value in milliseconds\n")
603
604 ALIAS_YANG(bfd_peer_shutdown, bfd_profile_shutdown_cmd,
605 "[no] shutdown",
606 NO_STR
607 "Disable BFD peer\n")
608
609 ALIAS_YANG(bfd_peer_passive, bfd_profile_passive_cmd,
610 "[no] passive-mode",
611 NO_STR
612 "Don't attempt to start sessions\n")
613
614 ALIAS_YANG(bfd_peer_minimum_ttl, bfd_profile_minimum_ttl_cmd,
615 "[no] minimum-ttl (1-254)$ttl",
616 NO_STR
617 "Expect packets with at least this TTL\n"
618 "Minimum TTL expected\n")
619
620 ALIAS_YANG(no_bfd_peer_minimum_ttl, no_bfd_profile_minimum_ttl_cmd,
621 "no minimum-ttl",
622 NO_STR
623 "Expect packets with at least this TTL\n")
624
625 ALIAS_YANG(bfd_peer_echo, bfd_profile_echo_cmd,
626 "[no] echo-mode",
627 NO_STR
628 "Configure echo mode\n")
629
630 ALIAS_YANG(bfd_peer_echo_interval, bfd_profile_echo_interval_cmd,
631 "echo-interval (10-60000)$interval",
632 "Configure peer echo interval\n"
633 "Configure peer echo interval value in milliseconds\n")
634
635 ALIAS_YANG(
636 bfd_peer_echo_transmit_interval, bfd_profile_echo_transmit_interval_cmd,
637 "echo transmit-interval (10-60000)$interval",
638 "Configure peer echo intervals\n"
639 "Configure desired transmit interval\n"
640 "Configure interval value in milliseconds\n")
641
642 ALIAS_YANG(
643 bfd_peer_echo_receive_interval, bfd_profile_echo_receive_interval_cmd,
644 "echo receive-interval <disabled$disabled|(10-60000)$interval>",
645 "Configure peer echo intervals\n"
646 "Configure required receive interval\n"
647 "Disable echo packets receive\n"
648 "Configure interval value in milliseconds\n")
649
650 DEFPY_YANG(bfd_peer_profile, bfd_peer_profile_cmd,
651 "[no] profile BFDPROF$pname",
652 NO_STR
653 "Use BFD profile settings\n"
654 BFD_PROFILE_NAME_STR)
655 {
656 if (no)
657 nb_cli_enqueue_change(vty, "./profile", NB_OP_DESTROY, NULL);
658 else
659 nb_cli_enqueue_change(vty, "./profile", NB_OP_MODIFY, pname);
660
661 return nb_cli_apply_changes(vty, NULL);
662 }
663
664 void bfd_cli_peer_profile_show(struct vty *vty, const struct lyd_node *dnode,
665 bool show_defaults)
666 {
667 vty_out(vty, " profile %s\n", yang_dnode_get_string(dnode, NULL));
668 }
669
670 struct cmd_node bfd_profile_node = {
671 .name = "bfd profile",
672 .node = BFD_PROFILE_NODE,
673 .parent_node = BFD_NODE,
674 .prompt = "%s(config-bfd-profile)# ",
675 };
676
677 static void bfd_profile_var(vector comps, struct cmd_token *token)
678 {
679 extern struct bfdproflist bplist;
680 struct bfd_profile *bp;
681
682 TAILQ_FOREACH (bp, &bplist, entry) {
683 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bp->name));
684 }
685 }
686
687 static const struct cmd_variable_handler bfd_vars[] = {
688 {.tokenname = "BFDPROF", .completions = bfd_profile_var},
689 {.completions = NULL}
690 };
691
692 void
693 bfdd_cli_init(void)
694 {
695 install_element(CONFIG_NODE, &bfd_enter_cmd);
696 install_element(CONFIG_NODE, &bfd_config_reset_cmd);
697
698 install_element(BFD_NODE, &bfd_peer_enter_cmd);
699 install_element(BFD_NODE, &bfd_no_peer_cmd);
700
701 install_element(BFD_PEER_NODE, &bfd_peer_shutdown_cmd);
702 install_element(BFD_PEER_NODE, &bfd_peer_mult_cmd);
703 install_element(BFD_PEER_NODE, &bfd_peer_rx_cmd);
704 install_element(BFD_PEER_NODE, &bfd_peer_tx_cmd);
705 install_element(BFD_PEER_NODE, &bfd_peer_echo_cmd);
706 install_element(BFD_PEER_NODE, &bfd_peer_echo_interval_cmd);
707 install_element(BFD_PEER_NODE, &bfd_peer_echo_transmit_interval_cmd);
708 install_element(BFD_PEER_NODE, &bfd_peer_echo_receive_interval_cmd);
709 install_element(BFD_PEER_NODE, &bfd_peer_profile_cmd);
710 install_element(BFD_PEER_NODE, &bfd_peer_passive_cmd);
711 install_element(BFD_PEER_NODE, &bfd_peer_minimum_ttl_cmd);
712 install_element(BFD_PEER_NODE, &no_bfd_peer_minimum_ttl_cmd);
713
714 /* Profile commands. */
715 cmd_variable_handler_register(bfd_vars);
716
717 install_node(&bfd_profile_node);
718 install_default(BFD_PROFILE_NODE);
719
720 install_element(BFD_NODE, &bfd_profile_cmd);
721 install_element(BFD_NODE, &no_bfd_profile_cmd);
722
723 install_element(BFD_PROFILE_NODE, &bfd_profile_mult_cmd);
724 install_element(BFD_PROFILE_NODE, &bfd_profile_tx_cmd);
725 install_element(BFD_PROFILE_NODE, &bfd_profile_rx_cmd);
726 install_element(BFD_PROFILE_NODE, &bfd_profile_shutdown_cmd);
727 install_element(BFD_PROFILE_NODE, &bfd_profile_echo_cmd);
728 install_element(BFD_PROFILE_NODE, &bfd_profile_echo_interval_cmd);
729 install_element(BFD_PROFILE_NODE, &bfd_profile_echo_transmit_interval_cmd);
730 install_element(BFD_PROFILE_NODE, &bfd_profile_echo_receive_interval_cmd);
731 install_element(BFD_PROFILE_NODE, &bfd_profile_passive_cmd);
732 install_element(BFD_PROFILE_NODE, &bfd_profile_minimum_ttl_cmd);
733 install_element(BFD_PROFILE_NODE, &no_bfd_profile_minimum_ttl_cmd);
734 }