bgpd: support TCP keepalive for BGP connection

TCP keepalive is enabled once BGP connection is established.

New vty commands:

bgp tcp-keepalive <1-65535> <1-65535> <1-30>
no bgp tcp-keepalive

Signed-off-by: Xiaofeng Liu <xiaofeng.liu@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2021-11-08 09:48:24 +01:00
parent 5c480b5db3
commit d1adb44843
5 changed files with 105 additions and 0 deletions

View File

@ -207,6 +207,25 @@ int bgp_md5_set(struct peer *peer)
return bgp_md5_set_password(peer, peer->password);
}
static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd)
{
if (!bgp)
return;
if (bgp->tcp_keepalive_idle != 0) {
int ret;
ret = setsockopt_tcp_keepalive(fd, bgp->tcp_keepalive_idle,
bgp->tcp_keepalive_intvl,
bgp->tcp_keepalive_probes);
if (ret < 0)
zlog_err(
"Can't set TCP keepalive on socket %d, idle %u intvl %u probes %u",
fd, bgp->tcp_keepalive_idle,
bgp->tcp_keepalive_intvl,
bgp->tcp_keepalive_probes);
}
}
int bgp_md5_unset(struct peer *peer)
{
/* Unset the password from listen socket. */
@ -415,6 +434,9 @@ static void bgp_accept(struct thread *thread)
bgp_socket_set_buffer_size(bgp_sock);
/* Set TCP keepalive when TCP keepalive is enabled */
bgp_update_setsockopt_tcp_keepalive(bgp, bgp_sock);
/* Check remote IP address */
peer1 = peer_lookup(bgp, &su);
@ -718,12 +740,16 @@ int bgp_connect(struct peer *peer)
bgp_socket_set_buffer_size(peer->fd);
/* Set TCP keepalive when TCP keepalive is enabled */
bgp_update_setsockopt_tcp_keepalive(peer->bgp, peer->fd);
if (bgp_set_socket_ttl(peer, peer->fd) < 0) {
peer->last_reset = PEER_DOWN_SOCKET_ERROR;
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s: Failure to set socket ttl for connection to %s, error received: %s(%d)",
__func__, peer->host, safe_strerror(errno),
errno);
return -1;
}

View File

@ -2335,6 +2335,15 @@ void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time);
}
/* BGP TCP keepalive */
static void bgp_config_tcp_keepalive(struct vty *vty, struct bgp *bgp)
{
if (bgp->tcp_keepalive_idle) {
vty_out(vty, " bgp tcp-keepalive %u %u %u\n",
bgp->tcp_keepalive_idle, bgp->tcp_keepalive_intvl,
bgp->tcp_keepalive_probes);
}
}
DEFUN (bgp_coalesce_time,
bgp_coalesce_time_cmd,
@ -2558,6 +2567,38 @@ DEFUN(no_bgp_minimum_holdtime, no_bgp_minimum_holdtime_cmd,
return CMD_SUCCESS;
}
DEFPY(bgp_tcp_keepalive, bgp_tcp_keepalive_cmd,
"bgp tcp-keepalive (1-65535)$idle (1-65535)$intvl (1-30)$probes",
BGP_STR
"TCP keepalive parameters\n"
"TCP keepalive idle time (seconds)\n"
"TCP keepalive interval (seconds)\n"
"TCP keepalive maximum probes\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_tcp_keepalive_set(bgp, (uint16_t)idle, (uint16_t)intvl,
(uint16_t)probes);
return CMD_SUCCESS;
}
DEFPY(no_bgp_tcp_keepalive, no_bgp_tcp_keepalive_cmd,
"no bgp tcp-keepalive [(1-65535) (1-65535) (1-30)]",
NO_STR
BGP_STR
"TCP keepalive parameters\n"
"TCP keepalive idle time (seconds)\n"
"TCP keepalive interval (seconds)\n"
"TCP keepalive maximum probes\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_tcp_keepalive_unset(bgp);
return CMD_SUCCESS;
}
DEFUN (bgp_client_to_client_reflection,
bgp_client_to_client_reflection_cmd,
"bgp client-to-client reflection",
@ -17633,6 +17674,9 @@ int bgp_config_write(struct vty *vty)
vty_out(vty,
" bgp graceful-restart preserve-fw-state\n");
/* BGP TCP keepalive */
bgp_config_tcp_keepalive(vty, bgp);
/* Stale timer for RIB */
if (bgp->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME)
vty_out(vty,
@ -19414,6 +19458,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &neighbor_ttl_security_cmd);
install_element(BGP_NODE, &no_neighbor_ttl_security_cmd);
/* "bgp tcp-keepalive" commands */
install_element(BGP_NODE, &bgp_tcp_keepalive_cmd);
install_element(BGP_NODE, &no_bgp_tcp_keepalive_cmd);
/* "show [ip] bgp memory" commands. */
install_element(VIEW_NODE, &show_bgp_memory_cmd);

View File

@ -564,6 +564,21 @@ void bgp_timers_unset(struct bgp *bgp)
bgp->default_delayopen = BGP_DEFAULT_DELAYOPEN;
}
void bgp_tcp_keepalive_set(struct bgp *bgp, uint16_t keepalive_idle,
uint16_t keepalive_intvl, uint16_t keepalive_probes)
{
bgp->tcp_keepalive_idle = keepalive_idle;
bgp->tcp_keepalive_intvl = keepalive_intvl;
bgp->tcp_keepalive_probes = keepalive_probes;
}
void bgp_tcp_keepalive_unset(struct bgp *bgp)
{
bgp->tcp_keepalive_idle = 0;
bgp->tcp_keepalive_intvl = 0;
bgp->tcp_keepalive_probes = 0;
}
/* BGP confederation configuration. */
void bgp_confederation_id_set(struct bgp *bgp, as_t as)
{
@ -3202,6 +3217,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
bgp->default_subgroup_pkt_queue_max =
BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
bgp_tcp_keepalive_unset(bgp);
bgp_timers_unset(bgp);
bgp->default_min_holdtime = 0;
bgp->restart_time = BGP_DEFAULT_RESTART_TIME;

View File

@ -132,6 +132,7 @@ struct bgp_master {
/* Various BGP global configuration. */
uint8_t options;
#define BGP_OPT_NO_FIB (1 << 0)
#define BGP_OPT_NO_LISTEN (1 << 1)
#define BGP_OPT_NO_ZEBRA (1 << 2)
@ -768,6 +769,10 @@ struct bgp {
char srv6_locator_name[SRV6_LOCNAME_SIZE];
struct list *srv6_locator_chunks;
struct list *srv6_functions;
/* TCP keepalive parameters for BGP connection */
uint16_t tcp_keepalive_idle;
uint16_t tcp_keepalive_intvl;
uint16_t tcp_keepalive_probes;
struct timeval ebgprequirespolicywarning;
#define FIFTEENMINUTE2USEC (int64_t)15 * 60 * 1000000
@ -2201,6 +2206,9 @@ extern int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
const char *rmap,
struct route_map *route_map);
extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
extern void bgp_tcp_keepalive_set(struct bgp *bgp, uint16_t idle,
uint16_t interval, uint16_t probes);
extern void bgp_tcp_keepalive_unset(struct bgp *bgp);
extern void peer_port_set(struct peer *, uint16_t);
extern void peer_port_unset(struct peer *);

View File

@ -1781,6 +1781,13 @@ Configuring Peers
with lower holdtime less than configured minimum holdtime.
When this command is not set, minimum holdtime does not work.
.. clicmd:: bgp tcp-keepalive (1-65535) (1-65535) (1-30)
This command allows user to configure TCP keepalive with new BGP peers.
Each parameter respectively stands for TCP keepalive idle timer (seconds),
interval (seconds), and maximum probes. By default, TCP keepalive is
disabled.
Displaying Information about Peers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^