From e59e3b58fdfeb48b4c6f17ef6d6a106cafc7b0de Mon Sep 17 00:00:00 2001 From: Sai Gomathi N Date: Wed, 11 Oct 2023 04:34:04 -0700 Subject: [PATCH] pim, pimv6: Removing upstreams and mroutes when "no ip pim"/"no ipv6 pim" configs applied in receiver connected interface When the (no ip pim/no ipv6 pim) pim/pimv6 configuration is removed from the receiver-connected interface in LHR, we observe inconsistent behavior in following scenarios. 1) When there is no pim/pimv6 configuration at the beginning and the traffic is initiated, no multicast routes are formed, and there is no available upstream frr# show ip pim upstream Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt frr# show ip mroute IP Multicast Routing Table Flags: S - Sparse, C - Connected, P - Pruned R - SGRpt Pruned, F - Register flag, T - SPT-bit set Source Group Flags Proto Input Output TTL Uptime 2) When the traffic is flowing and we remove the pim/pimv6 config in between, the (*,G) upstream transitions into the NotJ state, yet the mroutes remain intact. frr# show ip mroute IP Multicast Routing Table Flags: S - Sparse, C - Connected, P - Pruned R - SGRpt Pruned, F - Register flag, T - SPT-bit set Source Group Flags Proto Input Output TTL Uptime * 226.1.1.1 SC IGMP ens224 pimreg 1 00:00:56 IGMP ens192 1 frr# show ip pim upstream Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt ens224 * 226.1.1.1 NotJ 00:00:13 00:00:55 --:--:-- --:--:-- 1 Hence, to make the behaviour consistent, we remove both the upstream entries for (*,G) and the corresponding mroutes using the 'pim_igmp_if_reset' API call when dealing with the receiver-connected interface. The 'pim_ifchannel_local_membership_del' is returned when no ip pim/pimv6 config is applied due to 'pim_ifp->pim_enable' check. Therefore, removing this check in order to proceed with the deletion when the pim/pimv6 configurations are removed Signed-off-by: Sai Gomathi N --- pimd/pim6_mld.c | 9 +++++++++ pimd/pim6_mld.h | 1 + pimd/pim_ifchannel.c | 2 -- pimd/pim_pim.c | 7 +++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c index 20ef9216a9c9..7cf492d4b644 100644 --- a/pimd/pim6_mld.c +++ b/pimd/pim6_mld.c @@ -2151,6 +2151,15 @@ static void gm_start(struct interface *ifp) } } +void pim_gm_if_reset(struct interface *ifp) +{ + struct pim_interface *pim_ifp = ifp->info; + struct gm_if *gm_ifp = pim_ifp->mld; + + if (gm_ifp) + gm_group_delete(gm_ifp); +} + void gm_group_delete(struct gm_if *gm_ifp) { struct gm_sg *sg; diff --git a/pimd/pim6_mld.h b/pimd/pim6_mld.h index 183ab2fc508d..f8d7dafece93 100644 --- a/pimd/pim6_mld.h +++ b/pimd/pim6_mld.h @@ -357,6 +357,7 @@ struct gm_if { #if PIM_IPV == 6 extern void gm_ifp_update(struct interface *ifp); extern void gm_ifp_teardown(struct interface *ifp); +extern void pim_gm_if_reset(struct interface *ifp); extern void gm_group_delete(struct gm_if *gm_ifp); #else static inline void gm_ifp_update(struct interface *ifp) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index da5518994193..0d6625e5b03b 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -1232,8 +1232,6 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, pim_sgaddr *sg) pim_ifp = ifp->info; if (!pim_ifp) return; - if (!pim_ifp->pim_enable) - return; orig = ch = pim_ifchannel_find(ifp, sg); if (!ch) diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index a4c9178bb9fc..4be1d06f12b1 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -29,6 +29,7 @@ #include "pim_register.h" #include "pim_errors.h" #include "pim_bsm.h" +#include "pim6_mld.h" #include static void on_pim_hello_send(struct event *t); @@ -102,6 +103,8 @@ static void sock_close(struct interface *ifp) void pim_sock_delete(struct interface *ifp, const char *delete_message) { + struct pim_interface *pim_ifp = ifp->info; + zlog_info("PIM INTERFACE DOWN: on interface %s: %s", ifp->name, delete_message); @@ -124,6 +127,10 @@ void pim_sock_delete(struct interface *ifp, const char *delete_message) pim_neighbor_delete_all(ifp, delete_message); sock_close(ifp); + + if (pim_ifp->gm_enable) { + pim_gm_if_reset(ifp); + } } /* For now check dst address for hello, assrt and join/prune is all pim rtr */