forked from Mirror/frr
Merge pull request #16987 from opensourcerouting/bfd-echo-sock
bfdd: disable echo socket when not using it
This commit is contained in:
commit
e268fc4665
159
bfdd/bfd.c
159
bfdd/bfd.c
|
@ -1172,6 +1172,9 @@ void bfd_set_echo(struct bfd_session *bs, bool echo)
|
||||||
if (bs->bdc == NULL)
|
if (bs->bdc == NULL)
|
||||||
ptm_bfd_echo_stop(bs);
|
ptm_bfd_echo_stop(bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bs->vrf && bs->vrf->info)
|
||||||
|
bfd_vrf_toggle_echo(bs->vrf->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bfd_set_shutdown(struct bfd_session *bs, bool shutdown)
|
void bfd_set_shutdown(struct bfd_session *bs, bool shutdown)
|
||||||
|
@ -1800,6 +1803,69 @@ void bfd_profiles_remove(void)
|
||||||
bfd_profile_free(bp);
|
bfd_profile_free(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct __bfd_session_echo {
|
||||||
|
/* VRF peers must match */
|
||||||
|
struct vrf *vrf;
|
||||||
|
/* Echo enabled or not */
|
||||||
|
bool enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __bfd_session_has_echo(struct hash_bucket *hb, void *arg)
|
||||||
|
{
|
||||||
|
const struct bfd_session *session = hb->data;
|
||||||
|
struct __bfd_session_echo *has_echo = arg;
|
||||||
|
|
||||||
|
if (session->vrf != has_echo->vrf)
|
||||||
|
return HASHWALK_CONTINUE;
|
||||||
|
if (!CHECK_FLAG(session->flags, BFD_SESS_FLAG_ECHO))
|
||||||
|
return HASHWALK_CONTINUE;
|
||||||
|
|
||||||
|
has_echo->enabled = true;
|
||||||
|
return HASHWALK_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bfd_vrf_toggle_echo(struct bfd_vrf_global *bfd_vrf)
|
||||||
|
{
|
||||||
|
struct __bfd_session_echo has_echo = {
|
||||||
|
.enabled = false,
|
||||||
|
.vrf = bfd_vrf->vrf,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Check for peers using echo */
|
||||||
|
hash_walk(bfd_id_hash, __bfd_session_has_echo, &has_echo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No peers using echo, close all echo sockets.
|
||||||
|
*/
|
||||||
|
if (!has_echo.enabled) {
|
||||||
|
if (bfd_vrf->bg_echo != -1) {
|
||||||
|
event_cancel(&bfd_vrf->bg_ev[4]);
|
||||||
|
close(bfd_vrf->bg_echo);
|
||||||
|
bfd_vrf->bg_echo = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bfd_vrf->bg_echov6 != -1) {
|
||||||
|
event_cancel(&bfd_vrf->bg_ev[5]);
|
||||||
|
close(bfd_vrf->bg_echov6);
|
||||||
|
bfd_vrf->bg_echov6 = -1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At least one peer using echo, open echo sockets.
|
||||||
|
*/
|
||||||
|
if (bfd_vrf->bg_echo == -1)
|
||||||
|
bfd_vrf->bg_echo = bp_echo_socket(bfd_vrf->vrf);
|
||||||
|
if (bfd_vrf->bg_echov6 == -1)
|
||||||
|
bfd_vrf->bg_echov6 = bp_echov6_socket(bfd_vrf->vrf);
|
||||||
|
|
||||||
|
if (bfd_vrf->bg_ev[4] == NULL && bfd_vrf->bg_echo != -1)
|
||||||
|
event_add_read(master, bfd_recv_cb, bfd_vrf, bfd_vrf->bg_echo, &bfd_vrf->bg_ev[4]);
|
||||||
|
if (bfd_vrf->bg_ev[5] == NULL && bfd_vrf->bg_echov6 != -1)
|
||||||
|
event_add_read(master, bfd_recv_cb, bfd_vrf, bfd_vrf->bg_echov6, &bfd_vrf->bg_ev[5]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Profile related hash functions.
|
* Profile related hash functions.
|
||||||
*/
|
*/
|
||||||
|
@ -1842,9 +1908,23 @@ static void bfd_profile_detach(struct bfd_profile *bp)
|
||||||
*/
|
*/
|
||||||
static int bfd_vrf_new(struct vrf *vrf)
|
static int bfd_vrf_new(struct vrf *vrf)
|
||||||
{
|
{
|
||||||
|
struct bfd_vrf_global *bvrf;
|
||||||
|
|
||||||
if (bglobal.debug_zebra)
|
if (bglobal.debug_zebra)
|
||||||
zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
|
zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
|
bvrf = XCALLOC(MTYPE_BFDD_VRF, sizeof(struct bfd_vrf_global));
|
||||||
|
bvrf->vrf = vrf;
|
||||||
|
vrf->info = bvrf;
|
||||||
|
|
||||||
|
/* Invalidate all sockets */
|
||||||
|
bvrf->bg_shop = -1;
|
||||||
|
bvrf->bg_mhop = -1;
|
||||||
|
bvrf->bg_shop6 = -1;
|
||||||
|
bvrf->bg_mhop6 = -1;
|
||||||
|
bvrf->bg_echo = -1;
|
||||||
|
bvrf->bg_echov6 = -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1853,70 +1933,53 @@ static int bfd_vrf_delete(struct vrf *vrf)
|
||||||
if (bglobal.debug_zebra)
|
if (bglobal.debug_zebra)
|
||||||
zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
|
zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
|
XFREE(MTYPE_BFDD_VRF, vrf->info);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfd_vrf_enable(struct vrf *vrf)
|
static int bfd_vrf_enable(struct vrf *vrf)
|
||||||
{
|
{
|
||||||
struct bfd_vrf_global *bvrf;
|
struct bfd_vrf_global *bvrf = vrf->info;
|
||||||
|
|
||||||
/* a different name */
|
|
||||||
if (!vrf->info) {
|
|
||||||
bvrf = XCALLOC(MTYPE_BFDD_VRF, sizeof(struct bfd_vrf_global));
|
|
||||||
bvrf->vrf = vrf;
|
|
||||||
vrf->info = (void *)bvrf;
|
|
||||||
|
|
||||||
/* Disable sockets if using data plane. */
|
|
||||||
if (bglobal.bg_use_dplane) {
|
|
||||||
bvrf->bg_shop = -1;
|
|
||||||
bvrf->bg_mhop = -1;
|
|
||||||
bvrf->bg_shop6 = -1;
|
|
||||||
bvrf->bg_mhop6 = -1;
|
|
||||||
bvrf->bg_echo = -1;
|
|
||||||
bvrf->bg_echov6 = -1;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
bvrf = vrf->info;
|
|
||||||
|
|
||||||
if (bglobal.debug_zebra)
|
if (bglobal.debug_zebra)
|
||||||
zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
|
zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
if (!bvrf->bg_shop)
|
/* Don't open sockets when using data plane */
|
||||||
bvrf->bg_shop = bp_udp_shop(vrf);
|
if (bglobal.bg_use_dplane)
|
||||||
if (!bvrf->bg_mhop)
|
goto skip_sockets;
|
||||||
bvrf->bg_mhop = bp_udp_mhop(vrf);
|
|
||||||
if (!bvrf->bg_shop6)
|
|
||||||
bvrf->bg_shop6 = bp_udp6_shop(vrf);
|
|
||||||
if (!bvrf->bg_mhop6)
|
|
||||||
bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
|
|
||||||
if (!bvrf->bg_echo)
|
|
||||||
bvrf->bg_echo = bp_echo_socket(vrf);
|
|
||||||
if (!bvrf->bg_echov6)
|
|
||||||
bvrf->bg_echov6 = bp_echov6_socket(vrf);
|
|
||||||
|
|
||||||
if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
|
if (bvrf->bg_shop == -1)
|
||||||
|
bvrf->bg_shop = bp_udp_shop(vrf);
|
||||||
|
if (bvrf->bg_mhop == -1)
|
||||||
|
bvrf->bg_mhop = bp_udp_mhop(vrf);
|
||||||
|
if (bvrf->bg_shop6 == -1)
|
||||||
|
bvrf->bg_shop6 = bp_udp6_shop(vrf);
|
||||||
|
if (bvrf->bg_mhop6 == -1)
|
||||||
|
bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
|
||||||
|
|
||||||
|
if (bvrf->bg_ev[0] == NULL && bvrf->bg_shop != -1)
|
||||||
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
|
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
|
||||||
&bvrf->bg_ev[0]);
|
&bvrf->bg_ev[0]);
|
||||||
if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
|
if (bvrf->bg_ev[1] == NULL && bvrf->bg_mhop != -1)
|
||||||
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
|
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
|
||||||
&bvrf->bg_ev[1]);
|
&bvrf->bg_ev[1]);
|
||||||
if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
|
if (bvrf->bg_ev[2] == NULL && bvrf->bg_shop6 != -1)
|
||||||
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
|
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
|
||||||
&bvrf->bg_ev[2]);
|
&bvrf->bg_ev[2]);
|
||||||
if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
|
if (bvrf->bg_ev[3] == NULL && bvrf->bg_mhop6 != -1)
|
||||||
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
|
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
|
||||||
&bvrf->bg_ev[3]);
|
&bvrf->bg_ev[3]);
|
||||||
if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
|
|
||||||
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
|
|
||||||
&bvrf->bg_ev[4]);
|
|
||||||
if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
|
|
||||||
event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
|
|
||||||
&bvrf->bg_ev[5]);
|
|
||||||
|
|
||||||
|
/* Toggle echo if VRF was disabled. */
|
||||||
|
bfd_vrf_toggle_echo(bvrf);
|
||||||
|
|
||||||
|
skip_sockets:
|
||||||
if (vrf->vrf_id != VRF_DEFAULT) {
|
if (vrf->vrf_id != VRF_DEFAULT) {
|
||||||
bfdd_zclient_register(vrf->vrf_id);
|
bfdd_zclient_register(vrf->vrf_id);
|
||||||
bfdd_sessions_enable_vrf(vrf);
|
bfdd_sessions_enable_vrf(vrf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1948,17 +2011,9 @@ static int bfd_vrf_disable(struct vrf *vrf)
|
||||||
socket_close(&bvrf->bg_echo);
|
socket_close(&bvrf->bg_echo);
|
||||||
socket_close(&bvrf->bg_shop);
|
socket_close(&bvrf->bg_shop);
|
||||||
socket_close(&bvrf->bg_mhop);
|
socket_close(&bvrf->bg_mhop);
|
||||||
if (bvrf->bg_shop6 != -1)
|
socket_close(&bvrf->bg_shop6);
|
||||||
socket_close(&bvrf->bg_shop6);
|
socket_close(&bvrf->bg_mhop6);
|
||||||
if (bvrf->bg_mhop6 != -1)
|
socket_close(&bvrf->bg_echov6);
|
||||||
socket_close(&bvrf->bg_mhop6);
|
|
||||||
socket_close(&bvrf->bg_echo);
|
|
||||||
if (bvrf->bg_echov6 != -1)
|
|
||||||
socket_close(&bvrf->bg_echov6);
|
|
||||||
|
|
||||||
/* free context */
|
|
||||||
XFREE(MTYPE_BFDD_VRF, bvrf);
|
|
||||||
vrf->info = NULL;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,6 +610,8 @@ void bfd_sessions_remove_manual(void);
|
||||||
void bfd_profiles_remove(void);
|
void bfd_profiles_remove(void);
|
||||||
void bfd_rtt_init(struct bfd_session *bfd);
|
void bfd_rtt_init(struct bfd_session *bfd);
|
||||||
|
|
||||||
|
extern void bfd_vrf_toggle_echo(struct bfd_vrf_global *bfd_vrf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the BFD session echo state.
|
* Set the BFD session echo state.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue