Merge pull request #6969 from ton31337/feature/autoshutdown_if_rtt_higher_than_specified

bgpd: Add `neighbor <neigh> shutdown rtt` command
This commit is contained in:
Russ White 2020-09-08 11:28:40 -04:00 committed by GitHub
commit 5ceb842f45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 3 deletions

View file

@ -1105,6 +1105,9 @@ void bgp_fsm_change_status(struct peer *peer, int status)
peer->ostatus = peer->status; peer->ostatus = peer->status;
peer->status = status; peer->status = status;
/* Reset received keepalives counter on every FSM change */
peer->rtt_keepalive_rcv = 0;
/* Fire backward transition hook if that's the case */ /* Fire backward transition hook if that's the case */
if (peer->ostatus > peer->status) if (peer->ostatus > peer->status)
hook_call(peer_backward_transition, peer); hook_call(peer_backward_transition, peer);

View file

@ -1432,6 +1432,27 @@ static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size)
bgp_update_implicit_eors(peer); bgp_update_implicit_eors(peer);
peer->rtt = sockopt_tcp_rtt(peer->fd);
/* If the peer's RTT is higher than expected, shutdown
* the peer automatically.
*/
if (CHECK_FLAG(peer->flags, PEER_FLAG_RTT_SHUTDOWN)
&& peer->rtt > peer->rtt_expected) {
peer->rtt_keepalive_rcv++;
if (peer->rtt_keepalive_rcv > peer->rtt_keepalive_conf) {
zlog_warn(
"%s shutdown due to high round-trip-time (%dms > %dms)",
peer->host, peer->rtt, peer->rtt_expected);
peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
}
} else {
if (peer->rtt_keepalive_rcv)
peer->rtt_keepalive_rcv--;
}
return Receive_KEEPALIVE_message; return Receive_KEEPALIVE_message;
} }

View file

@ -4480,6 +4480,64 @@ ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n") "Administratively shut down this neighbor\n")
DEFUN(neighbor_shutdown_rtt,
neighbor_shutdown_rtt_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> shutdown rtt (1-65535) [count (1-255)]",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n"
"Shutdown if round-trip-time is higher than expected\n"
"Round-trip-time in milliseconds\n"
"Specify the number of keepalives before shutdown\n"
"The number of keepalives with higher RTT to shutdown\n")
{
int idx_peer = 1;
int idx_rtt = 4;
int idx_count = 0;
struct peer *peer;
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
peer->rtt_expected = strtol(argv[idx_rtt]->arg, NULL, 10);
if (argv_find(argv, argc, "count", &idx_count))
peer->rtt_keepalive_conf =
strtol(argv[idx_count + 1]->arg, NULL, 10);
return peer_flag_set_vty(vty, argv[idx_peer]->arg,
PEER_FLAG_RTT_SHUTDOWN);
}
DEFUN(no_neighbor_shutdown_rtt,
no_neighbor_shutdown_rtt_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown rtt [(1-65535) [count (1-255)]]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n"
"Shutdown if round-trip-time is higher than expected\n"
"Round-trip-time in milliseconds\n"
"Specify the number of keepalives before shutdown\n"
"The number of keepalives with higher RTT to shutdown\n")
{
int idx_peer = 2;
struct peer *peer;
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
peer->rtt_expected = 0;
peer->rtt_keepalive_conf = 1;
return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
PEER_FLAG_RTT_SHUTDOWN);
}
/* neighbor capability dynamic. */ /* neighbor capability dynamic. */
DEFUN (neighbor_capability_dynamic, DEFUN (neighbor_capability_dynamic,
neighbor_capability_dynamic_cmd, neighbor_capability_dynamic_cmd,
@ -14829,6 +14887,10 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
vty_out(vty, " neighbor %s shutdown\n", addr); vty_out(vty, " neighbor %s shutdown\n", addr);
} }
if (peergroup_flag_check(peer, PEER_FLAG_RTT_SHUTDOWN))
vty_out(vty, " neighbor %s shutdown rtt %u count %u\n", addr,
peer->rtt_expected, peer->rtt_keepalive_conf);
/* bfd */ /* bfd */
if (peer->bfd_info) { if (peer->bfd_info) {
if (!peer_group_active(peer) || !g_peer->bfd_info) { if (!peer_group_active(peer) || !g_peer->bfd_info) {
@ -16628,6 +16690,8 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &no_neighbor_shutdown_cmd); install_element(BGP_NODE, &no_neighbor_shutdown_cmd);
install_element(BGP_NODE, &neighbor_shutdown_msg_cmd); install_element(BGP_NODE, &neighbor_shutdown_msg_cmd);
install_element(BGP_NODE, &no_neighbor_shutdown_msg_cmd); install_element(BGP_NODE, &no_neighbor_shutdown_msg_cmd);
install_element(BGP_NODE, &neighbor_shutdown_rtt_cmd);
install_element(BGP_NODE, &no_neighbor_shutdown_rtt_cmd);
/* "neighbor capability extended-nexthop" commands.*/ /* "neighbor capability extended-nexthop" commands.*/
install_element(BGP_NODE, &neighbor_capability_enhe_cmd); install_element(BGP_NODE, &neighbor_capability_enhe_cmd);

View file

@ -1604,6 +1604,9 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
/* Default TTL set. */ /* Default TTL set. */
peer->ttl = (peer->sort == BGP_PEER_IBGP) ? MAXTTL : BGP_DEFAULT_TTL; peer->ttl = (peer->sort == BGP_PEER_IBGP) ? MAXTTL : BGP_DEFAULT_TTL;
/* Default configured keepalives count for shutdown rtt command */
peer->rtt_keepalive_conf = 1;
SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
if (afi && safi) { if (afi && safi) {
@ -3865,6 +3868,7 @@ struct peer_flag_action {
static const struct peer_flag_action peer_flag_action_list[] = { static const struct peer_flag_action peer_flag_action_list[] = {
{PEER_FLAG_PASSIVE, 0, peer_change_reset}, {PEER_FLAG_PASSIVE, 0, peer_change_reset},
{PEER_FLAG_SHUTDOWN, 0, peer_change_reset}, {PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
{PEER_FLAG_RTT_SHUTDOWN, 0, peer_change_none},
{PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none}, {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
{PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none}, {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
{PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none}, {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
@ -3967,6 +3971,7 @@ static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
peer_nsf_stop(peer); peer_nsf_stop(peer);
UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
if (peer->t_pmax_restart) { if (peer->t_pmax_restart) {
BGP_TIMER_OFF(peer->t_pmax_restart); BGP_TIMER_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer)) if (bgp_debug_neighbor_events(peer))

View file

@ -968,6 +968,9 @@ struct peer {
int fd; /* File descriptor */ int fd; /* File descriptor */
int ttl; /* TTL of TCP connection to the peer. */ int ttl; /* TTL of TCP connection to the peer. */
int rtt; /* Estimated round-trip-time from TCP_INFO */ int rtt; /* Estimated round-trip-time from TCP_INFO */
int rtt_expected; /* Expected round-trip-time for a peer */
uint8_t rtt_keepalive_rcv; /* Received count for RTT shutdown */
uint8_t rtt_keepalive_conf; /* Configured count for RTT shutdown */
int gtsm_hops; /* minimum hopcount to peer */ int gtsm_hops; /* minimum hopcount to peer */
char *desc; /* Description of the peer. */ char *desc; /* Description of the peer. */
unsigned short port; /* Destination port for peer */ unsigned short port; /* Destination port for peer */
@ -1118,6 +1121,7 @@ struct peer {
#define PEER_FLAG_GRACEFUL_RESTART_HELPER (1U << 23) /* Helper */ #define PEER_FLAG_GRACEFUL_RESTART_HELPER (1U << 23) /* Helper */
#define PEER_FLAG_GRACEFUL_RESTART (1U << 24) /* Graceful Restart */ #define PEER_FLAG_GRACEFUL_RESTART (1U << 24) /* Graceful Restart */
#define PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT (1U << 25) /* Global-Inherit */ #define PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT (1U << 25) /* Global-Inherit */
#define PEER_FLAG_RTT_SHUTDOWN (1U << 26) /* shutdown rtt */
/* /*
*GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART *GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART

View file

@ -1216,14 +1216,14 @@ Defining Peers
The time in milliseconds that BGP will delay before deciding what peers The time in milliseconds that BGP will delay before deciding what peers
can be put into an update-group together in order to generate a single can be put into an update-group together in order to generate a single
update for them. The default time is 1000. update for them. The default time is 1000.
.. _bgp-configuring-peers: .. _bgp-configuring-peers:
Configuring Peers Configuring Peers
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
.. index:: [no] neighbor PEER shutdown [message MSG...] .. index:: [no] neighbor PEER shutdown [message MSG...] [rtt (1-65535) [count (1-255)]]
.. clicmd:: [no] neighbor PEER shutdown [message MSG...] .. clicmd:: [no] neighbor PEER shutdown [message MSG...] [rtt (1-65535) [count (1-255)]]
Shutdown the peer. We can delete the neighbor's configuration by Shutdown the peer. We can delete the neighbor's configuration by
``no neighbor PEER remote-as ASN`` but all configuration of the neighbor ``no neighbor PEER remote-as ASN`` but all configuration of the neighbor
@ -1232,6 +1232,12 @@ Configuring Peers
Optionally you can specify a shutdown message `MSG`. Optionally you can specify a shutdown message `MSG`.
Also, you can specify optionally _rtt_ in milliseconds to automatically
shutdown the peer if round-trip-time becomes higher than defined.
Additional _count_ parameter is the number of keepalive messages to count
before shutdown the peer if round-trip-time becomes higher than defined.
.. index:: [no] neighbor PEER disable-connected-check .. index:: [no] neighbor PEER disable-connected-check
.. clicmd:: [no] neighbor PEER disable-connected-check .. clicmd:: [no] neighbor PEER disable-connected-check