]> git.puffer.fish Git - mirror/frr.git/commitdiff
ldpd: fix bug with dual-stack neighbors 849/head
authorRenato Westphal <renato@opensourcerouting.org>
Mon, 24 Jul 2017 21:57:20 +0000 (18:57 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Mon, 24 Jul 2017 22:43:09 +0000 (19:43 -0300)
We were assuming that a neighbor can be deleted only when all of its
adjacencies are dead. This is not the case for dual-stack neighbors. If
the transport-preference is IPv4 and all adjacencies are IPv6 (or
vice-versa), then it should be deleted and everything cleaned-up
accordingly.

Bug exposed by the new RB tree implementation on master, but the fix
also applies to stable/3.0.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
ldpd/neighbor.c

index 9a92a00d32327a811ae39888ee26ccac8b602e93..7cd3a3fd7dc22722732b2dccf692334aaf8e7900 100644 (file)
@@ -287,6 +287,8 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
 void
 nbr_del(struct nbr *nbr)
 {
+       struct adj              *adj;
+
        log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
 
        nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
@@ -312,6 +314,11 @@ nbr_del(struct nbr *nbr)
        mapping_list_clr(&nbr->release_list);
        mapping_list_clr(&nbr->abortreq_list);
 
+       while ((adj = RB_ROOT(&nbr->adj_tree)) != NULL) {
+               adj->nbr = NULL;
+               RB_REMOVE(nbr_adj_head, &nbr->adj_tree, adj);
+       }
+
        if (nbr->peerid)
                RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
        RB_REMOVE(nbr_id_head, &nbrs_by_id, nbr);