]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: support TCP keepalive for BGP connection
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 8 Nov 2021 08:48:24 +0000 (09:48 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 30 Aug 2022 13:09:28 +0000 (15:09 +0200)
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>
bgpd/bgp_network.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h
doc/user/bgp.rst

index 9ecc2ae4e42667a9c08a37bcc936ae3037f181d5..9582ec01ed757a9edef1d78c71ccf84365eb80f3 100644 (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;
        }
 
index 80c8753708c96d58c832776de26cae29c76b1e0c..029a6a0f8c2f48ad16b29f92ac8b53d60d785d8b 100644 (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);
 
index bd3e61377a65d6615d1b7f508f0b7106d3465898..15b4d7c5a9601db79bb1358a2ea931f1e51ebafc 100644 (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;
index bcb214873fae156d6de73d34d0b674dee28399ca..2d6b78d509812332d2e68ffc8fe2323ef4ba6a34 100644 (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 *);
index daaf80ae073aff2499b5da26f05f5629bf6a3e89..7993dd96c2eab1252a8ed2cfdbe9a7e66c8dc4c9 100644 (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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^