summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_iface.c8
-rw-r--r--pimd/pim_vxlan.c105
-rw-r--r--pimd/pim_vxlan.h6
-rw-r--r--pimd/pim_vxlan_instance.h1
4 files changed, 76 insertions, 44 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index c615540149..8cc720c535 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -498,6 +498,7 @@ void pim_if_addr_add(struct connected *ifc)
struct pim_interface *pim_ifp;
struct interface *ifp;
struct in_addr ifaddr;
+ bool vxlan_term;
zassert(ifc);
@@ -635,7 +636,8 @@ void pim_if_addr_add(struct connected *ifc)
address assigned, then try to create a vif_index.
*/
if (pim_ifp->mroute_vif_index < 0) {
- pim_if_add_vif(ifp, false, false /*vxlan_term*/);
+ vxlan_term = pim_vxlan_is_term_dev_cfg(pim_ifp->pim, ifp);
+ pim_if_add_vif(ifp, false, vxlan_term);
}
pim_ifchannel_scan_forward_start(ifp);
}
@@ -730,6 +732,7 @@ void pim_if_addr_add_all(struct interface *ifp)
int v4_addrs = 0;
int v6_addrs = 0;
struct pim_interface *pim_ifp = ifp->info;
+ bool vxlan_term;
/* PIM/IGMP enabled ? */
@@ -768,7 +771,8 @@ void pim_if_addr_add_all(struct interface *ifp)
* address assigned, then try to create a vif_index.
*/
if (pim_ifp->mroute_vif_index < 0) {
- pim_if_add_vif(ifp, false, false /*vxlan_term*/);
+ vxlan_term = pim_vxlan_is_term_dev_cfg(pim_ifp->pim, ifp);
+ pim_if_add_vif(ifp, false, vxlan_term);
}
pim_ifchannel_scan_forward_start(ifp);
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)
diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h
index 7adba2eee2..198d1c3281 100644
--- a/pimd/pim_vxlan.h
+++ b/pimd/pim_vxlan.h
@@ -119,6 +119,12 @@ static inline bool pim_vxlan_is_local_sip(struct pim_upstream *up)
if_is_loopback_or_vrf(up->rpf.source_nexthop.interface);
}
+static inline bool pim_vxlan_is_term_dev_cfg(struct pim_instance *pim,
+ struct interface *ifp)
+{
+ return pim->vxlan.term_if_cfg == ifp;
+}
+
extern struct pim_vxlan *pim_vxlan_p;
extern struct pim_vxlan_sg *pim_vxlan_sg_find(struct pim_instance *pim,
struct prefix_sg *sg);
diff --git a/pimd/pim_vxlan_instance.h b/pimd/pim_vxlan_instance.h
index 3f99483fbe..5b35bcbeaa 100644
--- a/pimd/pim_vxlan_instance.h
+++ b/pimd/pim_vxlan_instance.h
@@ -36,6 +36,7 @@ struct pim_vxlan_instance {
/* device used by the dataplane to terminate multicast encapsulated
* vxlan traffic
*/
+ struct interface *term_if_cfg;
struct interface *term_if;
};