diff options
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)  | 
