From 19bd3dffc19eb0a4fb13ec6da987c6bd00a1f727 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 7 Oct 2018 20:34:31 -0400 Subject: [PATCH] bgpd: Do a bit better job of tracking the bgp->peerhash When we add/remove peers we need to do a bit better job of tracking them in the bgp->peerhash. 1) When we have the doppelganger take over, make sure the winner is the one represented in the peerhash. 2) When creating the doppelganger, leave the current one in place instead of blindly replacing it. Signed-off-by: Donald Sharp --- bgpd/bgp_fsm.c | 9 +++++++++ bgpd/bgpd.c | 17 +++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 65b8b5bd2d..d17426e3ff 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1677,6 +1677,15 @@ static int bgp_establish(struct peer *peer) peer_delete(peer->doppelganger); } + /* + * If we are replacing the old peer for a doppelganger + * then switch it around in the bgp->peerhash + * the doppelgangers su and this peer's su are the same + * so the hash_release is the same for either. + */ + hash_release(peer->bgp->peerhash, peer); + hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); + bgp_bfd_register_peer(peer); return ret; } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ebaa0a3e5f..ed065c55fa 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1422,7 +1422,15 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp) } } -/* Create new BGP peer. */ +/* + * Create new BGP peer. + * + * conf_if and su are mutually exclusive if configuring from the cli. + * If we are handing a doppelganger, then we *must* pass in both + * the original peer's su and conf_if, so that we can appropriately + * track the bgp->peerhash( ie we don't want to remove the current + * one from the config ). + */ struct peer *peer_create(union sockunion *su, const char *conf_if, struct bgp *bgp, as_t local_as, as_t remote_as, int as_type, afi_t afi, safi_t safi, @@ -1435,12 +1443,13 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, peer = peer_new(bgp); if (conf_if) { peer->conf_if = XSTRDUP(MTYPE_PEER_CONF_IF, conf_if); - bgp_peer_conf_if_to_su_update(peer); + if (su) + peer->su = *su; + else + bgp_peer_conf_if_to_su_update(peer); if (peer->host) XFREE(MTYPE_BGP_PEER_HOST, peer->host); peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if); - if (su) - peer->su = *su; } else if (su) { peer->su = *su; sockunion2str(su, buf, SU_ADDRSTRLEN); -- 2.39.5