Merge pull request #6390 from opensourcerouting/bfd-cp-fix

bfdd: tell peer when our control plane is dead
This commit is contained in:
Russ White 2020-06-16 07:56:03 -04:00 committed by GitHub
commit cba183561b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -128,6 +128,35 @@ static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
timers[0], timers[1], timers[2], cbit_str); timers[0], timers[1], timers[2], cbit_str);
} }
static void _ptm_bfd_session_del(struct bfd_session *bs, uint8_t diag)
{
if (bglobal.debug_peer_event)
zlog_debug("session-delete: %s", bs_to_string(bs));
/* Change state and notify peer. */
bs->ses_state = PTM_BFD_DOWN;
bs->local_diag = diag;
ptm_bfd_snd(bs, 0);
/* Session reached refcount == 0, lets delete it. */
if (bs->refcount == 0) {
/*
* Sanity check: if there is a refcount bug, we can't delete
* the session a user configured manually. Lets leave a
* message here so we can catch the bug if it exists.
*/
if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG)) {
zlog_err(
"ptm-del-session: [%s] session refcount is "
"zero but it was configured by CLI",
bs_to_string(bs));
} else {
control_notify_config(BCM_NOTIFY_CONFIG_DELETE, bs);
bfd_session_free(bs);
}
}
}
static int _ptm_msg_address(struct stream *msg, int family, const void *addr) static int _ptm_msg_address(struct stream *msg, int family, const void *addr)
{ {
stream_putc(msg, family); stream_putc(msg, family);
@ -456,15 +485,20 @@ static void bfdd_dest_deregister(struct stream *msg, vrf_id_t vrf_id)
/* Unregister client peer notification. */ /* Unregister client peer notification. */
pcn = pcn_lookup(pc, bs); pcn = pcn_lookup(pc, bs);
if (pcn != NULL) {
pcn_free(pcn); pcn_free(pcn);
if (bs->refcount ||
CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
return; return;
}
bs->ses_state = PTM_BFD_ADM_DOWN; if (bglobal.debug_zebra)
ptm_bfd_snd(bs, 0); zlog_debug("ptm-del-dest: failed to find BFD session");
ptm_bfd_sess_del(&bpc); /*
* XXX: We either got a double deregistration or the daemon who
* created this is no longer around. Lets try to delete it anyway
* and the worst case is the refcount will detain us.
*/
_ptm_bfd_session_del(bs, BD_NEIGHBOR_DOWN);
} }
/* /*
@ -506,6 +540,9 @@ static void bfdd_client_deregister(struct stream *msg)
return; return;
} }
if (bglobal.debug_zebra)
zlog_debug("ptm-del-client: client pid %u", pid);
pc_free(pc); pc_free(pc);
return; return;
@ -827,9 +864,6 @@ static void pc_free(struct ptm_client *pc)
{ {
struct ptm_client_notification *pcn; struct ptm_client_notification *pcn;
if (pc == NULL)
return;
TAILQ_REMOVE(&pcqueue, pc, pc_entry); TAILQ_REMOVE(&pcqueue, pc, pc_entry);
while (!TAILQ_EMPTY(&pc->pc_pcnqueue)) { while (!TAILQ_EMPTY(&pc->pc_pcnqueue)) {
@ -891,14 +925,19 @@ static void pcn_free(struct ptm_client_notification *pcn)
struct ptm_client *pc; struct ptm_client *pc;
struct bfd_session *bs; struct bfd_session *bs;
if (pcn == NULL)
return;
/* Handle session de-registration. */ /* Handle session de-registration. */
bs = pcn->pcn_bs; bs = pcn->pcn_bs;
pcn->pcn_bs = NULL; pcn->pcn_bs = NULL;
bs->refcount--; bs->refcount--;
/* Log modification to users. */
if (bglobal.debug_zebra)
zlog_debug("ptm-del-session: [%s] refcount=%" PRIu64,
bs_to_string(bs), bs->refcount);
/* Set session down. */
_ptm_bfd_session_del(bs, BD_NEIGHBOR_DOWN);
/* Handle ptm_client deregistration. */ /* Handle ptm_client deregistration. */
pc = pcn->pcn_pc; pc = pcn->pcn_pc;
pcn->pcn_pc = NULL; pcn->pcn_pc = NULL;