From b4fcca6bf20e56d101391bff03e3793794073bc5 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 6 Jul 2017 00:46:34 -0300 Subject: [PATCH] ldpd: fix missing label mappings In some scenarios, it's possible to send a Label Withdraw to a neighbor and not receive a corresponding Label Release right away. This can happen during reconvergence after a network failure or configuration change. When this happens, the list of upstream mappings of a given FEC might not be empty even after sending a Label Withdraw to all neighbors. This situation holds until all neighbors either send a Label Release or are torn down (e.g. keepalive timeout). With that said, we shouldn't check for 'RB_EMPTY(&fn->upstream)' in lde_kernel_update() because it can prevent ldpd from sending label mappings in such circumstances. This check was introduced to avoid sending the same label mapping more than once to the same neighbor, but we need to remove this optimization for now until we find a better solution (which probably involves refactoring the whole zebra<->ldpd communication). While here, add a new debug message in lde_send_labelmapping() which can aid in troubleshooting label problems in the future. Signed-off-by: Renato Westphal --- ldpd/lde.c | 6 +++++- ldpd/lde_lib.c | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ldpd/lde.c b/ldpd/lde.c index 5e98efa477..588ccd6952 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -890,8 +890,12 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single) */ lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec); if (lw) { - if (!fec_find(&ln->sent_map_pending, &fn->fec)) + if (!fec_find(&ln->sent_map_pending, &fn->fec)) { + debug_evt("%s: FEC %s: scheduling to send label " + "mapping later (waiting for pending label release)", + __func__, log_fec(&fn->fec)); lde_map_pending_add(ln, fn); + } return; } diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index bafd33f266..c56b7e33d0 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -396,8 +396,7 @@ lde_kernel_update(struct fec *fec) lde_gc_start_timer(); } else { fn->local_label = lde_update_label(fn); - if (fn->local_label != NO_LABEL && - RB_EMPTY(lde_map_head, &fn->upstream)) + if (fn->local_label != NO_LABEL) /* FEC.1: perform lsr label distribution procedure */ RB_FOREACH(ln, nbr_tree, &lde_nbrs) lde_send_labelmapping(ln, fn, 1); -- 2.39.5