From 6e4762e1cca9888ce8e6baaf29ea8f191635fc6a Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 24 Jul 2017 18:57:20 -0300 Subject: [PATCH] ldpd: fix bug with dual-stack neighbors 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 --- ldpd/neighbor.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index f8d4b5f5fd..1671fce4f1 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -289,6 +289,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); @@ -314,6 +316,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); -- 2.39.5