diff options
-rw-r--r-- | pimd/pim_nht.c | 26 | ||||
-rw-r--r-- | pimd/pim_upstream.c | 28 |
2 files changed, 43 insertions, 11 deletions
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 37970923c..f89796517 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -171,6 +171,8 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr, struct pim_nexthop_cache *pnc = NULL; struct pim_nexthop_cache lookup; struct zclient *zclient = NULL; + struct listnode *upnode = NULL; + struct pim_upstream *upstream = NULL; zclient = pim_zebra_zclient_get(); @@ -178,8 +180,30 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr, lookup.rpf.rpf_addr = *addr; pnc = hash_lookup(pim->rpf_hash, &lookup); if (pnc) { - if (rp) + if (rp) { + /* Release the (*, G)upstream from pnc->upstream_hash, + * whose Group belongs to the RP getting deleted + */ + for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, + upstream)) { + struct prefix grp; + struct rp_info *trp_info; + + if (upstream->sg.src.s_addr != INADDR_ANY) + continue; + + grp.family = AF_INET; + grp.prefixlen = IPV4_MAX_BITLEN; + grp.u.prefix4 = upstream->sg.grp; + + trp_info = pim_rp_find_match_group(pim, &grp); + if (trp_info == rp) + hash_release(pnc->upstream_hash, + upstream); + } listnode_delete(pnc->rp_list, rp); + } + if (up) hash_release(pnc->upstream_hash, up); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index f1fb99832..9cf25f0f9 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -219,17 +219,25 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim, pim_msdp_up_del(pim, &up->sg); } - /* Deregister addr with Zebra NHT */ - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = up->upstream_addr; - if (PIM_DEBUG_TRACE) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&nht_p, buf, sizeof(buf)); - zlog_debug("%s: Deregister upstream %s addr %s with Zebra NHT", - __PRETTY_FUNCTION__, up->sg_str, buf); + /* When RP gets deleted, pim_rp_del() deregister addr with Zebra NHT + * and assign up->upstream_addr as INADDR_ANY. + * So before de-registering the upstream address, check if is not equal + * to INADDR_ANY. This is done in order to avoid de-registering for + * 255.255.255.255 which is maintained for some reason.. + */ + if (up->upstream_addr.s_addr != INADDR_ANY) { + /* Deregister addr with Zebra NHT */ + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = up->upstream_addr; + if (PIM_DEBUG_TRACE) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + zlog_debug("%s: Deregister upstream %s addr %s with Zebra NHT", + __PRETTY_FUNCTION__, up->sg_str, buf); + } + pim_delete_tracked_nexthop(pim, &nht_p, up, NULL); } - pim_delete_tracked_nexthop(pim, &nht_p, up, NULL); XFREE(MTYPE_PIM_UPSTREAM, up); |