forked from Mirror/frr
bfdd: support global BFD reset
Add command 'no bfd' to remove all BFD sessions configuration and fix other daemon integration. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
47a7b00c2d
commit
2a573ff672
30
bfdd/bfd.c
30
bfdd/bfd.c
|
@ -1290,6 +1290,7 @@ static unsigned int bfd_key_hash_do(const void *p);
|
||||||
static void _bfd_free(struct hash_bucket *hb,
|
static void _bfd_free(struct hash_bucket *hb,
|
||||||
void *arg __attribute__((__unused__)));
|
void *arg __attribute__((__unused__)));
|
||||||
int _bfd_session_next(struct hash_bucket *hb, void *arg);
|
int _bfd_session_next(struct hash_bucket *hb, void *arg);
|
||||||
|
void _bfd_session_remove_manual(struct hash_bucket *hb, void *arg);
|
||||||
|
|
||||||
/* BFD hash for our discriminator. */
|
/* BFD hash for our discriminator. */
|
||||||
static unsigned int bfd_id_hash_do(const void *p)
|
static unsigned int bfd_id_hash_do(const void *p)
|
||||||
|
@ -1587,6 +1588,35 @@ const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
|
||||||
return bsi.bsi_bs;
|
return bsi.bsi_bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _bfd_session_remove_manual(struct hash_bucket *hb,
|
||||||
|
void *arg __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
struct bfd_session *bs = hb->data;
|
||||||
|
|
||||||
|
/* Delete only manually configured sessions. */
|
||||||
|
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bs->refcount--;
|
||||||
|
BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
|
||||||
|
|
||||||
|
/* Don't delete sessions still in use. */
|
||||||
|
if (bs->refcount != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bfd_session_free(bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bfd_sessions_remove_manual: remove all manually configured sessions.
|
||||||
|
*
|
||||||
|
* NOTE: this function doesn't remove automatically created sessions.
|
||||||
|
*/
|
||||||
|
void bfd_sessions_remove_manual(void)
|
||||||
|
{
|
||||||
|
hash_iterate(bfd_key_hash, _bfd_session_remove_manual, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VRF related functions.
|
* VRF related functions.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -550,6 +550,7 @@ struct bfd_session *bs_registrate(struct bfd_session *bs);
|
||||||
void bfd_session_free(struct bfd_session *bs);
|
void bfd_session_free(struct bfd_session *bs);
|
||||||
const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
|
const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
|
||||||
bool mhop);
|
bool mhop);
|
||||||
|
void bfd_sessions_remove_manual(void);
|
||||||
|
|
||||||
/* BFD hash data structures interface */
|
/* BFD hash data structures interface */
|
||||||
void bfd_initialize(void);
|
void bfd_initialize(void);
|
||||||
|
|
|
@ -52,6 +52,16 @@
|
||||||
/*
|
/*
|
||||||
* Functions.
|
* Functions.
|
||||||
*/
|
*/
|
||||||
|
DEFUN(
|
||||||
|
bfd_config_reset, bfd_config_reset_cmd,
|
||||||
|
"no bfd",
|
||||||
|
NO_STR
|
||||||
|
"Configure BFD peers\n")
|
||||||
|
{
|
||||||
|
nb_cli_enqueue_change(vty, "/frr-bfdd:bfdd/bfd", NB_OP_DESTROY, NULL);
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void bfd_cli_show_header(struct vty *vty,
|
void bfd_cli_show_header(struct vty *vty,
|
||||||
struct lyd_node *dnode __attribute__((__unused__)),
|
struct lyd_node *dnode __attribute__((__unused__)),
|
||||||
bool show_defaults __attribute__((__unused__)))
|
bool show_defaults __attribute__((__unused__)))
|
||||||
|
@ -343,6 +353,8 @@ void bfd_cli_show_echo_interval(struct vty *vty, struct lyd_node *dnode,
|
||||||
void
|
void
|
||||||
bfdd_cli_init(void)
|
bfdd_cli_init(void)
|
||||||
{
|
{
|
||||||
|
install_element(CONFIG_NODE, &bfd_config_reset_cmd);
|
||||||
|
|
||||||
install_element(BFD_NODE, &bfd_peer_enter_cmd);
|
install_element(BFD_NODE, &bfd_peer_enter_cmd);
|
||||||
install_element(BFD_NODE, &bfd_no_peer_cmd);
|
install_element(BFD_NODE, &bfd_no_peer_cmd);
|
||||||
|
|
||||||
|
|
|
@ -71,11 +71,27 @@ int bfd_session_create(enum nb_event event, const struct lyd_node *dnode,
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
bfd_session_get_key(mhop, dnode, &bk);
|
bfd_session_get_key(mhop, dnode, &bk);
|
||||||
if (bfd_key_lookup(bk))
|
bs = bfd_key_lookup(bk);
|
||||||
|
|
||||||
|
/* This session was already configured by CLI. */
|
||||||
|
if (bs != NULL && BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
|
||||||
return NB_ERR_VALIDATION;
|
return NB_ERR_VALIDATION;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NB_EV_PREPARE:
|
case NB_EV_PREPARE:
|
||||||
|
bfd_session_get_key(mhop, dnode, &bk);
|
||||||
|
bs = bfd_key_lookup(bk);
|
||||||
|
|
||||||
|
/* This session was already configured by another daemon. */
|
||||||
|
if (bs != NULL) {
|
||||||
|
/* Now it is configured also by CLI. */
|
||||||
|
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
|
||||||
|
bs->refcount++;
|
||||||
|
|
||||||
|
resource->ptr = bs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bs = bfd_session_new();
|
bs = bfd_session_new();
|
||||||
if (bs == NULL)
|
if (bs == NULL)
|
||||||
return NB_ERR_RESOURCE;
|
return NB_ERR_RESOURCE;
|
||||||
|
@ -84,6 +100,7 @@ int bfd_session_create(enum nb_event event, const struct lyd_node *dnode,
|
||||||
bfd_session_get_key(mhop, dnode, &bs->key);
|
bfd_session_get_key(mhop, dnode, &bs->key);
|
||||||
|
|
||||||
/* Set configuration flags. */
|
/* Set configuration flags. */
|
||||||
|
bs->refcount = 1;
|
||||||
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
|
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
|
||||||
if (mhop)
|
if (mhop)
|
||||||
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_MH);
|
BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_MH);
|
||||||
|
@ -95,13 +112,17 @@ int bfd_session_create(enum nb_event event, const struct lyd_node *dnode,
|
||||||
|
|
||||||
case NB_EV_APPLY:
|
case NB_EV_APPLY:
|
||||||
bs = resource->ptr;
|
bs = resource->ptr;
|
||||||
if (bs_registrate(bs) == NULL)
|
|
||||||
|
/* Only attempt to registrate if freshly allocated. */
|
||||||
|
if (bs->discrs.my_discr == 0 && bs_registrate(bs) == NULL)
|
||||||
return NB_ERR_RESOURCE;
|
return NB_ERR_RESOURCE;
|
||||||
|
|
||||||
nb_running_set_entry(dnode, bs);
|
nb_running_set_entry(dnode, bs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NB_EV_ABORT:
|
case NB_EV_ABORT:
|
||||||
|
bs = resource->ptr;
|
||||||
|
if (bs->refcount <= 1)
|
||||||
bfd_session_free(resource->ptr);
|
bfd_session_free(resource->ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +133,7 @@ int bfd_session_create(enum nb_event event, const struct lyd_node *dnode,
|
||||||
int bfd_session_destroy(enum nb_event event, const struct lyd_node *dnode,
|
int bfd_session_destroy(enum nb_event event, const struct lyd_node *dnode,
|
||||||
bool mhop)
|
bool mhop)
|
||||||
{
|
{
|
||||||
|
struct bfd_session *bs;
|
||||||
struct bfd_key bk;
|
struct bfd_key bk;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -126,7 +148,18 @@ int bfd_session_destroy(enum nb_event event, const struct lyd_node *dnode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NB_EV_APPLY:
|
case NB_EV_APPLY:
|
||||||
bfd_session_free(nb_running_unset_entry(dnode));
|
bs = nb_running_unset_entry(dnode);
|
||||||
|
/* CLI is not using this session anymore. */
|
||||||
|
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
|
||||||
|
bs->refcount--;
|
||||||
|
/* There are still daemons using it. */
|
||||||
|
if (bs->refcount > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bfd_session_free(bs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NB_EV_ABORT:
|
case NB_EV_ABORT:
|
||||||
|
@ -152,8 +185,25 @@ static int bfdd_bfd_create(enum nb_event event,
|
||||||
|
|
||||||
static int bfdd_bfd_destroy(enum nb_event event, const struct lyd_node *dnode)
|
static int bfdd_bfd_destroy(enum nb_event event, const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
|
switch (event) {
|
||||||
|
case NB_EV_VALIDATE:
|
||||||
/* NOTHING */
|
/* NOTHING */
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
|
case NB_EV_PREPARE:
|
||||||
|
/* NOTHING */
|
||||||
|
return NB_OK;
|
||||||
|
|
||||||
|
case NB_EV_APPLY:
|
||||||
|
bfd_sessions_remove_manual();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NB_EV_ABORT:
|
||||||
|
/* NOTHING */
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue