pespin has uploaded this change for review.

View Change

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, 197 insertions(+), 3 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/81/40481/1
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..1383f32 100644
--- a/src/ss7_asp.c
+++ b/src/ss7_asp.c
@@ -227,6 +227,77 @@
};
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\n");
+
+ 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 +792,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:
+ rc = ss7_asp_apply_tcp_keepalive(asp);
+ break;
+ case IPPROTO_SCTP:
+ rc = 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..572b31d 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], "num-ostreams") == 0)
+ asp->cfg.tcp.keepalive_time_present = false;
+ else if (strcmp(argv[0], "max-instreams") == 0)
+ asp->cfg.tcp.keepalive_intvl_present = false;
+ else if (strcmp(argv[0], "max-attempts") == 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 cd937d2..d7806aa 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
...

To view, visit change 40481. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I2a9338053e741fb6dab94492c6bdc2badaf7afb1
Gerrit-Change-Number: 40481
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>