forked from Mirror/frr
bfdd: migrate session commands to northbound
Lets start using the new BFD yang model and translate the BFD session configuration commands to use the northbound. One important change: all sessions will default to use `VRF_DEFAULT_NAME` (usually "default") when no VRF is configured. All places which search for BFD sessions must now take this into account. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
3e4e7405ff
commit
adc26455bf
78
bfdd/bfd.c
78
bfdd/bfd.c
|
@ -34,7 +34,6 @@
|
|||
DEFINE_MTYPE_STATIC(BFDD, BFDD_CONFIG, "long-lived configuration memory")
|
||||
DEFINE_MTYPE_STATIC(BFDD, BFDD_SESSION_OBSERVER, "Session observer")
|
||||
DEFINE_MTYPE_STATIC(BFDD, BFDD_VRF, "BFD VRF")
|
||||
DEFINE_QOBJ_TYPE(bfd_session)
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
|
@ -85,6 +84,8 @@ void gen_bfd_key(struct bfd_key *key, struct sockaddr_any *peer,
|
|||
strlcpy(key->ifname, ifname, sizeof(key->ifname));
|
||||
if (vrfname && vrfname[0])
|
||||
strlcpy(key->vrfname, vrfname, sizeof(key->vrfname));
|
||||
else
|
||||
strlcpy(key->vrfname, VRF_DEFAULT_NAME, sizeof(key->vrfname));
|
||||
}
|
||||
|
||||
struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
|
||||
|
@ -390,17 +391,13 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
|
|||
|
||||
/* Search for session without using discriminator. */
|
||||
ifp = if_lookup_by_index(ifindex, vrfid);
|
||||
if (vrfid == VRF_DEFAULT) {
|
||||
/*
|
||||
* Don't use the default vrf, otherwise we won't find
|
||||
* sessions that doesn't specify it.
|
||||
*/
|
||||
vrf = NULL;
|
||||
} else
|
||||
if (vrfid != VRF_DEFAULT)
|
||||
vrf = vrf_lookup_by_id(vrfid);
|
||||
else
|
||||
vrf = NULL;
|
||||
|
||||
gen_bfd_key(&key, peer, local, is_mhop, ifp ? ifp->name : NULL,
|
||||
vrf ? vrf->name : NULL);
|
||||
vrf ? vrf->name : VRF_DEFAULT_NAME);
|
||||
|
||||
/* XXX maybe remoteDiscr should be checked for remoteHeard cases. */
|
||||
return bfd_key_lookup(key);
|
||||
|
@ -469,8 +466,6 @@ struct bfd_session *bfd_session_new(void)
|
|||
|
||||
bs = XCALLOC(MTYPE_BFDD_CONFIG, sizeof(*bs));
|
||||
|
||||
QOBJ_REG(bs, bfd_session);
|
||||
|
||||
bs->timers.desired_min_tx = BFD_DEFDESIREDMINTX;
|
||||
bs->timers.required_min_rx = BFD_DEFREQUIREDMINRX;
|
||||
bs->timers.required_min_echo = BFD_DEF_REQ_MIN_ECHO;
|
||||
|
@ -644,7 +639,6 @@ void bfd_session_free(struct bfd_session *bs)
|
|||
|
||||
pl_free(bs->pl);
|
||||
|
||||
QOBJ_UNREG(bs);
|
||||
XFREE(MTYPE_BFDD_CONFIG, bs);
|
||||
}
|
||||
|
||||
|
@ -680,6 +674,9 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
|||
if (bpc->bpc_has_vrfname)
|
||||
strlcpy(bfd->key.vrfname, bpc->bpc_vrfname,
|
||||
sizeof(bfd->key.vrfname));
|
||||
else
|
||||
strlcpy(bfd->key.vrfname, VRF_DEFAULT_NAME,
|
||||
sizeof(bfd->key.vrfname));
|
||||
|
||||
/* Copy remaining data. */
|
||||
if (bpc->bpc_ipv4 == false)
|
||||
|
@ -1292,6 +1289,7 @@ static unsigned int bfd_key_hash_do(const void *p);
|
|||
|
||||
static void _bfd_free(struct hash_bucket *hb,
|
||||
void *arg __attribute__((__unused__)));
|
||||
int _bfd_session_next(struct hash_bucket *hb, void *arg);
|
||||
|
||||
/* BFD hash for our discriminator. */
|
||||
static unsigned int bfd_id_hash_do(const void *p)
|
||||
|
@ -1533,6 +1531,62 @@ void bfd_shutdown(void)
|
|||
hash_free(bfd_key_hash);
|
||||
}
|
||||
|
||||
struct bfd_session_iterator {
|
||||
int bsi_stop;
|
||||
bool bsi_mhop;
|
||||
const struct bfd_session *bsi_bs;
|
||||
};
|
||||
|
||||
int _bfd_session_next(struct hash_bucket *hb, void *arg)
|
||||
{
|
||||
struct bfd_session_iterator *bsi = arg;
|
||||
struct bfd_session *bs = hb->data;
|
||||
|
||||
/* Previous entry signaled stop. */
|
||||
if (bsi->bsi_stop == 1) {
|
||||
/* Match the single/multi hop sessions. */
|
||||
if (bs->key.mhop != bsi->bsi_mhop)
|
||||
return HASHWALK_CONTINUE;
|
||||
|
||||
bsi->bsi_bs = bs;
|
||||
return HASHWALK_ABORT;
|
||||
}
|
||||
|
||||
/* We found the current item, stop in the next one. */
|
||||
if (bsi->bsi_bs == hb->data) {
|
||||
bsi->bsi_stop = 1;
|
||||
/* Set entry to NULL to signal end of list. */
|
||||
bsi->bsi_bs = NULL;
|
||||
} else if (bsi->bsi_bs == NULL && bsi->bsi_mhop == bs->key.mhop) {
|
||||
/* We want the first list item. */
|
||||
bsi->bsi_stop = 1;
|
||||
bsi->bsi_bs = hb->data;
|
||||
return HASHWALK_ABORT;
|
||||
}
|
||||
|
||||
return HASHWALK_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_session_next: uses the current session to find the next.
|
||||
*
|
||||
* `bs` might point to NULL to get the first item of the data structure.
|
||||
*/
|
||||
const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
|
||||
bool mhop)
|
||||
{
|
||||
struct bfd_session_iterator bsi;
|
||||
|
||||
bsi.bsi_stop = 0;
|
||||
bsi.bsi_bs = bs;
|
||||
bsi.bsi_mhop = mhop;
|
||||
hash_walk(bfd_key_hash, _bfd_session_next, &bsi);
|
||||
if (bsi.bsi_stop == 0)
|
||||
return NULL;
|
||||
|
||||
return bsi.bsi_bs;
|
||||
}
|
||||
|
||||
/*
|
||||
* VRF related functions.
|
||||
*/
|
||||
|
|
23
bfdd/bfd.h
23
bfdd/bfd.h
|
@ -252,11 +252,7 @@ struct bfd_session {
|
|||
struct bfd_timers remote_timers;
|
||||
|
||||
uint64_t refcount; /* number of pointers referencing this. */
|
||||
|
||||
/* VTY context data. */
|
||||
QOBJ_FIELDS
|
||||
};
|
||||
DECLARE_QOBJ_TYPE(bfd_session)
|
||||
|
||||
struct peer_label {
|
||||
TAILQ_ENTRY(peer_label) pl_entry;
|
||||
|
@ -552,6 +548,9 @@ void gen_bfd_key(struct bfd_key *key, struct sockaddr_any *peer,
|
|||
struct bfd_session *bfd_session_new(void);
|
||||
struct bfd_session *bs_registrate(struct bfd_session *bs);
|
||||
void bfd_session_free(struct bfd_session *bs);
|
||||
const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
|
||||
bool mhop);
|
||||
|
||||
/* BFD hash data structures interface */
|
||||
void bfd_initialize(void);
|
||||
void bfd_shutdown(void);
|
||||
|
@ -590,6 +589,14 @@ extern struct in6_addr zero_addr;
|
|||
void bfdd_vty_init(void);
|
||||
|
||||
|
||||
/*
|
||||
* bfdd_cli.c
|
||||
*
|
||||
* BFD daemon CLI implementation.
|
||||
*/
|
||||
void bfdd_cli_init(void);
|
||||
|
||||
|
||||
/*
|
||||
* ptm_adapter.c
|
||||
*/
|
||||
|
@ -602,4 +609,12 @@ void bfdd_sessions_disable_vrf(struct vrf *vrf);
|
|||
|
||||
int ptm_bfd_notify(struct bfd_session *bs);
|
||||
|
||||
|
||||
/*
|
||||
* bfdd_northbound.c
|
||||
*
|
||||
* BFD northbound callbacks.
|
||||
*/
|
||||
extern const struct frr_yang_module_info frr_bfdd_info;
|
||||
|
||||
#endif /* _BFD_H_ */
|
||||
|
|
|
@ -93,10 +93,17 @@ static struct quagga_signal_t bfd_signals[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct frr_yang_module_info *bfdd_yang_modules[] = {
|
||||
&frr_interface_info,
|
||||
&frr_bfdd_info,
|
||||
};
|
||||
|
||||
FRR_DAEMON_INFO(bfdd, BFD, .vty_port = 2617,
|
||||
.proghelp = "Implementation of the BFD protocol.",
|
||||
.signals = bfd_signals, .n_signals = array_size(bfd_signals),
|
||||
.privs = &bglobal.bfdd_privs)
|
||||
.privs = &bglobal.bfdd_privs,
|
||||
.yang_modules = bfdd_yang_modules,
|
||||
.n_yang_modules = array_size(bfdd_yang_modules))
|
||||
|
||||
#define OPTION_CTLSOCK 1001
|
||||
static struct option longopts[] = {
|
||||
|
|
232
bfdd/bfdd_cli.c
Normal file
232
bfdd/bfdd_cli.c
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* BFD daemon CLI implementation.
|
||||
*
|
||||
* Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
|
||||
* Rafael Zalamena
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "lib/command.h"
|
||||
#include "lib/log.h"
|
||||
#include "lib/northbound_cli.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bfdd/bfdd_cli_clippy.c"
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
#include "bfd.h"
|
||||
|
||||
/*
|
||||
* Definitions.
|
||||
*/
|
||||
#define PEER_STR "Configure peer\n"
|
||||
#define INTERFACE_NAME_STR "Configure interface name to use\n"
|
||||
#define PEER_IPV4_STR "IPv4 peer address\n"
|
||||
#define PEER_IPV6_STR "IPv6 peer address\n"
|
||||
#define MHOP_STR "Configure multihop\n"
|
||||
#define LOCAL_STR "Configure local address\n"
|
||||
#define LOCAL_IPV4_STR "IPv4 local address\n"
|
||||
#define LOCAL_IPV6_STR "IPv6 local address\n"
|
||||
#define LOCAL_INTF_STR "Configure local interface name to use\n"
|
||||
#define VRF_STR "Configure VRF\n"
|
||||
#define VRF_NAME_STR "Configure VRF name\n"
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Functions.
|
||||
*/
|
||||
DEFPY_NOSH(
|
||||
bfd_peer_enter, bfd_peer_enter_cmd,
|
||||
"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}]",
|
||||
PEER_STR
|
||||
PEER_IPV4_STR
|
||||
PEER_IPV6_STR
|
||||
MHOP_STR
|
||||
LOCAL_STR
|
||||
LOCAL_IPV4_STR
|
||||
LOCAL_IPV6_STR
|
||||
INTERFACE_STR
|
||||
LOCAL_INTF_STR
|
||||
VRF_STR
|
||||
VRF_NAME_STR)
|
||||
{
|
||||
int ret, slen;
|
||||
char xpath[XPATH_MAXLEN];
|
||||
char source_str[INET6_ADDRSTRLEN];
|
||||
|
||||
if (multihop)
|
||||
snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
|
||||
local_address_str);
|
||||
else
|
||||
source_str[0] = 0;
|
||||
|
||||
slen = snprintf(xpath, sizeof(xpath),
|
||||
"/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
|
||||
multihop ? "multi-hop" : "single-hop", source_str,
|
||||
peer_str);
|
||||
if (ifname)
|
||||
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
|
||||
"[interface='%s']", ifname);
|
||||
else
|
||||
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
|
||||
"[interface='']");
|
||||
if (vrf)
|
||||
snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']", vrf);
|
||||
else
|
||||
snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']",
|
||||
VRF_DEFAULT_NAME);
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
|
||||
/* Apply settings immediatly. */
|
||||
ret = nb_cli_apply_changes(vty, NULL);
|
||||
if (ret == CMD_SUCCESS)
|
||||
VTY_PUSH_XPATH(BFD_PEER_NODE, xpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_no_peer, bfd_no_peer_cmd,
|
||||
"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}]",
|
||||
NO_STR
|
||||
PEER_STR
|
||||
PEER_IPV4_STR
|
||||
PEER_IPV6_STR
|
||||
MHOP_STR
|
||||
LOCAL_STR
|
||||
LOCAL_IPV4_STR
|
||||
LOCAL_IPV6_STR
|
||||
INTERFACE_STR
|
||||
LOCAL_INTF_STR
|
||||
VRF_STR
|
||||
VRF_NAME_STR)
|
||||
{
|
||||
int slen;
|
||||
char xpath[XPATH_MAXLEN];
|
||||
char source_str[INET6_ADDRSTRLEN];
|
||||
|
||||
if (multihop)
|
||||
snprintf(source_str, sizeof(source_str), "[source-addr='%s']",
|
||||
local_address_str);
|
||||
else
|
||||
source_str[0] = 0;
|
||||
|
||||
slen = snprintf(xpath, sizeof(xpath),
|
||||
"/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
|
||||
multihop ? "multi-hop" : "single-hop", source_str,
|
||||
peer_str);
|
||||
if (ifname)
|
||||
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
|
||||
"[interface='%s']", ifname);
|
||||
else
|
||||
slen += snprintf(xpath + slen, sizeof(xpath) - slen,
|
||||
"[interface='']");
|
||||
if (vrf)
|
||||
snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']", vrf);
|
||||
else
|
||||
snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']",
|
||||
VRF_DEFAULT_NAME);
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
/* Apply settings immediatly. */
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_peer_shutdown, bfd_peer_shutdown_cmd,
|
||||
"[no] shutdown",
|
||||
NO_STR
|
||||
"Disable BFD peer")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./administrative-down", NB_OP_MODIFY,
|
||||
no ? "false" : "true");
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_peer_mult, bfd_peer_mult_cmd,
|
||||
"detect-multiplier (2-255)$multiplier",
|
||||
"Configure peer detection multiplier\n"
|
||||
"Configure peer detection multiplier value\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./detection-multiplier", NB_OP_MODIFY,
|
||||
multiplier_str);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_peer_rx, bfd_peer_rx_cmd,
|
||||
"receive-interval (10-60000)$interval",
|
||||
"Configure peer receive interval\n"
|
||||
"Configure peer receive interval value in milliseconds\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./required-receive-interval", NB_OP_MODIFY,
|
||||
interval_str);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_peer_tx, bfd_peer_tx_cmd,
|
||||
"transmit-interval (10-60000)$interval",
|
||||
"Configure peer transmit interval\n"
|
||||
"Configure peer transmit interval value in milliseconds\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./desired-transmission-interval",
|
||||
NB_OP_MODIFY, interval_str);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_peer_echo, bfd_peer_echo_cmd,
|
||||
"[no] echo-mode",
|
||||
NO_STR
|
||||
"Configure echo mode\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./echo-mode", NB_OP_MODIFY,
|
||||
no ? "false" : "true");
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_peer_echo_interval, bfd_peer_echo_interval_cmd,
|
||||
"echo-interval (10-60000)$interval",
|
||||
"Configure peer echo interval\n"
|
||||
"Configure peer echo interval value in milliseconds\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./desired-echo-transmission-interval",
|
||||
NB_OP_MODIFY, interval_str);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
bfdd_cli_init(void)
|
||||
{
|
||||
install_element(BFD_NODE, &bfd_peer_enter_cmd);
|
||||
install_element(BFD_NODE, &bfd_no_peer_cmd);
|
||||
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_shutdown_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_mult_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_rx_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_tx_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_echo_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_echo_interval_cmd);
|
||||
}
|
1060
bfdd/bfdd_northbound.c
Normal file
1060
bfdd/bfdd_northbound.c
Normal file
File diff suppressed because it is too large
Load diff
264
bfdd/bfdd_vty.c
264
bfdd/bfdd_vty.c
|
@ -34,8 +34,6 @@
|
|||
/*
|
||||
* Commands help string definitions.
|
||||
*/
|
||||
#define PEER_STR "Configure peer\n"
|
||||
#define INTERFACE_NAME_STR "Configure interface name to use\n"
|
||||
#define PEER_IPV4_STR "IPv4 peer address\n"
|
||||
#define PEER_IPV6_STR "IPv6 peer address\n"
|
||||
#define MHOP_STR "Configure multihop\n"
|
||||
|
@ -43,8 +41,6 @@
|
|||
#define LOCAL_IPV4_STR "IPv4 local address\n"
|
||||
#define LOCAL_IPV6_STR "IPv6 local address\n"
|
||||
#define LOCAL_INTF_STR "Configure local interface name to use\n"
|
||||
#define VRF_STR "Configure VRF\n"
|
||||
#define VRF_NAME_STR "Configure VRF name\n"
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
|
@ -88,256 +84,6 @@ DEFUN_NOSH(bfd_enter, bfd_enter_cmd, "bfd", "Configure BFD peers\n")
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_NOSH(
|
||||
bfd_peer_enter, bfd_peer_enter_cmd,
|
||||
"peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
|
||||
PEER_STR PEER_IPV4_STR PEER_IPV6_STR
|
||||
MHOP_STR
|
||||
LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
|
||||
INTERFACE_STR
|
||||
LOCAL_INTF_STR
|
||||
VRF_STR VRF_NAME_STR)
|
||||
{
|
||||
bool mhop;
|
||||
int idx;
|
||||
struct bfd_session *bs;
|
||||
const char *peer, *ifname, *local, *vrfname;
|
||||
struct bfd_peer_cfg bpc;
|
||||
struct sockaddr_any psa, lsa, *lsap;
|
||||
char errormsg[128];
|
||||
|
||||
vrfname = peer = ifname = local = NULL;
|
||||
|
||||
/* Gather all provided information. */
|
||||
peer = argv[1]->arg;
|
||||
|
||||
idx = 0;
|
||||
mhop = argv_find(argv, argc, "multihop", &idx);
|
||||
|
||||
idx = 0;
|
||||
if (argv_find(argv, argc, "interface", &idx))
|
||||
ifname = argv[idx + 1]->arg;
|
||||
|
||||
idx = 0;
|
||||
if (argv_find(argv, argc, "local-address", &idx))
|
||||
local = argv[idx + 1]->arg;
|
||||
|
||||
idx = 0;
|
||||
if (argv_find(argv, argc, "vrf", &idx))
|
||||
vrfname = argv[idx + 1]->arg;
|
||||
|
||||
strtosa(peer, &psa);
|
||||
if (local) {
|
||||
strtosa(local, &lsa);
|
||||
lsap = &lsa;
|
||||
} else
|
||||
lsap = NULL;
|
||||
|
||||
if (bfd_configure_peer(&bpc, mhop, &psa, lsap, ifname, vrfname,
|
||||
errormsg, sizeof(errormsg))
|
||||
!= 0) {
|
||||
vty_out(vty, "%% Invalid peer configuration: %s\n", errormsg);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
bs = bs_peer_find(&bpc);
|
||||
if (bs == NULL) {
|
||||
bs = ptm_bfd_sess_new(&bpc);
|
||||
if (bs == NULL) {
|
||||
vty_out(vty, "%% Failed to add peer.\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG)) {
|
||||
if (bs->refcount)
|
||||
vty_out(vty, "%% session peer is now configurable via bfd daemon.\n");
|
||||
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
|
||||
}
|
||||
|
||||
VTY_PUSH_CONTEXT(BFD_PEER_NODE, bs);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_peer_detectmultiplier, bfd_peer_detectmultiplier_cmd,
|
||||
"detect-multiplier (2-255)$multiplier",
|
||||
"Configure peer detection multiplier\n"
|
||||
"Configure peer detection multiplier value\n")
|
||||
{
|
||||
struct bfd_session *bs;
|
||||
|
||||
bs = VTY_GET_CONTEXT(bfd_session);
|
||||
if (bs->detect_mult == multiplier)
|
||||
return CMD_SUCCESS;
|
||||
|
||||
bs->detect_mult = multiplier;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_peer_recvinterval, bfd_peer_recvinterval_cmd,
|
||||
"receive-interval (10-60000)$interval",
|
||||
"Configure peer receive interval\n"
|
||||
"Configure peer receive interval value in milliseconds\n")
|
||||
{
|
||||
struct bfd_session *bs;
|
||||
|
||||
bs = VTY_GET_CONTEXT(bfd_session);
|
||||
if (bs->timers.required_min_rx == (uint32_t)(interval * 1000))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
bs->timers.required_min_rx = interval * 1000;
|
||||
bfd_set_polling(bs);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_peer_txinterval, bfd_peer_txinterval_cmd,
|
||||
"transmit-interval (10-60000)$interval",
|
||||
"Configure peer transmit interval\n"
|
||||
"Configure peer transmit interval value in milliseconds\n")
|
||||
{
|
||||
struct bfd_session *bs;
|
||||
|
||||
bs = VTY_GET_CONTEXT(bfd_session);
|
||||
if (bs->timers.desired_min_tx == (uint32_t)(interval * 1000))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
bs->timers.desired_min_tx = interval * 1000;
|
||||
bfd_set_polling(bs);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_peer_echointerval, bfd_peer_echointerval_cmd,
|
||||
"echo-interval (10-60000)$interval",
|
||||
"Configure peer echo interval\n"
|
||||
"Configure peer echo interval value in milliseconds\n")
|
||||
{
|
||||
struct bfd_session *bs;
|
||||
|
||||
bs = VTY_GET_CONTEXT(bfd_session);
|
||||
if (bs->timers.required_min_echo == (uint32_t)(interval * 1000))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
bs->timers.required_min_echo = interval * 1000;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_peer_shutdown, bfd_peer_shutdown_cmd, "[no] shutdown",
|
||||
NO_STR "Disable BFD peer")
|
||||
{
|
||||
struct bfd_session *bs;
|
||||
|
||||
bs = VTY_GET_CONTEXT(bfd_session);
|
||||
if (no) {
|
||||
if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
|
||||
|
||||
/* Change and notify state change. */
|
||||
bs->ses_state = PTM_BFD_DOWN;
|
||||
control_notify(bs);
|
||||
|
||||
/* Enable all timers. */
|
||||
bfd_recvtimer_update(bs);
|
||||
bfd_xmttimer_update(bs, bs->xmt_TO);
|
||||
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO)) {
|
||||
bfd_echo_recvtimer_update(bs);
|
||||
bfd_echo_xmttimer_update(bs, bs->echo_xmt_TO);
|
||||
}
|
||||
} else {
|
||||
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
|
||||
|
||||
/* Disable all events. */
|
||||
bfd_recvtimer_delete(bs);
|
||||
bfd_echo_recvtimer_delete(bs);
|
||||
bfd_xmttimer_delete(bs);
|
||||
bfd_echo_xmttimer_delete(bs);
|
||||
|
||||
/* Change and notify state change. */
|
||||
bs->ses_state = PTM_BFD_ADM_DOWN;
|
||||
control_notify(bs);
|
||||
|
||||
ptm_bfd_snd(bs, 0);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_peer_echo, bfd_peer_echo_cmd, "[no] echo-mode",
|
||||
NO_STR "Configure echo mode\n")
|
||||
{
|
||||
struct bfd_session *bs;
|
||||
|
||||
bs = VTY_GET_CONTEXT(bfd_session);
|
||||
if (no) {
|
||||
if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
|
||||
ptm_bfd_echo_stop(bs);
|
||||
} else {
|
||||
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_ECHO);
|
||||
/* Apply setting immediately. */
|
||||
if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN))
|
||||
bs_echo_timer_handler(bs);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(bfd_no_peer, bfd_no_peer_cmd,
|
||||
"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}]",
|
||||
NO_STR
|
||||
PEER_STR PEER_IPV4_STR PEER_IPV6_STR
|
||||
MHOP_STR
|
||||
LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
|
||||
INTERFACE_STR
|
||||
LOCAL_INTF_STR
|
||||
VRF_STR VRF_NAME_STR)
|
||||
{
|
||||
int idx;
|
||||
bool mhop;
|
||||
struct bfd_peer_cfg bpc;
|
||||
struct sockaddr_any psa, lsa, *lsap;
|
||||
char errormsg[128];
|
||||
|
||||
strtosa(peer_str, &psa);
|
||||
if (local) {
|
||||
strtosa(local_str, &lsa);
|
||||
lsap = &lsa;
|
||||
} else {
|
||||
lsap = NULL;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
mhop = argv_find(argv, argc, "multihop", &idx);
|
||||
|
||||
if (bfd_configure_peer(&bpc, mhop, &psa, lsap, ifname, vrfname,
|
||||
errormsg, sizeof(errormsg))
|
||||
!= 0) {
|
||||
vty_out(vty, "%% Invalid peer configuration: %s\n", errormsg);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
if (ptm_bfd_sess_del(&bpc) != 0) {
|
||||
vty_out(vty, "%% Failed to remove peer.\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Show commands helper functions
|
||||
|
@ -1070,16 +816,10 @@ void bfdd_vty_init(void)
|
|||
/* Install BFD node and commands. */
|
||||
install_node(&bfd_node, bfdd_write_config);
|
||||
install_default(BFD_NODE);
|
||||
install_element(BFD_NODE, &bfd_peer_enter_cmd);
|
||||
install_element(BFD_NODE, &bfd_no_peer_cmd);
|
||||
|
||||
/* Install BFD peer node. */
|
||||
install_node(&bfd_peer_node, bfdd_peer_write_config);
|
||||
install_default(BFD_PEER_NODE);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_detectmultiplier_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_recvinterval_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_txinterval_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_echointerval_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_shutdown_cmd);
|
||||
install_element(BFD_PEER_NODE, &bfd_peer_echo_cmd);
|
||||
|
||||
bfdd_cli_init();
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@ noinst_LIBRARIES += bfdd/libbfd.a
|
|||
sbin_PROGRAMS += bfdd/bfdd
|
||||
dist_examples_DATA += bfdd/bfdd.conf.sample
|
||||
vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c
|
||||
vtysh_scan += $(top_srcdir)/bfdd/bfdd_cli.c
|
||||
man8 += $(MANBUILD)/bfdd.8
|
||||
endif
|
||||
|
||||
bfdd_libbfd_a_SOURCES = \
|
||||
bfdd/bfd.c \
|
||||
bfdd/bfdd_northbound.c \
|
||||
bfdd/bfdd_vty.c \
|
||||
bfdd/bfdd_cli.c \
|
||||
bfdd/bfd_packet.c \
|
||||
bfdd/config.c \
|
||||
bfdd/control.c \
|
||||
|
@ -24,6 +27,9 @@ bfdd_libbfd_a_SOURCES = \
|
|||
bfdd/bfdd_vty_clippy.c: $(CLIPPY_DEPS)
|
||||
bfdd/bfdd_vty.$(OBJEXT): bfdd/bfdd_vty_clippy.c
|
||||
|
||||
bfdd/bfdd_cli_clippy.c: $(CLIPPY_DEPS)
|
||||
bfdd/bfdd_cli.$(OBJEXT): bfdd/bfdd_cli_clippy.c
|
||||
|
||||
noinst_HEADERS += \
|
||||
bfdd/bfdctl.h \
|
||||
bfdd/bfd.h \
|
||||
|
|
|
@ -24,6 +24,10 @@ dist_yangmodels_DATA += yang/frr-test-module.yang
|
|||
dist_yangmodels_DATA += yang/frr-interface.yang
|
||||
dist_yangmodels_DATA += yang/frr-route-types.yang
|
||||
|
||||
if BFDD
|
||||
dist_yangmodels_DATA += yang/frr-bfdd.yang
|
||||
endif
|
||||
|
||||
if RIPD
|
||||
dist_yangmodels_DATA += yang/frr-ripd.yang
|
||||
endif
|
||||
|
|
Loading…
Reference in a new issue