summaryrefslogtreecommitdiffstats
path: root/ldpd/lde_lib.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-03-03 21:50:22 +0100
committerRenato Westphal <renato@opensourcerouting.org>2017-03-03 21:50:22 +0100
commitbe8e0d318815395a49632f8c6546be1f96c17557 (patch)
treec78a986f79b7b7081a16837f1b065bae8bc165e8 /ldpd/lde_lib.c
parentldpd: the PW Status is an unknown TLV (diff)
downloadfrr-be8e0d318815395a49632f8c6546be1f96c17557.tar.xz
frr-be8e0d318815395a49632f8c6546be1f96c17557.zip
ldpd: fix processing of Label Withdraw messages
Whenever we receive a Label Withdraw message with an optional Label TLV, we should check if this label matches the label previously received from this neighbor for this FEC. If they don't match then we shouldn't uninstall the previous label from the kernel. This fixes a misinterpretation from the "Receive Label Withdraw" algorithm described in the A.1.5 section of RFC 5036. Also, simplify the check of pending withdraws in lde_check_release() and lde_check_release_wcard(). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to '')
-rw-r--r--ldpd/lde_lib.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index 6ec88a19b..02730189a 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -624,8 +624,7 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
/* 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 ||
- (lw->label != NO_LABEL && map->label == lw->label))) {
+ if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
/* LRl.4: delete record of outstanding label withdraw */
lde_wdraw_del(ln, lw);
}
@@ -654,8 +653,7 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
/* 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 ||
- (lw->label != NO_LABEL && map->label == lw->label))) {
+ if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
/* LRl.4: delete record of outstanding lbl withdraw */
lde_wdraw_del(ln, lw);
}
@@ -707,6 +705,9 @@ lde_check_withdraw(struct map *map, struct lde_nbr *ln)
default:
break;
}
+ if (map->label != NO_LABEL && map->label != fnh->remote_label)
+ continue;
+
lde_send_delete_klabel(fn, fnh);
fnh->remote_label = NO_LABEL;
}
@@ -751,6 +752,10 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln)
default:
break;
}
+ if (map->label != NO_LABEL && map->label !=
+ fnh->remote_label)
+ continue;
+
lde_send_delete_klabel(fn, fnh);
fnh->remote_label = NO_LABEL;
}