summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2020-09-08 11:28:40 -0400
committerGitHub <noreply@github.com>2020-09-08 11:28:40 -0400
commit5ceb842f455a9b5ec738f7f52aad3a33e1ebf67c (patch)
treeab748ac03177a7b7face84b1c85cf47542544f6e
parentd6165cf5437cea776baa5dcbcdc0cb3877acc9e9 (diff)
parent91052810f9df11b6858fbe01efbb1ea4d2590ba6 (diff)
Merge pull request #6969 from ton31337/feature/autoshutdown_if_rtt_higher_than_specified
bgpd: Add `neighbor <neigh> shutdown rtt` command
-rw-r--r--bgpd/bgp_fsm.c3
-rw-r--r--bgpd/bgp_packet.c21
-rw-r--r--bgpd/bgp_vty.c64
-rw-r--r--bgpd/bgpd.c5
-rw-r--r--bgpd/bgpd.h4
-rw-r--r--doc/user/bgp.rst12
6 files changed, 106 insertions, 3 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 4575b8afbe..14dcf2b593 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1105,6 +1105,9 @@ void bgp_fsm_change_status(struct peer *peer, int status)
peer->ostatus = peer->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 */
if (peer->ostatus > peer->status)
hook_call(peer_backward_transition, peer);
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 0d81403803..15dba37667 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1432,6 +1432,27 @@ static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size)
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;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index e94a31b685..d80667699a 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -4480,6 +4480,64 @@ ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"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. */
DEFUN (neighbor_capability_dynamic,
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);
}
+ 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 */
if (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, &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.*/
install_element(BGP_NODE, &neighbor_capability_enhe_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 3056a5fe62..d638c6686e 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1604,6 +1604,9 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
/* Default TTL set. */
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);
if (afi && safi) {
@@ -3865,6 +3868,7 @@ struct peer_flag_action {
static const struct peer_flag_action peer_flag_action_list[] = {
{PEER_FLAG_PASSIVE, 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_OVERRIDE_CAPABILITY, 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);
UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
+
if (peer->t_pmax_restart) {
BGP_TIMER_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer))
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 87cdcd2e71..8707ebacb6 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -968,6 +968,9 @@ struct peer {
int fd; /* File descriptor */
int ttl; /* TTL of TCP connection to the peer. */
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 */
char *desc; /* Description of the 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 (1U << 24) /* Graceful Restart */
#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
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 4a5bdc2428..25eaa577c1 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1216,14 +1216,14 @@ Defining 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
update for them. The default time is 1000.
-
+
.. _bgp-configuring-peers:
Configuring Peers
^^^^^^^^^^^^^^^^^
-.. index:: [no] neighbor PEER shutdown [message MSG...]
-.. clicmd:: [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...] [rtt (1-65535) [count (1-255)]]
Shutdown the peer. We can delete the neighbor's configuration by
``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`.
+ 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
.. clicmd:: [no] neighbor PEER disable-connected-check