summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrenato <renato@openbsd.org>2017-03-03 23:59:58 +0000
committerrenato <renato@openbsd.org>2017-03-03 23:59:58 +0000
commit438d900932bf676187e412bcbf40f176dbb5f0db (patch)
tree03bcd5c573cf30fd0cec90190be76deb6504c2cc
parentThe PW Status is an unknown TLV. (diff)
downloadwireguard-openbsd-438d900932bf676187e412bcbf40f176dbb5f0db.tar.xz
wireguard-openbsd-438d900932bf676187e412bcbf40f176dbb5f0db.zip
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().
-rw-r--r--usr.sbin/ldpd/lde_lib.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/usr.sbin/ldpd/lde_lib.c b/usr.sbin/ldpd/lde_lib.c
index 67a6eeca428..5db6eaf616b 100644
--- a/usr.sbin/ldpd/lde_lib.c
+++ b/usr.sbin/ldpd/lde_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lde_lib.c,v 1.64 2017/03/03 23:41:27 renato Exp $ */
+/* $OpenBSD: lde_lib.c,v 1.65 2017/03/03 23:59:58 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -592,8 +592,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);
}
@@ -622,8 +621,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);
}
@@ -675,6 +673,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;
}
@@ -719,6 +720,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;
}