mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 20:13:53 +00:00
bfdd: refactor state change handler
Expand state change handling into smaller functions with more explanatory commentaries. This also handles some corner cases that were not being handled. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
09720d3189
commit
aef131afc5
123
bfdd/bfd.c
123
bfdd/bfd.c
@ -694,6 +694,129 @@ void bfd_set_polling(struct bfd_session *bs)
|
||||
bs->polling = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* bs_<state>_handler() functions implement the BFD state machine
|
||||
* transition mechanism. `<state>` is the current session state and
|
||||
* the parameter `nstate` is the peer new state.
|
||||
*/
|
||||
void bs_admin_down_handler(struct bfd_session *bs, int nstate);
|
||||
void bs_down_handler(struct bfd_session *bs, int nstate);
|
||||
void bs_init_handler(struct bfd_session *bs, int nstate);
|
||||
void bs_up_handler(struct bfd_session *bs, int nstate);
|
||||
|
||||
void bs_admin_down_handler(struct bfd_session *bs __attribute__((__unused__)),
|
||||
int nstate __attribute__((__unused__)))
|
||||
{
|
||||
/*
|
||||
* We are administratively down, there is no state machine
|
||||
* handling.
|
||||
*/
|
||||
}
|
||||
|
||||
void bs_down_handler(struct bfd_session *bs, int nstate)
|
||||
{
|
||||
switch (nstate) {
|
||||
case PTM_BFD_ADM_DOWN:
|
||||
/*
|
||||
* Remote peer doesn't want to talk, so lets keep the
|
||||
* connection down.
|
||||
*/
|
||||
case PTM_BFD_UP:
|
||||
/* Peer can't be up yet, wait it go to 'init' or 'down'. */
|
||||
break;
|
||||
|
||||
case PTM_BFD_DOWN:
|
||||
/*
|
||||
* Remote peer agreed that the path is down, lets try to
|
||||
* bring it up.
|
||||
*/
|
||||
bs->ses_state = PTM_BFD_INIT;
|
||||
break;
|
||||
|
||||
case PTM_BFD_INIT:
|
||||
/*
|
||||
* Remote peer told us his path is up, lets turn
|
||||
* activate the session.
|
||||
*/
|
||||
ptm_bfd_ses_up(bs);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_debug("state-change: unhandled neighbor state: %d", nstate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bs_init_handler(struct bfd_session *bs, int nstate)
|
||||
{
|
||||
switch (nstate) {
|
||||
case PTM_BFD_ADM_DOWN:
|
||||
/*
|
||||
* Remote peer doesn't want to talk, so lets make the
|
||||
* connection down.
|
||||
*/
|
||||
bs->ses_state = PTM_BFD_DOWN;
|
||||
break;
|
||||
|
||||
case PTM_BFD_DOWN:
|
||||
/* Remote peer hasn't moved to first stage yet. */
|
||||
break;
|
||||
|
||||
case PTM_BFD_INIT:
|
||||
case PTM_BFD_UP:
|
||||
/* We agreed on the settings and the path is up. */
|
||||
ptm_bfd_ses_up(bs);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_debug("state-change: unhandled neighbor state: %d", nstate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bs_up_handler(struct bfd_session *bs, int nstate)
|
||||
{
|
||||
switch (nstate) {
|
||||
case PTM_BFD_ADM_DOWN:
|
||||
case PTM_BFD_DOWN:
|
||||
/* Peer lost or asked to shutdown connection. */
|
||||
ptm_bfd_ses_dn(bs, BD_NEIGHBOR_DOWN);
|
||||
break;
|
||||
|
||||
case PTM_BFD_INIT:
|
||||
case PTM_BFD_UP:
|
||||
/* Path is up and working. */
|
||||
break;
|
||||
|
||||
default:
|
||||
log_debug("state-change: unhandled neighbor state: %d", nstate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bs_state_handler(struct bfd_session *bs, int nstate)
|
||||
{
|
||||
switch (bs->ses_state) {
|
||||
case PTM_BFD_ADM_DOWN:
|
||||
bs_admin_down_handler(bs, nstate);
|
||||
break;
|
||||
case PTM_BFD_DOWN:
|
||||
bs_down_handler(bs, nstate);
|
||||
break;
|
||||
case PTM_BFD_INIT:
|
||||
bs_init_handler(bs, nstate);
|
||||
break;
|
||||
case PTM_BFD_UP:
|
||||
bs_up_handler(bs, nstate);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_debug("state-change: [%s] is in invalid state: %d",
|
||||
bs_to_string(bs), nstate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Helper functions.
|
||||
|
@ -525,6 +525,7 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name,
|
||||
struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc);
|
||||
int bfd_session_update_label(struct bfd_session *bs, const char *nlabel);
|
||||
void bfd_set_polling(struct bfd_session *bs);
|
||||
void bs_state_handler(struct bfd_session *, int);
|
||||
const char *satostr(struct sockaddr_any *sa);
|
||||
const char *diag2str(uint8_t diag);
|
||||
int strtosa(const char *addr, struct sockaddr_any *sa);
|
||||
|
@ -668,29 +668,8 @@ int bfd_recv_cb(struct thread *t)
|
||||
/* Save remote diagnostics before state switch. */
|
||||
bfd->remote_diag = cp->diag & BFD_DIAGMASK;
|
||||
|
||||
/* State switch from section 6.8.6 */
|
||||
if (BFD_GETSTATE(cp->flags) == PTM_BFD_ADM_DOWN) {
|
||||
if (bfd->ses_state != PTM_BFD_DOWN)
|
||||
ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN);
|
||||
} else {
|
||||
switch (bfd->ses_state) {
|
||||
case (PTM_BFD_DOWN):
|
||||
if (BFD_GETSTATE(cp->flags) == PTM_BFD_INIT)
|
||||
ptm_bfd_ses_up(bfd);
|
||||
else if (BFD_GETSTATE(cp->flags) == PTM_BFD_DOWN)
|
||||
bfd->ses_state = PTM_BFD_INIT;
|
||||
break;
|
||||
case (PTM_BFD_INIT):
|
||||
if (BFD_GETSTATE(cp->flags) == PTM_BFD_INIT
|
||||
|| BFD_GETSTATE(cp->flags) == PTM_BFD_UP)
|
||||
ptm_bfd_ses_up(bfd);
|
||||
break;
|
||||
case (PTM_BFD_UP):
|
||||
if (BFD_GETSTATE(cp->flags) == PTM_BFD_DOWN)
|
||||
ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* State switch from section 6.2. */
|
||||
bs_state_handler(bfd, BFD_GETSTATE(cp->flags));
|
||||
|
||||
/*
|
||||
* Handle echo packet status:
|
||||
|
Loading…
Reference in New Issue
Block a user