summaryrefslogtreecommitdiff
path: root/pimd/pim_vxlan.c
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2020-02-06 09:31:00 -0800
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2020-02-14 09:18:30 -0800
commit650d9ad1acf68b1c017a54139bddf5888fe3c835 (patch)
tree86f4b707a864d02665c42d3ef7e26ff9f7cfddb2 /pimd/pim_vxlan.c
parent20fcf61c376282fb94b894dbe1c61a8136cca039 (diff)
pimd: handle ipmr-lo operational state changes
ipmr-lo is an internally added device used for multicast vxlan tunnel termination. This device is not expected to be managed by the admin however in the case it is accidentally shut we need to be able handle it by recovering when it is "no shut" again. Ticket: CM-24985 Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Diffstat (limited to 'pimd/pim_vxlan.c')
-rw-r--r--pimd/pim_vxlan.c105
1 files changed, 63 insertions, 42 deletions
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index bd6998c4b8..1de0dda9da 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -1012,6 +1012,45 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
}
}
+static void pim_vxlan_term_mr_oif_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;
+
+ if (pim_vxlan_is_orig_mroute(vxlan_sg))
+ return;
+
+ if (vxlan_sg->term_oif == ifp)
+ return;
+
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("vxlan SG %s term oif changed from %s to %s",
+ vxlan_sg->sg_str,
+ vxlan_sg->term_oif ? vxlan_sg->term_oif->name : "-",
+ ifp ? ifp->name : "-");
+
+ pim_vxlan_term_mr_del(vxlan_sg);
+ vxlan_sg->term_oif = ifp;
+ pim_vxlan_term_mr_add(vxlan_sg);
+}
+
+static void pim_vxlan_term_oif_update(struct pim_instance *pim,
+ struct interface *ifp)
+{
+ if (pim->vxlan.term_if == ifp)
+ return;
+
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("vxlan term oif changed from %s to %s",
+ pim->vxlan.term_if ? pim->vxlan.term_if->name : "-",
+ ifp ? ifp->name : "-");
+
+ pim->vxlan.term_if = ifp;
+ if (pim->vxlan.sg_hash)
+ hash_iterate(pim->vxlan.sg_hash,
+ pim_vxlan_term_mr_oif_update, ifp);
+}
+
void pim_vxlan_add_vif(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
@@ -1026,6 +1065,9 @@ void pim_vxlan_add_vif(struct interface *ifp)
if (vxlan_mlag.flags & PIM_VXLAN_MLAGF_ENABLED &&
(ifp == vxlan_mlag.peerlink_rif))
pim_vxlan_set_peerlink_rif(pim, ifp);
+
+ if (pim->vxlan.term_if_cfg == ifp)
+ pim_vxlan_term_oif_update(pim, ifp);
}
void pim_vxlan_del_vif(struct interface *ifp)
@@ -1041,76 +1083,56 @@ void pim_vxlan_del_vif(struct interface *ifp)
if (pim->vxlan.peerlink_rif == ifp)
pim_vxlan_set_peerlink_rif(pim, NULL);
-}
-
-static void pim_vxlan_term_mr_oif_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;
-
- if (pim_vxlan_is_orig_mroute(vxlan_sg))
- return;
-
- if (vxlan_sg->term_oif == ifp)
- return;
-
- if (PIM_DEBUG_VXLAN)
- zlog_debug("vxlan SG %s term oif changed from %s to %s",
- vxlan_sg->sg_str,
- vxlan_sg->term_oif ? vxlan_sg->term_oif->name : "-",
- ifp ? ifp->name : "-");
- pim_vxlan_term_mr_del(vxlan_sg);
- vxlan_sg->term_oif = ifp;
- pim_vxlan_term_mr_add(vxlan_sg);
+ if (pim->vxlan.term_if == ifp)
+ pim_vxlan_term_oif_update(pim, NULL);
}
+/* enable pim implicitly on the termination device add */
void pim_vxlan_add_term_dev(struct pim_instance *pim,
struct interface *ifp)
{
struct pim_interface *pim_ifp;
- if (pim->vxlan.term_if == ifp)
+ if (pim->vxlan.term_if_cfg == ifp)
return;
if (PIM_DEBUG_VXLAN)
- zlog_debug("vxlan term oif changed from %s to %s",
- pim->vxlan.term_if ? pim->vxlan.term_if->name : "-",
- ifp->name);
+ zlog_debug("vxlan term oif cfg changed from %s to %s",
+ pim->vxlan.term_if_cfg ?
+ pim->vxlan.term_if_cfg->name : "-",
+ ifp->name);
+
+ pim->vxlan.term_if_cfg = ifp;
/* enable pim on the term ifp */
pim_ifp = (struct pim_interface *)ifp->info;
if (pim_ifp) {
PIM_IF_DO_PIM(pim_ifp->options);
+ /* ifp is already oper up; activate it as a term dev */
+ if (pim_ifp->mroute_vif_index >= 0)
+ pim_vxlan_term_oif_update(pim, ifp);
} else {
- pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/,
- false /*pimreg*/, true /*vxlan_term*/);
- /* ensure that pimreg existss before using the newly created
+ /* ensure that pimreg exists before using the newly created
* vxlan termination device
*/
pim_if_create_pimreg(pim);
+ pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/,
+ false /*pimreg*/, true /*vxlan_term*/);
}
-
- pim->vxlan.term_if = ifp;
-
- if (pim->vxlan.sg_hash)
- hash_iterate(pim_ifp->pim->vxlan.sg_hash,
- pim_vxlan_term_mr_oif_update, ifp);
}
+/* disable pim implicitly, if needed, on the termination device deletion */
void pim_vxlan_del_term_dev(struct pim_instance *pim)
{
- struct interface *ifp = pim->vxlan.term_if;
+ struct interface *ifp = pim->vxlan.term_if_cfg;
struct pim_interface *pim_ifp;
if (PIM_DEBUG_VXLAN)
- zlog_debug("vxlan term oif changed from %s to -", ifp->name);
+ zlog_debug("vxlan term oif cfg changed from %s to -",
+ ifp->name);
- pim->vxlan.term_if = NULL;
-
- if (pim->vxlan.sg_hash)
- hash_iterate(pim->vxlan.sg_hash,
- pim_vxlan_term_mr_oif_update, NULL);
+ pim->vxlan.term_if_cfg = NULL;
pim_ifp = (struct pim_interface *)ifp->info;
if (pim_ifp) {
@@ -1118,7 +1140,6 @@ void pim_vxlan_del_term_dev(struct pim_instance *pim)
if (!PIM_IF_TEST_IGMP(pim_ifp->options))
pim_if_delete(ifp);
}
-
}
void pim_vxlan_init(struct pim_instance *pim)