diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index ec331332cfca..b21d472066c0 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -60,7 +60,9 @@ enum pim_mlag_flags { /* initial dump of data done post peerlink flap */ PIM_MLAGF_PEER_REPLAY_DONE = (1 << 3), /* zebra is up on the peer */ - PIM_MLAGF_PEER_ZEBRA_UP = (1 << 4) + PIM_MLAGF_PEER_ZEBRA_UP = (1 << 4), + /* Local MLAGD session is not up*/ + PIM_MLAGF_PEER_ZEBRA_UP_NOTIFY_RECEIVE_PENDING = (1 << 5) }; struct pim_router { diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c index dcef2d0d33ab..216e34ead91a 100644 --- a/pimd/pim_mlag.c +++ b/pimd/pim_mlag.c @@ -552,6 +552,23 @@ static inline void pim_mlag_vxlan_state_update(void) /********************API to process PIM MLAG Data ************************/ +static void pim_mlag_peer_zebra_flag_set(void) +{ + if (CHECK_FLAG(router->mlag_flags, + PIM_MLAGF_PEER_ZEBRA_UP_NOTIFY_RECEIVE_PENDING)) { + if (!(CHECK_FLAG(router->mlag_flags, + PIM_MLAGF_PEER_ZEBRA_UP))) { + if (PIM_DEBUG_MLAG) + zlog_debug( + "%s: update Mlag flag with PIM_MLAGF_PEER_ZEBRA_UP", + __func__); + SET_FLAG(router->mlag_flags, PIM_MLAGF_PEER_ZEBRA_UP); + UNSET_FLAG( + router->mlag_flags, + PIM_MLAGF_PEER_ZEBRA_UP_NOTIFY_RECEIVE_PENDING); + } + } +} static void pim_mlag_process_mlagd_state_change(struct mlag_status msg) { @@ -612,6 +629,7 @@ static void pim_mlag_process_mlagd_state_change(struct mlag_status msg) router->connected_to_mlag = false; } + pim_mlag_peer_zebra_flag_set(); /* apply the changes */ /* when connection to mlagd comes up we hold send mroutes till we have * rxed the status and had a chance to re-valuate DF state @@ -620,7 +638,7 @@ static void pim_mlag_process_mlagd_state_change(struct mlag_status msg) router->mlag_flags |= PIM_MLAGF_STATUS_RXED; pim_mlag_vxlan_state_update(); /* on session up re-eval DF status */ - pim_mlag_up_local_reeval(false /*mlagd_send*/, "mlagd_up"); + pim_mlag_up_local_reeval(true /*mlagd_send*/, "mlagd_up"); /* replay all the upstream entries to the local MLAG daemon */ pim_mlag_up_local_replay(); return; @@ -657,9 +675,13 @@ static void pim_mlag_process_peer_frr_state_change(struct mlag_frr_status msg) (msg.frr_state == MLAG_FRR_STATE_UP ? "UP" : "DOWN")); if (!(router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)) { + SET_FLAG(router->mlag_flags, + PIM_MLAGF_PEER_ZEBRA_UP_NOTIFY_RECEIVE_PENDING); if (PIM_DEBUG_MLAG) - zlog_debug("%s: msg ignored mlagd process state down", - __func__); + zlog_debug( + "%s: msg ignored mlagd process state down, \ + Setting Local MLAG Pending flag", + __func__); return; } ++router->mlag_stats.msg.peer_zebra_status_updates; @@ -668,6 +690,10 @@ static void pim_mlag_process_peer_frr_state_change(struct mlag_frr_status msg) if (msg.frr_state == MLAG_FRR_STATE_UP) { if (!(router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)) { router->mlag_flags |= PIM_MLAGF_PEER_ZEBRA_UP; + if (PIM_DEBUG_MLAG) + zlog_debug( + "%s:%d: Mlag Peer FRR state is UP Setting PIM_MLAGF_PEER_ZEBRA_UP mlag flag %0x", + __func__, __LINE__, router->mlag_flags); /* XXX - when peer zebra comes up we need to wait for * for some time to let the peer setup MDTs before * before relinquishing DF status @@ -679,6 +705,10 @@ static void pim_mlag_process_peer_frr_state_change(struct mlag_frr_status msg) if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP) { ++router->mlag_stats.peer_zebra_downs; router->mlag_flags &= ~PIM_MLAGF_PEER_ZEBRA_UP; + if (PIM_DEBUG_MLAG) + zlog_debug( + "%s:%d: Mlag Peer FRR state is DOWN unsetting PIM_MLAGF_PEER_ZEBRA_UP mlag flag %0x", + __func__, __LINE__, router->mlag_flags); /* when a peer zebra goes down we assume DF role */ pim_mlag_up_local_reeval(true /*mlagd_send*/, "zebra_down"); @@ -881,6 +911,12 @@ int pim_zebra_mlag_process_up(ZAPI_CALLBACK_ARGS) */ router->connected_to_mlag = true; router->mlag_flags |= PIM_MLAGF_LOCAL_CONN_UP; + /* + * Handle when local mlag session comes up later, + * Update the Peer Zebra status once the local MLAG connection is + * restored based on peer connection status. + */ + pim_mlag_peer_zebra_flag_set(); return 0; }