#include "queue.h"
#include "filter.h"
#include "command.h"
+#include "lib_errors.h"
#include "lib/json.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_network.h"
if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
return from_peer;
+ /*
+ * Let's check that we are not going to loose known configuration
+ * state based upon doppelganger rules.
+ */
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (from_peer->afc[afi][safi] != peer->afc[afi][safi]) {
+ flog_err(
+ EC_BGP_DOPPELGANGER_CONFIG,
+ "from_peer->afc[%d][%d] is not the same as what we are overwriting",
+ afi, safi);
+ return NULL;
+ }
+ }
+
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)",
from_peer->host, from_peer, from_peer->fd, peer,
* runs in our pthread.
*/
if (peer->curr) {
- zlog_err(
+ flog_err(
+ EC_BGP_PKT_PROCESS,
"[%s] Dropping pending packet on connection transfer:",
peer->host);
uint16_t type = stream_getc_from(peer->curr,
peer->as = from_peer->as;
peer->v_holdtime = from_peer->v_holdtime;
peer->v_keepalive = from_peer->v_keepalive;
- peer->routeadv = from_peer->routeadv;
peer->v_routeadv = from_peer->v_routeadv;
peer->v_gr_restart = from_peer->v_gr_restart;
peer->cap = from_peer->cap;
}
if (bgp_getsockname(peer) < 0) {
- zlog_err(
+ flog_err(
+ EC_LIB_SOCKET,
"%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
(CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
? "accept"
}
if (from_peer->status > Active) {
if (bgp_getsockname(from_peer) < 0) {
- zlog_err(
+ flog_err(
+ EC_LIB_SOCKET,
"%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
+
(CHECK_FLAG(from_peer->sflags,
PEER_STATUS_ACCEPT_PEER)
? "accept"
}
}
-/* Called after event occured, this function change status and reset
+/* Called after event occurred, this function change status and reset
read/write and timer thread. */
void bgp_fsm_change_status(struct peer *peer, int status)
{
+ struct bgp *bgp;
+ uint32_t peer_count;
bgp_dump_state(peer, peer->status, status);
+ bgp = peer->bgp;
+ peer_count = bgp->established_peers;
+
+ if (status == Established)
+ bgp->established_peers++;
+ else if ((peer->status == Established) && (status != Established))
+ bgp->established_peers--;
+
+ if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS))
+ zlog_debug("%s : vrf %u, established_peers %u", __func__,
+ bgp->vrf_id, bgp->established_peers);
+ /* Set to router ID to the value provided by RIB if there are no peers
+ * in the established state and peer count did not change
+ */
+ if ((peer_count != bgp->established_peers) &&
+ (bgp->established_peers == 0))
+ bgp_router_id_zebra_bump(bgp->vrf_id, NULL);
+
/* Transition into Clearing or Deleted must /always/ clear all routes..
* (and must do so before actually changing into Deleted..
*/
"%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
peer->host,
(peer->hostname) ? peer->hostname : "Unknown",
- vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name
- : "Default")
+ vrf ? ((vrf->vrf_id != VRF_DEFAULT)
+ ? vrf->name
+ : VRF_DEFAULT_NAME)
: "",
peer_down_str[(int)peer->last_reset]);
}
}
/* Reset keepalive and holdtime */
- if (PEER_OR_GROUP_TIMER_SET(peer)) {
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
peer->v_keepalive = peer->keepalive;
peer->v_holdtime = peer->holdtime;
} else {
static int bgp_connect_success(struct peer *peer)
{
if (peer->fd < 0) {
- zlog_err("bgp_connect_success peer's fd is negative value %d",
+ flog_err(EC_BGP_CONNECT,
+ "bgp_connect_success peer's fd is negative value %d",
peer->fd);
bgp_stop(peer);
return -1;
}
if (bgp_getsockname(peer) < 0) {
- zlog_err("%s: bgp_getsockname(): failed for peer %s, fd %d",
- __FUNCTION__, peer->host, peer->fd);
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s: bgp_getsockname(): failed for peer %s, fd %d",
+ __FUNCTION__, peer->host, peer->fd);
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
0); /* internal error */
bgp_writes_on(peer);
if (BGP_PEER_START_SUPPRESSED(peer)) {
if (bgp_debug_neighbor_events(peer))
- zlog_err(
- "%s [FSM] Trying to start suppressed peer"
- " - this is never supposed to happen!",
- peer->host);
+ flog_err(EC_BGP_FSM,
+ "%s [FSM] Trying to start suppressed peer"
+ " - this is never supposed to happen!",
+ peer->host);
return -1;
}
if (peer->bgp->vrf_id == VRF_UNKNOWN) {
if (bgp_debug_neighbor_events(peer))
- zlog_err(
+ flog_err(
+ EC_BGP_FSM,
"%s [FSM] In a VRF that is not initialised yet",
peer->host);
return -1;
"%s [FSM] Non blocking connect waiting result, fd %d",
peer->host, peer->fd);
if (peer->fd < 0) {
- zlog_err("bgp_start peer's fd is negative value %d",
+ flog_err(EC_BGP_FSM,
+ "bgp_start peer's fd is negative value %d",
peer->fd);
return -1;
}
peer and change to Idle status. */
static int bgp_fsm_event_error(struct peer *peer)
{
- zlog_err("%s [FSM] unexpected packet received in state %s", peer->host,
- lookup_msg(bgp_status_msg, peer->status, NULL));
+ flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
+ peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, 0);
}
other = peer->doppelganger;
peer = peer_xfer_conn(peer);
if (!peer) {
- zlog_err("%%Neighbor failed in xfer_conn");
+ flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
return -1;
}
zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
peer->host,
(peer->hostname) ? peer->hostname : "Unknown",
- vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name
- : "Default")
+ vrf ? ((vrf->vrf_id != VRF_DEFAULT)
+ ? vrf->name
+ : VRF_DEFAULT_NAME)
: "");
}
/* assign update-group/subgroup */
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;
}
/* This is empty event. */
static int bgp_ignore(struct peer *peer)
{
- zlog_err(
+ flog_err(
+ EC_BGP_FSM,
"%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
peer->host, bgp_event_str[peer->cur_event],
lookup_msg(bgp_status_msg, peer->status, NULL),
/* This is to handle unexpected events.. */
static int bgp_fsm_exeption(struct peer *peer)
{
- zlog_err(
+ flog_err(
+ EC_BGP_FSM,
"%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
peer->host, bgp_event_str[peer->cur_event],
lookup_msg(bgp_status_msg, peer->status, NULL),
* code.
*/
if (!dyn_nbr && !passive_conn && peer->bgp) {
- zlog_err(
+ flog_err(
+ EC_BGP_FSM,
"%s [FSM] Failure handling event %s in state %s, "
"prior events %s, %s, fd %d",
peer->host, bgp_event_str[peer->cur_event],