diff options
| author | Renato Westphal <renato@opensourcerouting.org> | 2017-07-24 18:57:20 -0300 |
|---|---|---|
| committer | Renato Westphal <renato@opensourcerouting.org> | 2017-07-24 19:43:09 -0300 |
| commit | 69f93be55a9146ba58e814964a77961cdba13bf9 (patch) | |
| tree | 9fc814b37f15d3beb04b9ea57d56a6e2c7e291b3 | |
| parent | 1e4d264f2bce049de4a7e90d2f7b9c1673b14c57 (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.c | 7 |
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); |
