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 <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2018-10-07 20:34:31 -04:00
parent cc4d4ce822
commit 19bd3dffc1
2 changed files with 22 additions and 4 deletions

View File

@ -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;
}

View File

@ -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);