forked from Mirror/frr
pimd: prepare NHT for tracking BSM C-RPs
For BSMs, we should track which of the RP candidates in the BSM message are actually available, before trying to use them (which also puts them in NHT for that). This applies for both BSRs as well as BSM receivers. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
cca9bc193e
commit
b9a02da83b
|
@ -1451,3 +1451,8 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc)
|
||||||
|
{
|
||||||
|
/* stub for Candidate-RP */
|
||||||
|
}
|
||||||
|
|
|
@ -161,18 +161,27 @@ void pim_nht_bsr_add(struct pim_instance *pim, pim_addr addr)
|
||||||
pnc->bsr_count++;
|
pnc->bsr_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr)
|
||||||
|
{
|
||||||
|
struct pim_nexthop_cache *pnc;
|
||||||
|
|
||||||
|
pnc = pim_nht_get(pim, addr);
|
||||||
|
|
||||||
|
pnc->candrp_count++;
|
||||||
|
return CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
static void pim_nht_drop_maybe(struct pim_instance *pim,
|
static void pim_nht_drop_maybe(struct pim_instance *pim,
|
||||||
struct pim_nexthop_cache *pnc)
|
struct pim_nexthop_cache *pnc)
|
||||||
{
|
{
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug("%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u Cand-RP count:%u",
|
||||||
"%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u",
|
__func__, &pnc->rpf.rpf_addr, pim->vrf->name,
|
||||||
__func__, &pnc->rpf.rpf_addr, pim->vrf->name,
|
pnc->rp_list->count, pnc->upstream_hash->count,
|
||||||
pnc->rp_list->count, pnc->upstream_hash->count,
|
pnc->bsr_count, pnc->candrp_count);
|
||||||
pnc->bsr_count);
|
|
||||||
|
|
||||||
if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0
|
if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0 &&
|
||||||
&& pnc->bsr_count == 0) {
|
pnc->bsr_count == 0 && pnc->candrp_count == 0) {
|
||||||
struct zclient *zclient = pim_zebra_zclient_get();
|
struct zclient *zclient = pim_zebra_zclient_get();
|
||||||
|
|
||||||
pim_sendmsg_zebra_rnh(pim, zclient, pnc,
|
pim_sendmsg_zebra_rnh(pim, zclient, pnc,
|
||||||
|
@ -258,6 +267,27 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr addr)
|
||||||
pim_nht_drop_maybe(pim, pnc);
|
pim_nht_drop_maybe(pim, pnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pim_nht_candrp_del(struct pim_instance *pim, pim_addr addr)
|
||||||
|
{
|
||||||
|
struct pim_nexthop_cache *pnc = NULL;
|
||||||
|
struct pim_nexthop_cache lookup;
|
||||||
|
|
||||||
|
lookup.rpf.rpf_addr = addr;
|
||||||
|
|
||||||
|
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
||||||
|
|
||||||
|
if (!pnc) {
|
||||||
|
zlog_warn("attempting to delete nonexistent NHT C-RP entry %pPA",
|
||||||
|
&addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertf(pnc->candrp_count > 0, "addr=%pPA", &addr);
|
||||||
|
pnc->candrp_count--;
|
||||||
|
|
||||||
|
pim_nht_drop_maybe(pim, pnc);
|
||||||
|
}
|
||||||
|
|
||||||
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
|
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
|
||||||
struct interface *src_ifp, pim_addr src_ip)
|
struct interface *src_ifp, pim_addr src_ip)
|
||||||
{
|
{
|
||||||
|
@ -900,6 +930,9 @@ void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
|
||||||
pim_update_rp_nh(pim, pnc);
|
pim_update_rp_nh(pim, pnc);
|
||||||
if (pnc->upstream_hash->count)
|
if (pnc->upstream_hash->count)
|
||||||
pim_update_upstream_nh(pim, pnc);
|
pim_update_upstream_nh(pim, pnc);
|
||||||
|
|
||||||
|
if (pnc->candrp_count)
|
||||||
|
pim_crp_nht_update(pim, pnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct pim_nexthop_cache {
|
||||||
* same BSR
|
* same BSR
|
||||||
*/
|
*/
|
||||||
uint32_t bsr_count;
|
uint32_t bsr_count;
|
||||||
|
uint32_t candrp_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pnc_hash_walk_data {
|
struct pnc_hash_walk_data {
|
||||||
|
@ -71,4 +72,10 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr bsr_addr);
|
||||||
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
|
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
|
||||||
struct interface *src_ifp, pim_addr src_ip);
|
struct interface *src_ifp, pim_addr src_ip);
|
||||||
void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
|
void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
|
||||||
|
|
||||||
|
/* wrappers for usage with Candidate RPs in BSMs */
|
||||||
|
bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr);
|
||||||
|
void pim_nht_candrp_del(struct pim_instance *pim, pim_addr addr);
|
||||||
|
void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue