diff options
| author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-02-06 09:30:43 -0800 | 
|---|---|---|
| committer | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-02-14 09:18:30 -0800 | 
| commit | f03999caa6a5d88bc6b9441f4039915ea6f67bf8 (patch) | |
| tree | 4ad5cfcf9f9d87a613c5c3f95dc31634ed895bac /pimd/pim_vxlan.c | |
| parent | 95586137e6662f9cdeede87dc75e70ab70877360 (diff) | |
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>
Diffstat (limited to 'pimd/pim_vxlan.c')
| -rw-r--r-- | pimd/pim_vxlan.c | 63 | 
1 files changed, 60 insertions, 3 deletions
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index 58d988e920..abfea538e1 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -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)  | 
