summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_fsm.c')
-rw-r--r--bgpd/bgp_fsm.c439
1 files changed, 167 insertions, 272 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index d41ef8ab..94fca23e 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -602,6 +602,7 @@ const char *const peer_down_str[] = {
"Socket Error",
"Admin. shutdown (RTT)",
"Suppress Fib Turned On or Off",
+ "Password config change",
};
static void bgp_graceful_restart_timer_off(struct peer_connection *connection,
@@ -687,6 +688,11 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
COMMUNITY_NO_LLGR))
continue;
+ if (bgp_attr_get_community(pi->attr) &&
+ community_include(bgp_attr_get_community(pi->attr),
+ COMMUNITY_LLGR_STALE))
+ continue;
+
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
@@ -695,10 +701,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
attr = *pi->attr;
bgp_attr_add_llgr_community(&attr);
pi->attr = bgp_attr_intern(&attr);
- bgp_recalculate_afi_safi_bestpaths(
- peer->bgp, afi, safi);
-
- break;
+ bgp_process(peer->bgp, rm, pi, afi,
+ safi);
}
}
} else {
@@ -715,6 +719,11 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
COMMUNITY_NO_LLGR))
continue;
+ if (bgp_attr_get_community(pi->attr) &&
+ community_include(bgp_attr_get_community(pi->attr),
+ COMMUNITY_LLGR_STALE))
+ continue;
+
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
@@ -723,10 +732,7 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
attr = *pi->attr;
bgp_attr_add_llgr_community(&attr);
pi->attr = bgp_attr_intern(&attr);
- bgp_recalculate_afi_safi_bestpaths(peer->bgp,
- afi, safi);
-
- break;
+ bgp_process(peer->bgp, dest, pi, afi, safi);
}
}
}
@@ -1482,7 +1488,7 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection)
EVENT_OFF(connection->t_connect);
EVENT_OFF(connection->t_holdtime);
EVENT_OFF(connection->t_routeadv);
- EVENT_OFF(peer->connection->t_delayopen);
+ EVENT_OFF(connection->t_delayopen);
/* Clear input and output buffer. */
frr_with_mutex (&connection->io_mtx) {
@@ -1801,18 +1807,14 @@ bgp_connect_fail(struct peer_connection *connection)
*/
static void bgp_connect_in_progress_update_connection(struct peer *peer)
{
- if (bgp_getsockname(peer) < 0) {
- if (!peer->su_remote &&
- !BGP_CONNECTION_SU_UNSPEC(peer->connection)) {
- /* if connect initiated, then dest port and dest addresses are well known */
- peer->su_remote = sockunion_dup(&peer->connection->su);
- if (sockunion_family(peer->su_remote) == AF_INET)
- peer->su_remote->sin.sin_port =
- htons(peer->port);
- else if (sockunion_family(peer->su_remote) == AF_INET6)
- peer->su_remote->sin6.sin6_port =
- htons(peer->port);
- }
+ bgp_updatesockname(peer);
+ if (!peer->su_remote && !BGP_CONNECTION_SU_UNSPEC(peer->connection)) {
+ /* if connect initiated, then dest port and dest addresses are well known */
+ peer->su_remote = sockunion_dup(&peer->connection->su);
+ if (sockunion_family(peer->su_remote) == AF_INET)
+ peer->su_remote->sin.sin_port = htons(peer->port);
+ else if (sockunion_family(peer->su_remote) == AF_INET6)
+ peer->su_remote->sin6.sin6_port = htons(peer->port);
}
}
@@ -2046,9 +2048,10 @@ static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
}
gr_info->eor_required++;
/* Send message to RIB indicating route update pending */
- if (gr_info->af_enabled[afi][safi] == false) {
- gr_info->af_enabled[afi][safi] = true;
- /* Send message to RIB */
+ if (gr_info->af_enabled == false) {
+ gr_info->af_enabled = true;
+ gr_info->route_sync = false;
+ bgp->gr_route_sync_pending = true;
bgp_zebra_update(bgp, afi, safi,
ZEBRA_CLIENT_ROUTE_UPDATE_PENDING);
}
@@ -2082,7 +2085,7 @@ static int bgp_update_gr_info(struct peer *peer, afi_t afi, safi_t safi)
if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
&& BGP_PEER_RESTARTING_MODE(peer)) {
/* Check if the forwarding state is preserved */
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) {
+ if (bgp_gr_is_forwarding_preserved(bgp)) {
gr_info = &(bgp->gr_info[afi][safi]);
ret = bgp_start_deferral_timer(bgp, afi, safi, gr_info);
}
@@ -2199,8 +2202,7 @@ bgp_establish(struct peer_connection *connection)
} else {
if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) &&
BGP_PEER_RESTARTING_MODE(peer) &&
- CHECK_FLAG(peer->bgp->flags,
- BGP_FLAG_GR_PRESERVE_FWD))
+ bgp_gr_is_forwarding_preserved(peer->bgp))
peer->bgp->gr_info[afi][safi]
.eor_required++;
}
@@ -2695,53 +2697,61 @@ int bgp_event_update(struct peer_connection *connection,
}
/* BGP GR Code */
-int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
- enum global_mode global_new_state,
- enum global_mode global_old_state)
+static inline void
+bgp_peer_inherit_global_gr_mode(struct peer *peer,
+ enum global_mode global_gr_mode)
+{
+ switch (global_gr_mode) {
+ case GLOBAL_HELPER:
+ BGP_PEER_GR_HELPER_ENABLE(peer);
+ break;
+ case GLOBAL_GR:
+ BGP_PEER_GR_ENABLE(peer);
+ break;
+ case GLOBAL_DISABLE:
+ BGP_PEER_GR_DISABLE(peer);
+ break;
+ case GLOBAL_INVALID:
+ default:
+ zlog_err("Unexpected Global GR mode %d", global_gr_mode);
+ }
+}
+
+static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp,
+ enum global_mode global_new_state)
{
struct peer *peer = {0};
struct listnode *node = {0};
struct listnode *nnode = {0};
enum peer_mode peer_old_state = PEER_INVALID;
- for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
-
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__,
- peer->host);
+ /* TODO: Need to handle peer-groups. */
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
peer_old_state = bgp_peer_gr_mode_get(peer);
+ if (peer_old_state != PEER_GLOBAL_INHERIT)
+ continue;
- if (peer_old_state == PEER_GLOBAL_INHERIT) {
-
- /*
- *Reset only these peers and send a
- *new open message with the change capabilities.
- *Considering the mode to be "global_new_state" and
- *do all operation accordingly
- */
+ bgp_peer_inherit_global_gr_mode(peer, global_new_state);
+ bgp_peer_gr_flags_update(peer);
- switch (global_new_state) {
- case GLOBAL_HELPER:
- BGP_PEER_GR_HELPER_ENABLE(peer);
- break;
- case GLOBAL_GR:
- BGP_PEER_GR_ENABLE(peer);
- break;
- case GLOBAL_DISABLE:
- BGP_PEER_GR_DISABLE(peer);
- break;
- case GLOBAL_INVALID:
- zlog_debug("%s [BGP_GR] GLOBAL_INVALID",
- __func__);
- return BGP_ERR_GR_OPERATION_FAILED;
- }
- }
- }
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("%pBP: Inherited Global GR mode, GR flags 0x%x peer flags 0x%" PRIx64
+ "...resetting session",
+ peer, peer->peer_gr_new_status_flag,
+ peer->flags);
- bgp->global_gr_present_state = global_new_state;
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
- return BGP_GR_SUCCESS;
+ /* Reset session to match with behavior for other peer
+ * configs that require the session to be re-setup.
+ */
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
+ bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ else
+ bgp_session_reset_safe(peer, &nnode);
+ }
}
int bgp_gr_update_all(struct bgp *bgp, enum global_gr_command global_gr_cmd)
@@ -2749,46 +2759,27 @@ int bgp_gr_update_all(struct bgp *bgp, enum global_gr_command global_gr_cmd)
enum global_mode global_new_state = GLOBAL_INVALID;
enum global_mode global_old_state = GLOBAL_INVALID;
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("%s [BGP_GR]START: global_gr_cmd :%s:", __func__,
- print_global_gr_cmd(global_gr_cmd));
-
global_old_state = bgp_global_gr_mode_get(bgp);
+ global_new_state = bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd];
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("[BGP_GR] global_old_gr_state :%s:",
- print_global_gr_mode(global_old_state));
+ zlog_debug("%s: Handle GR command %s, current GR state %s, new GR state %s",
+ bgp->name_pretty, print_global_gr_cmd(global_gr_cmd),
+ print_global_gr_mode(global_old_state),
+ print_global_gr_mode(global_new_state));
- if (global_old_state != GLOBAL_INVALID) {
- global_new_state =
- bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd];
-
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("[BGP_GR] global_new_gr_state :%s:",
- print_global_gr_mode(global_new_state));
- } else {
- zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID",
- __func__);
+ if (global_old_state == GLOBAL_INVALID)
return BGP_ERR_GR_OPERATION_FAILED;
- }
-
- if (global_new_state == GLOBAL_INVALID) {
- zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID",
- __func__);
+ if (global_new_state == GLOBAL_INVALID)
return BGP_ERR_GR_INVALID_CMD;
- }
- if (global_new_state == global_old_state) {
- /* Trace msg */
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "%s [BGP_GR] global_new_state == global_old_state :%s",
- __func__,
- print_global_gr_mode(global_new_state));
+ if (global_new_state == global_old_state)
return BGP_GR_NO_OPERATION;
- }
- return bgp_gr_lookup_n_update_all_peer(bgp, global_new_state,
- global_old_state);
+ /* Update global GR mode and process all peers in instance. */
+ bgp->global_gr_present_state = global_new_state;
+ bgp_gr_update_mode_of_all_peers(bgp, global_new_state);
+
+ return BGP_GR_SUCCESS;
}
const char *print_peer_gr_mode(enum peer_mode pr_mode)
@@ -2903,179 +2894,102 @@ int bgp_neighbor_graceful_restart(struct peer *peer,
{
enum peer_mode peer_new_state = PEER_INVALID;
enum peer_mode peer_old_state = PEER_INVALID;
- struct bgp_peer_gr peer_state;
+ struct bgp_peer_gr gr_fsm;
int result = BGP_GR_FAILURE;
- /*
- * fetch peer_old_state from peer structure also
- * fetch global_old_state from bgp structure,
- * peer had a back pointer to bgpo struct ;
- */
-
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:",
- __func__, peer->host,
- print_peer_gr_cmd(peer_gr_cmd));
-
peer_old_state = bgp_peer_gr_mode_get(peer);
+ gr_fsm = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd];
+ peer_new_state = gr_fsm.next_state;
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("%s [BGP_GR] peer_old_state: %d", __func__,
- peer_old_state);
+ zlog_debug("%pBP: Handle GR command %s, current GR state %s, new GR state %s",
+ peer, print_peer_gr_cmd(peer_gr_cmd),
+ print_peer_gr_mode(peer_old_state),
+ print_peer_gr_mode(peer_new_state));
if (peer_old_state == PEER_INVALID)
return BGP_ERR_GR_OPERATION_FAILED;
- peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd];
- peer_new_state = peer_state.next_state;
-
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("%s [BGP_GR] peer_new_state: %d", __func__,
- peer_new_state);
-
if (peer_new_state == PEER_INVALID)
return BGP_ERR_GR_INVALID_CMD;
- if (peer_new_state != peer_old_state) {
- result = peer_state.action_fun(peer, peer_old_state,
- peer_new_state);
- } else {
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] peer_old_state == peer_new_state !");
+ if (peer_new_state == peer_old_state)
return BGP_GR_NO_OPERATION;
- }
-
- if (result == BGP_GR_SUCCESS) {
- /* Update the mode i.e peer_new_state into the peer structure */
- peer->peer_gr_present_state = peer_new_state;
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] Successfully change the state of the peer to : %s : !",
- print_peer_gr_mode(peer_new_state));
-
- return BGP_GR_SUCCESS;
- }
+ result = gr_fsm.action_fun(peer, peer_old_state, peer_new_state);
return result;
}
-unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_peer_state,
- enum peer_mode new_peer_state)
+static inline bool gr_mode_matches(enum peer_mode peer_gr_mode,
+ enum global_mode global_gr_mode)
{
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!",
- __func__, print_peer_gr_mode(old_peer_state),
- print_peer_gr_mode(new_peer_state));
+ if ((peer_gr_mode == PEER_HELPER && global_gr_mode == GLOBAL_HELPER) ||
+ (peer_gr_mode == PEER_GR && global_gr_mode == GLOBAL_GR) ||
+ (peer_gr_mode == PEER_DISABLE && global_gr_mode == GLOBAL_DISABLE))
+ return true;
+ return false;
+}
- enum global_mode bgp_gr_global_mode = GLOBAL_INVALID;
- unsigned int ret = BGP_GR_FAILURE;
+unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state,
+ enum peer_mode new_state)
+{
+ enum global_mode global_gr_mode;
+ bool session_reset = true;
- if (old_peer_state == new_peer_state) {
- /* Nothing to do over here as the present and old state is the
- * same */
+ if (old_state == new_state)
return BGP_GR_NO_OPERATION;
- }
- if ((old_peer_state == PEER_INVALID)
- || (new_peer_state == PEER_INVALID)) {
- /* something bad happend , print error message */
+ if ((old_state == PEER_INVALID) || (new_state == PEER_INVALID))
return BGP_ERR_GR_INVALID_CMD;
- }
- bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp);
-
- if ((old_peer_state == PEER_GLOBAL_INHERIT)
- && (new_peer_state != PEER_GLOBAL_INHERIT)) {
-
- /* fetch the Mode running in the Global state machine
- *from the bgp structure into a variable called
- *bgp_gr_global_mode
- */
-
- /* Here we are checking if the
- *1. peer_new_state == global_mode == helper_mode
- *2. peer_new_state == global_mode == GR_mode
- *3. peer_new_state == global_mode == disabled_mode
- */
+ global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
+ if ((old_state == PEER_GLOBAL_INHERIT) &&
+ (new_state != PEER_GLOBAL_INHERIT)) {
BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer);
- if ((int)new_peer_state == (int)bgp_gr_global_mode) {
- /* This is incremental updates i.e no tear down
- * of the existing session
- * as the peer is already working in the same mode.
+ if (gr_mode_matches(new_state, global_gr_mode))
+ /* Peer was inheriting the global state and
+ * its new state still is the same, so a
+ * session reset is not needed.
*/
- ret = BGP_GR_SUCCESS;
- } else {
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] Peer state changed from :%s ",
- print_peer_gr_mode(old_peer_state));
-
- bgp_peer_move_to_gr_mode(peer, new_peer_state);
-
- ret = BGP_GR_SUCCESS;
- }
- }
- /* In the case below peer is going into Global inherit mode i.e.
- * the peer would work as the mode configured at the global level
- */
- else if ((new_peer_state == PEER_GLOBAL_INHERIT)
- && (old_peer_state != PEER_GLOBAL_INHERIT)) {
- /* Here in this case it would be destructive
- * in all the cases except one case when,
- * Global GR is configured Disabled
- * and present_peer_state is not disable
- */
-
+ session_reset = false;
+ } else if ((new_state == PEER_GLOBAL_INHERIT) &&
+ (old_state != PEER_GLOBAL_INHERIT)) {
BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
- if ((int)old_peer_state == (int)bgp_gr_global_mode) {
- /* This is incremental updates
- *i.e no tear down of the existing session
- *as the peer is already working in the same mode.
- */
- ret = BGP_GR_SUCCESS;
- } else {
- /* Destructive always */
- /* Tear down the old session
- * and send the new capability
- * as per the bgp_gr_global_mode
+ if (gr_mode_matches(old_state, global_gr_mode))
+ /* Peer is inheriting the global state and
+ * its old state was also the same, so a
+ * session reset is not needed.
*/
+ session_reset = false;
+ }
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] Peer state changed from :%s",
- print_peer_gr_mode(old_peer_state));
+ /* Ensure we move to the new state and update flags */
+ bgp_peer_move_to_gr_mode(peer, new_state);
- bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode);
+ if (session_reset) {
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
- ret = BGP_GR_SUCCESS;
- }
- } else {
- /*
- *This else case, it include all the cases except -->
- *(new_peer_state != Peer_Global) &&
- *( old_peer_state != Peer_Global )
+ /* Reset session to match with behavior for other peer
+ * configs that require the session to be re-setup.
*/
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("[BGP_GR] Peer state changed from :%s",
- print_peer_gr_mode(old_peer_state));
-
- bgp_peer_move_to_gr_mode(peer, new_peer_state);
-
- ret = BGP_GR_SUCCESS;
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
+ bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ else
+ bgp_session_reset(peer);
}
- return ret;
+ return BGP_GR_SUCCESS;
}
-inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
+void bgp_peer_move_to_gr_mode(struct peer *peer, enum peer_mode new_state)
{
- int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
+ enum global_mode global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
+ enum peer_mode old_state = bgp_peer_gr_mode_get(peer);
switch (new_state) {
case PEER_HELPER:
@@ -3089,57 +3003,38 @@ inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
break;
case PEER_GLOBAL_INHERIT:
BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
-
- if (bgp_global_gr_mode == GLOBAL_HELPER) {
- BGP_PEER_GR_HELPER_ENABLE(peer);
- } else if (bgp_global_gr_mode == GLOBAL_GR) {
- BGP_PEER_GR_ENABLE(peer);
- } else if (bgp_global_gr_mode == GLOBAL_DISABLE) {
- BGP_PEER_GR_DISABLE(peer);
- } else {
- zlog_err(
- "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
- }
+ bgp_peer_inherit_global_gr_mode(peer, global_gr_mode);
break;
+ case PEER_INVALID:
default:
zlog_err(
"[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
break;
}
+ bgp_peer_gr_flags_update(peer);
+ peer->peer_gr_present_state = new_state;
+
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
- new_state);
+ zlog_debug("%pBP: Peer GR mode changed from %s to %s, GR flags 0x%x peer flags 0x%" PRIx64,
+ peer, print_peer_gr_mode(old_state),
+ print_peer_gr_mode(new_state),
+ peer->peer_gr_new_status_flag, peer->flags);
}
void bgp_peer_gr_flags_update(struct peer *peer)
{
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug("%s [BGP_GR] called !", __func__);
if (CHECK_FLAG(peer->peer_gr_new_status_flag,
PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
else
UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
- peer->host,
- (CHECK_FLAG(peer->flags,
- PEER_FLAG_GRACEFUL_RESTART_HELPER)
- ? "Set"
- : "UnSet"));
+
if (CHECK_FLAG(peer->peer_gr_new_status_flag,
PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
else
UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
- if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
- peer->host,
- (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
- ? "Set"
- : "UnSet"));
+
if (CHECK_FLAG(peer->peer_gr_new_status_flag,
PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
SET_FLAG(peer->flags,
@@ -3147,28 +3042,28 @@ void bgp_peer_gr_flags_update(struct peer *peer)
else
UNSET_FLAG(peer->flags,
PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
+
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
- zlog_debug(
- "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
- peer->host,
- (CHECK_FLAG(peer->flags,
- PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT)
- ? "Set"
- : "UnSet"));
-
- if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
- && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) {
- zlog_debug("[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!",
- peer->host);
+ zlog_debug("%pBP: Peer flags updated to 0x%" PRIx64
+ ", GR flags 0x%x, GR mode %s",
+ peer, peer->flags, peer->peer_gr_new_status_flag,
+ print_peer_gr_mode(bgp_peer_gr_mode_get(peer)));
+ /*
+ * If GR has been completely disabled for the peer and we were
+ * acting as the Helper for the peer (i.e., keeping stale routes
+ * and running the restart timer or stalepath timer), clear those
+ * states.
+ */
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) &&
+ !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) {
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
-
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug("%pBP: GR disabled, stopping NSF and clearing stale routes",
+ peer);
peer_nsf_stop(peer);
- zlog_debug(
- "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",
- peer->host);
}
}
}