diff options
author | Renato Westphal <renato@opensourcerouting.org> | 2017-04-22 03:10:42 +0200 |
---|---|---|
committer | Renato Westphal <renato@opensourcerouting.org> | 2017-04-26 15:36:33 +0200 |
commit | 7c2abbd734a8dab416e378be7b200797b2331e47 (patch) | |
tree | a30b027de4f3c5be5f63bd53690733a63c479594 /ldpd/lde_lib.c | |
parent | ldpd: improve ldp_zebra_read_route() (diff) | |
download | frr-7c2abbd734a8dab416e378be7b200797b2331e47.tar.xz frr-7c2abbd734a8dab416e378be7b200797b2331e47.zip |
ldpd: schedule the sending of label messages when necessary
Once we send a Label Withdraw, we can't send a Label Mapping for the
same FEC until we receive a Label Release from the peer. This is due to
some limitations in the LDP algorithms described in Appendix A. ("LDP
Label Distribution Procedures") of RFC 5036.
To workaround this issue, make it possible to schedule the sending of
a Label Mapping as soon as a Label Release is received for the same FEC.
The easiest way to test this patch is by typing the "label local advertise
explicit-null" command. ldpd will withdraw all null labels using a
Wildcard FEC and then send new Label Mappings as soon the corresponding
Label Releases are received.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'ldpd/lde_lib.c')
-rw-r--r-- | ldpd/lde_lib.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index b074bf349..37a670bc8 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -662,6 +662,7 @@ lde_check_release(struct map *map, struct lde_nbr *ln) struct fec_node *fn; struct lde_wdraw *lw; struct lde_map *me; + struct fec *pending_map; /* wildcard label release */ if (map->type == MAP_TYPE_WILDCARD || @@ -677,17 +678,24 @@ lde_check_release(struct map *map, struct lde_nbr *ln) if (fn == NULL) return; + /* LRl.6: check sent map list and remove it if available */ + me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec); + if (me && (map->label == NO_LABEL || map->label == me->map.label)) + lde_map_del(ln, me, 1); + /* LRl.3: first check if we have a pending withdraw running */ lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec); if (lw && (map->label == NO_LABEL || map->label == lw->label)) { /* LRl.4: delete record of outstanding label withdraw */ lde_wdraw_del(ln, lw); - } - /* LRl.6: check sent map list and remove it if available */ - me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec); - if (me && (map->label == NO_LABEL || map->label == me->map.label)) - lde_map_del(ln, me, 1); + /* send pending label mapping if any */ + pending_map = fec_find(&ln->sent_map_pending, &fn->fec); + if (pending_map) { + lde_send_labelmapping(ln, fn, 1); + lde_map_pending_del(ln, pending_map); + } + } /* * LRl.11 - 13 are unnecessary since we remove the label from @@ -702,6 +710,7 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln) struct fec_node *fn; struct lde_wdraw *lw; struct lde_map *me; + struct fec *pending_map; RB_FOREACH(f, fec_tree, &ft) { fn = (struct fec_node *)f; @@ -711,17 +720,24 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln) if (lde_wildcard_apply(map, &fn->fec, me) == 0) continue; + /* LRl.6: check sent map list and remove it if available */ + if (me && + (map->label == NO_LABEL || map->label == me->map.label)) + lde_map_del(ln, me, 1); + /* LRl.3: first check if we have a pending withdraw running */ lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec); if (lw && (map->label == NO_LABEL || map->label == lw->label)) { /* LRl.4: delete record of outstanding lbl withdraw */ lde_wdraw_del(ln, lw); - } - /* LRl.6: check sent map list and remove it if available */ - if (me && - (map->label == NO_LABEL || map->label == me->map.label)) - lde_map_del(ln, me, 1); + /* send pending label mapping if any */ + pending_map = fec_find(&ln->sent_map_pending, &fn->fec); + if (pending_map) { + lde_send_labelmapping(ln, fn, 1); + lde_map_pending_del(ln, pending_map); + } + } /* * LRl.11 - 13 are unnecessary since we remove the label from |