mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 16:20:08 +00:00
pimd: increase RPF metric via the peerlink_rif by plus-10
The RPF cost is incremented by 10 if the RPF interface is the peerlink-rif. This is used to force the MLAG switch with the lowest cost to the RPF to become the MLAG DF. If a switch has to go via the peerlink-rif to get to the RP or source it simplly cannot be the designated forwarder. Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
95586137e6
commit
f03999caa6
@ -36,6 +36,7 @@
|
||||
#include "pim_time.h"
|
||||
#include "pim_nht.h"
|
||||
#include "pim_oil.h"
|
||||
#include "pim_mlag.h"
|
||||
|
||||
static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
|
||||
|
||||
|
@ -921,6 +921,14 @@ uint32_t pim_up_mlag_local_cost(struct pim_upstream *up)
|
||||
if (!(pim_up_mlag_is_local(up)))
|
||||
return router->infinite_assert_metric.route_metric;
|
||||
|
||||
if ((up->rpf.source_nexthop.interface ==
|
||||
up->pim->vxlan.peerlink_rif) &&
|
||||
(up->rpf.source_nexthop.mrib_route_metric <
|
||||
(router->infinite_assert_metric.route_metric -
|
||||
PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC)))
|
||||
return up->rpf.source_nexthop.mrib_route_metric +
|
||||
PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC;
|
||||
|
||||
return up->rpf.source_nexthop.mrib_route_metric;
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,12 @@
|
||||
#define PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE)
|
||||
#define PIM_UPSTREAM_FLAG_UNSET_USE_RPT(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_USE_RPT)
|
||||
|
||||
/* The RPF cost is incremented by 10 if the RPF interface is the peerlink-rif.
|
||||
* This is used to force the MLAG switch with the lowest cost to the RPF
|
||||
* to become the MLAG DF.
|
||||
*/
|
||||
#define PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC 10
|
||||
|
||||
enum pim_upstream_state {
|
||||
PIM_UPSTREAM_NOTJOINED,
|
||||
PIM_UPSTREAM_JOINED,
|
||||
|
@ -477,13 +477,14 @@ static void pim_vxlan_orig_mr_del(struct pim_vxlan_sg *vxlan_sg)
|
||||
|
||||
static void pim_vxlan_orig_mr_iif_update(struct hash_backet *backet, void *arg)
|
||||
{
|
||||
struct interface *ifp = (struct interface *)arg;
|
||||
struct interface *ifp;
|
||||
struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
|
||||
struct interface *old_iif = vxlan_sg->iif;
|
||||
|
||||
if (!pim_vxlan_is_orig_mroute(vxlan_sg))
|
||||
return;
|
||||
|
||||
ifp = pim_vxlan_orig_mr_iif_get(vxlan_sg->pim);
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s iif changed from %s to %s",
|
||||
vxlan_sg->sg_str,
|
||||
@ -895,7 +896,63 @@ static void pim_vxlan_set_default_iif(struct pim_instance *pim,
|
||||
*/
|
||||
if (pim->vxlan.sg_hash)
|
||||
hash_iterate(pim->vxlan.sg_hash,
|
||||
pim_vxlan_orig_mr_iif_update, ifp);
|
||||
pim_vxlan_orig_mr_iif_update, NULL);
|
||||
}
|
||||
|
||||
static void pim_vxlan_up_cost_update(struct pim_instance *pim,
|
||||
struct pim_upstream *up,
|
||||
struct interface *old_peerlink_rif)
|
||||
{
|
||||
if (!PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(up->flags))
|
||||
return;
|
||||
|
||||
if (up->rpf.source_nexthop.interface &&
|
||||
((up->rpf.source_nexthop.interface ==
|
||||
pim->vxlan.peerlink_rif) ||
|
||||
(up->rpf.source_nexthop.interface ==
|
||||
old_peerlink_rif))) {
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("RPF cost adjust for %s on peerlink-rif (old: %s, new: %s) change",
|
||||
up->sg_str,
|
||||
old_peerlink_rif ?
|
||||
old_peerlink_rif->name : "-",
|
||||
pim->vxlan.peerlink_rif ?
|
||||
pim->vxlan.peerlink_rif->name : "-");
|
||||
pim_mlag_up_local_add(pim, up);
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_cost_update(struct hash_backet *backet,
|
||||
void *arg)
|
||||
{
|
||||
struct interface *old_peerlink_rif = (struct interface *)arg;
|
||||
struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
|
||||
struct pim_upstream *up;
|
||||
struct listnode *listnode;
|
||||
struct pim_upstream *child;
|
||||
|
||||
if (pim_vxlan_is_orig_mroute(vxlan_sg))
|
||||
return;
|
||||
|
||||
/* Lookup all XG and SG entries with RPF-interface peerlink_rif */
|
||||
up = vxlan_sg->up;
|
||||
if (!up)
|
||||
return;
|
||||
|
||||
pim_vxlan_up_cost_update(vxlan_sg->pim, up,
|
||||
old_peerlink_rif);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(up->sources, listnode,
|
||||
child))
|
||||
pim_vxlan_up_cost_update(vxlan_sg->pim, child,
|
||||
old_peerlink_rif);
|
||||
}
|
||||
|
||||
static void pim_vxlan_sg_peerlink_rif_update(struct hash_backet *backet,
|
||||
void *arg)
|
||||
{
|
||||
pim_vxlan_orig_mr_iif_update(backet, NULL);
|
||||
pim_vxlan_term_mr_cost_update(backet, arg);
|
||||
}
|
||||
|
||||
static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
|
||||
@ -928,7 +985,7 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
|
||||
*/
|
||||
if (pim->vxlan.sg_hash)
|
||||
hash_iterate(pim->vxlan.sg_hash,
|
||||
pim_vxlan_orig_mr_iif_update, ifp);
|
||||
pim_vxlan_sg_peerlink_rif_update, old_iif);
|
||||
}
|
||||
|
||||
void pim_vxlan_add_vif(struct interface *ifp)
|
||||
|
Loading…
Reference in New Issue
Block a user