mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 11:30:30 +00:00
Merge pull request #5197 from SumitAgarwal123/BFD_ADMIN_DOWN
bfdd: Handling local and remote admin-down
This commit is contained in:
commit
37cdb6e91d
46
bfdd/bfd.c
46
bfdd/bfd.c
@ -49,6 +49,8 @@ static void bs_admin_down_handler(struct bfd_session *bs, int nstate);
|
|||||||
static void bs_down_handler(struct bfd_session *bs, int nstate);
|
static void bs_down_handler(struct bfd_session *bs, int nstate);
|
||||||
static void bs_init_handler(struct bfd_session *bs, int nstate);
|
static void bs_init_handler(struct bfd_session *bs, int nstate);
|
||||||
static void bs_up_handler(struct bfd_session *bs, int nstate);
|
static void bs_up_handler(struct bfd_session *bs, int nstate);
|
||||||
|
static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
|
||||||
|
uint8_t diag);
|
||||||
|
|
||||||
/* Zeroed array with the size of an IPv6 address. */
|
/* Zeroed array with the size of an IPv6 address. */
|
||||||
struct in6_addr zero_addr;
|
struct in6_addr zero_addr;
|
||||||
@ -312,7 +314,7 @@ void ptm_bfd_sess_up(struct bfd_session *bfd)
|
|||||||
/* Start sending control packets with poll bit immediately. */
|
/* Start sending control packets with poll bit immediately. */
|
||||||
ptm_bfd_snd(bfd, 0);
|
ptm_bfd_snd(bfd, 0);
|
||||||
|
|
||||||
control_notify(bfd);
|
control_notify(bfd, bfd->ses_state);
|
||||||
|
|
||||||
if (old_state != bfd->ses_state) {
|
if (old_state != bfd->ses_state) {
|
||||||
bfd->stats.session_up++;
|
bfd->stats.session_up++;
|
||||||
@ -347,7 +349,7 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag)
|
|||||||
|
|
||||||
/* only signal clients when going from up->down state */
|
/* only signal clients when going from up->down state */
|
||||||
if (old_state == PTM_BFD_UP)
|
if (old_state == PTM_BFD_UP)
|
||||||
control_notify(bfd);
|
control_notify(bfd, PTM_BFD_DOWN);
|
||||||
|
|
||||||
/* Stop echo packet transmission if they are active */
|
/* Stop echo packet transmission if they are active */
|
||||||
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
|
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
|
||||||
@ -582,7 +584,7 @@ skip_echo:
|
|||||||
|
|
||||||
/* Change and notify state change. */
|
/* Change and notify state change. */
|
||||||
bs->ses_state = PTM_BFD_ADM_DOWN;
|
bs->ses_state = PTM_BFD_ADM_DOWN;
|
||||||
control_notify(bs);
|
control_notify(bs, bs->ses_state);
|
||||||
|
|
||||||
/* Don't try to send packets with a disabled session. */
|
/* Don't try to send packets with a disabled session. */
|
||||||
if (bs->sock != -1)
|
if (bs->sock != -1)
|
||||||
@ -596,7 +598,7 @@ skip_echo:
|
|||||||
|
|
||||||
/* Change and notify state change. */
|
/* Change and notify state change. */
|
||||||
bs->ses_state = PTM_BFD_DOWN;
|
bs->ses_state = PTM_BFD_DOWN;
|
||||||
control_notify(bs);
|
control_notify(bs, bs->ses_state);
|
||||||
|
|
||||||
/* Enable all timers. */
|
/* Enable all timers. */
|
||||||
bfd_recvtimer_update(bs);
|
bfd_recvtimer_update(bs);
|
||||||
@ -868,10 +870,46 @@ static void bs_init_handler(struct bfd_session *bs, int nstate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
|
||||||
|
uint8_t diag)
|
||||||
|
{
|
||||||
|
int old_state = bfd->ses_state;
|
||||||
|
|
||||||
|
bfd->local_diag = diag;
|
||||||
|
bfd->discrs.remote_discr = 0;
|
||||||
|
bfd->ses_state = PTM_BFD_DOWN;
|
||||||
|
bfd->polling = 0;
|
||||||
|
bfd->demand_mode = 0;
|
||||||
|
monotime(&bfd->downtime);
|
||||||
|
|
||||||
|
/* Slow down the control packets, the connection is down. */
|
||||||
|
bs_set_slow_timers(bfd);
|
||||||
|
|
||||||
|
/* only signal clients when going from up->down state */
|
||||||
|
if (old_state == PTM_BFD_UP)
|
||||||
|
control_notify(bfd, PTM_BFD_ADM_DOWN);
|
||||||
|
|
||||||
|
/* Stop echo packet transmission if they are active */
|
||||||
|
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
|
||||||
|
ptm_bfd_echo_stop(bfd);
|
||||||
|
|
||||||
|
if (old_state != bfd->ses_state) {
|
||||||
|
bfd->stats.session_down++;
|
||||||
|
|
||||||
|
log_info("state-change: [%s] %s -> %s reason:%s",
|
||||||
|
bs_to_string(bfd), state_list[old_state].str,
|
||||||
|
state_list[bfd->ses_state].str,
|
||||||
|
get_diag_str(bfd->local_diag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void bs_up_handler(struct bfd_session *bs, int nstate)
|
static void bs_up_handler(struct bfd_session *bs, int nstate)
|
||||||
{
|
{
|
||||||
switch (nstate) {
|
switch (nstate) {
|
||||||
case PTM_BFD_ADM_DOWN:
|
case PTM_BFD_ADM_DOWN:
|
||||||
|
bs_neighbour_admin_down_handler(bs, BD_ADMIN_DOWN);
|
||||||
|
break;
|
||||||
|
|
||||||
case PTM_BFD_DOWN:
|
case PTM_BFD_DOWN:
|
||||||
/* Peer lost or asked to shutdown connection. */
|
/* Peer lost or asked to shutdown connection. */
|
||||||
ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
|
ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
|
||||||
|
@ -365,7 +365,7 @@ TAILQ_HEAD(bcslist, bfd_control_socket);
|
|||||||
|
|
||||||
int control_init(const char *path);
|
int control_init(const char *path);
|
||||||
void control_shutdown(void);
|
void control_shutdown(void);
|
||||||
int control_notify(struct bfd_session *bs);
|
int control_notify(struct bfd_session *bs, uint8_t notify_state);
|
||||||
int control_notify_config(const char *op, struct bfd_session *bs);
|
int control_notify_config(const char *op, struct bfd_session *bs);
|
||||||
int control_accept(struct thread *t);
|
int control_accept(struct thread *t);
|
||||||
|
|
||||||
@ -628,7 +628,7 @@ void bfdd_sessions_enable_vrf(struct vrf *vrf);
|
|||||||
void bfdd_sessions_disable_vrf(struct vrf *vrf);
|
void bfdd_sessions_disable_vrf(struct vrf *vrf);
|
||||||
void bfd_session_update_vrf_name(struct bfd_session *bs, struct vrf *vrf);
|
void bfd_session_update_vrf_name(struct bfd_session *bs, struct vrf *vrf);
|
||||||
|
|
||||||
int ptm_bfd_notify(struct bfd_session *bs);
|
int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -431,7 +431,7 @@ static int bfdd_bfd_sessions_single_hop_administrative_down_modify(
|
|||||||
|
|
||||||
/* Change and notify state change. */
|
/* Change and notify state change. */
|
||||||
bs->ses_state = PTM_BFD_DOWN;
|
bs->ses_state = PTM_BFD_DOWN;
|
||||||
control_notify(bs);
|
control_notify(bs, bs->ses_state);
|
||||||
|
|
||||||
/* Enable all timers. */
|
/* Enable all timers. */
|
||||||
bfd_recvtimer_update(bs);
|
bfd_recvtimer_update(bs);
|
||||||
@ -454,7 +454,7 @@ static int bfdd_bfd_sessions_single_hop_administrative_down_modify(
|
|||||||
|
|
||||||
/* Change and notify state change. */
|
/* Change and notify state change. */
|
||||||
bs->ses_state = PTM_BFD_ADM_DOWN;
|
bs->ses_state = PTM_BFD_ADM_DOWN;
|
||||||
control_notify(bs);
|
control_notify(bs, bs->ses_state);
|
||||||
|
|
||||||
ptm_bfd_snd(bs, 0);
|
ptm_bfd_snd(bs, 0);
|
||||||
}
|
}
|
||||||
|
@ -774,13 +774,13 @@ static void _control_notify(struct bfd_control_socket *bcs,
|
|||||||
control_queue_enqueue(bcs, bcm);
|
control_queue_enqueue(bcs, bcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
int control_notify(struct bfd_session *bs)
|
int control_notify(struct bfd_session *bs, uint8_t notify_state)
|
||||||
{
|
{
|
||||||
struct bfd_control_socket *bcs;
|
struct bfd_control_socket *bcs;
|
||||||
struct bfd_notify_peer *bnp;
|
struct bfd_notify_peer *bnp;
|
||||||
|
|
||||||
/* Notify zebra listeners as well. */
|
/* Notify zebra listeners as well. */
|
||||||
ptm_bfd_notify(bs);
|
ptm_bfd_notify(bs, notify_state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PERFORMANCE: reuse the bfd_control_msg allocated data for
|
* PERFORMANCE: reuse the bfd_control_msg allocated data for
|
||||||
|
@ -153,7 +153,7 @@ static int _ptm_msg_address(struct stream *msg, int family, const void *addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ptm_bfd_notify(struct bfd_session *bs)
|
int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state)
|
||||||
{
|
{
|
||||||
struct stream *msg;
|
struct stream *msg;
|
||||||
|
|
||||||
@ -204,12 +204,15 @@ int ptm_bfd_notify(struct bfd_session *bs)
|
|||||||
_ptm_msg_address(msg, bs->key.family, &bs->key.peer);
|
_ptm_msg_address(msg, bs->key.family, &bs->key.peer);
|
||||||
|
|
||||||
/* BFD status */
|
/* BFD status */
|
||||||
switch (bs->ses_state) {
|
switch (notify_state) {
|
||||||
case PTM_BFD_UP:
|
case PTM_BFD_UP:
|
||||||
stream_putl(msg, BFD_STATUS_UP);
|
stream_putl(msg, BFD_STATUS_UP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PTM_BFD_ADM_DOWN:
|
case PTM_BFD_ADM_DOWN:
|
||||||
|
stream_putl(msg, BFD_STATUS_ADMIN_DOWN);
|
||||||
|
break;
|
||||||
|
|
||||||
case PTM_BFD_DOWN:
|
case PTM_BFD_DOWN:
|
||||||
case PTM_BFD_INIT:
|
case PTM_BFD_INIT:
|
||||||
stream_putl(msg, BFD_STATUS_DOWN);
|
stream_putl(msg, BFD_STATUS_DOWN);
|
||||||
@ -432,7 +435,7 @@ static void bfdd_dest_register(struct stream *msg, vrf_id_t vrf_id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptm_bfd_notify(bs);
|
ptm_bfd_notify(bs, bs->ses_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bfdd_dest_deregister(struct stream *msg, vrf_id_t vrf_id)
|
static void bfdd_dest_deregister(struct stream *msg, vrf_id_t vrf_id)
|
||||||
@ -461,6 +464,10 @@ static void bfdd_dest_deregister(struct stream *msg, vrf_id_t vrf_id)
|
|||||||
if (bs->refcount ||
|
if (bs->refcount ||
|
||||||
BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
|
BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bs->ses_state = PTM_BFD_ADM_DOWN;
|
||||||
|
ptm_bfd_snd(bs, 0);
|
||||||
|
|
||||||
ptm_bfd_sess_del(&bpc);
|
ptm_bfd_sess_del(&bpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +282,8 @@ static void bgp_bfd_peer_status_update(struct peer *peer, int status,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
old_status = bfd_info->status;
|
old_status = bfd_info->status;
|
||||||
bfd_info->status = status;
|
BFD_SET_CLIENT_STATUS(bfd_info->status, status);
|
||||||
|
|
||||||
bfd_info->last_update = bgp_clock();
|
bfd_info->last_update = bgp_clock();
|
||||||
|
|
||||||
if (status != old_status) {
|
if (status != old_status) {
|
||||||
|
@ -118,7 +118,8 @@ static void bfd_adj_event(struct isis_adjacency *adj, struct prefix *dst,
|
|||||||
|
|
||||||
int old_status = adj->bfd_session->status;
|
int old_status = adj->bfd_session->status;
|
||||||
|
|
||||||
adj->bfd_session->status = new_status;
|
BFD_SET_CLIENT_STATUS(adj->bfd_session->status, new_status);
|
||||||
|
|
||||||
if (old_status == new_status)
|
if (old_status == new_status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -315,6 +315,8 @@ const char *bfd_get_status_str(int status)
|
|||||||
return "Down";
|
return "Down";
|
||||||
case BFD_STATUS_UP:
|
case BFD_STATUS_UP:
|
||||||
return "Up";
|
return "Up";
|
||||||
|
case BFD_STATUS_ADMIN_DOWN:
|
||||||
|
return "Admin Down";
|
||||||
case BFD_STATUS_UNKNOWN:
|
case BFD_STATUS_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
@ -54,6 +54,14 @@ struct bfd_gbl {
|
|||||||
#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
|
#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
|
||||||
#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
|
#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
|
||||||
#define BFD_STATUS_UP (1 << 2) /* BFD session status is up */
|
#define BFD_STATUS_UP (1 << 2) /* BFD session status is up */
|
||||||
|
#define BFD_STATUS_ADMIN_DOWN (1 << 3) /* BFD session is admin down */
|
||||||
|
|
||||||
|
#define BFD_SET_CLIENT_STATUS(current_status, new_status) \
|
||||||
|
do { \
|
||||||
|
(current_status) = \
|
||||||
|
(((new_status) == BFD_STATUS_ADMIN_DOWN) ? \
|
||||||
|
BFD_STATUS_DOWN : (new_status));\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
enum bfd_sess_type {
|
enum bfd_sess_type {
|
||||||
BFD_TYPE_NOT_CONFIGURED,
|
BFD_TYPE_NOT_CONFIGURED,
|
||||||
|
@ -236,7 +236,7 @@ static int ospf6_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
old_status = bfd_info->status;
|
old_status = bfd_info->status;
|
||||||
bfd_info->status = status;
|
BFD_SET_CLIENT_STATUS(bfd_info->status, status);
|
||||||
monotime(&tv);
|
monotime(&tv);
|
||||||
bfd_info->last_update = tv.tv_sec;
|
bfd_info->last_update = tv.tv_sec;
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
old_status = bfd_info->status;
|
old_status = bfd_info->status;
|
||||||
bfd_info->status = status;
|
BFD_SET_CLIENT_STATUS(bfd_info->status, status);
|
||||||
monotime(&tv);
|
monotime(&tv);
|
||||||
bfd_info->last_update = tv.tv_sec;
|
bfd_info->last_update = tv.tv_sec;
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
old_status = bfd_info->status;
|
old_status = bfd_info->status;
|
||||||
bfd_info->status = status;
|
BFD_SET_CLIENT_STATUS(bfd_info->status, status);
|
||||||
monotime(&tv);
|
monotime(&tv);
|
||||||
bfd_info->last_update = tv.tv_sec;
|
bfd_info->last_update = tv.tv_sec;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user