diff options
author | Binu Abraham <binu_abraham@looptelecom.com> | 2019-07-10 09:13:08 +0200 |
---|---|---|
committer | Binu Abraham <binu_abraham@looptelecom.com> | 2019-07-15 08:05:51 +0200 |
commit | f4ec681c8151ba75a7951db589ca5dcc6870f887 (patch) | |
tree | a5e95ff9ff19675b2e9e3fd6850ca02fbdd70a74 /ldpd | |
parent | Merge pull request #4658 from chiragshah6/ospf_vrf_dev (diff) | |
download | frr-f4ec681c8151ba75a7951db589ca5dcc6870f887.tar.xz frr-f4ec681c8151ba75a7951db589ca5dcc6870f887.zip |
ldpd: Fix to release MPLS label if its not used anymore
LDP should release labels allocated from zebra if its not getting used.
Signed-off-by: Binu <binu_abraham@looptelecom.com>
Diffstat (limited to 'ldpd')
-rw-r--r-- | ldpd/lde.c | 39 | ||||
-rw-r--r-- | ldpd/lde.h | 1 | ||||
-rw-r--r-- | ldpd/lde_lib.c | 3 |
3 files changed, 43 insertions, 0 deletions
diff --git a/ldpd/lde.c b/ldpd/lde.c index 0ddf4f07d..ac680b47a 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -1654,6 +1654,19 @@ lde_del_label_chunk(void *val) } static int +lde_release_label_chunk(uint32_t start, uint32_t end) +{ + int ret; + + ret = lm_release_label_chunk(zclient_sync, start, end); + if (ret < 0) { + log_warnx("Error releasing label chunk!"); + return (-1); + } + return (0); +} + +static int lde_get_label_chunk(void) { int ret; @@ -1709,6 +1722,32 @@ on_get_label_chunk_response(uint32_t start, uint32_t end) current_label_chunk = listtail(label_chunk_list); } +void +lde_free_label(uint32_t label) +{ + struct listnode *node; + struct label_chunk *label_chunk; + uint64_t pos; + + for (ALL_LIST_ELEMENTS_RO(label_chunk_list, node, label_chunk)) { + if (label <= label_chunk->end && label >= label_chunk->start) { + pos = 1ULL << (label - label_chunk->start); + label_chunk->used_mask &= ~pos; + /* if nobody is using this chunk and it's not current_label_chunk, then free it */ + if (!label_chunk->used_mask && (current_label_chunk != node)) { + if (lde_release_label_chunk(label_chunk->start, label_chunk->end) != 0) + log_warnx("%s: Error releasing label chunk!", __func__); + else { + listnode_delete(label_chunk_list, label_chunk); + lde_del_label_chunk(label_chunk); + } + } + break; + } + } + return; +} + static uint32_t lde_get_next_label(void) { diff --git a/ldpd/lde.h b/ldpd/lde.h index 94077d163..0a7d0a58f 100644 --- a/ldpd/lde.h +++ b/ldpd/lde.h @@ -147,6 +147,7 @@ void lde_imsg_compose_parent_sync(int, pid_t, void *, uint16_t); int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t); int lde_acl_check(char *, int, union ldpd_addr *, uint8_t); uint32_t lde_update_label(struct fec_node *); +void lde_free_label(uint32_t label); void lde_send_change_klabel(struct fec_node *, struct fec_nh *); void lde_send_delete_klabel(struct fec_node *, struct fec_nh *); void lde_fec2map(struct fec *, struct map *); diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 28e455c7a..0957a5455 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -919,6 +919,9 @@ lde_gc_timer(struct thread *thread) !RB_EMPTY(lde_map_head, &fn->upstream)) continue; + if (fn->local_label != NO_LABEL) + lde_free_label(fn->local_label); + fec_remove(&ft, &fn->fec); free(fn); count++; |