From abf26ce1ad68528009f782bbcfd5c119ec4a038e Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Fri, 8 Sep 2023 14:16:07 +0200 Subject: [PATCH] Allow configuring per-ASP SCTP INIT parameters Related: SYS#6558 Depends: libosmo-netif.git Change-Id I5343c7659881b29e0201e72badbc2d07e1ef2dca Change-Id: I4c104f0313b549efab7fae2e81a163474e9bcd4b --- include/osmocom/sigtran/osmo_ss7.h | 17 +++++ src/osmo_ss7_asp.c | 16 ++++ src/osmo_ss7_vty.c | 118 +++++++++++++++++++++++++++++ src/osmo_ss7_xua_srv.c | 8 ++ tests/vty/ss7_asp_test.vty | 10 +++ 5 files changed, 169 insertions(+) diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index ed3d4098..98e11876 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -442,6 +442,17 @@ struct osmo_ss7_asp { /* T_defs used by the default_lm: */ struct osmo_tdef *T_defs_lm; + + struct { + bool num_ostreams_present; + bool max_instreams_present; + bool max_attempts_present; + bool max_init_timeo_present; + uint16_t num_ostreams_value; + uint16_t max_instreams_value; + uint16_t max_attempts_value; + uint16_t max_init_timeo_value; /* ms */ + } sctp_init; } cfg; }; @@ -524,6 +535,12 @@ struct osmo_xua_server { bool accept_dyn_reg; struct osmo_ss7_asp_peer local; enum osmo_ss7_asp_protocol proto; + struct { + bool num_ostreams_present; + bool max_instreams_present; + uint16_t num_ostreams_value; + uint16_t max_instreams_value; + } sctp_init; } cfg; }; diff --git a/src/osmo_ss7_asp.c b/src/osmo_ss7_asp.c index ab01abdc..596e7aef 100644 --- a/src/osmo_ss7_asp.c +++ b/src/osmo_ss7_asp.c @@ -763,6 +763,22 @@ int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED, &byte, sizeof(byte)); byte = 1; /* enable, don't abort socket creation if ASCONF can't be enabled */ osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_ASCONF_SUPPORTED, &byte, sizeof(byte)); + if (asp->cfg.sctp_init.num_ostreams_present) + osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_SCTP_INIT_NUM_OSTREAMS, + &asp->cfg.sctp_init.num_ostreams_value, + sizeof(asp->cfg.sctp_init.num_ostreams_value)); + if (asp->cfg.sctp_init.max_instreams_present) + osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_SCTP_INIT_MAX_INSTREAMS, + &asp->cfg.sctp_init.max_instreams_value, + sizeof(asp->cfg.sctp_init.max_instreams_value)); + if (asp->cfg.sctp_init.max_attempts_present) + osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_SCTP_INIT_MAX_ATTEMPTS, + &asp->cfg.sctp_init.max_attempts_value, + sizeof(asp->cfg.sctp_init.max_attempts_value)); + if (asp->cfg.sctp_init.max_init_timeo_present) + osmo_stream_cli_set_param(asp->client, OSMO_STREAM_CLI_PAR_SCTP_INIT_TIMEOUT, + &asp->cfg.sctp_init.max_init_timeo_value, + sizeof(asp->cfg.sctp_init.max_init_timeo_value)); rc = osmo_stream_cli_open(asp->client); if (rc < 0) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Unable to open stream" diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index df4c8fc2..4e13522c 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -528,6 +528,51 @@ DEFUN_ATTR(xua_accept_dyn_asp, xua_accept_dyn_asp_cmd, return CMD_SUCCESS; } +#define XUA_SRV_SCTP_PARAM_INIT_DESC \ + "Configure SCTP parameters\n" \ + "Configure INIT related parameters\n" \ + "Configure INIT Number of Outbound Streams\n" \ + "Configure INIT Maximum Inboud Streams\n" +#define XUA_SRV_SCTP_PARAM_INIT_FIELDS "(num-ostreams|max-instreams)" + +DEFUN_ATTR(xua_sctp_param_init, xua_sctp_param_init_cmd, + "sctp-param init " XUA_SRV_SCTP_PARAM_INIT_FIELDS " <0-65535>", + XUA_SRV_SCTP_PARAM_INIT_DESC + "Value of the parameter\n", + CMD_ATTR_NODE_EXIT) +{ + struct osmo_xua_server *xs = vty->index; + + uint16_t val = atoi(argv[1]); + + if (strcmp(argv[0], "num-ostreams") == 0) { + xs->cfg.sctp_init.num_ostreams_present = true; + xs->cfg.sctp_init.num_ostreams_value = val; + } else if (strcmp(argv[0], "max-instreams") == 0) { + xs->cfg.sctp_init.max_instreams_present = true; + xs->cfg.sctp_init.max_instreams_value = val; + } else { + OSMO_ASSERT(0); + } + return CMD_SUCCESS; +} + +DEFUN_ATTR(xua_no_sctp_param_init, xua_no_sctp_param_init_cmd, + "no sctp-param init " XUA_SRV_SCTP_PARAM_INIT_FIELDS, + NO_STR XUA_SRV_SCTP_PARAM_INIT_DESC, + CMD_ATTR_NODE_EXIT) +{ + struct osmo_xua_server *xs = vty->index; + + if (strcmp(argv[0], "num-ostreams") == 0) + xs->cfg.sctp_init.num_ostreams_present = false; + else if (strcmp(argv[0], "max-instreams") == 0) + xs->cfg.sctp_init.max_instreams_present = false; + else + OSMO_ASSERT(0); + return CMD_SUCCESS; +} + static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { int i; @@ -541,6 +586,10 @@ static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) } if (xs->cfg.accept_dyn_reg) vty_out(vty, " accept-asp-connections dynamic-permitted%s", VTY_NEWLINE); + if (xs->cfg.sctp_init.num_ostreams_present) + vty_out(vty, " sctp-param init num-ostreams %u%s", xs->cfg.sctp_init.num_ostreams_value, VTY_NEWLINE); + if (xs->cfg.sctp_init.max_instreams_present) + vty_out(vty, " sctp-param init max-instreams %u%s", xs->cfg.sctp_init.max_instreams_value, VTY_NEWLINE); } static void vty_dump_xua_server(struct vty *vty, struct osmo_xua_server *xs) @@ -746,6 +795,63 @@ DEFUN_ATTR(sctp_role, asp_sctp_role_cmd, return CMD_SUCCESS; } +#define ASP_SCTP_PARAM_INIT_DESC \ + "Configure SCTP parameters\n" \ + "Configure INIT related parameters\n" \ + "Configure INIT Number of Outbound Streams\n" \ + "Configure INIT Maximum Inboud Streams\n" \ + "Configure INIT Maximum Attempts\n" \ + "Configure INIT Timeout (milliseconds)\n" +#define ASP_SCTP_PARAM_INIT_FIELDS "(num-ostreams|max-instreams|max-attempts|timeout)" + +DEFUN_ATTR(asp_sctp_param_init, asp_sctp_param_init_cmd, + "sctp-param init " ASP_SCTP_PARAM_INIT_FIELDS " <0-65535>", + ASP_SCTP_PARAM_INIT_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], "num-ostreams") == 0) { + asp->cfg.sctp_init.num_ostreams_present = true; + asp->cfg.sctp_init.num_ostreams_value = val; + } else if (strcmp(argv[0], "max-instreams") == 0) { + asp->cfg.sctp_init.max_instreams_present = true; + asp->cfg.sctp_init.max_instreams_value = val; + } else if (strcmp(argv[0], "max-attempts") == 0) { + asp->cfg.sctp_init.max_attempts_present = true; + asp->cfg.sctp_init.max_attempts_value = val; + } else if (strcmp(argv[0], "timeout") == 0) { + asp->cfg.sctp_init.max_init_timeo_present = true; + asp->cfg.sctp_init.max_init_timeo_value = val; + } else { + OSMO_ASSERT(0); + } + return CMD_SUCCESS; +} + +DEFUN_ATTR(asp_no_sctp_param_init, asp_no_sctp_param_init_cmd, + "no sctp-param init " ASP_SCTP_PARAM_INIT_FIELDS, + NO_STR ASP_SCTP_PARAM_INIT_DESC, + CMD_ATTR_NODE_EXIT) +{ + struct osmo_ss7_asp *asp = vty->index; + + if (strcmp(argv[0], "num-ostreams") == 0) + asp->cfg.sctp_init.num_ostreams_present = false; + else if (strcmp(argv[0], "max-instreams") == 0) + asp->cfg.sctp_init.max_instreams_present = false; + else if (strcmp(argv[0], "max-attempts") == 0) + asp->cfg.sctp_init.max_attempts_present = false; + else if (strcmp(argv[0], "timeout") == 0) + asp->cfg.sctp_init.max_init_timeo_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", @@ -956,6 +1062,14 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp, bool show_d vty_out(vty, " role %s%s", osmo_str_tolower(get_value_string(osmo_ss7_asp_role_names, asp->cfg.role)), VTY_NEWLINE); vty_out(vty, " sctp-role %s%s", asp->cfg.is_server ? "server" : "client", VTY_NEWLINE); + if (asp->cfg.sctp_init.num_ostreams_present) + vty_out(vty, " sctp-param init num-ostreams %u%s", asp->cfg.sctp_init.num_ostreams_value, VTY_NEWLINE); + if (asp->cfg.sctp_init.max_instreams_present) + vty_out(vty, " sctp-param init max-instreams %u%s", asp->cfg.sctp_init.max_instreams_value, VTY_NEWLINE); + if (asp->cfg.sctp_init.max_attempts_present) + 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); for (i = 0; i < sizeof(uint32_t) * 8; i++) { if (!(asp->cfg.quirks & ((uint32_t) 1 << i))) continue; @@ -2203,6 +2317,8 @@ static void vty_init_shared(void *ctx) install_lib_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_role_cmd); 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_block_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); install_lib_element(L_CS7_ASP_NODE, &asp_quirk_cmd); @@ -2255,4 +2371,6 @@ void osmo_ss7_vty_init_sg(void *ctx) install_lib_element(L_CS7_NODE, &no_cs7_xua_cmd); install_lib_element(L_CS7_XUA_NODE, &xua_local_ip_cmd); install_lib_element(L_CS7_XUA_NODE, &xua_accept_dyn_asp_cmd); + install_lib_element(L_CS7_XUA_NODE, &xua_sctp_param_init_cmd); + install_lib_element(L_CS7_XUA_NODE, &xua_no_sctp_param_init_cmd); } diff --git a/src/osmo_ss7_xua_srv.c b/src/osmo_ss7_xua_srv.c index 57e909a2..dc27c835 100644 --- a/src/osmo_ss7_xua_srv.c +++ b/src/osmo_ss7_xua_srv.c @@ -243,6 +243,14 @@ osmo_ss7_xua_server_bind(struct osmo_xua_server *xs) osmo_stream_srv_link_set_param(xs->server, OSMO_STREAM_SRV_LINK_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED, &byte, sizeof(byte)); byte = 1; /* enable, don't abort socket creation if ASCONF can't be enabled */ osmo_stream_srv_link_set_param(xs->server, OSMO_STREAM_SRV_LINK_PAR_SCTP_SOCKOPT_ASCONF_SUPPORTED, &byte, sizeof(byte)); + if (xs->cfg.sctp_init.num_ostreams_present) + osmo_stream_srv_link_set_param(xs->server, OSMO_STREAM_SRV_LINK_PAR_SCTP_INIT_NUM_OSTREAMS, + &xs->cfg.sctp_init.num_ostreams_value, + sizeof(xs->cfg.sctp_init.num_ostreams_value)); + if (xs->cfg.sctp_init.max_instreams_present) + osmo_stream_srv_link_set_param(xs->server, OSMO_STREAM_SRV_LINK_PAR_SCTP_INIT_MAX_INSTREAMS, + &xs->cfg.sctp_init.max_instreams_value, + sizeof(xs->cfg.sctp_init.max_instreams_value)); return osmo_stream_srv_link_open(xs->server); } diff --git a/tests/vty/ss7_asp_test.vty b/tests/vty/ss7_asp_test.vty index d23f9c0b..09a3dba5 100644 --- a/tests/vty/ss7_asp_test.vty +++ b/tests/vty/ss7_asp_test.vty @@ -225,6 +225,8 @@ ss7_asp_vty_test(config-cs7-asp)# list qos-class <0-255> role (sg|asp|ipsp) sctp-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) block shutdown ... @@ -237,10 +239,18 @@ ss7_asp_vty_test(config-cs7-asp)# ? qos-class Specify QoS Class of ASP role Specify the xUA role for this ASP sctp-role Specify the SCTP role for this ASP + sctp-param Configure SCTP parameters + no Negate a command or set its defaults block Allows a SCTP Association with ASP, but doesn't let it become active shutdown Terminates SCTP association; New associations will be rejected ... +ss7_asp_vty_test(config-cs7-asp)# no ? +... + sctp-param Configure SCTP parameters + quirk Disable quirk to work around interop issues +... + ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.200 ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.100 ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp