2 * BFD daemon CLI implementation.
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
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.
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.
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
25 #include "lib/command.h"
27 #include "lib/northbound_cli.h"
29 #ifndef VTYSH_EXTRACT_PL
30 #include "bfdd/bfdd_cli_clippy.c"
31 #endif /* VTYSH_EXTRACT_PL */
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"
59 bfd_enter
, bfd_enter_cmd
,
61 "Configure BFD peers\n")
65 nb_cli_enqueue_change(vty
, "/frr-bfdd:bfdd/bfd", NB_OP_CREATE
, NULL
);
66 ret
= nb_cli_apply_changes(vty
, NULL
);
67 if (ret
== CMD_SUCCESS
)
68 VTY_PUSH_XPATH(BFD_NODE
, "/frr-bfdd:bfdd/bfd");
74 bfd_config_reset
, bfd_config_reset_cmd
,
77 "Configure BFD peers\n")
79 nb_cli_enqueue_change(vty
, "/frr-bfdd:bfdd/bfd", NB_OP_DESTROY
, NULL
);
80 return nb_cli_apply_changes(vty
, NULL
);
83 void bfd_cli_show_header(struct vty
*vty
,
84 struct lyd_node
*dnode
__attribute__((__unused__
)),
85 bool show_defaults
__attribute__((__unused__
)))
87 vty_out(vty
, "!\nbfd\n");
90 void bfd_cli_show_header_end(struct vty
*vty
,
91 struct lyd_node
*dnode
__attribute__((__unused__
)))
97 bfd_peer_enter
, bfd_peer_enter_cmd
,
98 "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 char source_str
[INET6_ADDRSTRLEN
+ 32];
113 char xpath
[XPATH_MAXLEN
], xpath_srcaddr
[XPATH_MAXLEN
+ 32];
116 snprintf(source_str
, sizeof(source_str
), "[source-addr='%s']",
121 slen
= snprintf(xpath
, sizeof(xpath
),
122 "/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
123 multihop
? "multi-hop" : "single-hop", source_str
,
126 slen
+= snprintf(xpath
+ slen
, sizeof(xpath
) - slen
,
127 "[interface='%s']", ifname
);
129 slen
+= snprintf(xpath
+ slen
, sizeof(xpath
) - slen
,
132 snprintf(xpath
+ slen
, sizeof(xpath
) - slen
, "[vrf='%s']", vrf
);
134 snprintf(xpath
+ slen
, sizeof(xpath
) - slen
, "[vrf='%s']",
137 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
138 if (multihop
== NULL
&& local_address_str
!= NULL
) {
139 snprintf(xpath_srcaddr
, sizeof(xpath_srcaddr
),
140 "%s/source-addr", xpath
);
141 nb_cli_enqueue_change(vty
, xpath_srcaddr
, NB_OP_MODIFY
,
145 /* Apply settings immediately. */
146 ret
= nb_cli_apply_changes(vty
, NULL
);
147 if (ret
== CMD_SUCCESS
)
148 VTY_PUSH_XPATH(BFD_PEER_NODE
, xpath
);
154 bfd_no_peer
, bfd_no_peer_cmd
,
155 "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}]",
170 char xpath
[XPATH_MAXLEN
];
171 char source_str
[INET6_ADDRSTRLEN
+ 32];
174 snprintf(source_str
, sizeof(source_str
), "[source-addr='%s']",
179 slen
= snprintf(xpath
, sizeof(xpath
),
180 "/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
181 multihop
? "multi-hop" : "single-hop", source_str
,
184 slen
+= snprintf(xpath
+ slen
, sizeof(xpath
) - slen
,
185 "[interface='%s']", ifname
);
187 slen
+= snprintf(xpath
+ slen
, sizeof(xpath
) - slen
,
190 snprintf(xpath
+ slen
, sizeof(xpath
) - slen
, "[vrf='%s']", vrf
);
192 snprintf(xpath
+ slen
, sizeof(xpath
) - slen
, "[vrf='%s']",
195 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
197 /* Apply settings immediatly. */
198 return nb_cli_apply_changes(vty
, NULL
);
201 static void _bfd_cli_show_peer(struct vty
*vty
, struct lyd_node
*dnode
,
202 bool show_defaults
__attribute__((__unused__
)),
205 const char *vrf
= yang_dnode_get_string(dnode
, "./vrf");
206 const char *ifname
= yang_dnode_get_string(dnode
, "./interface");
208 vty_out(vty
, " peer %s",
209 yang_dnode_get_string(dnode
, "./dest-addr"));
212 vty_out(vty
, " multihop");
214 if (yang_dnode_exists(dnode
, "./source-addr"))
215 vty_out(vty
, " local-address %s",
216 yang_dnode_get_string(dnode
, "./source-addr"));
218 if (strcmp(vrf
, VRF_DEFAULT_NAME
))
219 vty_out(vty
, " vrf %s", vrf
);
221 if (strcmp(ifname
, "*"))
222 vty_out(vty
, " interface %s", ifname
);
227 void bfd_cli_show_single_hop_peer(struct vty
*vty
,
228 struct lyd_node
*dnode
,
231 _bfd_cli_show_peer(vty
, dnode
, show_defaults
, false);
234 void bfd_cli_show_multi_hop_peer(struct vty
*vty
,
235 struct lyd_node
*dnode
,
238 _bfd_cli_show_peer(vty
, dnode
, show_defaults
, true);
241 void bfd_cli_show_peer_end(struct vty
*vty
,
242 struct lyd_node
*dnode
__attribute__((__unused__
)))
244 vty_out(vty
, " !\n");
248 bfd_peer_shutdown
, bfd_peer_shutdown_cmd
,
251 "Disable BFD peer\n")
253 nb_cli_enqueue_change(vty
, "./administrative-down", NB_OP_MODIFY
,
254 no
? "false" : "true");
255 return nb_cli_apply_changes(vty
, NULL
);
258 void bfd_cli_show_shutdown(struct vty
*vty
, struct lyd_node
*dnode
,
262 vty_out(vty
, " shutdown\n");
264 vty_out(vty
, " %sshutdown\n",
265 yang_dnode_get_bool(dnode
, NULL
) ? "" : "no ");
269 bfd_peer_passive
, bfd_peer_passive_cmd
,
272 "Don't attempt to start sessions\n")
274 nb_cli_enqueue_change(vty
, "./passive-mode", NB_OP_MODIFY
,
275 no
? "false" : "true");
276 return nb_cli_apply_changes(vty
, NULL
);
279 void bfd_cli_show_passive(struct vty
*vty
, struct lyd_node
*dnode
,
283 vty_out(vty
, " no passive-mode\n");
285 vty_out(vty
, " %spassive-mode\n",
286 yang_dnode_get_bool(dnode
, NULL
) ? "" : "no ");
290 bfd_peer_minimum_ttl
, bfd_peer_minimum_ttl_cmd
,
291 "[no] minimum-ttl (1-254)$ttl",
293 "Expect packets with at least this TTL\n"
294 "Minimum TTL expected\n")
297 nb_cli_enqueue_change(vty
, "./minimum-ttl", NB_OP_DESTROY
,
300 nb_cli_enqueue_change(vty
, "./minimum-ttl", NB_OP_MODIFY
,
302 return nb_cli_apply_changes(vty
, NULL
);
306 no_bfd_peer_minimum_ttl
, no_bfd_peer_minimum_ttl_cmd
,
309 "Expect packets with at least this TTL\n")
311 nb_cli_enqueue_change(vty
, "./minimum-ttl", NB_OP_DESTROY
, NULL
);
312 return nb_cli_apply_changes(vty
, NULL
);
315 void bfd_cli_show_minimum_ttl(struct vty
*vty
, struct lyd_node
*dnode
,
319 vty_out(vty
, " minimum-ttl 254\n");
321 vty_out(vty
, " minimum-ttl %s\n",
322 yang_dnode_get_string(dnode
, NULL
));
326 bfd_peer_mult
, bfd_peer_mult_cmd
,
327 "detect-multiplier (2-255)$multiplier",
328 "Configure peer detection multiplier\n"
329 "Configure peer detection multiplier value\n")
331 nb_cli_enqueue_change(vty
, "./detection-multiplier", NB_OP_MODIFY
,
333 return nb_cli_apply_changes(vty
, NULL
);
336 void bfd_cli_show_mult(struct vty
*vty
, struct lyd_node
*dnode
,
340 vty_out(vty
, " detect-multiplier %d\n",
343 vty_out(vty
, " detect-multiplier %s\n",
344 yang_dnode_get_string(dnode
, NULL
));
348 bfd_peer_rx
, bfd_peer_rx_cmd
,
349 "receive-interval (10-60000)$interval",
350 "Configure peer receive interval\n"
351 "Configure peer receive interval value in milliseconds\n")
355 snprintf(value
, sizeof(value
), "%ld", interval
* 1000);
356 nb_cli_enqueue_change(vty
, "./required-receive-interval", NB_OP_MODIFY
,
359 return nb_cli_apply_changes(vty
, NULL
);
362 void bfd_cli_show_rx(struct vty
*vty
, struct lyd_node
*dnode
,
368 vty_out(vty
, " receive-interval %d\n",
369 BFD_DEFREQUIREDMINRX
);
371 value
= yang_dnode_get_uint32(dnode
, NULL
);
372 vty_out(vty
, " receive-interval %u\n", value
/ 1000);
377 bfd_peer_tx
, bfd_peer_tx_cmd
,
378 "transmit-interval (10-60000)$interval",
379 "Configure peer transmit interval\n"
380 "Configure peer transmit interval value in milliseconds\n")
384 snprintf(value
, sizeof(value
), "%ld", interval
* 1000);
385 nb_cli_enqueue_change(vty
, "./desired-transmission-interval",
386 NB_OP_MODIFY
, value
);
388 return nb_cli_apply_changes(vty
, NULL
);
391 void bfd_cli_show_tx(struct vty
*vty
, struct lyd_node
*dnode
,
397 vty_out(vty
, " transmit-interval %d\n",
398 BFD_DEFDESIREDMINTX
);
400 value
= yang_dnode_get_uint32(dnode
, NULL
);
401 vty_out(vty
, " transmit-interval %u\n", value
/ 1000);
406 bfd_peer_echo
, bfd_peer_echo_cmd
,
409 "Configure echo mode\n")
411 nb_cli_enqueue_change(vty
, "./echo-mode", NB_OP_MODIFY
,
412 no
? "false" : "true");
413 return nb_cli_apply_changes(vty
, NULL
);
416 void bfd_cli_show_echo(struct vty
*vty
, struct lyd_node
*dnode
,
420 vty_out(vty
, " no echo-mode\n");
422 vty_out(vty
, " %secho-mode\n",
423 yang_dnode_get_bool(dnode
, NULL
) ? "" : "no ");
427 bfd_peer_echo_interval
, bfd_peer_echo_interval_cmd
,
428 "echo-interval (10-60000)$interval",
429 "Configure peer echo interval\n"
430 "Configure peer echo interval value in milliseconds\n")
434 snprintf(value
, sizeof(value
), "%ld", interval
* 1000);
435 nb_cli_enqueue_change(vty
, "./desired-echo-transmission-interval",
436 NB_OP_MODIFY
, value
);
438 return nb_cli_apply_changes(vty
, NULL
);
441 void bfd_cli_show_echo_interval(struct vty
*vty
, struct lyd_node
*dnode
,
447 vty_out(vty
, " echo-interval %d\n",
448 BFD_DEF_REQ_MIN_ECHO
);
450 value
= yang_dnode_get_uint32(dnode
, NULL
);
451 vty_out(vty
, " echo-interval %u\n", value
/ 1000);
458 DEFPY_YANG_NOSH(bfd_profile
, bfd_profile_cmd
,
461 BFD_PROFILE_NAME_STR
)
463 char xpath
[XPATH_MAXLEN
];
466 snprintf(xpath
, sizeof(xpath
), "/frr-bfdd:bfdd/bfd/profile[name='%s']",
469 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
471 /* Apply settings immediately. */
472 rv
= nb_cli_apply_changes(vty
, NULL
);
473 if (rv
== CMD_SUCCESS
)
474 VTY_PUSH_XPATH(BFD_PROFILE_NODE
, xpath
);
479 DEFPY_YANG(no_bfd_profile
, no_bfd_profile_cmd
,
480 "no profile BFDPROF$name",
483 BFD_PROFILE_NAME_STR
)
485 char xpath
[XPATH_MAXLEN
];
487 snprintf(xpath
, sizeof(xpath
), "/frr-bfdd:bfdd/bfd/profile[name='%s']",
490 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
492 /* Apply settings immediately. */
493 return nb_cli_apply_changes(vty
, NULL
);
496 void bfd_cli_show_profile(struct vty
*vty
, struct lyd_node
*dnode
,
499 vty_out(vty
, " profile %s\n", yang_dnode_get_string(dnode
, "./name"));
502 ALIAS_YANG(bfd_peer_mult
, bfd_profile_mult_cmd
,
503 "detect-multiplier (2-255)$multiplier",
504 "Configure peer detection multiplier\n"
505 "Configure peer detection multiplier value\n")
507 ALIAS_YANG(bfd_peer_tx
, bfd_profile_tx_cmd
,
508 "transmit-interval (10-60000)$interval",
509 "Configure peer transmit interval\n"
510 "Configure peer transmit interval value in milliseconds\n")
512 ALIAS_YANG(bfd_peer_rx
, bfd_profile_rx_cmd
,
513 "receive-interval (10-60000)$interval",
514 "Configure peer receive interval\n"
515 "Configure peer receive interval value in milliseconds\n")
517 ALIAS_YANG(bfd_peer_shutdown
, bfd_profile_shutdown_cmd
,
520 "Disable BFD peer\n")
522 ALIAS_YANG(bfd_peer_passive
, bfd_profile_passive_cmd
,
525 "Don't attempt to start sessions\n")
527 ALIAS_YANG(bfd_peer_minimum_ttl
, bfd_profile_minimum_ttl_cmd
,
528 "[no] minimum-ttl (1-254)$ttl",
530 "Expect packets with at least this TTL\n"
531 "Minimum TTL expected\n")
533 ALIAS_YANG(no_bfd_peer_minimum_ttl
, no_bfd_profile_minimum_ttl_cmd
,
536 "Expect packets with at least this TTL\n")
538 ALIAS_YANG(bfd_peer_echo
, bfd_profile_echo_cmd
,
541 "Configure echo mode\n")
543 ALIAS_YANG(bfd_peer_echo_interval
, bfd_profile_echo_interval_cmd
,
544 "echo-interval (10-60000)$interval",
545 "Configure peer echo interval\n"
546 "Configure peer echo interval value in milliseconds\n")
548 DEFPY_YANG(bfd_peer_profile
, bfd_peer_profile_cmd
,
549 "[no] profile BFDPROF$pname",
551 "Use BFD profile settings\n"
552 BFD_PROFILE_NAME_STR
)
555 nb_cli_enqueue_change(vty
, "./profile", NB_OP_DESTROY
, NULL
);
557 nb_cli_enqueue_change(vty
, "./profile", NB_OP_MODIFY
, pname
);
559 return nb_cli_apply_changes(vty
, NULL
);
562 void bfd_cli_peer_profile_show(struct vty
*vty
, struct lyd_node
*dnode
,
565 vty_out(vty
, " profile %s\n", yang_dnode_get_string(dnode
, NULL
));
568 struct cmd_node bfd_profile_node
= {
569 .name
= "bfd profile",
570 .node
= BFD_PROFILE_NODE
,
571 .parent_node
= BFD_NODE
,
572 .prompt
= "%s(config-bfd-profile)# ",
575 static void bfd_profile_var(vector comps
, struct cmd_token
*token
)
577 extern struct bfdproflist bplist
;
578 struct bfd_profile
*bp
;
580 TAILQ_FOREACH (bp
, &bplist
, entry
) {
581 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bp
->name
));
585 static const struct cmd_variable_handler bfd_vars
[] = {
586 {.tokenname
= "BFDPROF", .completions
= bfd_profile_var
},
587 {.completions
= NULL
}
593 install_element(CONFIG_NODE
, &bfd_enter_cmd
);
594 install_element(CONFIG_NODE
, &bfd_config_reset_cmd
);
596 install_element(BFD_NODE
, &bfd_peer_enter_cmd
);
597 install_element(BFD_NODE
, &bfd_no_peer_cmd
);
599 install_element(BFD_PEER_NODE
, &bfd_peer_shutdown_cmd
);
600 install_element(BFD_PEER_NODE
, &bfd_peer_mult_cmd
);
601 install_element(BFD_PEER_NODE
, &bfd_peer_rx_cmd
);
602 install_element(BFD_PEER_NODE
, &bfd_peer_tx_cmd
);
603 install_element(BFD_PEER_NODE
, &bfd_peer_echo_cmd
);
604 install_element(BFD_PEER_NODE
, &bfd_peer_echo_interval_cmd
);
605 install_element(BFD_PEER_NODE
, &bfd_peer_profile_cmd
);
606 install_element(BFD_PEER_NODE
, &bfd_peer_passive_cmd
);
607 install_element(BFD_PEER_NODE
, &bfd_peer_minimum_ttl_cmd
);
608 install_element(BFD_PEER_NODE
, &no_bfd_peer_minimum_ttl_cmd
);
610 /* Profile commands. */
611 cmd_variable_handler_register(bfd_vars
);
613 install_node(&bfd_profile_node
);
614 install_default(BFD_PROFILE_NODE
);
616 install_element(BFD_NODE
, &bfd_profile_cmd
);
617 install_element(BFD_NODE
, &no_bfd_profile_cmd
);
619 install_element(BFD_PROFILE_NODE
, &bfd_profile_mult_cmd
);
620 install_element(BFD_PROFILE_NODE
, &bfd_profile_tx_cmd
);
621 install_element(BFD_PROFILE_NODE
, &bfd_profile_rx_cmd
);
622 install_element(BFD_PROFILE_NODE
, &bfd_profile_shutdown_cmd
);
623 install_element(BFD_PROFILE_NODE
, &bfd_profile_echo_cmd
);
624 install_element(BFD_PROFILE_NODE
, &bfd_profile_echo_interval_cmd
);
625 install_element(BFD_PROFILE_NODE
, &bfd_profile_passive_cmd
);
626 install_element(BFD_PROFILE_NODE
, &bfd_profile_minimum_ttl_cmd
);
627 install_element(BFD_PROFILE_NODE
, &no_bfd_profile_minimum_ttl_cmd
);