diff options
Diffstat (limited to 'zebra/zebra_mpls.c')
| -rw-r--r-- | zebra/zebra_mpls.c | 96 |
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) { |
