summaryrefslogtreecommitdiff
path: root/zebra/zebra_mpls.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r--zebra/zebra_mpls.c96
1 files changed, 50 insertions, 46 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index c167e6a8ad..d373fdf370 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -93,6 +93,8 @@ static void lsp_processq_del(struct work_queue *wq, void *data);
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,
@@ -186,7 +188,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
* the label advertised by the recursive nexthop (plus we don't have the
* logic yet to push multiple labels).
*/
- for (nexthop = re->nhe->nhg->nexthop;
+ for (nexthop = re->nhe->nhg.nexthop;
nexthop; nexthop = nexthop->next) {
/* Skip inactive and recursive entries. */
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
@@ -250,14 +252,8 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
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;
}
@@ -313,14 +309,8 @@ static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label)
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;
}
@@ -638,7 +628,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
|| !CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED))
continue;
- for (match_nh = match->nhe->nhg->nexthop; match_nh;
+ for (match_nh = match->nhe->nhg.nexthop; match_nh;
match_nh = match_nh->next) {
if (match->type == ZEBRA_ROUTE_CONNECT
|| nexthop->ifindex == match_nh->ifindex) {
@@ -689,10 +679,10 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
break;
}
- if (!match || !match->nhe->nhg->nexthop)
+ if (!match || !match->nhe->nhg.nexthop)
return 0;
- nexthop->ifindex = match->nhe->nhg->nexthop->ifindex;
+ nexthop->ifindex = match->nhe->nhg.nexthop->ifindex;
return 1;
}
@@ -1047,14 +1037,8 @@ static void lsp_processq_del(struct work_queue *wq, void *data)
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);
}
/*
@@ -1104,6 +1088,37 @@ static void *lsp_alloc(void *p)
}
/*
+ * 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.
*/
static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
@@ -1334,14 +1349,8 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
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;
}
@@ -2631,7 +2640,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
* We can't just change the values here since we are hashing
* on labels. We need to create a whole new group
*/
- nexthop_group_copy(&new_grp, re->nhe->nhg);
+ nexthop_group_copy(&new_grp, &(re->nhe->nhg));
found = false;
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
@@ -2712,7 +2721,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
if (re == NULL)
return -1;
- nexthop_group_copy(&new_grp, re->nhe->nhg);
+ nexthop_group_copy(&new_grp, &(re->nhe->nhg));
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next)
nexthop_del_labels(nexthop);
@@ -2872,14 +2881,9 @@ int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
/* 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;
}
@@ -2949,7 +2953,7 @@ static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
RNODE_FOREACH_RE (rn, re) {
struct nexthop_group new_grp = {};
- nexthop_group_copy(&new_grp, re->nhe->nhg);
+ nexthop_group_copy(&new_grp, &(re->nhe->nhg));
for (nexthop = new_grp.nexthop; nexthop;
nexthop = nexthop->next) {