diff options
author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-02-06 18:30:36 +0100 |
---|---|---|
committer | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-02-14 18:18:30 +0100 |
commit | 05ca004b804b85343f450c99792b065254c5ccc3 (patch) | |
tree | 4d37c93a47c6ee36238b8c097a3e03c7aa625ea9 /pimd/pim_rpf.c | |
parent | pimd: register with MLAG on the first VxLAN SG (diff) | |
download | frr-05ca004b804b85343f450c99792b065254c5ccc3.tar.xz frr-05ca004b804b85343f450c99792b065254c5ccc3.zip |
pim: DF election for tunnel termination mroutes in an anycast-VTEP setup
1. Upstream entries associated with tunnel termination mroutes are
synced to the MLAG peer via the local MLAG daemon.
2. These entries are installed in the peer switch (via an upstream
ref flag).
3. DF (Designated Forwarder) election is run per-upstream entry by both
the MLAG switches -
a. The switch with the lowest RPF cost is the DF winner
b. If both switches have the same RPF cost the MLAG role is
used as a tie breaker with the MLAG primary becoming the DF
winner.
4. The DF winner terminates the multicast traffic by adding the tunnel
termination device to the OIL. The non-DF suppresses the termination
device from the OIL.
Note: Before the PIM-MLAG interface was available hidden config was
used to test the EVPN-PIM functionality with MLAG. I have removed the
code to persist that config to avoid confusion. The hidden commands are
still available.
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Diffstat (limited to 'pimd/pim_rpf.c')
-rw-r--r-- | pimd/pim_rpf.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 24519adb1..889e0704c 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -194,6 +194,32 @@ static int nexthop_mismatch(const struct pim_nexthop *nh1, || (nh1->mrib_route_metric != nh2->mrib_route_metric); } +static void pim_rpf_cost_change(struct pim_instance *pim, + struct pim_upstream *up, uint32_t old_cost) +{ + struct pim_rpf *rpf = &up->rpf; + uint32_t new_cost; + + new_cost = pim_up_mlag_local_cost(up); + if (PIM_DEBUG_MLAG) + zlog_debug( + "%s: Cost_to_rp of upstream-%s changed to:%u, from:%u", + __func__, up->sg_str, new_cost, old_cost); + + if (old_cost == new_cost) + return; + + /* Cost changed, it might Impact MLAG DF election, update */ + if (PIM_DEBUG_MLAG) + zlog_debug( + "%s: Cost_to_rp of upstream-%s changed to:%u", + __func__, up->sg_str, + rpf->source_nexthop.mrib_route_metric); + + if (pim_up_mlag_is_local(up)) + pim_mlag_up_local_add(pim, up); +} + enum pim_rpf_result pim_rpf_update(struct pim_instance *pim, struct pim_upstream *up, struct pim_rpf *old, const char *caller) @@ -203,6 +229,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim, struct prefix nht_p; struct prefix src, grp; bool neigh_needed = true; + uint32_t saved_mrib_route_metric; if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)) return PIM_RPF_OK; @@ -215,6 +242,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim, saved.source_nexthop = rpf->source_nexthop; saved.rpf_addr = rpf->rpf_addr; + saved_mrib_route_metric = pim_up_mlag_local_cost(up); if (old) { old->source_nexthop = saved.source_nexthop; old->rpf_addr = saved.rpf_addr; @@ -236,8 +264,12 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim, neigh_needed = false; pim_find_or_track_nexthop(pim, &nht_p, up, NULL, false, NULL); if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src, &grp, - neigh_needed)) + neigh_needed)) { + /* Route is Deleted in Zebra, reset the stored NH data */ + pim_upstream_rpf_clear(pim, up); + pim_rpf_cost_change(pim, up, saved_mrib_route_metric); return PIM_RPF_FAILURE; + } rpf->rpf_addr.family = AF_INET; rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up); @@ -290,10 +322,18 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim, if (saved.rpf_addr.u.prefix4.s_addr != rpf->rpf_addr.u.prefix4.s_addr || saved.source_nexthop .interface != rpf->source_nexthop.interface) { - + pim_rpf_cost_change(pim, up, saved_mrib_route_metric); return PIM_RPF_CHANGED; } + if (PIM_DEBUG_MLAG) + zlog_debug( + "%s(%s): Cost_to_rp of upstream-%s changed to:%u", + __func__, caller, up->sg_str, + rpf->source_nexthop.mrib_route_metric); + + pim_rpf_cost_change(pim, up, saved_mrib_route_metric); + return PIM_RPF_OK; } |