]> git.proxmox.com Git - mirror_frr.git/blame - bfdd/bfdd_cli.c
Merge pull request #6845 from opensourcerouting/foreach-safi-formatting
[mirror_frr.git] / bfdd / bfdd_cli.c
CommitLineData
adc26455
RZ
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
8e0c84ff
RZ
23#include <zebra.h>
24
adc26455
RZ
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"
6c574029 34#include "bfdd_nb.h"
adc26455
RZ
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
55/*
56 * Functions.
57 */
fdf8ac87
RZ
58DEFPY_NOSH(
59 bfd_enter, bfd_enter_cmd,
60 "bfd",
61 "Configure BFD peers\n")
62{
63 int ret;
64
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");
69
70 return ret;
71}
72
2a573ff6
RZ
73DEFUN(
74 bfd_config_reset, bfd_config_reset_cmd,
75 "no bfd",
76 NO_STR
77 "Configure BFD peers\n")
78{
79 nb_cli_enqueue_change(vty, "/frr-bfdd:bfdd/bfd", NB_OP_DESTROY, NULL);
80 return nb_cli_apply_changes(vty, NULL);
81}
82
0287a64a
RZ
83void bfd_cli_show_header(struct vty *vty,
84 struct lyd_node *dnode __attribute__((__unused__)),
85 bool show_defaults __attribute__((__unused__)))
86{
87 vty_out(vty, "!\nbfd\n");
88}
89
90void bfd_cli_show_header_end(struct vty *vty,
91 struct lyd_node *dnode __attribute__((__unused__)))
92{
93 vty_out(vty, "!\n");
94}
95
adc26455
RZ
96DEFPY_NOSH(
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}]",
99 PEER_STR
100 PEER_IPV4_STR
101 PEER_IPV6_STR
102 MHOP_STR
103 LOCAL_STR
104 LOCAL_IPV4_STR
105 LOCAL_IPV6_STR
106 INTERFACE_STR
107 LOCAL_INTF_STR
108 VRF_STR
109 VRF_NAME_STR)
110{
111 int ret, slen;
adc26455 112 char source_str[INET6_ADDRSTRLEN];
284062bf 113 char xpath[XPATH_MAXLEN], xpath_srcaddr[XPATH_MAXLEN + 32];
adc26455
RZ
114
115 if (multihop)
116 snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
117 local_address_str);
118 else
119 source_str[0] = 0;
120
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,
124 peer_str);
125 if (ifname)
126 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
127 "[interface='%s']", ifname);
128 else
129 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
130 "[interface='']");
131 if (vrf)
132 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']", vrf);
133 else
134 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']",
135 VRF_DEFAULT_NAME);
136
137 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
284062bf
RZ
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,
142 local_address_str);
143 }
adc26455 144
fdf8ac87 145 /* Apply settings immediately. */
adc26455
RZ
146 ret = nb_cli_apply_changes(vty, NULL);
147 if (ret == CMD_SUCCESS)
148 VTY_PUSH_XPATH(BFD_PEER_NODE, xpath);
149
150 return ret;
151}
152
153DEFPY(
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}]",
156 NO_STR
157 PEER_STR
158 PEER_IPV4_STR
159 PEER_IPV6_STR
160 MHOP_STR
161 LOCAL_STR
162 LOCAL_IPV4_STR
163 LOCAL_IPV6_STR
164 INTERFACE_STR
165 LOCAL_INTF_STR
166 VRF_STR
167 VRF_NAME_STR)
168{
169 int slen;
170 char xpath[XPATH_MAXLEN];
171 char source_str[INET6_ADDRSTRLEN];
172
173 if (multihop)
174 snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
175 local_address_str);
176 else
177 source_str[0] = 0;
178
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,
182 peer_str);
183 if (ifname)
184 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
185 "[interface='%s']", ifname);
186 else
187 slen += snprintf(xpath + slen, sizeof(xpath) - slen,
188 "[interface='']");
189 if (vrf)
190 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']", vrf);
191 else
192 snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']",
193 VRF_DEFAULT_NAME);
194
195 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
196
197 /* Apply settings immediatly. */
198 return nb_cli_apply_changes(vty, NULL);
199}
200
0287a64a
RZ
201static void _bfd_cli_show_peer(struct vty *vty, struct lyd_node *dnode,
202 bool show_defaults __attribute__((__unused__)),
203 bool mhop)
204{
205 const char *vrf = yang_dnode_get_string(dnode, "./vrf");
206 const char *ifname = yang_dnode_get_string(dnode, "./interface");
207
208 vty_out(vty, " peer %s",
209 yang_dnode_get_string(dnode, "./dest-addr"));
210
211 if (mhop)
212 vty_out(vty, " multihop");
213
214 if (yang_dnode_exists(dnode, "./source-addr"))
215 vty_out(vty, " local-address %s",
216 yang_dnode_get_string(dnode, "./source-addr"));
217
218 if (strcmp(vrf, VRF_DEFAULT_NAME))
219 vty_out(vty, " vrf %s", vrf);
220
221 if (ifname[0])
222 vty_out(vty, " interface %s", ifname);
223
224 vty_out(vty, "\n");
225}
226
227void bfd_cli_show_single_hop_peer(struct vty *vty,
228 struct lyd_node *dnode,
229 bool show_defaults)
230{
231 _bfd_cli_show_peer(vty, dnode, show_defaults, false);
232}
233
234void bfd_cli_show_multi_hop_peer(struct vty *vty,
235 struct lyd_node *dnode,
236 bool show_defaults)
237{
238 _bfd_cli_show_peer(vty, dnode, show_defaults, true);
239}
240
241void bfd_cli_show_peer_end(struct vty *vty,
242 struct lyd_node *dnode __attribute__((__unused__)))
243{
244 vty_out(vty, " !\n");
245}
246
adc26455
RZ
247DEFPY(
248 bfd_peer_shutdown, bfd_peer_shutdown_cmd,
249 "[no] shutdown",
250 NO_STR
7818c5fb 251 "Disable BFD peer\n")
adc26455
RZ
252{
253 nb_cli_enqueue_change(vty, "./administrative-down", NB_OP_MODIFY,
254 no ? "false" : "true");
255 return nb_cli_apply_changes(vty, NULL);
256}
257
0287a64a
RZ
258void bfd_cli_show_shutdown(struct vty *vty, struct lyd_node *dnode,
259 bool show_defaults)
260{
261 if (show_defaults)
262 vty_out(vty, " shutdown\n");
263 else
264 vty_out(vty, " %sshutdown\n",
265 yang_dnode_get_bool(dnode, NULL) ? "" : "no ");
266}
267
adc26455
RZ
268DEFPY(
269 bfd_peer_mult, bfd_peer_mult_cmd,
270 "detect-multiplier (2-255)$multiplier",
271 "Configure peer detection multiplier\n"
272 "Configure peer detection multiplier value\n")
273{
274 nb_cli_enqueue_change(vty, "./detection-multiplier", NB_OP_MODIFY,
275 multiplier_str);
276 return nb_cli_apply_changes(vty, NULL);
277}
278
0287a64a
RZ
279void bfd_cli_show_mult(struct vty *vty, struct lyd_node *dnode,
280 bool show_defaults)
281{
282 if (show_defaults)
283 vty_out(vty, " detect-multiplier %d\n",
284 BFD_DEFDETECTMULT);
285 else
286 vty_out(vty, " detect-multiplier %s\n",
287 yang_dnode_get_string(dnode, NULL));
288}
289
adc26455
RZ
290DEFPY(
291 bfd_peer_rx, bfd_peer_rx_cmd,
292 "receive-interval (10-60000)$interval",
293 "Configure peer receive interval\n"
294 "Configure peer receive interval value in milliseconds\n")
295{
8a676ce6
RZ
296 char value[32];
297
298 snprintf(value, sizeof(value), "%ld", interval * 1000);
adc26455 299 nb_cli_enqueue_change(vty, "./required-receive-interval", NB_OP_MODIFY,
8a676ce6
RZ
300 value);
301
adc26455
RZ
302 return nb_cli_apply_changes(vty, NULL);
303}
304
0287a64a
RZ
305void bfd_cli_show_rx(struct vty *vty, struct lyd_node *dnode,
306 bool show_defaults)
307{
8a676ce6
RZ
308 uint32_t value;
309
0287a64a
RZ
310 if (show_defaults)
311 vty_out(vty, " receive-interval %d\n",
312 BFD_DEFREQUIREDMINRX);
8a676ce6
RZ
313 else {
314 value = yang_dnode_get_uint32(dnode, NULL);
6cde4b45 315 vty_out(vty, " receive-interval %u\n", value / 1000);
8a676ce6 316 }
0287a64a
RZ
317}
318
adc26455
RZ
319DEFPY(
320 bfd_peer_tx, bfd_peer_tx_cmd,
321 "transmit-interval (10-60000)$interval",
322 "Configure peer transmit interval\n"
323 "Configure peer transmit interval value in milliseconds\n")
324{
8a676ce6
RZ
325 char value[32];
326
327 snprintf(value, sizeof(value), "%ld", interval * 1000);
adc26455 328 nb_cli_enqueue_change(vty, "./desired-transmission-interval",
8a676ce6
RZ
329 NB_OP_MODIFY, value);
330
adc26455
RZ
331 return nb_cli_apply_changes(vty, NULL);
332}
333
0287a64a
RZ
334void bfd_cli_show_tx(struct vty *vty, struct lyd_node *dnode,
335 bool show_defaults)
336{
8a676ce6
RZ
337 uint32_t value;
338
0287a64a
RZ
339 if (show_defaults)
340 vty_out(vty, " transmit-interval %d\n",
341 BFD_DEFDESIREDMINTX);
8a676ce6
RZ
342 else {
343 value = yang_dnode_get_uint32(dnode, NULL);
6cde4b45 344 vty_out(vty, " transmit-interval %u\n", value / 1000);
8a676ce6 345 }
0287a64a
RZ
346}
347
adc26455
RZ
348DEFPY(
349 bfd_peer_echo, bfd_peer_echo_cmd,
350 "[no] echo-mode",
351 NO_STR
352 "Configure echo mode\n")
353{
354 nb_cli_enqueue_change(vty, "./echo-mode", NB_OP_MODIFY,
355 no ? "false" : "true");
356 return nb_cli_apply_changes(vty, NULL);
357}
358
0287a64a
RZ
359void bfd_cli_show_echo(struct vty *vty, struct lyd_node *dnode,
360 bool show_defaults)
361{
362 if (show_defaults)
363 vty_out(vty, " no echo-mode\n");
364 else
365 vty_out(vty, " %secho-mode\n",
366 yang_dnode_get_bool(dnode, NULL) ? "" : "no ");
367}
368
adc26455
RZ
369DEFPY(
370 bfd_peer_echo_interval, bfd_peer_echo_interval_cmd,
371 "echo-interval (10-60000)$interval",
372 "Configure peer echo interval\n"
373 "Configure peer echo interval value in milliseconds\n")
374{
8a676ce6
RZ
375 char value[32];
376
377 snprintf(value, sizeof(value), "%ld", interval * 1000);
adc26455 378 nb_cli_enqueue_change(vty, "./desired-echo-transmission-interval",
8a676ce6
RZ
379 NB_OP_MODIFY, value);
380
adc26455
RZ
381 return nb_cli_apply_changes(vty, NULL);
382}
383
0287a64a
RZ
384void bfd_cli_show_echo_interval(struct vty *vty, struct lyd_node *dnode,
385 bool show_defaults)
386{
8a676ce6
RZ
387 uint32_t value;
388
0287a64a
RZ
389 if (show_defaults)
390 vty_out(vty, " echo-interval %d\n",
391 BFD_DEF_REQ_MIN_ECHO);
8a676ce6
RZ
392 else {
393 value = yang_dnode_get_uint32(dnode, NULL);
6cde4b45 394 vty_out(vty, " echo-interval %u\n", value / 1000);
8a676ce6 395 }
0287a64a
RZ
396}
397
d40d6c22
RZ
398/*
399 * Profile commands.
400 */
401DEFPY_NOSH(bfd_profile, bfd_profile_cmd,
402 "profile WORD$name",
403 BFD_PROFILE_STR
404 BFD_PROFILE_NAME_STR)
405{
ccc9ada8
RZ
406 char xpath[XPATH_MAXLEN];
407 int rv;
408
409 snprintf(xpath, sizeof(xpath), "/frr-bfdd:bfdd/bfd/profile[name='%s']",
410 name);
411
412 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
413
414 /* Apply settings immediately. */
415 rv = nb_cli_apply_changes(vty, NULL);
416 if (rv == CMD_SUCCESS)
417 VTY_PUSH_XPATH(BFD_PROFILE_NODE, xpath);
418
d40d6c22
RZ
419 return CMD_SUCCESS;
420}
421
422DEFPY(no_bfd_profile, no_bfd_profile_cmd,
423 "no profile BFDPROF$name",
424 NO_STR
425 BFD_PROFILE_STR
426 BFD_PROFILE_NAME_STR)
427{
ccc9ada8
RZ
428 char xpath[XPATH_MAXLEN];
429
430 snprintf(xpath, sizeof(xpath), "/frr-bfdd:bfdd/bfd/profile[name='%s']",
431 name);
432
433 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
434
435 /* Apply settings immediately. */
436 return nb_cli_apply_changes(vty, NULL);
437}
438
439void bfd_cli_show_profile(struct vty *vty, struct lyd_node *dnode,
440 bool show_defaults)
441{
442 vty_out(vty, " profile %s\n", yang_dnode_get_string(dnode, "./name"));
443}
444
445ALIAS(bfd_peer_mult, bfd_profile_mult_cmd,
446 "detect-multiplier (2-255)$multiplier",
447 "Configure peer detection multiplier\n"
448 "Configure peer detection multiplier value\n")
449
450ALIAS(bfd_peer_tx, bfd_profile_tx_cmd,
451 "transmit-interval (10-60000)$interval",
452 "Configure peer transmit interval\n"
453 "Configure peer transmit interval value in milliseconds\n")
454
455ALIAS(bfd_peer_rx, bfd_profile_rx_cmd,
456 "receive-interval (10-60000)$interval",
457 "Configure peer receive interval\n"
458 "Configure peer receive interval value in milliseconds\n")
459
460ALIAS(bfd_peer_shutdown, bfd_profile_shutdown_cmd,
461 "[no] shutdown",
462 NO_STR
463 "Disable BFD peer\n")
464
465ALIAS(bfd_peer_echo, bfd_profile_echo_cmd,
466 "[no] echo-mode",
467 NO_STR
468 "Configure echo mode\n")
469
470ALIAS(bfd_peer_echo_interval, bfd_profile_echo_interval_cmd,
471 "echo-interval (10-60000)$interval",
472 "Configure peer echo interval\n"
473 "Configure peer echo interval value in milliseconds\n")
474
475DEFPY(bfd_peer_profile, bfd_peer_profile_cmd,
476 "[no] profile BFDPROF$pname",
477 NO_STR
478 "Use BFD profile settings\n"
479 BFD_PROFILE_NAME_STR)
480{
481 if (no)
482 nb_cli_enqueue_change(vty, "./profile", NB_OP_DESTROY, NULL);
483 else
484 nb_cli_enqueue_change(vty, "./profile", NB_OP_MODIFY, pname);
485
486 return nb_cli_apply_changes(vty, NULL);
487}
488
489void bfd_cli_peer_profile_show(struct vty *vty, struct lyd_node *dnode,
490 bool show_defaults)
491{
492 vty_out(vty, " profile %s\n", yang_dnode_get_string(dnode, NULL));
d40d6c22
RZ
493}
494
495struct cmd_node bfd_profile_node = {
496 .name = "bfd profile",
497 .node = BFD_PROFILE_NODE,
498 .parent_node = BFD_NODE,
499 .prompt = "%s(config-bfd-profile)# ",
500};
501
ccc9ada8
RZ
502static void bfd_profile_var(vector comps, struct cmd_token *token)
503{
504 extern struct bfdproflist bplist;
505 struct bfd_profile *bp;
506
507 TAILQ_FOREACH (bp, &bplist, entry) {
508 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bp->name));
509 }
510}
511
512static const struct cmd_variable_handler bfd_vars[] = {
513 {.tokenname = "BFDPROF", .completions = bfd_profile_var},
514 {.completions = NULL}
515};
516
adc26455
RZ
517void
518bfdd_cli_init(void)
519{
fdf8ac87 520 install_element(CONFIG_NODE, &bfd_enter_cmd);
2a573ff6
RZ
521 install_element(CONFIG_NODE, &bfd_config_reset_cmd);
522
adc26455
RZ
523 install_element(BFD_NODE, &bfd_peer_enter_cmd);
524 install_element(BFD_NODE, &bfd_no_peer_cmd);
525
526 install_element(BFD_PEER_NODE, &bfd_peer_shutdown_cmd);
527 install_element(BFD_PEER_NODE, &bfd_peer_mult_cmd);
528 install_element(BFD_PEER_NODE, &bfd_peer_rx_cmd);
529 install_element(BFD_PEER_NODE, &bfd_peer_tx_cmd);
530 install_element(BFD_PEER_NODE, &bfd_peer_echo_cmd);
531 install_element(BFD_PEER_NODE, &bfd_peer_echo_interval_cmd);
ccc9ada8 532 install_element(BFD_PEER_NODE, &bfd_peer_profile_cmd);
d40d6c22
RZ
533
534 /* Profile commands. */
ccc9ada8
RZ
535 cmd_variable_handler_register(bfd_vars);
536
d40d6c22
RZ
537 install_node(&bfd_profile_node);
538 install_default(BFD_PROFILE_NODE);
539
540 install_element(BFD_NODE, &bfd_profile_cmd);
541 install_element(BFD_NODE, &no_bfd_profile_cmd);
ccc9ada8
RZ
542
543 install_element(BFD_PROFILE_NODE, &bfd_profile_mult_cmd);
544 install_element(BFD_PROFILE_NODE, &bfd_profile_tx_cmd);
545 install_element(BFD_PROFILE_NODE, &bfd_profile_rx_cmd);
546 install_element(BFD_PROFILE_NODE, &bfd_profile_shutdown_cmd);
547 install_element(BFD_PROFILE_NODE, &bfd_profile_echo_cmd);
548 install_element(BFD_PROFILE_NODE, &bfd_profile_echo_interval_cmd);
adc26455 549}