summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-07-24 18:57:20 -0300
committerRenato Westphal <renato@opensourcerouting.org>2017-07-24 19:43:09 -0300
commit69f93be55a9146ba58e814964a77961cdba13bf9 (patch)
tree9fc814b37f15d3beb04b9ea57d56a6e2c7e291b3
parent1e4d264f2bce049de4a7e90d2f7b9c1673b14c57 (diff)
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 <renato@opensourcerouting.org>
-rw-r--r--ldpd/neighbor.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c
index 9a92a00d32..7cd3a3fd7d 100644
--- a/ldpd/neighbor.c
+++ b/ldpd/neighbor.c
@@ -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);