pimd: update vxlan mroute entries when the lo or peerlink vif is updated

For vxlan origination mroutes the IIF is pinned to
a. lo for single VTEPs
b. peerlink-rif for anycast VTEPs

This commit includes the changes to react to  pim-vifi add/del for these
devices.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
Anuradha Karuppiah 2019-03-23 08:25:20 -07:00
parent 332087df41
commit 269c1fe1e7
3 changed files with 134 additions and 0 deletions

View File

@ -47,6 +47,7 @@
#include "pim_nht.h" #include "pim_nht.h"
#include "pim_jp_agg.h" #include "pim_jp_agg.h"
#include "pim_igmp_join.h" #include "pim_igmp_join.h"
#include "pim_vxlan.h"
static void pim_if_igmp_join_del_all(struct interface *ifp); static void pim_if_igmp_join_del_all(struct interface *ifp);
static int igmp_join_sock(const char *ifname, ifindex_t ifindex, static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
@ -977,6 +978,10 @@ int pim_if_add_vif(struct interface *ifp, bool ispimreg, bool is_vxlan_term)
} }
pim_ifp->pim->iface_vif_index[pim_ifp->mroute_vif_index] = 1; pim_ifp->pim->iface_vif_index[pim_ifp->mroute_vif_index] = 1;
/* if the device qualifies as pim_vxlan iif/oif update vxlan entries */
pim_vxlan_add_vif(ifp);
return 0; return 0;
} }
@ -991,6 +996,9 @@ int pim_if_del_vif(struct interface *ifp)
return -1; return -1;
} }
/* if the device was a pim_vxlan iif/oif update vxlan mroute entries */
pim_vxlan_del_vif(ifp);
pim_mroute_del_vif(ifp); pim_mroute_del_vif(ifp);
/* /*

View File

@ -468,6 +468,34 @@ static void pim_vxlan_orig_mr_del(struct pim_vxlan_sg *vxlan_sg)
pim_vxlan_orig_mr_up_del(vxlan_sg); pim_vxlan_orig_mr_up_del(vxlan_sg);
} }
static void pim_vxlan_orig_mr_iif_update(struct hash_backet *backet, void *arg)
{
struct interface *ifp = (struct interface *)arg;
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;
if (PIM_DEBUG_VXLAN)
zlog_debug("vxlan SG %s iif changed from %s to %s",
vxlan_sg->sg_str,
old_iif ? old_iif->name : "-",
ifp ? ifp->name : "-");
if (pim_vxlan_orig_mr_add_is_ok(vxlan_sg)) {
if (vxlan_sg->up) {
/* upstream exists but iif changed */
pim_vxlan_orig_mr_up_iif_update(vxlan_sg);
} else {
/* install mroute */
pim_vxlan_orig_mr_install(vxlan_sg);
}
} else {
pim_vxlan_orig_mr_del(vxlan_sg);
}
}
/**************************** vxlan termination mroutes *********************** /**************************** vxlan termination mroutes ***********************
* For every bum-mcast-grp registered by evpn a *G termination * For every bum-mcast-grp registered by evpn a *G termination
* mroute is setup by pimd. The purpose of this mroute is to pull down vxlan * mroute is setup by pimd. The purpose of this mroute is to pull down vxlan
@ -682,6 +710,102 @@ void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg)
XFREE(MTYPE_PIM_VXLAN_SG, vxlan_sg); XFREE(MTYPE_PIM_VXLAN_SG, vxlan_sg);
} }
/****************************** misc callbacks *******************************/
static void pim_vxlan_set_default_iif(struct pim_instance *pim,
struct interface *ifp)
{
struct interface *old_iif;
if (pim->vxlan.default_iif == ifp)
return;
old_iif = pim->vxlan.default_iif;
if (PIM_DEBUG_VXLAN)
zlog_debug("%s: vxlan default iif changed from %s to %s",
__PRETTY_FUNCTION__,
old_iif ? old_iif->name : "-",
ifp ? ifp->name : "-");
old_iif = pim_vxlan_orig_mr_iif_get(pim);
pim->vxlan.default_iif = ifp;
ifp = pim_vxlan_orig_mr_iif_get(pim);
if (old_iif == ifp)
return;
if (PIM_DEBUG_VXLAN)
zlog_debug("%s: vxlan orig iif changed from %s to %s",
__PRETTY_FUNCTION__, old_iif ? old_iif->name : "-",
ifp ? ifp->name : "-");
/* add/del upstream entries for the existing vxlan SG when the
* interface becomes available
*/
hash_iterate(pim->vxlan.sg_hash, pim_vxlan_orig_mr_iif_update, ifp);
}
static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
struct interface *ifp)
{
struct interface *old_iif;
if (pim->vxlan.peerlink_rif == ifp)
return;
old_iif = pim->vxlan.peerlink_rif;
if (PIM_DEBUG_VXLAN)
zlog_debug("%s: vxlan peerlink_rif changed from %s to %s",
__PRETTY_FUNCTION__, old_iif ? old_iif->name : "-",
ifp ? ifp->name : "-");
old_iif = pim_vxlan_orig_mr_iif_get(pim);
pim->vxlan.peerlink_rif = ifp;
ifp = pim_vxlan_orig_mr_iif_get(pim);
if (old_iif == ifp)
return;
if (PIM_DEBUG_VXLAN)
zlog_debug("%s: vxlan orig iif changed from %s to %s",
__PRETTY_FUNCTION__, old_iif ? old_iif->name : "-",
ifp ? ifp->name : "-");
/* add/del upstream entries for the existing vxlan SG when the
* interface becomes available
*/
hash_iterate(pim->vxlan.sg_hash, pim_vxlan_orig_mr_iif_update, ifp);
}
void pim_vxlan_add_vif(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
struct pim_instance *pim = pim_ifp->pim;
pim = ((struct pim_interface *)ifp->info)->pim;
if (pim->vrf_id != VRF_DEFAULT)
return;
if (if_is_loopback_or_vrf(ifp))
pim_vxlan_set_default_iif(pim, ifp);
if (vxlan_mlag.flags & PIM_VXLAN_MLAGF_ENABLED &&
(ifp == vxlan_mlag.peerlink_rif))
pim_vxlan_set_peerlink_rif(pim, ifp);
}
void pim_vxlan_del_vif(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
struct pim_instance *pim = pim_ifp->pim;
if (pim->vrf_id != VRF_DEFAULT)
return;
if (pim->vxlan.default_iif == ifp)
pim_vxlan_set_default_iif(pim, NULL);
if (pim->vxlan.peerlink_rif == ifp)
pim_vxlan_set_peerlink_rif(pim, NULL);
}
void pim_vxlan_init(struct pim_instance *pim) void pim_vxlan_init(struct pim_instance *pim)
{ {
char hash_name[64]; char hash_name[64];

View File

@ -123,5 +123,7 @@ extern void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg);
extern void pim_vxlan_update_sg_reg_state(struct pim_instance *pim, extern void pim_vxlan_update_sg_reg_state(struct pim_instance *pim,
struct pim_upstream *up, bool reg_join); struct pim_upstream *up, bool reg_join);
extern struct pim_interface *pim_vxlan_get_term_ifp(struct pim_instance *pim); extern struct pim_interface *pim_vxlan_get_term_ifp(struct pim_instance *pim);
extern void pim_vxlan_add_vif(struct interface *ifp);
extern void pim_vxlan_del_vif(struct interface *ifp);
#endif /* PIM_VXLAN_H */ #endif /* PIM_VXLAN_H */