summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);