summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_fsm.c36
-rw-r--r--bgpd/bgp_io.c16
-rw-r--r--bgpd/bgp_network.c24
-rw-r--r--bgpd/bgp_open.c2
-rw-r--r--bgpd/bgpd.c5
-rw-r--r--bgpd/bgpd.h1
6 files changed, 76 insertions, 8 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 5e5ac636ed..a86c457b62 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -251,6 +251,20 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
peer->remote_id = from_peer->remote_id;
peer->last_reset = from_peer->last_reset;
+ peer->peer_gr_present_state = from_peer->peer_gr_present_state;
+ peer->peer_gr_new_status_flag = from_peer->peer_gr_new_status_flag;
+ bgp_peer_gr_flags_update(peer);
+
+ if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
+
+ UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
+
+ if (CHECK_FLAG(peer->sflags,
+ PEER_STATUS_NSF_WAIT)) {
+ peer_nsf_stop(peer);
+ }
+ }
+
if (from_peer->hostname != NULL) {
if (peer->hostname) {
XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
@@ -2604,5 +2618,25 @@ void bgp_peer_gr_flags_update(struct peer *peer)
peer->host,
(CHECK_FLAG(peer->flags,
PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT) ?
- "Set" : "UnSet"));
+ "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);
+
+ UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
+
+ if (CHECK_FLAG(peer->sflags,
+ PEER_STATUS_NSF_WAIT)) {
+
+ peer_nsf_stop(peer);
+ zlog_debug(
+ "BGP_GR:: Peer %s UNSET PEER_STATUS_NSF_WAIT!",
+ peer->host);
+ }
+ }
}
diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c
index fed34e5b65..626c36ff05 100644
--- a/bgpd/bgp_io.c
+++ b/bgpd/bgp_io.c
@@ -462,7 +462,12 @@ static uint16_t bgp_read(struct peer *peer)
safe_strerror(errno));
if (peer->status == Established) {
- if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)) {
+ if ((CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART) ||
+ CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART_HELPER)) &&
+ CHECK_FLAG(peer->sflags,
+ PEER_STATUS_NSF_MODE)) {
peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
} else
@@ -475,10 +480,15 @@ static uint16_t bgp_read(struct peer *peer)
} else if (nbytes == 0) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [Event] BGP connection closed fd %d",
- peer->host, peer->fd);
+ peer->host, peer->fd);
if (peer->status == Established) {
- if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)) {
+ if ((CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART) ||
+ CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART_HELPER)) &&
+ CHECK_FLAG(peer->sflags,
+ PEER_STATUS_NSF_MODE)) {
peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
} else
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 4031d2dfde..4487684de5 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -487,6 +487,18 @@ static int bgp_accept(struct thread *thread)
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
peer_xfer_config(peer, peer1);
+ bgp_peer_gr_flags_update(peer);
+
+ if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
+
+ UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
+
+ if (CHECK_FLAG(peer->sflags,
+ PEER_STATUS_NSF_WAIT)) {
+ peer_nsf_stop(peer);
+ }
+ }
+
UNSET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
peer->doppelganger = peer1;
@@ -497,10 +509,9 @@ static int bgp_accept(struct thread *thread)
BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */
SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
-
/* Make dummy peer until read Open packet. */
if (peer1->status == Established
- && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
+ && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
/* If we have an existing established connection with graceful
* restart
* capability announced with one or more address families, then
@@ -508,7 +519,14 @@ static int bgp_accept(struct thread *thread)
* existing established connection and move state to connect.
*/
peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
- SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
+
+ if (CHECK_FLAG(peer1->flags,
+ PEER_FLAG_GRACEFUL_RESTART) ||
+ CHECK_FLAG(peer1->flags,
+ PEER_FLAG_GRACEFUL_RESTART_HELPER))
+ SET_FLAG(peer1->sflags,
+ PEER_STATUS_NSF_WAIT);
+
bgp_event_update(peer1, TCP_connection_closed);
}
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index eb6dc1a753..89437a5149 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -462,6 +462,8 @@ static int bgp_capability_restart(struct peer *peer,
restart_flag_time = stream_getw(s);
if (CHECK_FLAG(restart_flag_time, RESTART_R_BIT))
SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV);
+ else
+ UNSET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV);
UNSET_FLAG(restart_flag_time, 0xF000);
peer->v_gr_restart = restart_flag_time;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index fae91655ab..2c60b818ef 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1326,6 +1326,9 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
peer_dst->flags = peer_src->flags;
peer_dst->cap = peer_src->cap;
+ peer_dst->peer_gr_present_state = peer_src->peer_gr_present_state;
+ peer_dst->peer_gr_new_status_flag = peer_src->peer_gr_new_status_flag;
+
peer_dst->local_as = peer_src->local_as;
peer_dst->port = peer_src->port;
(void)peer_sort(peer_dst);
@@ -2213,7 +2216,7 @@ int peer_afc_set(struct peer *peer, afi_t afi, safi_t safi, int enable)
return peer_deactivate(peer, afi, safi);
}
-static void peer_nsf_stop(struct peer *peer)
+void peer_nsf_stop(struct peer *peer)
{
afi_t afi;
safi_t safi;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 390dc8a7ff..a8ba6ad258 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -2081,5 +2081,6 @@ extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
/* Hooks */
DECLARE_HOOK(peer_status_changed, (struct peer * peer), (peer))
+void peer_nsf_stop(struct peer *peer);
#endif /* _QUAGGA_BGPD_H */