summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-10-07 20:34:31 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-10-07 20:55:52 -0400
commit19bd3dffc19eb0a4fb13ec6da987c6bd00a1f727 (patch)
tree20e1fe85427dba8e091cf771f442285b423cba99
parentcc4d4ce8229d6107599eb42d4f646eddbea5ddc7 (diff)
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>
-rw-r--r--bgpd/bgp_fsm.c9
-rw-r--r--bgpd/bgpd.c17
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);