static void lsp_processq_complete(struct work_queue *wq);
static int lsp_processq_add(zebra_lsp_t *lsp);
static void *lsp_alloc(void *p);
+/* Free lsp; sets caller's pointer to NULL */
+static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp);
static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size);
static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
if (lsp_processq_add(lsp))
return -1;
} else if (!lsp->nhlfe_list
- && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- XFREE(MTYPE_LSP, lsp);
- }
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
+ lsp_free(lsp_table, &lsp);
return 0;
}
if (lsp_processq_add(lsp))
return -1;
} else if (!lsp->nhlfe_list
- && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Del LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- XFREE(MTYPE_LSP, lsp);
- }
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
+ lsp_free(lsp_table, &lsp);
return 0;
}
nhlfe_del(nhlfe);
}
- if (!lsp->nhlfe_list) {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- XFREE(MTYPE_LSP, lsp);
- }
+ if (!lsp->nhlfe_list)
+ lsp_free(lsp_table, &lsp);
}
/*
return ((void *)lsp);
}
+/*
+ * Dtor for an LSP: remove from ile hash, release any internal allocations,
+ * free LSP object.
+ */
+static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
+{
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe, *nhlfe_next;
+
+ if (plsp == NULL || *plsp == NULL)
+ return;
+
+ lsp = *plsp;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Free LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ /* Free nhlfes, if any. */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
+ nhlfe_next = nhlfe->next;
+
+ nhlfe_del(nhlfe);
+ }
+
+ hash_release(lsp_table, &lsp->ile);
+ XFREE(MTYPE_LSP, lsp);
+
+ *plsp = NULL;
+}
+
/*
* Create printable string for NHLFE entry.
*/
if (lsp_processq_add(lsp))
return -1;
} else if (!lsp->nhlfe_list
- && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- XFREE(MTYPE_LSP, lsp);
- }
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
+ lsp_free(lsp_table, &lsp);
return 0;
}
/* Free LSP entry if no other NHLFEs and not scheduled. */
if (!lsp->nhlfe_list
- && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
+ lsp_free(lsp_table, &lsp);
- lsp = hash_release(lsp_table, &lsp->ile);
- XFREE(MTYPE_LSP, lsp);
- }
}
return 0;
}