pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/40481?usp=email )
Change subject: asp: Introduce support to configure and enable TCP keep-alive ......................................................................
asp: Introduce support to configure and enable TCP keep-alive
Depends: libosmo-netif.git Change-Id Ie748ad581c1c42f4c24f9409ce7d34d419cbca8b Change-Id: I2a9338053e741fb6dab94492c6bdc2badaf7afb1 --- M TODO-RELEASE M src/ss7_asp.c M src/ss7_asp.h M src/ss7_asp_vty.c M src/ss7_xua_srv.c M tests/vty/osmo_stp_test.vty 6 files changed, 200 insertions(+), 3 deletions(-)
Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified
diff --git a/TODO-RELEASE b/TODO-RELEASE index 0ed7189..2d94ad1 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -7,3 +7,4 @@ # If any interfaces have been added since the last public release: c:r:a + 1. # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line +libosmo-netif >1.6.0 stream OSMO_STREAM_{CLI,SRV}_TCP_SOCKOPT_KEEP* diff --git a/src/ss7_asp.c b/src/ss7_asp.c index d7e9b12..ca4a4c6 100644 --- a/src/ss7_asp.c +++ b/src/ss7_asp.c @@ -227,6 +227,80 @@ }; static unsigned int g_ss7_asp_rcg_idx;
+int ss7_asp_apply_tcp_keepalive(const struct osmo_ss7_asp *asp) +{ + uint8_t byte = 1; + int val; + int rc; + + if (!asp->cfg.tcp.keepalive_enable) + return 0; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Enabling TCP keep-alive time=%d intvl=%d probes=%d\n", + asp->cfg.tcp.keepalive_time_present ? asp->cfg.tcp.keepalive_time_value : -1, + asp->cfg.tcp.keepalive_intvl_present ? asp->cfg.tcp.keepalive_intvl_value : -1, + asp->cfg.tcp.keepalive_probes_present ? asp->cfg.tcp.keepalive_probes_value : -1); + + if (asp->server) { + rc = osmo_stream_srv_set_param(asp->server, OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPALIVE, + &byte, sizeof(byte)); + if (rc < 0) + return rc; + + if (asp->cfg.tcp.keepalive_time_present) { + val = asp->cfg.tcp.keepalive_time_value; + rc = osmo_stream_srv_set_param(asp->server, OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPIDLE, + &val, sizeof(val)); + if (rc < 0) + return rc; + } + if (asp->cfg.tcp.keepalive_intvl_present) { + val = asp->cfg.tcp.keepalive_intvl_value; + rc = osmo_stream_srv_set_param(asp->server, OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPINTVL, + &val, sizeof(val)); + if (rc < 0) + return rc; + } + if (asp->cfg.tcp.keepalive_probes_present) { + val = asp->cfg.tcp.keepalive_probes_value; + rc = osmo_stream_srv_set_param(asp->server, OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPCNT, + &val, sizeof(val)); + if (rc < 0) + return rc; + } + + } else if (asp->client) { + rc = osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPALIVE, + &byte, sizeof(byte)); + if (rc < 0) + return rc; + + if (asp->cfg.tcp.keepalive_time_present) { + val = asp->cfg.tcp.keepalive_time_value; + rc = osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPIDLE, + &val, sizeof(val)); + if (rc < 0) + return rc; + } + if (asp->cfg.tcp.keepalive_intvl_present) { + val = asp->cfg.tcp.keepalive_intvl_value; + rc = osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPINTVL, + &val, sizeof(val)); + if (rc < 0) + return rc; + } + if (asp->cfg.tcp.keepalive_probes_present) { + val = asp->cfg.tcp.keepalive_probes_value; + rc = osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPCNT, + &val, sizeof(val)); + if (rc < 0) + return rc; + } + } + + return 0; +} + int ss7_asp_apply_new_local_address(const struct osmo_ss7_asp *asp, unsigned int loc_idx) { const char *new_loc_addr; @@ -721,8 +795,16 @@ } osmo_stream_cli_set_data(asp->client, asp);
- if (asp->cfg.trans_proto == IPPROTO_SCTP) - asp_client_apply_sctp_init_pars(asp); + switch (asp->cfg.trans_proto) { + case IPPROTO_TCP: + (void)ss7_asp_apply_tcp_keepalive(asp); + break; + case IPPROTO_SCTP: + (void)asp_client_apply_sctp_init_pars(asp); + break; + default: + OSMO_ASSERT(0); + }
rc = osmo_stream_cli_open(asp->client); return rc; diff --git a/src/ss7_asp.h b/src/ss7_asp.h index 889b5c9..00c6825 100644 --- a/src/ss7_asp.h +++ b/src/ss7_asp.h @@ -130,6 +130,16 @@ uint16_t max_init_timeo_value; /* ms */ } sctp_init;
+ struct { + bool keepalive_enable; + bool keepalive_time_present; + bool keepalive_intvl_present; + bool keepalive_probes_present; + int keepalive_time_value; /* seconds */ + int keepalive_intvl_value; /* seconds */ + int keepalive_probes_value; + } tcp; + /*! The underlaying transport protocol (one of IPPROTO_*) */ int trans_proto; } cfg; @@ -143,6 +153,7 @@ int ss7_asp_get_fd(const struct osmo_ss7_asp *asp); int ss7_asp_disconnect_stream(struct osmo_ss7_asp *asp);
+int ss7_asp_apply_tcp_keepalive(const struct osmo_ss7_asp *asp); int ss7_asp_apply_peer_primary_address(const struct osmo_ss7_asp *asp); int ss7_asp_apply_primary_address(const struct osmo_ss7_asp *asp); int ss7_asp_apply_new_local_address(const struct osmo_ss7_asp *asp, unsigned int loc_idx); diff --git a/src/ss7_asp_vty.c b/src/ss7_asp_vty.c index 3e22465..534c1d9 100644 --- a/src/ss7_asp_vty.c +++ b/src/ss7_asp_vty.c @@ -445,6 +445,81 @@ return CMD_SUCCESS; }
+#define ASP_TCP_PARAM_KEEPALIVE_DESC \ + "Configure TCP parameters\n" \ + "Configure TCP keep-alive related parameters\n" \ + +DEFUN_ATTR(asp_tcp_param_keepalive_enabled, asp_tcp_param_keepalive_enabled_cmd, + "tcp-param keepalive enabled", + ASP_TCP_PARAM_KEEPALIVE_DESC + "Enable TCP keep-alive\n", + CMD_ATTR_NODE_EXIT) +{ + struct osmo_ss7_asp *asp = vty->index; + asp->cfg.tcp.keepalive_enable = true; + return CMD_SUCCESS; +} + +DEFUN_ATTR(asp_no_tcp_param_keepalive, asp_no_tcp_param_keepalive_cmd, + "no tcp-param keepalive", + NO_STR ASP_TCP_PARAM_KEEPALIVE_DESC, + CMD_ATTR_NODE_EXIT) +{ + struct osmo_ss7_asp *asp = vty->index; + asp->cfg.tcp.keepalive_enable = false; + return CMD_SUCCESS; +} + +#define ASP_TCP_PARAM_KEEPALIVE_CFG_DESC \ + ASP_TCP_PARAM_KEEPALIVE_DESC \ + "Configure number of seconds a connection needs to be idle before beggining to send probes\n" \ + "Configure number of seconds between probes\n" \ + "Configure max number of probes to send before giving up if no response is obtained\n" +#define ASP_TCP_PARAM_KEEPALIVE_CFG_FIELDS "(time|intvl|probes)" + +DEFUN_ATTR(asp_tcp_param_keepalive_cfg, asp_tcp_param_keepalive_cfg_cmd, + "tcp-param keepalive " ASP_TCP_PARAM_KEEPALIVE_CFG_FIELDS " <0-65535>", + ASP_TCP_PARAM_KEEPALIVE_CFG_DESC + "Value of the parameter\n", + CMD_ATTR_NODE_EXIT) +{ + struct osmo_ss7_asp *asp = vty->index; + + uint16_t val = atoi(argv[1]); + + if (strcmp(argv[0], "time") == 0) { + asp->cfg.tcp.keepalive_time_present = true; + asp->cfg.tcp.keepalive_time_value = val; + } else if (strcmp(argv[0], "intvl") == 0) { + asp->cfg.tcp.keepalive_intvl_present = true; + asp->cfg.tcp.keepalive_intvl_value = val; + } else if (strcmp(argv[0], "probes") == 0) { + asp->cfg.tcp.keepalive_probes_present = true; + asp->cfg.tcp.keepalive_probes_value = val; + } else { + OSMO_ASSERT(0); + } + return CMD_SUCCESS; +} + +DEFUN_ATTR(asp_no_tcp_param_keepalive_cfg, asp_no_tcp_param_keepalive_cfg_cmd, + "no tcp-param keepalive " ASP_TCP_PARAM_KEEPALIVE_CFG_FIELDS, + NO_STR ASP_TCP_PARAM_KEEPALIVE_CFG_DESC, + CMD_ATTR_NODE_EXIT) +{ + struct osmo_ss7_asp *asp = vty->index; + + if (strcmp(argv[0], "time") == 0) + asp->cfg.tcp.keepalive_time_present = false; + else if (strcmp(argv[0], "intvl") == 0) + asp->cfg.tcp.keepalive_intvl_present = false; + else if (strcmp(argv[0], "probes") == 0) + asp->cfg.tcp.keepalive_probes_present = false; + else + OSMO_ASSERT(0); + return CMD_SUCCESS; +} + DEFUN_ATTR(asp_block, asp_block_cmd, "block", "Allows a SCTP Association with ASP, but doesn't let it become active\n", @@ -1141,6 +1216,19 @@ vty_out(vty, " sctp-param init max-attempts %u%s", asp->cfg.sctp_init.max_attempts_value, VTY_NEWLINE); if (asp->cfg.sctp_init.max_init_timeo_present) vty_out(vty, " sctp-param init timeout %u%s", asp->cfg.sctp_init.max_init_timeo_value, VTY_NEWLINE); + + if (asp->cfg.tcp.keepalive_enable) { + vty_out(vty, " tcp-param keepalive enabled%s", VTY_NEWLINE); + if (asp->cfg.tcp.keepalive_time_present) + vty_out(vty, " tcp-param keepalive time %d%s", asp->cfg.tcp.keepalive_time_value, VTY_NEWLINE); + if (asp->cfg.tcp.keepalive_intvl_present) + vty_out(vty, " tcp-param keepalive intvl %d%s", asp->cfg.tcp.keepalive_intvl_value, VTY_NEWLINE); + if (asp->cfg.tcp.keepalive_probes_present) + vty_out(vty, " tcp-param keepalive probes %d%s", asp->cfg.tcp.keepalive_probes_value, VTY_NEWLINE); + } else if (asp->cfg.trans_proto == IPPROTO_TCP) { + vty_out(vty, " no tcp-param keepalive%s", VTY_NEWLINE); + } + for (i = 0; i < sizeof(uint32_t) * 8; i++) { if (!(asp->cfg.quirks & ((uint32_t) 1 << i))) continue; @@ -1226,6 +1314,10 @@ install_lib_element(L_CS7_ASP_NODE, &asp_sctp_role_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_sctp_param_init_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_no_sctp_param_init_cmd); + install_lib_element(L_CS7_ASP_NODE, &asp_tcp_param_keepalive_enabled_cmd); + install_lib_element(L_CS7_ASP_NODE, &asp_tcp_param_keepalive_cfg_cmd); + install_lib_element(L_CS7_ASP_NODE, &asp_no_tcp_param_keepalive_cmd); + install_lib_element(L_CS7_ASP_NODE, &asp_no_tcp_param_keepalive_cfg_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_quirk_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_no_quirk_cmd); gen_asp_timer_xua_cmd_strs(&asp_timer_xua_cmd); diff --git a/src/ss7_xua_srv.c b/src/ss7_xua_srv.c index 120f165..b60acf6 100644 --- a/src/ss7_xua_srv.c +++ b/src/ss7_xua_srv.c @@ -191,9 +191,14 @@ * data */ osmo_stream_srv_set_data(srv, asp);
- if (asp->cfg.trans_proto == IPPROTO_SCTP) { + switch (asp->cfg.trans_proto) { + case IPPROTO_TCP: + rc = ss7_asp_apply_tcp_keepalive(asp); + break; + case IPPROTO_SCTP: rc = ss7_asp_apply_peer_primary_address(asp); rc = ss7_asp_apply_primary_address(asp); + break; }
/* send M-SCTP_ESTABLISH.ind to Layer Manager */ diff --git a/tests/vty/osmo_stp_test.vty b/tests/vty/osmo_stp_test.vty index be2beb5..b89bb30 100644 --- a/tests/vty/osmo_stp_test.vty +++ b/tests/vty/osmo_stp_test.vty @@ -283,6 +283,10 @@ transport-role (client|server) sctp-param init (num-ostreams|max-instreams|max-attempts|timeout) <0-65535> no sctp-param init (num-ostreams|max-instreams|max-attempts|timeout) + tcp-param keepalive enabled + tcp-param keepalive (time|intvl|probes) <0-65535> + no tcp-param keepalive + no tcp-param keepalive (time|intvl|probes) quirk (no_notify|daud_in_asp|snm_inactive) no quirk (no_notify|daud_in_asp|snm_inactive) timer xua (ack|beat) <1-999999> @@ -302,6 +306,7 @@ role Specify the xUA role for this ASP transport-role Specify the transport layer role for this ASP sctp-param Configure SCTP parameters + tcp-param Configure TCP parameters quirk Enable quirk to work around interop issues timer Configure ASP default timer values block Allows a SCTP Association with ASP, but doesn't let it become active @@ -311,6 +316,7 @@ OsmoSTP(config-cs7-asp)# no ? ... sctp-param Configure SCTP parameters + tcp-param Configure TCP parameters quirk Disable quirk to work around interop issues shutdown Terminates SCTP association; New associations will be rejected ...