diff options
| author | Russ White <russ@riw.us> | 2024-11-26 08:51:07 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-26 08:51:07 -0500 |
| commit | e268fc4665e18cd9c3226fab93158cc30c0eb0e6 (patch) | |
| tree | 0c39971517e20ab77f44e1508ed7f6bf5534730b /bfdd | |
| parent | e8fdbbeb7b11963c95ed34e7a88892e50754b16f (diff) | |
| parent | 20c3756f30f69ae71d9d7acefb925dfb9d526303 (diff) | |
Merge pull request #16987 from opensourcerouting/bfd-echo-sock
bfdd: disable echo socket when not using it
Diffstat (limited to 'bfdd')
| -rw-r--r-- | bfdd/bfd.c | 151 | ||||
| -rw-r--r-- | bfdd/bfd.h | 2 |
2 files changed, 105 insertions, 48 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c index eb9c300313..f32bc2598b 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -1172,6 +1172,9 @@ void bfd_set_echo(struct bfd_session *bs, bool echo) if (bs->bdc == NULL) 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) @@ -1800,6 +1803,69 @@ void bfd_profiles_remove(void) 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. */ @@ -1842,9 +1908,23 @@ static void bfd_profile_detach(struct bfd_profile *bp) */ static int bfd_vrf_new(struct vrf *vrf) { + struct bfd_vrf_global *bvrf; + if (bglobal.debug_zebra) 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; } @@ -1853,70 +1933,53 @@ static int bfd_vrf_delete(struct vrf *vrf) if (bglobal.debug_zebra) zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id); + XFREE(MTYPE_BFDD_VRF, vrf->info); + return 0; } static int bfd_vrf_enable(struct vrf *vrf) { - struct bfd_vrf_global *bvrf; - - /* 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; + struct bfd_vrf_global *bvrf = vrf->info; if (bglobal.debug_zebra) 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 */ + if (bglobal.bg_use_dplane) + goto skip_sockets; + + if (bvrf->bg_shop == -1) bvrf->bg_shop = bp_udp_shop(vrf); - if (!bvrf->bg_mhop) + if (bvrf->bg_mhop == -1) bvrf->bg_mhop = bp_udp_mhop(vrf); - if (!bvrf->bg_shop6) + if (bvrf->bg_shop6 == -1) bvrf->bg_shop6 = bp_udp6_shop(vrf); - if (!bvrf->bg_mhop6) + if (bvrf->bg_mhop6 == -1) 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_ev[0] == NULL && bvrf->bg_shop != -1) event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop, &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, &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, &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, &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) { bfdd_zclient_register(vrf->vrf_id); bfdd_sessions_enable_vrf(vrf); } + return 0; } @@ -1948,17 +2011,9 @@ static int bfd_vrf_disable(struct vrf *vrf) socket_close(&bvrf->bg_echo); socket_close(&bvrf->bg_shop); socket_close(&bvrf->bg_mhop); - if (bvrf->bg_shop6 != -1) - socket_close(&bvrf->bg_shop6); - if (bvrf->bg_mhop6 != -1) - 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; + socket_close(&bvrf->bg_shop6); + socket_close(&bvrf->bg_mhop6); + socket_close(&bvrf->bg_echov6); return 0; } diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 2f83b245eb..d4d14ffce6 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -610,6 +610,8 @@ void bfd_sessions_remove_manual(void); void bfd_profiles_remove(void); 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. * |
