summaryrefslogtreecommitdiff
path: root/pimd/pim_vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_vxlan.c')
-rw-r--r--pimd/pim_vxlan.c105
1 files changed, 61 insertions, 44 deletions
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 57b922a531..569b04d278 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -85,8 +85,16 @@ static void pim_vxlan_do_reg_work(void)
if (PIM_DEBUG_VXLAN)
zlog_debug("vxlan SG %s periodic NULL register",
vxlan_sg->sg_str);
- pim_null_register_send(vxlan_sg->up);
- ++work_cnt;
+
+ /*
+ * If we are on the work queue *and* the rpf
+ * has been lost on the vxlan_sg->up let's
+ * make sure that we don't send it.
+ */
+ if (vxlan_sg->up->rpf.source_nexthop.interface) {
+ pim_null_register_send(vxlan_sg->up);
+ ++work_cnt;
+ }
}
if (work_cnt > vxlan_info.max_work_cnt) {
@@ -217,6 +225,7 @@ static void pim_vxlan_orig_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
vxlan_sg->sg_str);
vxlan_sg->up = NULL;
+
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG) {
/* clear out all the vxlan properties */
up->flags &= ~(PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG |
@@ -239,8 +248,7 @@ static void pim_vxlan_orig_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
* origination mroutes active sources but just in
* case
*/
- up = pim_upstream_del(vxlan_sg->pim, up,
- __PRETTY_FUNCTION__);
+ up = pim_upstream_del(vxlan_sg->pim, up, __func__);
}
/* if there are other references register the source
* for nht
@@ -285,6 +293,7 @@ static void pim_vxlan_orig_mr_up_iif_update(struct pim_vxlan_sg *vxlan_sg)
static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
{
struct pim_upstream *up;
+ struct pim_interface *term_ifp;
int flags = 0;
struct prefix nht_p;
struct pim_instance *pim = vxlan_sg->pim;
@@ -344,8 +353,13 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
}
/* We are acting FHR; clear out use_rpt setting if any */
pim_upstream_update_use_rpt(up, false /*update_mroute*/);
- pim_upstream_ref(up, flags, __PRETTY_FUNCTION__);
+ pim_upstream_ref(up, flags, __func__);
vxlan_sg->up = up;
+ term_ifp = pim_vxlan_get_term_ifp(pim);
+ /* mute termination device on origination mroutes */
+ if (term_ifp)
+ pim_channel_update_oif_mute(up->channel_oil,
+ term_ifp);
pim_vxlan_orig_mr_up_iif_update(vxlan_sg);
/* mute pimreg on origination mroutes */
if (pim->regiface)
@@ -353,8 +367,7 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
pim->regiface->info);
} else {
up = pim_upstream_add(vxlan_sg->pim, &vxlan_sg->sg,
- vxlan_sg->iif, flags,
- __PRETTY_FUNCTION__, NULL);
+ vxlan_sg->iif, flags, __func__, NULL);
vxlan_sg->up = up;
}
@@ -475,7 +488,7 @@ 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)
+static void pim_vxlan_orig_mr_iif_update(struct hash_bucket *backet, void *arg)
{
struct interface *ifp;
struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
@@ -614,9 +627,8 @@ static void pim_vxlan_term_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
/* enable MLAG designated-forwarder election on termination mroutes */
PIM_UPSTREAM_FLAG_SET_MLAG_VXLAN(flags);
- up = pim_upstream_add(vxlan_sg->pim, &vxlan_sg->sg,
- NULL /* iif */, flags,
- __PRETTY_FUNCTION__, NULL);
+ up = pim_upstream_add(vxlan_sg->pim, &vxlan_sg->sg, NULL /* iif */,
+ flags, __func__, NULL);
vxlan_sg->up = up;
if (!up) {
@@ -648,8 +660,7 @@ static void pim_vxlan_term_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
up->flags &= ~(PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM |
PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN);
pim_mlag_up_local_del(vxlan_sg->pim, up);
- pim_upstream_del(vxlan_sg->pim, up,
- __PRETTY_FUNCTION__);
+ pim_upstream_del(vxlan_sg->pim, up, __func__);
}
}
@@ -752,14 +763,8 @@ struct pim_vxlan_sg *pim_vxlan_sg_add(struct pim_instance *pim,
return vxlan_sg;
}
-void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg)
+static void pim_vxlan_sg_del_item(struct pim_vxlan_sg *vxlan_sg)
{
- struct pim_vxlan_sg *vxlan_sg;
-
- vxlan_sg = pim_vxlan_sg_find(pim, sg);
- if (!vxlan_sg)
- return;
-
vxlan_sg->flags |= PIM_VXLAN_SGF_DEL_IN_PROG;
pim_vxlan_del_work(vxlan_sg);
@@ -769,14 +774,24 @@ void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg)
else
pim_vxlan_term_mr_del(vxlan_sg);
- hash_release(vxlan_sg->pim->vxlan.sg_hash, vxlan_sg);
-
if (PIM_DEBUG_VXLAN)
zlog_debug("vxlan SG %s free", vxlan_sg->sg_str);
XFREE(MTYPE_PIM_VXLAN_SG, vxlan_sg);
}
+void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg)
+{
+ struct pim_vxlan_sg *vxlan_sg;
+
+ vxlan_sg = pim_vxlan_sg_find(pim, sg);
+ if (!vxlan_sg)
+ return;
+
+ pim_vxlan_sg_del_item(vxlan_sg);
+ hash_release(pim->vxlan.sg_hash, vxlan_sg);
+}
+
/******************************* MLAG handling *******************************/
bool pim_vxlan_do_mlag_reg(void)
{
@@ -788,8 +803,8 @@ bool pim_vxlan_do_mlag_reg(void)
* to the MLAG peer which may mroute it over the underlay if there are any
* interested receivers.
*/
-static void pim_vxlan_sg_peerlink_oif_update(struct hash_backet *backet,
- void *arg)
+static void pim_vxlan_sg_peerlink_oif_update(struct hash_bucket *backet,
+ void *arg)
{
struct interface *new_oif = (struct interface *)arg;
struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
@@ -881,9 +896,8 @@ static void pim_vxlan_set_default_iif(struct pim_instance *pim,
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 : "-");
+ __func__, old_iif ? old_iif->name : "-",
+ ifp ? ifp->name : "-");
old_iif = pim_vxlan_orig_mr_iif_get(pim);
pim->vxlan.default_iif = ifp;
@@ -892,9 +906,9 @@ static void pim_vxlan_set_default_iif(struct pim_instance *pim,
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 : "-");
+ zlog_debug("%s: vxlan orig iif changed from %s to %s", __func__,
+ old_iif ? old_iif->name : "-",
+ ifp ? ifp->name : "-");
/* add/del upstream entries for the existing vxlan SG when the
* interface becomes available
@@ -927,8 +941,7 @@ static void pim_vxlan_up_cost_update(struct pim_instance *pim,
}
}
-static void pim_vxlan_term_mr_cost_update(struct hash_backet *backet,
- void *arg)
+static void pim_vxlan_term_mr_cost_update(struct hash_bucket *backet, void *arg)
{
struct interface *old_peerlink_rif = (struct interface *)arg;
struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
@@ -953,8 +966,8 @@ static void pim_vxlan_term_mr_cost_update(struct hash_backet *backet,
old_peerlink_rif);
}
-static void pim_vxlan_sg_peerlink_rif_update(struct hash_backet *backet,
- void *arg)
+static void pim_vxlan_sg_peerlink_rif_update(struct hash_bucket *backet,
+ void *arg)
{
pim_vxlan_orig_mr_iif_update(backet, NULL);
pim_vxlan_term_mr_cost_update(backet, arg);
@@ -974,8 +987,8 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
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 : "-");
+ __func__, old_iif ? old_iif->name : "-",
+ ifp ? ifp->name : "-");
old_iif = pim_vxlan_orig_mr_iif_get(pim);
old_oif = pim_vxlan_orig_mr_oif_get(pim);
@@ -985,9 +998,8 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
if (old_iif != new_iif) {
if (PIM_DEBUG_VXLAN)
zlog_debug("%s: vxlan orig iif changed from %s to %s",
- __PRETTY_FUNCTION__,
- old_iif ? old_iif->name : "-",
- new_iif ? new_iif->name : "-");
+ __func__, old_iif ? old_iif->name : "-",
+ new_iif ? new_iif->name : "-");
/* add/del upstream entries for the existing vxlan SG when the
* interface becomes available
@@ -1002,9 +1014,8 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
if (old_oif != new_oif) {
if (PIM_DEBUG_VXLAN)
zlog_debug("%s: vxlan orig oif changed from %s to %s",
- __PRETTY_FUNCTION__,
- old_oif ? old_oif->name : "-",
- new_oif ? new_oif->name : "-");
+ __func__, old_oif ? old_oif->name : "-",
+ new_oif ? new_oif->name : "-");
if (pim->vxlan.sg_hash)
hash_iterate(pim->vxlan.sg_hash,
pim_vxlan_sg_peerlink_oif_update,
@@ -1012,7 +1023,7 @@ 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)
+static void pim_vxlan_term_mr_oif_update(struct hash_bucket *backet, void *arg)
{
struct interface *ifp = (struct interface *)arg;
struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
@@ -1155,8 +1166,14 @@ void pim_vxlan_init(struct pim_instance *pim)
void pim_vxlan_exit(struct pim_instance *pim)
{
if (pim->vxlan.sg_hash) {
- hash_clean(pim->vxlan.sg_hash, NULL);
+ hash_clean(pim->vxlan.sg_hash,
+ (void (*)(void *))pim_vxlan_sg_del_item);
hash_free(pim->vxlan.sg_hash);
pim->vxlan.sg_hash = NULL;
}
}
+
+void pim_vxlan_terminate(void)
+{
+ pim_vxlan_work_timer_setup(false);
+}