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;
}
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
peer1->as, peer1->as_type, 0, 0, NULL);
- peer->su = su;
hash_release(peer->bgp->peerhash, peer);
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
NULL, 0);
}
+static void show_bgp_peerhash_entry(struct hash_backet *backet, void *arg)
+{
+ struct vty *vty = arg;
+ struct peer *peer = backet->data;
+ char buf[SU_ADDRSTRLEN];
+
+ vty_out(vty, "\tPeer: %s %s\n", peer->host,
+ sockunion2str(&peer->su, buf, sizeof(buf)));
+}
+
+DEFUN (show_bgp_peerhash,
+ show_bgp_peerhash_cmd,
+ "show bgp peerhash",
+ SHOW_STR
+ BGP_STR
+ "Display information about the BGP peerhash\n")
+{
+ struct list *instances = bm->bgp;
+ struct listnode *node;
+ struct bgp *bgp;
+
+ for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
+ vty_out(vty, "BGP: %s\n", bgp->name);
+ hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
+ vty);
+ }
+
+ return CMD_SUCCESS;
+}
+
/* also used for encap safi */
static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi)
/* show bgp ipv4 flowspec detailed */
install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
+ install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
}
void bgp_route_finish(void)
peer = peer_lookup_by_conf_if(bgp, conf_if);
if (peer) {
if (as_str)
- ret = peer_remote_as(bgp, &su, conf_if, &as, as_type,
+ ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
afi, safi);
} else {
if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)
}
}
-/* 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,
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);