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