Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pimd/pim_bsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ void pim_bsm_clear(struct pim_instance *pim)

/* RP not found for the group grp */
if (!trp_info || pim_rpf_addr_is_inaddr_any(&trp_info->rp)) {
pim_nht_delete_tracked_upstream(pim, up->upstream_addr, up);
pim_upstream_rpf_clear(pim, up);
pim_rp_set_upstream_addr(pim, &up->upstream_addr,
up->sg.src, up->sg.grp);
Expand Down
3 changes: 3 additions & 0 deletions pimd/pim_mroute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,9 @@ int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name)
vifi_t iif;
char buf[1000];

if (!c_oil)
return 0;

iif = pim_upstream_get_mroute_iif(c_oil, name);
if (*oil_incoming_vif(c_oil) == iif) {
/* no change */
Expand Down
38 changes: 37 additions & 1 deletion pimd/pim_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,42 @@ static void pim_nht_drop_maybe(struct pim_instance *pim, struct pim_nexthop_cach
}
}

void pim_nht_delete_tracked_upstream(struct pim_instance *pim, pim_addr addr,
struct pim_upstream *up)
{
struct pim_nexthop_cache *pnc = NULL;
struct pim_nexthop_cache lookup;

if (!up || pim_addr_is_any(addr))
return;

lookup.addr = addr;
pnc = hash_lookup(pim->nht_hash, &lookup);
if (!pnc) {
if (PIM_DEBUG_PIM_NHT)
zlog_debug("%s: NHT %pPA(%s) not found for upstream %s; nothing to release",
__func__, &addr, pim->vrf->name, up->sg_str);
return;
}

/*
* This helper is used when an upstream can already have been removed
* by RP cleanup. Missing entries are harmless; the important part is
* to remove the upstream from its old NHT bucket before upstream_addr
* is changed to ANY.
*/
if (hash_release(pnc->upstream_hash, up)) {
if (PIM_DEBUG_PIM_NHT)
zlog_debug("%s: released upstream %s from NHT %pPA(%s); remaining upstream count:%ld",
__func__, up->sg_str, &addr, pim->vrf->name,
pnc->upstream_hash->count);
pim_nht_drop_maybe(pim, pnc);
} else if (PIM_DEBUG_PIM_NHT) {
zlog_debug("%s: upstream %s not in NHT %pPA(%s) bucket; redundant cleanup",
__func__, up->sg_str, &addr, pim->vrf->name);
}
}
Comment thread
hnattamaisub marked this conversation as resolved.

void pim_nht_delete_tracked(struct pim_instance *pim, pim_addr addr, struct pim_upstream *up,
struct rp_info *rp)
{
Expand Down Expand Up @@ -959,7 +995,7 @@ static int pim_update_upstream_nh_helper(struct hash_bucket *bucket, void *arg)
* RPF nbr is now unreachable the MFC has already been updated
* by pim_rpf_clear
*/
if (rpf_result == PIM_RPF_CHANGED)
if (rpf_result == PIM_RPF_CHANGED && up->channel_oil)
pim_upstream_mroute_iif_update(up->channel_oil, __func__);

if (rpf_result == PIM_RPF_CHANGED ||
Expand Down
8 changes: 8 additions & 0 deletions pimd/pim_nht.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr);
void pim_nht_delete_tracked(struct pim_instance *pim, pim_addr addr, struct pim_upstream *up,
struct rp_info *rp);

/* Remove an upstream from an NHT entry that may have already been torn down
* by RP cleanup. Safe to call when the entry is missing; used right before
* upstream_addr is reset to ANY so the upstream is detached from its old
* NHT bucket.
*/
void pim_nht_delete_tracked_upstream(struct pim_instance *pim, pim_addr addr,
struct pim_upstream *up);

/* Delete a tracked addr and decrement BSR count, if no-one else is interested, stop tracking */
void pim_nht_bsr_del(struct pim_instance *pim, pim_addr bsr_addr);

Expand Down
2 changes: 2 additions & 0 deletions pimd/pim_rp.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ int pim_rp_del(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
if (trp_info == rp_all) {
pim_nht_delete_tracked_upstream(pim, rpf_addr, up);
pim_upstream_rpf_clear(pim, up);
up->upstream_addr = PIMADDR_ANY;
}
Expand Down Expand Up @@ -844,6 +845,7 @@ int pim_rp_del(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,

/* RP not found for the group grp */
if (!trp_info || pim_rpf_addr_is_inaddr_any(&trp_info->rp)) {
pim_nht_delete_tracked_upstream(pim, rpf_addr, up);
pim_upstream_rpf_clear(pim, up);
pim_rp_set_upstream_addr(
pim, &up->upstream_addr, up->sg.src,
Expand Down
3 changes: 2 additions & 1 deletion pimd/pim_rpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ void pim_upstream_rpf_clear(struct pim_instance *pim,
up->rpf.source_nexthop.mrib_route_metric =
router->infinite_assert_metric.route_metric;
up->rpf.rpf_addr = PIMADDR_ANY;
pim_upstream_mroute_iif_update(up->channel_oil, __func__);
if (up->channel_oil)
pim_upstream_mroute_iif_update(up->channel_oil, __func__);
}
}

Expand Down
Loading