From db89f2a3ebd29b53fc06e2c6735b6ff0ff9dcf8a Mon Sep 17 00:00:00 2001 From: plsaranya Date: Wed, 23 Mar 2022 19:16:46 +0530 Subject: [PATCH 1/2] pimd: Assert fixes Problem: PIM assert is not triggered even after receiving WRONGVIF notification because of Could_assert flag not set. CouldAssert(S,G,I) = SPTbit(S,G)==TRUE AND (RPF_interface(S) != I) AND (I in ( ( joins(*,G) (-) prunes(S,G,rpt) ) (+) ( pim_include(*,G) (-) pim_exclude(S,G) ) (-) lost_assert(*,G) (+) joins(S,G) (+) pim_include(S,G) ) ) Once SPTbit is set, Could_assert has to be reevaluated Signed-off-by: plsaranya --- pimd/pim_upstream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 571117ac0a..70f16d066a 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -2062,6 +2062,7 @@ static bool pim_upstream_sg_running_proc(struct pim_upstream *up) if ((up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) && (up->rpf.source_nexthop.interface)) { pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface); + pim_upstream_update_could_assert(up); } return rv; From 2145e986b4ded4f029d4725a4dd175c10f1fb1c9 Mon Sep 17 00:00:00 2001 From: plsaranya Date: Wed, 23 Mar 2022 19:19:43 +0530 Subject: [PATCH 2/2] pimd: RPF change after winner election Problem: Once Assert election is over and winner is elected, the downstream router has to prune from the upstream LOSER if it has joined already and have to join with upstream elected WINNER pim_rpf_update function takes care of changing the rpf_ch if the existing one is PIM_IFASSERT_I_AM_LOSER Signed-off-by: plsaranya --- pimd/pim_assert.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index e7fff4db6f..6bd8321f07 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -34,6 +34,7 @@ #include "pim_hello.h" #include "pim_macro.h" #include "pim_assert.h" +#include "pim_zebra.h" #include "pim_ifchannel.h" static int assert_action_a3(struct pim_ifchannel *ch); @@ -50,6 +51,8 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch, int winner_changed = !!pim_addr_cmp(ch->ifassert_winner, winner); int metric_changed = !pim_assert_metric_match( &ch->ifassert_winner_metric, &winner_metric); + enum pim_rpf_result rpf_result; + struct pim_rpf old_rpf; if (PIM_DEBUG_PIM_EVENTS) { if (ch->ifassert_state != new_state) { @@ -74,6 +77,22 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch, ch->ifassert_creation = pim_time_monotonic_sec(); if (winner_changed || metric_changed) { + if (winner_changed) { + old_rpf.source_nexthop.interface = + ch->upstream->rpf.source_nexthop.interface; + rpf_result = pim_rpf_update(pim_ifp->pim, ch->upstream, + &old_rpf, __func__); + if (rpf_result == PIM_RPF_CHANGED || + (rpf_result == PIM_RPF_FAILURE && + old_rpf.source_nexthop.interface)) + pim_zebra_upstream_rpf_changed( + pim_ifp->pim, ch->upstream, &old_rpf); + /* update kernel multicast forwarding cache (MFC) */ + if (ch->upstream->rpf.source_nexthop.interface && + ch->upstream->channel_oil) + pim_upstream_mroute_iif_update( + ch->upstream->channel_oil, __func__); + } pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream); pim_ifchannel_update_could_assert(ch); pim_ifchannel_update_assert_tracking_desired(ch);