mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 05:13:07 +00:00
Merge pull request #7349 from opensourcerouting/bgp-delayopen
bgpd: RFC 4271 optional session attribute DelayOpenTimer
This commit is contained in:
commit
3cc92134a3
177
bgpd/bgp_fsm.c
177
bgpd/bgp_fsm.c
@ -67,12 +67,14 @@ static const char *const bgp_event_str[] = {
|
|||||||
"BGP_Start",
|
"BGP_Start",
|
||||||
"BGP_Stop",
|
"BGP_Stop",
|
||||||
"TCP_connection_open",
|
"TCP_connection_open",
|
||||||
|
"TCP_connection_open_w_delay",
|
||||||
"TCP_connection_closed",
|
"TCP_connection_closed",
|
||||||
"TCP_connection_open_failed",
|
"TCP_connection_open_failed",
|
||||||
"TCP_fatal_error",
|
"TCP_fatal_error",
|
||||||
"ConnectRetry_timer_expired",
|
"ConnectRetry_timer_expired",
|
||||||
"Hold_Timer_expired",
|
"Hold_Timer_expired",
|
||||||
"KeepAlive_timer_expired",
|
"KeepAlive_timer_expired",
|
||||||
|
"DelayOpen_timer_expired",
|
||||||
"Receive_OPEN_message",
|
"Receive_OPEN_message",
|
||||||
"Receive_KEEPALIVE_message",
|
"Receive_KEEPALIVE_message",
|
||||||
"Receive_UPDATE_message",
|
"Receive_UPDATE_message",
|
||||||
@ -92,6 +94,7 @@ int bgp_event(struct thread *);
|
|||||||
static int bgp_start_timer(struct thread *);
|
static int bgp_start_timer(struct thread *);
|
||||||
static int bgp_connect_timer(struct thread *);
|
static int bgp_connect_timer(struct thread *);
|
||||||
static int bgp_holdtime_timer(struct thread *);
|
static int bgp_holdtime_timer(struct thread *);
|
||||||
|
static int bgp_delayopen_timer(struct thread *);
|
||||||
|
|
||||||
/* BGP FSM functions. */
|
/* BGP FSM functions. */
|
||||||
static int bgp_start(struct peer *);
|
static int bgp_start(struct peer *);
|
||||||
@ -174,10 +177,12 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
|
|||||||
|
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
BGP_TIMER_OFF(peer->t_connect);
|
BGP_TIMER_OFF(peer->t_connect);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
BGP_TIMER_OFF(peer->t_connect_check_r);
|
BGP_TIMER_OFF(peer->t_connect_check_r);
|
||||||
BGP_TIMER_OFF(peer->t_connect_check_w);
|
BGP_TIMER_OFF(peer->t_connect_check_w);
|
||||||
BGP_TIMER_OFF(from_peer->t_routeadv);
|
BGP_TIMER_OFF(from_peer->t_routeadv);
|
||||||
BGP_TIMER_OFF(from_peer->t_connect);
|
BGP_TIMER_OFF(from_peer->t_connect);
|
||||||
|
BGP_TIMER_OFF(from_peer->t_delayopen);
|
||||||
BGP_TIMER_OFF(from_peer->t_connect_check_r);
|
BGP_TIMER_OFF(from_peer->t_connect_check_r);
|
||||||
BGP_TIMER_OFF(from_peer->t_connect_check_w);
|
BGP_TIMER_OFF(from_peer->t_connect_check_w);
|
||||||
BGP_TIMER_OFF(from_peer->t_process_packet);
|
BGP_TIMER_OFF(from_peer->t_process_packet);
|
||||||
@ -233,6 +238,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
|
|||||||
peer->v_holdtime = from_peer->v_holdtime;
|
peer->v_holdtime = from_peer->v_holdtime;
|
||||||
peer->v_keepalive = from_peer->v_keepalive;
|
peer->v_keepalive = from_peer->v_keepalive;
|
||||||
peer->v_routeadv = from_peer->v_routeadv;
|
peer->v_routeadv = from_peer->v_routeadv;
|
||||||
|
peer->v_delayopen = from_peer->v_delayopen;
|
||||||
peer->v_gr_restart = from_peer->v_gr_restart;
|
peer->v_gr_restart = from_peer->v_gr_restart;
|
||||||
peer->cap = from_peer->cap;
|
peer->cap = from_peer->cap;
|
||||||
status = peer->status;
|
status = peer->status;
|
||||||
@ -364,6 +370,7 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
BGP_TIMER_OFF(peer->t_holdtime);
|
BGP_TIMER_OFF(peer->t_holdtime);
|
||||||
bgp_keepalives_off(peer);
|
bgp_keepalives_off(peer);
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Connect:
|
case Connect:
|
||||||
@ -371,8 +378,13 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
status. Make sure start timer is off and connect timer is
|
status. Make sure start timer is off and connect timer is
|
||||||
on. */
|
on. */
|
||||||
BGP_TIMER_OFF(peer->t_start);
|
BGP_TIMER_OFF(peer->t_start);
|
||||||
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
peer->v_connect);
|
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
|
||||||
|
(peer->v_delayopen + peer->v_connect));
|
||||||
|
else
|
||||||
|
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
|
||||||
|
peer->v_connect);
|
||||||
|
|
||||||
BGP_TIMER_OFF(peer->t_holdtime);
|
BGP_TIMER_OFF(peer->t_holdtime);
|
||||||
bgp_keepalives_off(peer);
|
bgp_keepalives_off(peer);
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
@ -387,8 +399,13 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
|| CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
|
|| CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
|
||||||
BGP_TIMER_OFF(peer->t_connect);
|
BGP_TIMER_OFF(peer->t_connect);
|
||||||
} else {
|
} else {
|
||||||
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
peer->v_connect);
|
BGP_TIMER_ON(
|
||||||
|
peer->t_connect, bgp_connect_timer,
|
||||||
|
(peer->v_delayopen + peer->v_connect));
|
||||||
|
else
|
||||||
|
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
|
||||||
|
peer->v_connect);
|
||||||
}
|
}
|
||||||
BGP_TIMER_OFF(peer->t_holdtime);
|
BGP_TIMER_OFF(peer->t_holdtime);
|
||||||
bgp_keepalives_off(peer);
|
bgp_keepalives_off(peer);
|
||||||
@ -407,6 +424,7 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
}
|
}
|
||||||
bgp_keepalives_off(peer);
|
bgp_keepalives_off(peer);
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenConfirm:
|
case OpenConfirm:
|
||||||
@ -425,6 +443,7 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
bgp_keepalives_on(peer);
|
bgp_keepalives_on(peer);
|
||||||
}
|
}
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Established:
|
case Established:
|
||||||
@ -432,6 +451,7 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
off. */
|
off. */
|
||||||
BGP_TIMER_OFF(peer->t_start);
|
BGP_TIMER_OFF(peer->t_start);
|
||||||
BGP_TIMER_OFF(peer->t_connect);
|
BGP_TIMER_OFF(peer->t_connect);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
|
|
||||||
/* Same as OpenConfirm, if holdtime is zero then both holdtime
|
/* Same as OpenConfirm, if holdtime is zero then both holdtime
|
||||||
and keepalive must be turned off. */
|
and keepalive must be turned off. */
|
||||||
@ -455,6 +475,7 @@ void bgp_timer_set(struct peer *peer)
|
|||||||
BGP_TIMER_OFF(peer->t_holdtime);
|
BGP_TIMER_OFF(peer->t_holdtime);
|
||||||
bgp_keepalives_off(peer);
|
bgp_keepalives_off(peer);
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
break;
|
break;
|
||||||
case BGP_STATUS_MAX:
|
case BGP_STATUS_MAX:
|
||||||
flog_err(EC_LIB_DEVELOPMENT,
|
flog_err(EC_LIB_DEVELOPMENT,
|
||||||
@ -488,6 +509,10 @@ static int bgp_connect_timer(struct thread *thread)
|
|||||||
|
|
||||||
peer = THREAD_ARG(thread);
|
peer = THREAD_ARG(thread);
|
||||||
|
|
||||||
|
/* stop the DelayOpenTimer if it is running */
|
||||||
|
if (peer->t_delayopen)
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
|
|
||||||
assert(!peer->t_write);
|
assert(!peer->t_write);
|
||||||
assert(!peer->t_read);
|
assert(!peer->t_read);
|
||||||
|
|
||||||
@ -564,6 +589,23 @@ int bgp_routeadv_timer(struct thread *thread)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RFC 4271 DelayOpenTimer */
|
||||||
|
int bgp_delayopen_timer(struct thread *thread)
|
||||||
|
{
|
||||||
|
struct peer *peer;
|
||||||
|
|
||||||
|
peer = THREAD_ARG(thread);
|
||||||
|
|
||||||
|
if (bgp_debug_neighbor_events(peer))
|
||||||
|
zlog_debug("%s [FSM] Timer (DelayOpentimer expire)",
|
||||||
|
peer->host);
|
||||||
|
|
||||||
|
THREAD_VAL(thread) = DelayOpen_timer_expired;
|
||||||
|
bgp_event(thread); /* bgp_event unlocks peer */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* BGP Peer Down Cause */
|
/* BGP Peer Down Cause */
|
||||||
const char *const peer_down_str[] = {"",
|
const char *const peer_down_str[] = {"",
|
||||||
"Router ID changed",
|
"Router ID changed",
|
||||||
@ -1299,6 +1341,7 @@ int bgp_stop(struct peer *peer)
|
|||||||
BGP_TIMER_OFF(peer->t_connect);
|
BGP_TIMER_OFF(peer->t_connect);
|
||||||
BGP_TIMER_OFF(peer->t_holdtime);
|
BGP_TIMER_OFF(peer->t_holdtime);
|
||||||
BGP_TIMER_OFF(peer->t_routeadv);
|
BGP_TIMER_OFF(peer->t_routeadv);
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
|
|
||||||
/* Clear input and output buffer. */
|
/* Clear input and output buffer. */
|
||||||
frr_with_mutex(&peer->io_mtx) {
|
frr_with_mutex(&peer->io_mtx) {
|
||||||
@ -1357,6 +1400,12 @@ int bgp_stop(struct peer *peer)
|
|||||||
peer->v_holdtime = peer->bgp->default_holdtime;
|
peer->v_holdtime = peer->bgp->default_holdtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset DelayOpenTime */
|
||||||
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
peer->v_delayopen = peer->delayopen;
|
||||||
|
else
|
||||||
|
peer->v_delayopen = peer->bgp->default_delayopen;
|
||||||
|
|
||||||
peer->update_time = 0;
|
peer->update_time = 0;
|
||||||
|
|
||||||
/* Until we are sure that there is no problem about prefix count
|
/* Until we are sure that there is no problem about prefix count
|
||||||
@ -1469,7 +1518,10 @@ static int bgp_connect_check(struct thread *thread)
|
|||||||
|
|
||||||
/* When status is 0 then TCP connection is established. */
|
/* When status is 0 then TCP connection is established. */
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
BGP_EVENT_ADD(peer, TCP_connection_open);
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
|
||||||
|
else
|
||||||
|
BGP_EVENT_ADD(peer, TCP_connection_open);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
if (bgp_debug_neighbor_events(peer))
|
if (bgp_debug_neighbor_events(peer))
|
||||||
@ -1516,11 +1568,63 @@ static int bgp_connect_success(struct peer *peer)
|
|||||||
zlog_debug("%s passive open", peer->host);
|
zlog_debug("%s passive open", peer->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send an open message */
|
||||||
bgp_open_send(peer);
|
bgp_open_send(peer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TCP connection open with RFC 4271 optional session attribute DelayOpen flag
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
static int bgp_connect_success_w_delayopen(struct peer *peer)
|
||||||
|
{
|
||||||
|
if (peer->fd < 0) {
|
||||||
|
flog_err(EC_BGP_CONNECT, "%s: peer's fd is negative value %d",
|
||||||
|
__func__, peer->fd);
|
||||||
|
bgp_stop(peer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bgp_getsockname(peer) < 0) {
|
||||||
|
flog_err_sys(EC_LIB_SOCKET,
|
||||||
|
"%s: bgp_getsockname(): failed for peer %s, fd %d",
|
||||||
|
__func__, peer->host, peer->fd);
|
||||||
|
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
|
||||||
|
bgp_fsm_error_subcode(peer->status));
|
||||||
|
bgp_writes_on(peer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bgp_reads_on(peer);
|
||||||
|
|
||||||
|
if (bgp_debug_neighbor_events(peer)) {
|
||||||
|
char buf1[SU_ADDRSTRLEN];
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
|
||||||
|
zlog_debug("%s open active, local address %s",
|
||||||
|
peer->host,
|
||||||
|
sockunion2str(peer->su_local, buf1,
|
||||||
|
SU_ADDRSTRLEN));
|
||||||
|
else
|
||||||
|
zlog_debug("%s passive open", peer->host);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the DelayOpenTime to the inital value */
|
||||||
|
peer->v_delayopen = peer->delayopen;
|
||||||
|
|
||||||
|
/* Start the DelayOpenTimer if it is not already running */
|
||||||
|
if (!peer->t_delayopen)
|
||||||
|
BGP_TIMER_ON(peer->t_delayopen, bgp_delayopen_timer,
|
||||||
|
peer->v_delayopen);
|
||||||
|
|
||||||
|
if (bgp_debug_neighbor_events(peer))
|
||||||
|
zlog_debug("%s [FSM] BGP OPEN message delayed for %d seconds",
|
||||||
|
peer->host, peer->delayopen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* TCP connect fail */
|
/* TCP connect fail */
|
||||||
static int bgp_connect_fail(struct peer *peer)
|
static int bgp_connect_fail(struct peer *peer)
|
||||||
{
|
{
|
||||||
@ -1535,7 +1639,8 @@ static int bgp_connect_fail(struct peer *peer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function is the first starting point of all BGP connection. It
|
/* This function is the first starting point of all BGP connection. It
|
||||||
try to connect to remote peer with non-blocking IO. */
|
* try to connect to remote peer with non-blocking IO.
|
||||||
|
*/
|
||||||
int bgp_start(struct peer *peer)
|
int bgp_start(struct peer *peer)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
@ -1633,6 +1738,7 @@ int bgp_start(struct peer *peer)
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s [FSM] Connect immediately success, fd %d",
|
"%s [FSM] Connect immediately success, fd %d",
|
||||||
peer->host, peer->fd);
|
peer->host, peer->fd);
|
||||||
|
|
||||||
BGP_EVENT_ADD(peer, TCP_connection_open);
|
BGP_EVENT_ADD(peer, TCP_connection_open);
|
||||||
break;
|
break;
|
||||||
case connect_in_progress:
|
case connect_in_progress:
|
||||||
@ -1682,6 +1788,10 @@ static int bgp_reconnect(struct peer *peer)
|
|||||||
|
|
||||||
static int bgp_fsm_open(struct peer *peer)
|
static int bgp_fsm_open(struct peer *peer)
|
||||||
{
|
{
|
||||||
|
/* If DelayOpen is active, we may still need to send an open message */
|
||||||
|
if ((peer->status == Connect) || (peer->status == Active))
|
||||||
|
bgp_open_send(peer);
|
||||||
|
|
||||||
/* Send keepalive and make keepalive timer */
|
/* Send keepalive and make keepalive timer */
|
||||||
bgp_keepalive_send(peer);
|
bgp_keepalive_send(peer);
|
||||||
|
|
||||||
@ -1709,6 +1819,21 @@ static int bgp_fsm_holdtime_expire(struct peer *peer)
|
|||||||
return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
|
return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RFC 4271 DelayOpenTimer_Expires event */
|
||||||
|
static int bgp_fsm_delayopen_timer_expire(struct peer *peer)
|
||||||
|
{
|
||||||
|
/* Stop the DelayOpenTimer */
|
||||||
|
BGP_TIMER_OFF(peer->t_delayopen);
|
||||||
|
|
||||||
|
/* Send open message to peer */
|
||||||
|
bgp_open_send(peer);
|
||||||
|
|
||||||
|
/* Set the HoldTimer to a large value (4 minutes) */
|
||||||
|
peer->v_holdtime = 245;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Start the selection deferral timer thread for the specified AFI, SAFI */
|
/* Start the selection deferral timer thread for the specified AFI, SAFI */
|
||||||
static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
|
static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
struct graceful_restart_info *gr_info)
|
struct graceful_restart_info *gr_info)
|
||||||
@ -2089,12 +2214,14 @@ static const struct {
|
|||||||
{bgp_start, Connect}, /* BGP_Start */
|
{bgp_start, Connect}, /* BGP_Start */
|
||||||
{bgp_stop, Idle}, /* BGP_Stop */
|
{bgp_stop, Idle}, /* BGP_Stop */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_open */
|
{bgp_stop, Idle}, /* TCP_connection_open */
|
||||||
|
{bgp_stop, Idle}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_closed */
|
{bgp_stop, Idle}, /* TCP_connection_closed */
|
||||||
{bgp_ignore, Idle}, /* TCP_connection_open_failed */
|
{bgp_ignore, Idle}, /* TCP_connection_open_failed */
|
||||||
{bgp_stop, Idle}, /* TCP_fatal_error */
|
{bgp_stop, Idle}, /* TCP_fatal_error */
|
||||||
{bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
|
{bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_ignore, Idle}, /* Hold_Timer_expired */
|
{bgp_ignore, Idle}, /* Hold_Timer_expired */
|
||||||
{bgp_ignore, Idle}, /* KeepAlive_timer_expired */
|
{bgp_ignore, Idle}, /* KeepAlive_timer_expired */
|
||||||
|
{bgp_ignore, Idle}, /* DelayOpen_timer_expired */
|
||||||
{bgp_ignore, Idle}, /* Receive_OPEN_message */
|
{bgp_ignore, Idle}, /* Receive_OPEN_message */
|
||||||
{bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
|
{bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
|
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
|
||||||
@ -2106,46 +2233,56 @@ static const struct {
|
|||||||
{bgp_ignore, Connect}, /* BGP_Start */
|
{bgp_ignore, Connect}, /* BGP_Start */
|
||||||
{bgp_stop, Idle}, /* BGP_Stop */
|
{bgp_stop, Idle}, /* BGP_Stop */
|
||||||
{bgp_connect_success, OpenSent}, /* TCP_connection_open */
|
{bgp_connect_success, OpenSent}, /* TCP_connection_open */
|
||||||
|
{bgp_connect_success_w_delayopen,
|
||||||
|
Connect}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_closed */
|
{bgp_stop, Idle}, /* TCP_connection_closed */
|
||||||
{bgp_connect_fail, Active}, /* TCP_connection_open_failed */
|
{bgp_connect_fail, Active}, /* TCP_connection_open_failed */
|
||||||
{bgp_connect_fail, Idle}, /* TCP_fatal_error */
|
{bgp_connect_fail, Idle}, /* TCP_fatal_error */
|
||||||
{bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
|
{bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
|
{bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
|
{bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
|
{bgp_fsm_delayopen_timer_expire,
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
|
OpenSent}, /* DelayOpen_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
|
{bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
|
||||||
{bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
|
{bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_fsm_exeption, Idle}, /* Clearing_Completed */
|
{bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
|
||||||
|
{bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* Clearing_Completed */
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* Active, */
|
/* Active, */
|
||||||
{bgp_ignore, Active}, /* BGP_Start */
|
{bgp_ignore, Active}, /* BGP_Start */
|
||||||
{bgp_stop, Idle}, /* BGP_Stop */
|
{bgp_stop, Idle}, /* BGP_Stop */
|
||||||
{bgp_connect_success, OpenSent}, /* TCP_connection_open */
|
{bgp_connect_success, OpenSent}, /* TCP_connection_open */
|
||||||
|
{bgp_connect_success_w_delayopen,
|
||||||
|
Active}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_closed */
|
{bgp_stop, Idle}, /* TCP_connection_closed */
|
||||||
{bgp_ignore, Active}, /* TCP_connection_open_failed */
|
{bgp_ignore, Active}, /* TCP_connection_open_failed */
|
||||||
{bgp_fsm_exeption, Idle}, /* TCP_fatal_error */
|
{bgp_fsm_exeption, Idle}, /* TCP_fatal_error */
|
||||||
{bgp_start, Connect}, /* ConnectRetry_timer_expired */
|
{bgp_start, Connect}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
|
{bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
|
{bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
|
{bgp_fsm_delayopen_timer_expire,
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
|
OpenSent}, /* DelayOpen_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
|
{bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_NOTIFICATION_message */
|
{bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_fsm_exeption, Idle}, /* Clearing_Completed */
|
{bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* Receive_NOTIFICATION_message */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* Clearing_Completed */
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* OpenSent, */
|
/* OpenSent, */
|
||||||
{bgp_ignore, OpenSent}, /* BGP_Start */
|
{bgp_ignore, OpenSent}, /* BGP_Start */
|
||||||
{bgp_stop, Idle}, /* BGP_Stop */
|
{bgp_stop, Idle}, /* BGP_Stop */
|
||||||
{bgp_stop, Active}, /* TCP_connection_open */
|
{bgp_stop, Active}, /* TCP_connection_open */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Active}, /* TCP_connection_closed */
|
{bgp_stop, Active}, /* TCP_connection_closed */
|
||||||
{bgp_stop, Active}, /* TCP_connection_open_failed */
|
{bgp_stop, Active}, /* TCP_connection_open_failed */
|
||||||
{bgp_stop, Active}, /* TCP_fatal_error */
|
{bgp_stop, Active}, /* TCP_fatal_error */
|
||||||
{bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
|
{bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
|
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
|
{bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* DelayOpen_timer_expired */
|
||||||
{bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
|
{bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
|
||||||
{bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
|
{bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
|
{bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
|
||||||
@ -2157,12 +2294,14 @@ static const struct {
|
|||||||
{bgp_ignore, OpenConfirm}, /* BGP_Start */
|
{bgp_ignore, OpenConfirm}, /* BGP_Start */
|
||||||
{bgp_stop, Idle}, /* BGP_Stop */
|
{bgp_stop, Idle}, /* BGP_Stop */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_open */
|
{bgp_stop, Idle}, /* TCP_connection_open */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_closed */
|
{bgp_stop, Idle}, /* TCP_connection_closed */
|
||||||
{bgp_stop, Idle}, /* TCP_connection_open_failed */
|
{bgp_stop, Idle}, /* TCP_connection_open_failed */
|
||||||
{bgp_stop, Idle}, /* TCP_fatal_error */
|
{bgp_stop, Idle}, /* TCP_fatal_error */
|
||||||
{bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
|
{bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
|
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
|
||||||
{bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
|
{bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* DelayOpen_timer_expired */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
|
{bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
|
||||||
{bgp_establish, Established}, /* Receive_KEEPALIVE_message */
|
{bgp_establish, Established}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
|
{bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
|
||||||
@ -2174,12 +2313,14 @@ static const struct {
|
|||||||
{bgp_ignore, Established}, /* BGP_Start */
|
{bgp_ignore, Established}, /* BGP_Start */
|
||||||
{bgp_stop, Clearing}, /* BGP_Stop */
|
{bgp_stop, Clearing}, /* BGP_Stop */
|
||||||
{bgp_stop, Clearing}, /* TCP_connection_open */
|
{bgp_stop, Clearing}, /* TCP_connection_open */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Clearing}, /* TCP_connection_closed */
|
{bgp_stop, Clearing}, /* TCP_connection_closed */
|
||||||
{bgp_stop, Clearing}, /* TCP_connection_open_failed */
|
{bgp_stop, Clearing}, /* TCP_connection_open_failed */
|
||||||
{bgp_stop, Clearing}, /* TCP_fatal_error */
|
{bgp_stop, Clearing}, /* TCP_fatal_error */
|
||||||
{bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
|
{bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
|
{bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
|
||||||
{bgp_ignore, Established}, /* KeepAlive_timer_expired */
|
{bgp_ignore, Established}, /* KeepAlive_timer_expired */
|
||||||
|
{bgp_fsm_exeption, Idle}, /* DelayOpen_timer_expired */
|
||||||
{bgp_stop, Clearing}, /* Receive_OPEN_message */
|
{bgp_stop, Clearing}, /* Receive_OPEN_message */
|
||||||
{bgp_fsm_keepalive,
|
{bgp_fsm_keepalive,
|
||||||
Established}, /* Receive_KEEPALIVE_message */
|
Established}, /* Receive_KEEPALIVE_message */
|
||||||
@ -2193,12 +2334,14 @@ static const struct {
|
|||||||
{bgp_ignore, Clearing}, /* BGP_Start */
|
{bgp_ignore, Clearing}, /* BGP_Start */
|
||||||
{bgp_stop, Clearing}, /* BGP_Stop */
|
{bgp_stop, Clearing}, /* BGP_Stop */
|
||||||
{bgp_stop, Clearing}, /* TCP_connection_open */
|
{bgp_stop, Clearing}, /* TCP_connection_open */
|
||||||
|
{bgp_stop, Clearing}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_stop, Clearing}, /* TCP_connection_closed */
|
{bgp_stop, Clearing}, /* TCP_connection_closed */
|
||||||
{bgp_stop, Clearing}, /* TCP_connection_open_failed */
|
{bgp_stop, Clearing}, /* TCP_connection_open_failed */
|
||||||
{bgp_stop, Clearing}, /* TCP_fatal_error */
|
{bgp_stop, Clearing}, /* TCP_fatal_error */
|
||||||
{bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
|
{bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_stop, Clearing}, /* Hold_Timer_expired */
|
{bgp_stop, Clearing}, /* Hold_Timer_expired */
|
||||||
{bgp_stop, Clearing}, /* KeepAlive_timer_expired */
|
{bgp_stop, Clearing}, /* KeepAlive_timer_expired */
|
||||||
|
{bgp_stop, Clearing}, /* DelayOpen_timer_expired */
|
||||||
{bgp_stop, Clearing}, /* Receive_OPEN_message */
|
{bgp_stop, Clearing}, /* Receive_OPEN_message */
|
||||||
{bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
|
{bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_stop, Clearing}, /* Receive_UPDATE_message */
|
{bgp_stop, Clearing}, /* Receive_UPDATE_message */
|
||||||
@ -2210,12 +2353,14 @@ static const struct {
|
|||||||
{bgp_ignore, Deleted}, /* BGP_Start */
|
{bgp_ignore, Deleted}, /* BGP_Start */
|
||||||
{bgp_ignore, Deleted}, /* BGP_Stop */
|
{bgp_ignore, Deleted}, /* BGP_Stop */
|
||||||
{bgp_ignore, Deleted}, /* TCP_connection_open */
|
{bgp_ignore, Deleted}, /* TCP_connection_open */
|
||||||
|
{bgp_ignore, Deleted}, /* TCP_connection_open_w_delay */
|
||||||
{bgp_ignore, Deleted}, /* TCP_connection_closed */
|
{bgp_ignore, Deleted}, /* TCP_connection_closed */
|
||||||
{bgp_ignore, Deleted}, /* TCP_connection_open_failed */
|
{bgp_ignore, Deleted}, /* TCP_connection_open_failed */
|
||||||
{bgp_ignore, Deleted}, /* TCP_fatal_error */
|
{bgp_ignore, Deleted}, /* TCP_fatal_error */
|
||||||
{bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
|
{bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
|
||||||
{bgp_ignore, Deleted}, /* Hold_Timer_expired */
|
{bgp_ignore, Deleted}, /* Hold_Timer_expired */
|
||||||
{bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
|
{bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
|
||||||
|
{bgp_ignore, Deleted}, /* DelayOpen_timer_expired */
|
||||||
{bgp_ignore, Deleted}, /* Receive_OPEN_message */
|
{bgp_ignore, Deleted}, /* Receive_OPEN_message */
|
||||||
{bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
|
{bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
|
||||||
{bgp_ignore, Deleted}, /* Receive_UPDATE_message */
|
{bgp_ignore, Deleted}, /* Receive_UPDATE_message */
|
||||||
|
@ -1425,8 +1425,8 @@ int bgp_global_global_config_timers_hold_time_modify(
|
|||||||
keepalive = yang_dnode_get_uint16(args->dnode, "../keepalive");
|
keepalive = yang_dnode_get_uint16(args->dnode, "../keepalive");
|
||||||
holdtime = yang_dnode_get_uint16(args->dnode, NULL);
|
holdtime = yang_dnode_get_uint16(args->dnode, NULL);
|
||||||
|
|
||||||
bgp_timers_set(bgp, keepalive, holdtime,
|
bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY,
|
||||||
DFLT_BGP_CONNECT_RETRY);
|
BGP_DEFAULT_DELAYOPEN);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1466,8 +1466,8 @@ int bgp_global_global_config_timers_keepalive_modify(
|
|||||||
keepalive = yang_dnode_get_uint16(args->dnode, NULL);
|
keepalive = yang_dnode_get_uint16(args->dnode, NULL);
|
||||||
holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time");
|
holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time");
|
||||||
|
|
||||||
bgp_timers_set(bgp, keepalive, holdtime,
|
bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY,
|
||||||
DFLT_BGP_CONNECT_RETRY);
|
BGP_DEFAULT_DELAYOPEN);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -457,8 +457,16 @@ static int bgp_accept(struct thread *thread)
|
|||||||
BGP_TIMER_OFF(
|
BGP_TIMER_OFF(
|
||||||
peer1->t_start); /* created in peer_create() */
|
peer1->t_start); /* created in peer_create() */
|
||||||
|
|
||||||
if (peer_active(peer1))
|
if (peer_active(peer1)) {
|
||||||
BGP_EVENT_ADD(peer1, TCP_connection_open);
|
if (CHECK_FLAG(peer1->flags,
|
||||||
|
PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
BGP_EVENT_ADD(
|
||||||
|
peer1,
|
||||||
|
TCP_connection_open_w_delay);
|
||||||
|
else
|
||||||
|
BGP_EVENT_ADD(peer1,
|
||||||
|
TCP_connection_open);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -595,7 +603,10 @@ static int bgp_accept(struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (peer_active(peer)) {
|
if (peer_active(peer)) {
|
||||||
BGP_EVENT_ADD(peer, TCP_connection_open);
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
|
||||||
|
else
|
||||||
|
BGP_EVENT_ADD(peer, TCP_connection_open);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -461,7 +461,7 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
|
|||||||
|
|
||||||
if (ret == BGP_CREATED) {
|
if (ret == BGP_CREATED) {
|
||||||
bgp_timers_set(*bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME,
|
bgp_timers_set(*bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME,
|
||||||
DFLT_BGP_CONNECT_RETRY);
|
DFLT_BGP_CONNECT_RETRY, BGP_DEFAULT_DELAYOPEN);
|
||||||
|
|
||||||
if (DFLT_BGP_IMPORT_CHECK)
|
if (DFLT_BGP_IMPORT_CHECK)
|
||||||
SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK);
|
SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK);
|
||||||
@ -7373,6 +7373,54 @@ DEFUN_YANG (no_neighbor_timers_connect,
|
|||||||
return nb_cli_apply_changes(vty, base_xpath);
|
return nb_cli_apply_changes(vty, base_xpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFPY (neighbor_timers_delayopen,
|
||||||
|
neighbor_timers_delayopen_cmd,
|
||||||
|
"neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor timers delayopen (1-240)$interval",
|
||||||
|
NEIGHBOR_STR
|
||||||
|
NEIGHBOR_ADDR_STR2
|
||||||
|
"BGP per neighbor timers\n"
|
||||||
|
"RFC 4271 DelayOpenTimer\n"
|
||||||
|
"DelayOpenTime timer interval\n")
|
||||||
|
{
|
||||||
|
struct peer *peer;
|
||||||
|
|
||||||
|
peer = peer_and_group_lookup_vty(vty, neighbor);
|
||||||
|
if (!peer)
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
|
||||||
|
if (!interval) {
|
||||||
|
if (peer_timers_delayopen_unset(peer))
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
} else {
|
||||||
|
if (peer_timers_delayopen_set(peer, interval))
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY (no_neighbor_timers_delayopen,
|
||||||
|
no_neighbor_timers_delayopen_cmd,
|
||||||
|
"no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor timers delayopen [(0-65535)]",
|
||||||
|
NO_STR
|
||||||
|
NEIGHBOR_STR
|
||||||
|
NEIGHBOR_ADDR_STR2
|
||||||
|
"BGP per neighbor timers\n"
|
||||||
|
"RFC 4271 DelayOpenTimer\n"
|
||||||
|
"DelayOpenTime timer interval\n")
|
||||||
|
{
|
||||||
|
struct peer *peer;
|
||||||
|
|
||||||
|
peer = peer_and_group_lookup_vty(vty, neighbor);
|
||||||
|
if (!peer)
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
|
||||||
|
if (peer_timers_delayopen_unset(peer))
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN_YANG (neighbor_advertise_interval,
|
DEFUN_YANG (neighbor_advertise_interval,
|
||||||
neighbor_advertise_interval_cmd,
|
neighbor_advertise_interval_cmd,
|
||||||
"neighbor <A.B.C.D|X:X::X:X|WORD> advertisement-interval (0-600)",
|
"neighbor <A.B.C.D|X:X::X:X|WORD> advertisement-interval (0-600)",
|
||||||
@ -12607,6 +12655,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
|
|||||||
json_object_int_add(json_neigh,
|
json_object_int_add(json_neigh,
|
||||||
"bgpTimerKeepAliveIntervalMsecs",
|
"bgpTimerKeepAliveIntervalMsecs",
|
||||||
p->v_keepalive * 1000);
|
p->v_keepalive * 1000);
|
||||||
|
if (CHECK_FLAG(p->flags, PEER_FLAG_TIMER_DELAYOPEN)) {
|
||||||
|
json_object_int_add(json_neigh,
|
||||||
|
"bgpTimerDelayOpenTimeMsecs",
|
||||||
|
p->v_delayopen * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(p->flags, PEER_FLAG_TIMER)) {
|
if (CHECK_FLAG(p->flags, PEER_FLAG_TIMER)) {
|
||||||
json_object_int_add(json_neigh,
|
json_object_int_add(json_neigh,
|
||||||
"bgpTimerConfiguredHoldTimeMsecs",
|
"bgpTimerConfiguredHoldTimeMsecs",
|
||||||
@ -12686,6 +12740,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
|
|||||||
vty_out(vty, ", keepalive interval is %d seconds\n",
|
vty_out(vty, ", keepalive interval is %d seconds\n",
|
||||||
bgp->default_keepalive);
|
bgp->default_keepalive);
|
||||||
}
|
}
|
||||||
|
if (CHECK_FLAG(p->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
vty_out(vty,
|
||||||
|
" Configured DelayOpenTime is %d seconds\n",
|
||||||
|
p->delayopen);
|
||||||
}
|
}
|
||||||
/* Capability. */
|
/* Capability. */
|
||||||
if (p->status == Established) {
|
if (p->status == Established) {
|
||||||
@ -16402,6 +16460,18 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
|
|||||||
vty_out(vty, " neighbor %s timers connect %u\n", addr,
|
vty_out(vty, " neighbor %s timers connect %u\n", addr,
|
||||||
peer->bgp->default_connect_retry);
|
peer->bgp->default_connect_retry);
|
||||||
|
|
||||||
|
/* timers delayopen */
|
||||||
|
if (peergroup_flag_check(peer, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
vty_out(vty, " neighbor %s timers delayopen %u\n", addr,
|
||||||
|
peer->delayopen);
|
||||||
|
/* Save config even though flag is not set if default values have been
|
||||||
|
* changed
|
||||||
|
*/
|
||||||
|
else if (!peer_group_active(peer) && !peer->delayopen
|
||||||
|
&& peer->bgp->default_delayopen != BGP_DEFAULT_DELAYOPEN)
|
||||||
|
vty_out(vty, " neighbor %s timers delayopen %u\n", addr,
|
||||||
|
peer->bgp->default_delayopen);
|
||||||
|
|
||||||
/* capability dynamic */
|
/* capability dynamic */
|
||||||
if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY))
|
if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY))
|
||||||
vty_out(vty, " neighbor %s capability dynamic\n", addr);
|
vty_out(vty, " neighbor %s capability dynamic\n", addr);
|
||||||
@ -18261,6 +18331,10 @@ void bgp_vty_init(void)
|
|||||||
install_element(BGP_NODE, &neighbor_timers_connect_cmd);
|
install_element(BGP_NODE, &neighbor_timers_connect_cmd);
|
||||||
install_element(BGP_NODE, &no_neighbor_timers_connect_cmd);
|
install_element(BGP_NODE, &no_neighbor_timers_connect_cmd);
|
||||||
|
|
||||||
|
/* "neighbor timers delayopen" commands. */
|
||||||
|
install_element(BGP_NODE, &neighbor_timers_delayopen_cmd);
|
||||||
|
install_element(BGP_NODE, &no_neighbor_timers_delayopen_cmd);
|
||||||
|
|
||||||
/* "neighbor advertisement-interval" commands. */
|
/* "neighbor advertisement-interval" commands. */
|
||||||
install_element(BGP_NODE, &neighbor_advertise_interval_cmd);
|
install_element(BGP_NODE, &neighbor_advertise_interval_cmd);
|
||||||
install_element(BGP_NODE, &no_neighbor_advertise_interval_cmd);
|
install_element(BGP_NODE, &no_neighbor_advertise_interval_cmd);
|
||||||
|
99
bgpd/bgpd.c
99
bgpd/bgpd.c
@ -491,12 +491,13 @@ time_t bgp_clock(void)
|
|||||||
|
|
||||||
/* BGP timer configuration. */
|
/* BGP timer configuration. */
|
||||||
void bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime,
|
void bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime,
|
||||||
uint32_t connect_retry)
|
uint32_t connect_retry, uint32_t delayopen)
|
||||||
{
|
{
|
||||||
bgp->default_keepalive =
|
bgp->default_keepalive =
|
||||||
(keepalive < holdtime / 3 ? keepalive : holdtime / 3);
|
(keepalive < holdtime / 3 ? keepalive : holdtime / 3);
|
||||||
bgp->default_holdtime = holdtime;
|
bgp->default_holdtime = holdtime;
|
||||||
bgp->default_connect_retry = connect_retry;
|
bgp->default_connect_retry = connect_retry;
|
||||||
|
bgp->default_delayopen = delayopen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mostly for completeness - CLI uses its own defaults */
|
/* mostly for completeness - CLI uses its own defaults */
|
||||||
@ -505,6 +506,7 @@ void bgp_timers_unset(struct bgp *bgp)
|
|||||||
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
|
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
|
||||||
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
|
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
|
||||||
bgp->default_connect_retry = BGP_DEFAULT_CONNECT_RETRY;
|
bgp->default_connect_retry = BGP_DEFAULT_CONNECT_RETRY;
|
||||||
|
bgp->default_delayopen = BGP_DEFAULT_DELAYOPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BGP confederation configuration. */
|
/* BGP confederation configuration. */
|
||||||
@ -1410,10 +1412,12 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
|
|||||||
peer_dst->holdtime = peer_src->holdtime;
|
peer_dst->holdtime = peer_src->holdtime;
|
||||||
peer_dst->keepalive = peer_src->keepalive;
|
peer_dst->keepalive = peer_src->keepalive;
|
||||||
peer_dst->connect = peer_src->connect;
|
peer_dst->connect = peer_src->connect;
|
||||||
|
peer_dst->delayopen = peer_src->delayopen;
|
||||||
peer_dst->v_holdtime = peer_src->v_holdtime;
|
peer_dst->v_holdtime = peer_src->v_holdtime;
|
||||||
peer_dst->v_keepalive = peer_src->v_keepalive;
|
peer_dst->v_keepalive = peer_src->v_keepalive;
|
||||||
peer_dst->routeadv = peer_src->routeadv;
|
peer_dst->routeadv = peer_src->routeadv;
|
||||||
peer_dst->v_routeadv = peer_src->v_routeadv;
|
peer_dst->v_routeadv = peer_src->v_routeadv;
|
||||||
|
peer_dst->v_delayopen = peer_src->v_delayopen;
|
||||||
|
|
||||||
/* password apply */
|
/* password apply */
|
||||||
if (peer_src->password && !peer_dst->password)
|
if (peer_src->password && !peer_dst->password)
|
||||||
@ -2577,6 +2581,14 @@ static void peer_group2peer_config_copy(struct peer_group *group,
|
|||||||
peer->v_connect = peer->bgp->default_connect_retry;
|
peer->v_connect = peer->bgp->default_connect_retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_DELAYOPEN)) {
|
||||||
|
PEER_ATTR_INHERIT(peer, group, delayopen);
|
||||||
|
if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
peer->v_delayopen = conf->delayopen;
|
||||||
|
else
|
||||||
|
peer->v_delayopen = peer->bgp->default_delayopen;
|
||||||
|
}
|
||||||
|
|
||||||
/* advertisement-interval apply */
|
/* advertisement-interval apply */
|
||||||
if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_ROUTEADV)) {
|
if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_ROUTEADV)) {
|
||||||
PEER_ATTR_INHERIT(peer, group, routeadv);
|
PEER_ATTR_INHERIT(peer, group, routeadv);
|
||||||
@ -4018,6 +4030,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
|
|||||||
{PEER_FLAG_ROUTEADV, 0, peer_change_none},
|
{PEER_FLAG_ROUTEADV, 0, peer_change_none},
|
||||||
{PEER_FLAG_TIMER, 0, peer_change_none},
|
{PEER_FLAG_TIMER, 0, peer_change_none},
|
||||||
{PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
|
{PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
|
||||||
|
{PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none},
|
||||||
{PEER_FLAG_PASSWORD, 0, peer_change_none},
|
{PEER_FLAG_PASSWORD, 0, peer_change_none},
|
||||||
{PEER_FLAG_LOCAL_AS, 0, peer_change_none},
|
{PEER_FLAG_LOCAL_AS, 0, peer_change_none},
|
||||||
{PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none},
|
{PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none},
|
||||||
@ -5403,6 +5416,90 @@ int peer_advertise_interval_unset(struct peer *peer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set the peers RFC 4271 DelayOpen session attribute flag and DelayOpenTimer
|
||||||
|
* interval
|
||||||
|
*/
|
||||||
|
int peer_timers_delayopen_set(struct peer *peer, uint32_t delayopen)
|
||||||
|
{
|
||||||
|
struct peer *member;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
/* Set peers session attribute flag and timer interval. */
|
||||||
|
peer_flag_set(peer, PEER_FLAG_TIMER_DELAYOPEN);
|
||||||
|
peer->delayopen = delayopen;
|
||||||
|
peer->v_delayopen = delayopen;
|
||||||
|
|
||||||
|
/* Skip group mechanics for regular peers. */
|
||||||
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Set flag and configuration on all peer-group members, unless they are
|
||||||
|
* explicitely overriding peer-group configuration.
|
||||||
|
*/
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
|
||||||
|
/* Skip peers with overridden configuration. */
|
||||||
|
if (CHECK_FLAG(member->flags_override,
|
||||||
|
PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Set session attribute flag and timer intervals on peer-group
|
||||||
|
* member.
|
||||||
|
*/
|
||||||
|
SET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN);
|
||||||
|
member->delayopen = delayopen;
|
||||||
|
member->v_delayopen = delayopen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unset the peers RFC 4271 DelayOpen session attribute flag and reset the
|
||||||
|
* DelayOpenTimer interval to the default value.
|
||||||
|
*/
|
||||||
|
int peer_timers_delayopen_unset(struct peer *peer)
|
||||||
|
{
|
||||||
|
struct peer *member;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
/* Inherit configuration from peer-group if peer is member. */
|
||||||
|
if (peer_group_active(peer)) {
|
||||||
|
peer_flag_inherit(peer, PEER_FLAG_TIMER_DELAYOPEN);
|
||||||
|
PEER_ATTR_INHERIT(peer, peer->group, delayopen);
|
||||||
|
} else {
|
||||||
|
/* Otherwise remove session attribute flag and set timer
|
||||||
|
* interval to default value.
|
||||||
|
*/
|
||||||
|
peer_flag_unset(peer, PEER_FLAG_TIMER_DELAYOPEN);
|
||||||
|
peer->delayopen = peer->bgp->default_delayopen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set timer value to zero */
|
||||||
|
peer->v_delayopen = 0;
|
||||||
|
|
||||||
|
/* Skip peer-group mechanics for regular peers. */
|
||||||
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Remove flag and configuration from all peer-group members, unless
|
||||||
|
* they are explicitely overriding peer-group configuration.
|
||||||
|
*/
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
|
||||||
|
/* Skip peers with overridden configuration. */
|
||||||
|
if (CHECK_FLAG(member->flags_override,
|
||||||
|
PEER_FLAG_TIMER_DELAYOPEN))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Remove session attribute flag, reset the timer interval to
|
||||||
|
* the default value and set the timer value to zero.
|
||||||
|
*/
|
||||||
|
UNSET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN);
|
||||||
|
member->delayopen = peer->bgp->default_delayopen;
|
||||||
|
member->v_delayopen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* neighbor interface */
|
/* neighbor interface */
|
||||||
void peer_interface_set(struct peer *peer, const char *str)
|
void peer_interface_set(struct peer *peer, const char *str)
|
||||||
{
|
{
|
||||||
|
16
bgpd/bgpd.h
16
bgpd/bgpd.h
@ -560,6 +560,7 @@ struct bgp {
|
|||||||
uint32_t default_holdtime;
|
uint32_t default_holdtime;
|
||||||
uint32_t default_keepalive;
|
uint32_t default_keepalive;
|
||||||
uint32_t default_connect_retry;
|
uint32_t default_connect_retry;
|
||||||
|
uint32_t default_delayopen;
|
||||||
|
|
||||||
/* BGP graceful restart */
|
/* BGP graceful restart */
|
||||||
uint32_t restart_time;
|
uint32_t restart_time;
|
||||||
@ -904,12 +905,14 @@ enum bgp_fsm_events {
|
|||||||
BGP_Start = 1,
|
BGP_Start = 1,
|
||||||
BGP_Stop,
|
BGP_Stop,
|
||||||
TCP_connection_open,
|
TCP_connection_open,
|
||||||
|
TCP_connection_open_w_delay,
|
||||||
TCP_connection_closed,
|
TCP_connection_closed,
|
||||||
TCP_connection_open_failed,
|
TCP_connection_open_failed,
|
||||||
TCP_fatal_error,
|
TCP_fatal_error,
|
||||||
ConnectRetry_timer_expired,
|
ConnectRetry_timer_expired,
|
||||||
Hold_Timer_expired,
|
Hold_Timer_expired,
|
||||||
KeepAlive_timer_expired,
|
KeepAlive_timer_expired,
|
||||||
|
DelayOpen_timer_expired,
|
||||||
Receive_OPEN_message,
|
Receive_OPEN_message,
|
||||||
Receive_KEEPALIVE_message,
|
Receive_KEEPALIVE_message,
|
||||||
Receive_UPDATE_message,
|
Receive_UPDATE_message,
|
||||||
@ -1166,6 +1169,8 @@ struct peer {
|
|||||||
*and PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
|
*and PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define PEER_FLAG_TIMER_DELAYOPEN (1 << 27) /* delayopen timer */
|
||||||
|
|
||||||
struct bgp_peer_gr PEER_GR_FSM[BGP_PEER_GR_MODE][BGP_PEER_GR_EVENT_CMD];
|
struct bgp_peer_gr PEER_GR_FSM[BGP_PEER_GR_MODE][BGP_PEER_GR_EVENT_CMD];
|
||||||
enum peer_mode peer_gr_present_state;
|
enum peer_mode peer_gr_present_state;
|
||||||
/* Non stop forwarding afi-safi count for BGP gr feature*/
|
/* Non stop forwarding afi-safi count for BGP gr feature*/
|
||||||
@ -1259,6 +1264,7 @@ struct peer {
|
|||||||
_Atomic uint32_t keepalive;
|
_Atomic uint32_t keepalive;
|
||||||
_Atomic uint32_t connect;
|
_Atomic uint32_t connect;
|
||||||
_Atomic uint32_t routeadv;
|
_Atomic uint32_t routeadv;
|
||||||
|
_Atomic uint32_t delayopen;
|
||||||
|
|
||||||
/* Timer values. */
|
/* Timer values. */
|
||||||
_Atomic uint32_t v_start;
|
_Atomic uint32_t v_start;
|
||||||
@ -1266,6 +1272,7 @@ struct peer {
|
|||||||
_Atomic uint32_t v_holdtime;
|
_Atomic uint32_t v_holdtime;
|
||||||
_Atomic uint32_t v_keepalive;
|
_Atomic uint32_t v_keepalive;
|
||||||
_Atomic uint32_t v_routeadv;
|
_Atomic uint32_t v_routeadv;
|
||||||
|
_Atomic uint32_t v_delayopen;
|
||||||
_Atomic uint32_t v_pmax_restart;
|
_Atomic uint32_t v_pmax_restart;
|
||||||
_Atomic uint32_t v_gr_restart;
|
_Atomic uint32_t v_gr_restart;
|
||||||
|
|
||||||
@ -1278,6 +1285,7 @@ struct peer {
|
|||||||
struct thread *t_connect;
|
struct thread *t_connect;
|
||||||
struct thread *t_holdtime;
|
struct thread *t_holdtime;
|
||||||
struct thread *t_routeadv;
|
struct thread *t_routeadv;
|
||||||
|
struct thread *t_delayopen;
|
||||||
struct thread *t_pmax_restart;
|
struct thread *t_pmax_restart;
|
||||||
struct thread *t_gr_restart;
|
struct thread *t_gr_restart;
|
||||||
struct thread *t_gr_stale;
|
struct thread *t_gr_stale;
|
||||||
@ -1673,6 +1681,9 @@ struct bgp_nlri {
|
|||||||
#define BGP_DEFAULT_EBGP_ROUTEADV 0
|
#define BGP_DEFAULT_EBGP_ROUTEADV 0
|
||||||
#define BGP_DEFAULT_IBGP_ROUTEADV 0
|
#define BGP_DEFAULT_IBGP_ROUTEADV 0
|
||||||
|
|
||||||
|
/* BGP RFC 4271 DelayOpenTime default value */
|
||||||
|
#define BGP_DEFAULT_DELAYOPEN 120
|
||||||
|
|
||||||
/* BGP default local preference. */
|
/* BGP default local preference. */
|
||||||
#define BGP_DEFAULT_LOCAL_PREF 100
|
#define BGP_DEFAULT_LOCAL_PREF 100
|
||||||
|
|
||||||
@ -1877,7 +1888,7 @@ extern int bgp_confederation_peers_add(struct bgp *, as_t);
|
|||||||
extern int bgp_confederation_peers_remove(struct bgp *, as_t);
|
extern int bgp_confederation_peers_remove(struct bgp *, as_t);
|
||||||
|
|
||||||
extern void bgp_timers_set(struct bgp *, uint32_t keepalive, uint32_t holdtime,
|
extern void bgp_timers_set(struct bgp *, uint32_t keepalive, uint32_t holdtime,
|
||||||
uint32_t connect_retry);
|
uint32_t connect_retry, uint32_t delayopen);
|
||||||
extern void bgp_timers_unset(struct bgp *);
|
extern void bgp_timers_unset(struct bgp *);
|
||||||
|
|
||||||
extern int bgp_default_local_preference_set(struct bgp *, uint32_t);
|
extern int bgp_default_local_preference_set(struct bgp *, uint32_t);
|
||||||
@ -1953,6 +1964,9 @@ extern int peer_timers_connect_unset(struct peer *);
|
|||||||
extern int peer_advertise_interval_set(struct peer *, uint32_t);
|
extern int peer_advertise_interval_set(struct peer *, uint32_t);
|
||||||
extern int peer_advertise_interval_unset(struct peer *);
|
extern int peer_advertise_interval_unset(struct peer *);
|
||||||
|
|
||||||
|
extern int peer_timers_delayopen_set(struct peer *peer, uint32_t delayopen);
|
||||||
|
extern int peer_timers_delayopen_unset(struct peer *peer);
|
||||||
|
|
||||||
extern void peer_interface_set(struct peer *, const char *);
|
extern void peer_interface_set(struct peer *, const char *);
|
||||||
extern void peer_interface_unset(struct peer *);
|
extern void peer_interface_unset(struct peer *);
|
||||||
|
|
||||||
|
@ -1596,6 +1596,15 @@ Configuring Peers
|
|||||||
peer in question. This number is between 0 and 600 seconds,
|
peer in question. This number is between 0 and 600 seconds,
|
||||||
with the default advertisement interval being 0.
|
with the default advertisement interval being 0.
|
||||||
|
|
||||||
|
.. index:: [no] neighbor PEER timers delayopen (1-240)
|
||||||
|
.. clicmd:: [no] neighbor PEER timers delayopen (1-240)
|
||||||
|
|
||||||
|
This command allows the user enable the
|
||||||
|
`RFC 4271 <https://tools.ietf.org/html/rfc4271/>` DelayOpenTimer with the
|
||||||
|
specified interval or disable it with the negating command for the peer. By
|
||||||
|
default, the DelayOpenTimer is disabled. The timer interval may be set to a
|
||||||
|
duration of 1 to 240 seconds.
|
||||||
|
|
||||||
Displaying Information about Peers
|
Displaying Information about Peers
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"192.168.101.2":{
|
||||||
|
"remoteAs":65100,
|
||||||
|
"bgpTimerDelayOpenTimeMsecs":240000
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65000,
|
||||||
|
"peers":{
|
||||||
|
"192.168.101.2":{
|
||||||
|
"remoteAs":65100,
|
||||||
|
"state":"Established"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65000,
|
||||||
|
"peers":{
|
||||||
|
"192.168.101.2":{
|
||||||
|
"remoteAs":65100,
|
||||||
|
"state":"Idle (Admin)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"192.168.201.2":{
|
||||||
|
"remoteAs":65200,
|
||||||
|
"bgpTimerDelayOpenTimeMsecs":60000
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65000,
|
||||||
|
"peers":{
|
||||||
|
"192.168.201.2":{
|
||||||
|
"remoteAs":65200,
|
||||||
|
"state":"Connect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65000,
|
||||||
|
"peers":{
|
||||||
|
"192.168.201.2":{
|
||||||
|
"remoteAs":65200,
|
||||||
|
"state":"Established"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65000,
|
||||||
|
"peers":{
|
||||||
|
"192.168.201.2":{
|
||||||
|
"remoteAs":65200,
|
||||||
|
"state":"Idle (Admin)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65100,
|
||||||
|
"peers":{
|
||||||
|
"192.168.101.1":{
|
||||||
|
"remoteAs":65000,
|
||||||
|
"state":"Established"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65100,
|
||||||
|
"peers":{
|
||||||
|
"192.168.101.1":{
|
||||||
|
"remoteAs":65000,
|
||||||
|
"state":"Idle (Admin)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"192.168.201.1":{
|
||||||
|
"remoteAs":65000,
|
||||||
|
"bgpTimerDelayOpenTimeMsecs":30000
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65200,
|
||||||
|
"peers":{
|
||||||
|
"192.168.201.1":{
|
||||||
|
"remoteAs":65000,
|
||||||
|
"state":"Connect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65200,
|
||||||
|
"peers":{
|
||||||
|
"192.168.201.1":{
|
||||||
|
"remoteAs":65000,
|
||||||
|
"state":"Established"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"as":65200,
|
||||||
|
"peers":{
|
||||||
|
"192.168.201.1":{
|
||||||
|
"remoteAs":65000,
|
||||||
|
"state":"Idle (Admin)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
# Save the Current Working Directory to find configuration files.
|
# Save the Current Working Directory to find configuration files.
|
||||||
CWD = os.path.dirname(os.path.realpath(__file__))
|
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||||
@ -745,6 +746,215 @@ def test_bgp_disable_norib_routes():
|
|||||||
# tgen.mininet_cli()
|
# tgen.mininet_cli()
|
||||||
|
|
||||||
|
|
||||||
|
def test_bgp_delayopen_without():
|
||||||
|
"Optional test of BGP functionality and behaviour without DelayOpenTimer enabled to establish a reference for following tests"
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
# part 1: no delay r1 <=> no delay r4
|
||||||
|
logger.info("Starting optional test of BGP functionality without DelayOpenTimer enabled to establish a reference for following tests")
|
||||||
|
|
||||||
|
# 1.1 enable peering shutdown
|
||||||
|
logger.info("Enable shutdown of peering between r1 and r4")
|
||||||
|
tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.2 shutdown"')
|
||||||
|
tgen.net["r4"].cmd('vtysh -c "conf t" -c "router bgp 65100" -c "neighbor 192.168.101.1 shutdown"')
|
||||||
|
|
||||||
|
# 1.2 wait for peers to shut down (poll output)
|
||||||
|
for router_num in [1, 4]:
|
||||||
|
logger.info("Checking BGP summary after enabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_shutdown.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=3, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not shut down peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
# 1.3 disable peering shutdown
|
||||||
|
logger.info("Disable shutdown of peering between r1 and r4")
|
||||||
|
tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.101.2 shutdown"')
|
||||||
|
tgen.net["r4"].cmd('vtysh -c "conf t" -c "router bgp 65100" -c "no neighbor 192.168.101.1 shutdown"')
|
||||||
|
|
||||||
|
# 1.4 wait for peers to establish connection (poll output)
|
||||||
|
for router_num in [1, 4]:
|
||||||
|
logger.info("Checking BGP summary after disabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_established.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=5, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not establish a connection with peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
#tgen.mininet_cli()
|
||||||
|
|
||||||
|
# end test_bgp_delayopen_without
|
||||||
|
|
||||||
|
|
||||||
|
def test_bgp_delayopen_singular():
|
||||||
|
"Test of BGP functionality and behaviour with DelayOpenTimer enabled on one side of the peering"
|
||||||
|
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
# part 2: delay 240s r1 <=> no delay r4
|
||||||
|
logger.info("Starting test of BGP functionality and behaviour with DelayOpenTimer enabled on one side of the peering")
|
||||||
|
|
||||||
|
# 2.1 enable peering shutdown
|
||||||
|
logger.info("Enable shutdown of peering between r1 and r4")
|
||||||
|
tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.2 shutdown"')
|
||||||
|
tgen.net["r4"].cmd('vtysh -c "conf t" -c "router bgp 65100" -c "neighbor 192.168.101.1 shutdown"')
|
||||||
|
|
||||||
|
# 2.2 wait for peers to shut down (poll output)
|
||||||
|
for router_num in [1, 4]:
|
||||||
|
logger.info("Checking BGP summary after disabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_shutdown.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=3, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not shut down peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
# 2.3 set delayopen on R1 to 240
|
||||||
|
logger.info("Setting DelayOpenTime for neighbor r4 to 240 seconds on r1")
|
||||||
|
tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.2 timers delayopen 240"')
|
||||||
|
|
||||||
|
# 2.4 check config (poll output)
|
||||||
|
logger.info("Checking BGP neighbor configuration after setting DelayOpenTime on r1")
|
||||||
|
router = tgen.gears["r1"]
|
||||||
|
reffile = os.path.join(CWD, "r1/bgp_delayopen_neighbor.json")
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show bgp neighbors json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=3, wait=1)
|
||||||
|
assertmsg = "BGP session on r1 failed to set DelayOpenTime for r4"
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
# 2.5 disable peering shutdown
|
||||||
|
logger.info("Disable shutdown of peering between r1 and r4")
|
||||||
|
tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.101.2 shutdown"')
|
||||||
|
tgen.net["r4"].cmd('vtysh -c "conf t" -c "router bgp 65100" -c "no neighbor 192.168.101.1 shutdown"')
|
||||||
|
|
||||||
|
# 2.6 wait for peers to establish connection (poll output)
|
||||||
|
for router_num in [1, 4]:
|
||||||
|
logger.info("Checking BGP summary after disabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_established.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=5, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not establish a connection with peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
# 2.7 unset delayopen on R1
|
||||||
|
logger.info("Disabling DelayOpenTimer for neighbor r4 on r1")
|
||||||
|
tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.101.2 timers delayopen"')
|
||||||
|
|
||||||
|
# 2.8 check config (poll output)
|
||||||
|
logger.info("Checking BGP neighbor configuration after disabling DelayOpenTimer on r1")
|
||||||
|
delayopen_cfg = tgen.net["r1"].cmd('vtysh -c "show bgp neighbors json" | grep "DelayOpenTimeMsecs"').rstrip()
|
||||||
|
assertmsg = "BGP session on r1 failed disable DelayOpenTimer for peer r4"
|
||||||
|
assert delayopen_cfg == "", assertmsg
|
||||||
|
|
||||||
|
#tgen.mininet_cli()
|
||||||
|
|
||||||
|
# end test_bgp_delayopen_singular
|
||||||
|
|
||||||
|
|
||||||
|
def test_bgp_delayopen_dual():
|
||||||
|
"Test of BGP functionality and behaviour with DelayOpenTimer enabled on both sides of the peering with different timer intervals"
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
# part 3: delay 60s R2 <=> delay 30s R5
|
||||||
|
logger.info("Starting test of BGP functionality and behaviour with DelayOpenTimer enabled on both sides of the peering with different timer intervals")
|
||||||
|
|
||||||
|
# 3.1 enable peering shutdown
|
||||||
|
logger.info("Enable shutdown of peering between r2 and r5")
|
||||||
|
tgen.net["r2"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.201.2 shutdown"')
|
||||||
|
tgen.net["r5"].cmd('vtysh -c "conf t" -c "router bgp 65200" -c "neighbor 192.168.201.1 shutdown"')
|
||||||
|
|
||||||
|
# 3.2 wait for peers to shut down (pool output)
|
||||||
|
for router_num in [2, 5]:
|
||||||
|
logger.info("Checking BGP summary after disabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_shutdown.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=3, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not shut down peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
# 3.3 set delayopen on R2 to 60s and on R5 to 30s
|
||||||
|
logger.info("Setting DelayOpenTime for neighbor r5 to 60 seconds on r2")
|
||||||
|
tgen.net["r2"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.201.2 timers delayopen 60"')
|
||||||
|
logger.info("Setting DelayOpenTime for neighbor r2 to 30 seconds on r5")
|
||||||
|
tgen.net["r5"].cmd('vtysh -c "conf t" -c "router bgp 65200" -c "neighbor 192.168.201.1 timers delayopen 30"')
|
||||||
|
|
||||||
|
# 3.4 check config (poll output)
|
||||||
|
for router_num in [2, 5]:
|
||||||
|
logger.info("Checking BGP neighbor configuration after setting DelayOpenTime on r{}i".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_neighbor.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show bgp neighbors json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=3, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} failed to set DelayOpenTime".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
## 3.5 disable peering shutdown
|
||||||
|
logger.info("Disable shutdown of peering between r2 and r5")
|
||||||
|
tgen.net["r2"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.201.2 shutdown"')
|
||||||
|
tgen.net["r5"].cmd('vtysh -c "conf t" -c "router bgp 65200" -c "no neighbor 192.168.201.1 shutdown"')
|
||||||
|
|
||||||
|
## 3.6 wait for peers to reach connect or active state (poll output)
|
||||||
|
delay_start = int(time.time())
|
||||||
|
for router_num in [2, 5]:
|
||||||
|
logger.info("Checking BGP summary after disabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_connect.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=3, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not enter Connect state with peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
## 3.7 wait for peers to establish connection (poll output)
|
||||||
|
for router_num in [2, 5]:
|
||||||
|
logger.info("Checking BGP summary after disabling shutdown of peering on r{}".format(router_num))
|
||||||
|
router = tgen.gears["r{}".format(router_num)]
|
||||||
|
reffile = os.path.join(CWD, "r{}/bgp_delayopen_summary_established.json".format(router_num))
|
||||||
|
expected = json.loads(open(reffile).read())
|
||||||
|
test_func = functools.partial(topotest.router_json_cmp, router, "show ip bgp summary json", expected)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=35, wait=1)
|
||||||
|
assertmsg = "BGP session on r{} did not establish a connection with peer".format(router_num)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
delay_stop = int(time.time())
|
||||||
|
assertmsg = "BGP peering between r2 and r5 was established before DelayOpenTimer (30sec) on r2 could expire"
|
||||||
|
assert (delay_stop - delay_start) > 30, assertmsg
|
||||||
|
|
||||||
|
# 3.8 unset delayopen on R2 and R5
|
||||||
|
logger.info("Disabling DelayOpenTimer for neighbor r5 on r2")
|
||||||
|
tgen.net["r2"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.201.2 timers delayopen"')
|
||||||
|
logger.info("Disabling DelayOpenTimer for neighbor r2 on r5")
|
||||||
|
tgen.net["r5"].cmd('vtysh -c "conf t" -c "router bgp 65200" -c "no neighbor 192.168.201.1 timers delayopen"')
|
||||||
|
|
||||||
|
# 3.9 check config (poll output)
|
||||||
|
for router_num in [2, 5]:
|
||||||
|
logger.info("Checking BGP neighbor configuration after disabling DelayOpenTimer on r{}".format(router_num))
|
||||||
|
delayopen_cfg = tgen.net["r{}".format(router_num)].cmd('vtysh -c "show bgp neighbors json" | grep "DelayOpenTimeMsecs"').rstrip()
|
||||||
|
assertmsg = "BGP session on r{} failed disable DelayOpenTimer".format(router_num)
|
||||||
|
assert delayopen_cfg == "", assertmsg
|
||||||
|
|
||||||
|
#tgen.mininet_cli()
|
||||||
|
|
||||||
|
# end test_bgp_delayopen_dual
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
args = ["-s"] + sys.argv[1:]
|
args = ["-s"] + sys.argv[1:]
|
||||||
sys.exit(pytest.main(args))
|
sys.exit(pytest.main(args))
|
||||||
|
Loading…
Reference in New Issue
Block a user