3 * Copyright (C) 2018 Network Device Education Foundation, Inc. ("NetDEF")
5 * FRR is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2, or (at your option) any
10 * FRR is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with FRR; see the file COPYING. If not, write to the Free
17 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 #include "lib/command.h"
30 #ifndef VTYSH_EXTRACT_PL
31 #include "bfdd/bfdd_vty_clippy.c"
35 * Commands help string definitions.
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"
52 static int bfdd_write_config(struct vty
*vty
);
53 static int bfdd_peer_write_config(struct vty
*vty
);
54 static void _bfdd_peer_write_config(struct hash_backet
*hb
, void *arg
);
55 static int bfd_configure_peer(struct bfd_peer_cfg
*bpc
, bool mhop
,
56 const struct sockaddr_any
*peer
,
57 const struct sockaddr_any
*local
,
58 const char *ifname
, const char *vrfname
,
59 char *ebuf
, size_t ebuflen
);
61 static struct json_object
*__display_peer_json(struct bfd_session
*bs
);
62 static void _display_peer_json(struct vty
*vty
, struct bfd_session
*bs
);
63 static void _display_peer(struct vty
*vty
, struct bfd_session
*bs
);
64 static void _display_all_peers(struct vty
*vty
, bool use_json
);
65 static void _display_peer_iter(struct hash_backet
*hb
, void *arg
);
66 static void _display_peer_json_iter(struct hash_backet
*hb
, void *arg
);
70 * Commands definition.
72 DEFUN_NOSH(bfd_enter
, bfd_enter_cmd
, "bfd", "Configure BFD peers\n")
79 bfd_peer_enter
, bfd_peer_enter_cmd
,
80 "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
81 PEER_STR PEER_IPV4_STR PEER_IPV6_STR
83 LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
90 struct bfd_session
*bs
;
91 const char *peer
, *ifname
, *local
, *vrfname
;
92 struct bfd_peer_cfg bpc
;
93 struct sockaddr_any psa
, lsa
, *lsap
;
96 vrfname
= peer
= ifname
= local
= NULL
;
98 /* Gather all provided information. */
102 mhop
= argv_find(argv
, argc
, "multihop", &idx
);
105 if (argv_find(argv
, argc
, "interface", &idx
))
106 ifname
= argv
[idx
+ 1]->arg
;
109 if (argv_find(argv
, argc
, "local-address", &idx
))
110 local
= argv
[idx
+ 1]->arg
;
113 if (argv_find(argv
, argc
, "vrf", &idx
))
114 vrfname
= argv
[idx
+ 1]->arg
;
116 if (vrfname
&& ifname
) {
117 vty_out(vty
, "%% VRF is not mixable with interface\n");
118 return CMD_WARNING_CONFIG_FAILED
;
123 strtosa(local
, &lsa
);
128 if (bfd_configure_peer(&bpc
, mhop
, &psa
, lsap
, ifname
, vrfname
,
129 errormsg
, sizeof(errormsg
))
131 vty_out(vty
, "%% Invalid peer configuration: %s\n", errormsg
);
132 return CMD_WARNING_CONFIG_FAILED
;
135 bs
= bs_peer_find(&bpc
);
137 bs
= ptm_bfd_sess_new(&bpc
);
139 vty_out(vty
, "%% Failed to add peer.\n");
140 return CMD_WARNING_CONFIG_FAILED
;
144 VTY_PUSH_CONTEXT(BFD_PEER_NODE
, bs
);
149 DEFPY(bfd_peer_detectmultiplier
, bfd_peer_detectmultiplier_cmd
,
150 "detect-multiplier (2-255)$multiplier",
151 "Configure peer detection multiplier\n"
152 "Configure peer detection multiplier value\n")
154 struct bfd_session
*bs
;
156 bs
= VTY_GET_CONTEXT(bfd_session
);
157 if (bs
->detect_mult
== multiplier
)
160 bs
->detect_mult
= multiplier
;
166 DEFPY(bfd_peer_recvinterval
, bfd_peer_recvinterval_cmd
,
167 "receive-interval (10-60000)$interval",
168 "Configure peer receive interval\n"
169 "Configure peer receive interval value in milliseconds\n")
171 struct bfd_session
*bs
;
173 bs
= VTY_GET_CONTEXT(bfd_session
);
174 if (bs
->timers
.required_min_rx
== (uint32_t)(interval
* 1000))
177 bs
->timers
.required_min_rx
= interval
* 1000;
183 DEFPY(bfd_peer_txinterval
, bfd_peer_txinterval_cmd
,
184 "transmit-interval (10-60000)$interval",
185 "Configure peer transmit interval\n"
186 "Configure peer transmit interval value in milliseconds\n")
188 struct bfd_session
*bs
;
190 bs
= VTY_GET_CONTEXT(bfd_session
);
191 if (bs
->up_min_tx
== (uint32_t)(interval
* 1000))
194 bs
->up_min_tx
= interval
* 1000;
200 DEFPY(bfd_peer_echointerval
, bfd_peer_echointerval_cmd
,
201 "echo-interval (10-60000)$interval",
202 "Configure peer echo interval\n"
203 "Configure peer echo interval value in milliseconds\n")
205 struct bfd_session
*bs
;
207 bs
= VTY_GET_CONTEXT(bfd_session
);
208 if (bs
->timers
.required_min_echo
== (uint32_t)(interval
* 1000))
211 bs
->timers
.required_min_echo
= interval
* 1000;
217 DEFPY(bfd_peer_shutdown
, bfd_peer_shutdown_cmd
, "[no] shutdown",
218 NO_STR
"Disable BFD peer")
220 struct bfd_session
*bs
;
222 bs
= VTY_GET_CONTEXT(bfd_session
);
224 if (!BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_SHUTDOWN
))
227 BFD_UNSET_FLAG(bs
->flags
, BFD_SESS_FLAG_SHUTDOWN
);
229 /* Change and notify state change. */
230 bs
->ses_state
= PTM_BFD_DOWN
;
233 /* Enable all timers. */
234 bfd_recvtimer_update(bs
);
235 bfd_xmttimer_update(bs
, bs
->xmt_TO
);
236 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
)) {
237 bfd_echo_recvtimer_update(bs
);
238 bfd_echo_xmttimer_update(bs
, bs
->echo_xmt_TO
);
241 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_SHUTDOWN
))
244 BFD_SET_FLAG(bs
->flags
, BFD_SESS_FLAG_SHUTDOWN
);
246 /* Disable all events. */
247 bfd_recvtimer_delete(bs
);
248 bfd_echo_recvtimer_delete(bs
);
249 bfd_xmttimer_delete(bs
);
250 bfd_echo_xmttimer_delete(bs
);
252 /* Change and notify state change. */
253 bs
->ses_state
= PTM_BFD_ADM_DOWN
;
262 DEFPY(bfd_peer_echo
, bfd_peer_echo_cmd
, "[no] echo-mode",
263 NO_STR
"Configure echo mode\n")
265 struct bfd_session
*bs
;
267 bs
= VTY_GET_CONTEXT(bfd_session
);
269 if (!BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
))
272 BFD_UNSET_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
);
273 ptm_bfd_echo_stop(bs
, 0);
275 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
))
278 BFD_SET_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
);
279 /* Apply setting immediately. */
280 if (!BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_SHUTDOWN
)) {
281 ptm_bfd_echo_start(bs
);
282 bfd_echo_recvtimer_update(bs
);
289 DEFPY(bfd_peer_label
, bfd_peer_label_cmd
, "label WORD$label",
290 "Register peer label\n"
291 "Register peer label identification\n")
293 struct bfd_session
*bs
;
295 /* Validate label length. */
296 if (strlen(label
) >= MAXNAMELEN
) {
297 vty_out(vty
, "%% Label name is too long\n");
298 return CMD_WARNING_CONFIG_FAILED
;
301 bs
= VTY_GET_CONTEXT(bfd_session
);
302 if (bfd_session_update_label(bs
, label
) == -1) {
303 vty_out(vty
, "%% Failed to update peer label.\n");
304 return CMD_WARNING_CONFIG_FAILED
;
310 DEFPY(bfd_no_peer
, bfd_no_peer_cmd
,
311 "no peer <A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$local|interface IFNAME$ifname|vrf NAME$vrfname}]",
313 PEER_STR PEER_IPV4_STR PEER_IPV6_STR
315 LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
318 VRF_STR VRF_NAME_STR
)
322 struct bfd_peer_cfg bpc
;
323 struct sockaddr_any psa
, lsa
, *lsap
;
326 strtosa(peer_str
, &psa
);
328 strtosa(local_str
, &lsa
);
335 mhop
= argv_find(argv
, argc
, "multihop", &idx
);
337 if (bfd_configure_peer(&bpc
, mhop
, &psa
, lsap
, ifname
, vrfname
,
338 errormsg
, sizeof(errormsg
))
340 vty_out(vty
, "%% Invalid peer configuration: %s\n", errormsg
);
341 return CMD_WARNING_CONFIG_FAILED
;
344 if (ptm_bfd_ses_del(&bpc
) != 0) {
345 vty_out(vty
, "%% Failed to remove peer.\n");
346 return CMD_WARNING_CONFIG_FAILED
;
354 * Show commands helper functions
356 static void _display_peer(struct vty
*vty
, struct bfd_session
*bs
)
361 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_MH
)) {
362 vty_out(vty
, "\tpeer %s", satostr(&bs
->mhop
.peer
));
363 vty_out(vty
, " multihop");
364 vty_out(vty
, " local-address %s", satostr(&bs
->mhop
.local
));
365 if (bs
->mhop
.vrf_name
[0])
366 vty_out(vty
, " vrf %s", bs
->mhop
.vrf_name
);
369 vty_out(vty
, "\tpeer %s", satostr(&bs
->shop
.peer
));
370 if (bs
->local_address
.sa_sin
.sin_family
!= AF_UNSPEC
)
371 vty_out(vty
, " local-address %s",
372 satostr(&bs
->local_address
));
373 if (bs
->shop
.port_name
[0])
374 vty_out(vty
, " interface %s", bs
->shop
.port_name
);
379 vty_out(vty
, "\t\tlabel: %s\n", bs
->pl
->pl_label
);
381 vty_out(vty
, "\t\tID: %u\n", bs
->discrs
.my_discr
);
382 vty_out(vty
, "\t\tRemote ID: %u\n", bs
->discrs
.remote_discr
);
384 vty_out(vty
, "\t\tStatus: ");
385 switch (bs
->ses_state
) {
386 case PTM_BFD_ADM_DOWN
:
387 vty_out(vty
, "shutdown\n");
390 vty_out(vty
, "down\n");
392 now
= monotime(NULL
);
393 integer2timestr(now
- bs
->uptime
.tv_sec
, buf
, sizeof(buf
));
394 vty_out(vty
, "\t\tDowntime: %s\n", buf
);
397 vty_out(vty
, "init\n");
400 vty_out(vty
, "up\n");
402 now
= monotime(NULL
);
403 integer2timestr(now
- bs
->uptime
.tv_sec
, buf
, sizeof(buf
));
404 vty_out(vty
, "\t\tUptime: %s\n", buf
);
408 vty_out(vty
, "unknown\n");
412 vty_out(vty
, "\t\tDiagnostics: %s\n", diag2str(bs
->local_diag
));
413 vty_out(vty
, "\t\tRemote diagnostics: %s\n", diag2str(bs
->remote_diag
));
415 vty_out(vty
, "\t\tLocal timers:\n");
416 vty_out(vty
, "\t\t\tReceive interval: %" PRIu32
"ms\n",
417 bs
->timers
.required_min_rx
/ 1000);
418 vty_out(vty
, "\t\t\tTransmission interval: %" PRIu32
"ms",
419 bs
->timers
.desired_min_tx
/ 1000);
420 if (bs
->up_min_tx
!= bs
->timers
.desired_min_tx
)
421 vty_out(vty
, " (configured %" PRIu32
"ms)\n",
422 bs
->up_min_tx
/ 1000);
426 vty_out(vty
, "\t\t\tEcho transmission interval: ");
427 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
))
428 vty_out(vty
, "%" PRIu32
"ms\n",
429 bs
->timers
.required_min_echo
/ 1000);
431 vty_out(vty
, "disabled\n");
433 vty_out(vty
, "\t\tRemote timers:\n");
434 vty_out(vty
, "\t\t\tReceive interval: %" PRIu32
"ms\n",
435 bs
->remote_timers
.required_min_rx
/ 1000);
436 vty_out(vty
, "\t\t\tTransmission interval: %" PRIu32
"ms\n",
437 bs
->remote_timers
.desired_min_tx
/ 1000);
438 vty_out(vty
, "\t\t\tEcho transmission interval: %" PRIu32
"ms\n",
439 bs
->remote_timers
.required_min_echo
/ 1000);
444 static struct json_object
*__display_peer_json(struct bfd_session
*bs
)
446 struct json_object
*jo
= json_object_new_object();
448 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_MH
)) {
449 json_object_boolean_true_add(jo
, "multihop");
450 json_object_string_add(jo
, "peer", satostr(&bs
->mhop
.peer
));
451 json_object_string_add(jo
, "local", satostr(&bs
->mhop
.local
));
452 if (bs
->mhop
.vrf_name
[0])
453 json_object_string_add(jo
, "vrf", bs
->mhop
.vrf_name
);
455 json_object_boolean_false_add(jo
, "multihop");
456 json_object_string_add(jo
, "peer", satostr(&bs
->shop
.peer
));
457 if (bs
->local_address
.sa_sin
.sin_family
!= AF_UNSPEC
)
458 json_object_string_add(jo
, "local",
459 satostr(&bs
->local_address
));
460 if (bs
->shop
.port_name
[0])
461 json_object_string_add(jo
, "interface",
466 json_object_string_add(jo
, "label", bs
->pl
->pl_label
);
468 json_object_int_add(jo
, "id", bs
->discrs
.my_discr
);
469 json_object_int_add(jo
, "remote-id", bs
->discrs
.remote_discr
);
471 switch (bs
->ses_state
) {
472 case PTM_BFD_ADM_DOWN
:
473 json_object_string_add(jo
, "status", "shutdown");
476 json_object_string_add(jo
, "status", "down");
477 json_object_int_add(jo
, "downtime",
478 monotime(NULL
) - bs
->uptime
.tv_sec
);
481 json_object_string_add(jo
, "status", "init");
484 json_object_string_add(jo
, "status", "up");
485 json_object_int_add(jo
, "uptime",
486 monotime(NULL
) - bs
->uptime
.tv_sec
);
490 json_object_string_add(jo
, "status", "unknown");
494 json_object_string_add(jo
, "diagnostic", diag2str(bs
->local_diag
));
495 json_object_string_add(jo
, "remote-diagnostic",
496 diag2str(bs
->remote_diag
));
498 json_object_int_add(jo
, "receive-interval",
499 bs
->timers
.required_min_rx
/ 1000);
500 json_object_int_add(jo
, "transmit-interval",
501 bs
->timers
.desired_min_tx
/ 1000);
502 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
))
503 json_object_int_add(jo
, "echo-interval",
504 bs
->timers
.required_min_echo
/ 1000);
506 json_object_int_add(jo
, "echo-interval", 0);
508 json_object_int_add(jo
, "remote-receive-interval",
509 bs
->remote_timers
.required_min_rx
/ 1000);
510 json_object_int_add(jo
, "remote-transmit-interval",
511 bs
->remote_timers
.desired_min_tx
/ 1000);
512 json_object_int_add(jo
, "remote-echo-interval",
513 bs
->remote_timers
.required_min_echo
/ 1000);
518 static void _display_peer_json(struct vty
*vty
, struct bfd_session
*bs
)
520 struct json_object
*jo
= __display_peer_json(bs
);
522 vty_out(vty
, "%s\n", json_object_to_json_string_ext(jo
, 0));
523 json_object_free(jo
);
526 static void _display_peer_iter(struct hash_backet
*hb
, void *arg
)
528 struct vty
*vty
= arg
;
529 struct bfd_session
*bs
= hb
->data
;
531 _display_peer(vty
, bs
);
534 static void _display_peer_json_iter(struct hash_backet
*hb
, void *arg
)
536 struct json_object
*jo
= arg
, *jon
= NULL
;
537 struct bfd_session
*bs
= hb
->data
;
539 jon
= __display_peer_json(bs
);
541 log_warning("%s: not enough memory", __func__
);
545 json_object_array_add(jo
, jon
);
548 static void _display_all_peers(struct vty
*vty
, bool use_json
)
550 struct json_object
*jo
;
552 if (use_json
== false) {
553 bfd_id_iterate(_display_peer_iter
, vty
);
557 jo
= json_object_new_array();
558 bfd_id_iterate(_display_peer_json_iter
, jo
);
560 vty_out(vty
, "%s\n", json_object_to_json_string_ext(jo
, 0));
561 json_object_free(jo
);
564 DEFPY(bfd_show_peers
, bfd_show_peers_cmd
, "show bfd peers [json]",
566 "Bidirection Forwarding Detection\n"
570 bool json
= use_json(argc
, argv
);
573 _display_all_peers(vty
, true);
575 vty_out(vty
, "BFD Peers:\n");
576 _display_all_peers(vty
, false);
582 DEFPY(bfd_show_peer
, bfd_show_peer_cmd
,
583 "show bfd peer <WORD$label|<A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$local|interface IFNAME$ifname|vrf NAME$vrfname}]> [json]",
585 "Bidirection Forwarding Detection\n"
588 PEER_IPV4_STR PEER_IPV6_STR
590 LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
598 struct bfd_session
*bs
= NULL
;
599 struct peer_label
*pl
;
600 struct bfd_peer_cfg bpc
;
601 struct sockaddr_any psa
, lsa
, *lsap
;
604 /* Look up the BFD peer. */
610 strtosa(peer_str
, &psa
);
612 strtosa(local_str
, &lsa
);
618 mhop
= argv_find(argv
, argc
, "multihop", &idx
);
620 if (bfd_configure_peer(&bpc
, mhop
, &psa
, lsap
, ifname
, vrfname
,
621 errormsg
, sizeof(errormsg
))
623 vty_out(vty
, "%% Invalid peer configuration: %s\n",
625 return CMD_WARNING_CONFIG_FAILED
;
628 bs
= bs_peer_find(&bpc
);
631 /* Find peer data. */
633 vty_out(vty
, "%% Unable to find 'peer %s",
634 label
? label
: peer_str
);
636 vty_out(vty
, " interface %s", ifname
);
638 vty_out(vty
, " local-address %s", local_str
);
640 vty_out(vty
, " vrf %s", vrfname
);
643 return CMD_WARNING_CONFIG_FAILED
;
646 if (use_json(argc
, argv
)) {
647 _display_peer_json(vty
, bs
);
649 vty_out(vty
, "BFD Peer:\n");
650 _display_peer(vty
, bs
);
658 * Function definitions.
662 * Configuration rules:
665 * peer + (optional vxlan or interface name)
668 * peer + local + (optional vrf)
670 * Anything else is misconfiguration.
672 static int bfd_configure_peer(struct bfd_peer_cfg
*bpc
, bool mhop
,
673 const struct sockaddr_any
*peer
,
674 const struct sockaddr_any
*local
,
675 const char *ifname
, const char *vrfname
,
676 char *ebuf
, size_t ebuflen
)
678 memset(bpc
, 0, sizeof(*bpc
));
681 bpc
->bpc_shutdown
= true;
682 bpc
->bpc_detectmultiplier
= BPC_DEF_DETECTMULTIPLIER
;
683 bpc
->bpc_recvinterval
= BPC_DEF_RECEIVEINTERVAL
;
684 bpc
->bpc_txinterval
= BPC_DEF_TRANSMITINTERVAL
;
685 bpc
->bpc_echointerval
= BPC_DEF_ECHOINTERVAL
;
686 bpc
->bpc_lastevent
= monotime(NULL
);
688 /* Safety check: when no error buf is provided len must be zero. */
692 /* Peer is always mandatory. */
694 snprintf(ebuf
, ebuflen
, "peer must not be empty");
698 /* Validate address families. */
699 if (peer
->sa_sin
.sin_family
== AF_INET
) {
700 if (local
&& local
->sa_sin
.sin_family
!= AF_INET
) {
701 snprintf(ebuf
, ebuflen
,
702 "local is IPv6, but peer is IPv4");
706 bpc
->bpc_ipv4
= true;
707 } else if (peer
->sa_sin
.sin_family
== AF_INET6
) {
708 if (local
&& local
->sa_sin
.sin_family
!= AF_INET6
) {
709 snprintf(ebuf
, ebuflen
,
710 "local is IPv4, but peer is IPv6");
714 bpc
->bpc_ipv4
= false;
716 snprintf(ebuf
, ebuflen
, "invalid peer address family");
720 /* Copy local and/or peer addresses. */
722 bpc
->bpc_local
= *local
;
725 bpc
->bpc_peer
= *peer
;
727 /* Peer configuration is mandatory. */
728 snprintf(ebuf
, ebuflen
, "no peer configured");
732 bpc
->bpc_mhop
= mhop
;
735 /* Handle VxLAN configuration. */
737 if (vxlan
> ((1 << 24) - 1)) {
738 snprintf(ebuf
, ebuflen
, "invalid VxLAN %d", vxlan
);
742 snprintf(ebuf
, ebuflen
,
743 "multihop doesn't accept VxLAN");
747 bpc
->bpc_vxlan
= vxlan
;
751 /* Handle interface specification configuration. */
754 snprintf(ebuf
, ebuflen
,
755 "multihop doesn't accept interface names");
759 bpc
->bpc_has_localif
= true;
760 if (strlcpy(bpc
->bpc_localif
, ifname
, sizeof(bpc
->bpc_localif
))
761 > sizeof(bpc
->bpc_localif
)) {
762 snprintf(ebuf
, ebuflen
, "interface name too long");
767 /* Handle VRF configuration. */
769 bpc
->bpc_has_vrfname
= true;
770 if (strlcpy(bpc
->bpc_vrfname
, vrfname
, sizeof(bpc
->bpc_vrfname
))
771 > sizeof(bpc
->bpc_vrfname
)) {
772 snprintf(ebuf
, ebuflen
, "vrf name too long");
779 static int bfdd_write_config(struct vty
*vty
)
781 vty_out(vty
, "bfd\n");
786 static void _bfdd_peer_write_config(struct hash_backet
*hb
, void *arg
)
788 struct vty
*vty
= arg
;
789 struct bfd_session
*bs
= hb
->data
;
791 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_MH
)) {
792 vty_out(vty
, " peer %s", satostr(&bs
->mhop
.peer
));
793 vty_out(vty
, " multihop");
794 vty_out(vty
, " local-address %s", satostr(&bs
->mhop
.local
));
795 if (bs
->mhop
.vrf_name
[0])
796 vty_out(vty
, " vrf %s", bs
->mhop
.vrf_name
);
799 vty_out(vty
, " peer %s", satostr(&bs
->shop
.peer
));
800 if (bs
->local_address
.sa_sin
.sin_family
!= AF_UNSPEC
)
801 vty_out(vty
, " local-address %s",
802 satostr(&bs
->local_address
));
803 if (bs
->shop
.port_name
[0])
804 vty_out(vty
, " interface %s", bs
->shop
.port_name
);
808 if (bs
->detect_mult
!= BPC_DEF_DETECTMULTIPLIER
)
809 vty_out(vty
, " detect-multiplier %d\n", bs
->detect_mult
);
810 if (bs
->timers
.required_min_rx
!= (BPC_DEF_RECEIVEINTERVAL
* 1000))
811 vty_out(vty
, " receive-interval %" PRIu32
"\n",
812 bs
->timers
.required_min_rx
/ 1000);
813 if (bs
->up_min_tx
!= (BPC_DEF_TRANSMITINTERVAL
* 1000))
814 vty_out(vty
, " transmit-interval %" PRIu32
"\n",
815 bs
->up_min_tx
/ 1000);
816 if (bs
->timers
.required_min_echo
!= (BPC_DEF_ECHOINTERVAL
* 1000))
817 vty_out(vty
, " echo-interval %" PRIu32
"\n",
818 bs
->timers
.required_min_echo
/ 1000);
820 vty_out(vty
, " label %s\n", bs
->pl
->pl_label
);
821 if (BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_ECHO
))
822 vty_out(vty
, " echo-mode\n");
824 vty_out(vty
, " %sshutdown\n",
825 BFD_CHECK_FLAG(bs
->flags
, BFD_SESS_FLAG_SHUTDOWN
) ? "" : "no ");
827 vty_out(vty
, " !\n");
830 static int bfdd_peer_write_config(struct vty
*vty
)
832 bfd_id_iterate(_bfdd_peer_write_config
, vty
);
836 struct cmd_node bfd_node
= {
842 struct cmd_node bfd_peer_node
= {
844 "%s(config-bfd-peer)# ",
848 void bfdd_vty_init(void)
850 install_element(ENABLE_NODE
, &bfd_show_peers_cmd
);
851 install_element(ENABLE_NODE
, &bfd_show_peer_cmd
);
852 install_element(CONFIG_NODE
, &bfd_enter_cmd
);
854 /* Install BFD node and commands. */
855 install_node(&bfd_node
, bfdd_write_config
);
856 install_default(BFD_NODE
);
857 install_element(BFD_NODE
, &bfd_peer_enter_cmd
);
858 install_element(BFD_NODE
, &bfd_no_peer_cmd
);
860 /* Install BFD peer node. */
861 install_node(&bfd_peer_node
, bfdd_peer_write_config
);
862 install_default(BFD_PEER_NODE
);
863 install_element(BFD_PEER_NODE
, &bfd_peer_detectmultiplier_cmd
);
864 install_element(BFD_PEER_NODE
, &bfd_peer_recvinterval_cmd
);
865 install_element(BFD_PEER_NODE
, &bfd_peer_txinterval_cmd
);
866 install_element(BFD_PEER_NODE
, &bfd_peer_echointerval_cmd
);
867 install_element(BFD_PEER_NODE
, &bfd_peer_shutdown_cmd
);
868 install_element(BFD_PEER_NODE
, &bfd_peer_echo_cmd
);
869 install_element(BFD_PEER_NODE
, &bfd_peer_label_cmd
);