]> git.puffer.fish Git - mirror/frr.git/commitdiff
ldpd: fix processing of Label Withdraw messages
authorRenato Westphal <renato@opensourcerouting.org>
Fri, 3 Mar 2017 20:50:22 +0000 (17:50 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Fri, 3 Mar 2017 20:50:22 +0000 (17:50 -0300)
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>
ldpd/lde_lib.c

index 6ec88a19bd4821656faf79bfa874ea8280479ce4..02730189a8ac0ed234ab156b80a42e2e9e675f0c 100644 (file)
@@ -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;
                }