diff options
author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2019-03-23 16:25:20 +0100 |
---|---|---|
committer | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2019-04-20 17:33:23 +0200 |
commit | 269c1fe1e75a8ca7c73680b81641d7e05efc4335 (patch) | |
tree | 1230e791a88ac853193963664b4f8dd90d086aa6 /pimd | |
parent | pimd: add termination mroutes for each vxlan multicast tunnels (diff) | |
download | frr-269c1fe1e75a8ca7c73680b81641d7e05efc4335.tar.xz frr-269c1fe1e75a8ca7c73680b81641d7e05efc4335.zip |
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>
Diffstat (limited to 'pimd')
-rw-r--r-- | pimd/pim_iface.c | 8 | ||||
-rw-r--r-- | pimd/pim_vxlan.c | 124 | ||||
-rw-r--r-- | pimd/pim_vxlan.h | 2 |
3 files changed, 134 insertions, 0 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index a7b5511f3..0fb7f176c 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -47,6 +47,7 @@ #include "pim_nht.h" #include "pim_jp_agg.h" #include "pim_igmp_join.h" +#include "pim_vxlan.h" static void pim_if_igmp_join_del_all(struct interface *ifp); 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; + + /* if the device qualifies as pim_vxlan iif/oif update vxlan entries */ + pim_vxlan_add_vif(ifp); + return 0; } @@ -991,6 +996,9 @@ int pim_if_del_vif(struct interface *ifp) 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); /* diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index b51329ea8..02878b505 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -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); } +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 *********************** * 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 @@ -682,6 +710,102 @@ void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *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) { char hash_name[64]; diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h index ad84fa8e0..0a6e409c7 100644 --- a/pimd/pim_vxlan.h +++ b/pimd/pim_vxlan.h @@ -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, struct pim_upstream *up, bool reg_join); 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 */ |