pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/43755?usp=email )
Change subject: vty: Implement '[no] shutdown' in 'listen' node ......................................................................
vty: Implement '[no] shutdown' in 'listen' node
Prior to this patch, there was no way to stop the listening socket and resume it without erasing it from configuration with "no listen" VTY command.
It is sometimes useful to pause it to avoid serving clients for a while for administrative purposes.
Related: OS#7039 Change-Id: I18bae91fdf5b820138bc54e6f4751c3d0b8eee28 --- M contrib/test/osmo-stp.cfg M doc/examples/osmo-stp-multihome.cfg M doc/examples/osmo-stp.cfg M src/sccp_instance.c M src/ss7_xua_srv.c M src/ss7_xua_srv.h M src/ss7_xua_srv_vty.c M tests/vty/osmo_stp_route_prio.vty M tests/vty/osmo_stp_test.vty M tests/vty/vty_test_runner.py 10 files changed, 119 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/55/43755/1
diff --git a/contrib/test/osmo-stp.cfg b/contrib/test/osmo-stp.cfg index 9003131..1ff5118 100644 --- a/contrib/test/osmo-stp.cfg +++ b/contrib/test/osmo-stp.cfg @@ -44,5 +44,7 @@ update route 0.3.0 0.3.0 linkset as-s-0 listen m3ua 2905 local-ip 172.18.0.200 + no shutdown listen sua 14001 local-ip 172.18.0.200 + no shutdown diff --git a/doc/examples/osmo-stp-multihome.cfg b/doc/examples/osmo-stp-multihome.cfg index 64874da..1d04cad 100644 --- a/doc/examples/osmo-stp-multihome.cfg +++ b/doc/examples/osmo-stp-multihome.cfg @@ -21,3 +21,4 @@ local-ip 127.0.0.2 local-ip 127.0.0.1 local-ip ::1 + no shutdown diff --git a/doc/examples/osmo-stp.cfg b/doc/examples/osmo-stp.cfg index 602a9ce..11c969e 100644 --- a/doc/examples/osmo-stp.cfg +++ b/doc/examples/osmo-stp.cfg @@ -15,3 +15,4 @@ xua rkm routing-key-allocation dynamic-permitted listen m3ua 2905 accept-asp-connections dynamic-permitted + no shutdown diff --git a/src/sccp_instance.c b/src/sccp_instance.c index d6937d6..fc7edaf 100644 --- a/src/sccp_instance.c +++ b/src/sccp_instance.c @@ -850,7 +850,7 @@ if (!xs) goto out_ss7;
- rc = ss7_xua_server_bind(xs); + rc = ss7_xua_server_restart(xs); if (rc < 0) goto out_xs;
diff --git a/src/ss7_xua_srv.c b/src/ss7_xua_srv.c index 1a4c8e5..c742016 100644 --- a/src/ss7_xua_srv.c +++ b/src/ss7_xua_srv.c @@ -331,7 +331,7 @@ * \param[in] xs xUA server to operate * \returns 0 on success, negative value on error. */ -int +static int ss7_xua_server_bind(struct osmo_xua_server *xs) { char buf[512]; @@ -340,9 +340,9 @@
rc = ss7_asp_peer_snprintf(buf, sizeof(buf), &xs->cfg.local); if (rc < 0) { - LOGPOXS(xs, DLSS7, LOGL_INFO, "Failed parsing %s Server osmo_ss7_asp_peer\n", proto); + LOGPOXS(xs, DLSS7, LOGL_ERROR, "Failed parsing %s Server osmo_ss7_asp_peer\n", proto); } else { - LOGPOXS(xs, DLSS7, LOGL_INFO, "(Re)binding %s Server to %s\n", + LOGPOXS(xs, DLSS7, LOGL_NOTICE, "(Re)binding %s Server to %s\n", proto, buf); }
@@ -420,6 +420,34 @@ return true; }
+int ss7_xua_server_restart(struct osmo_xua_server *oxs) +{ + int rc; + + if (oxs->cfg.adm_state.shutdown) { + if (osmo_stream_srv_link_is_opened(oxs->server)) { + LOGPOXS(oxs, DLSS7, LOGL_NOTICE, "Stop listening (Adm State 'shutdown')\n"); + osmo_stream_srv_link_close(oxs->server); + } + return 0; + } + + /* ss7_xua_server_bind() through osmo_stream_srv_link_open() takes care of + * closing and re-opening the old listening socket if needed: */ + rc = ss7_xua_server_bind(oxs); + return rc; +} + +/* Apply sane configs for unconfigured options and restart the xUA Server. */ +int ss7_xua_server_restart_after_reconfigure(struct osmo_xua_server *oxs) +{ + int rc; + /* If no local addr was set, or erased after _create(): */ + ss7_xua_server_set_default_local_hosts(oxs); + rc = ss7_xua_server_restart(oxs); + return rc; +} + void ss7_xua_server_destroy(struct osmo_xua_server *xs) { struct osmo_ss7_asp *asp, *asp2; diff --git a/src/ss7_xua_srv.h b/src/ss7_xua_srv.h index 58ff1e8..b3e5148 100644 --- a/src/ss7_xua_srv.h +++ b/src/ss7_xua_srv.h @@ -31,12 +31,23 @@ uint8_t ip_dscp; enum osmo_ss7_asp_protocol proto; struct { + /*! no listening transport (SCTP, TCP) socket */ + bool shutdown:1; + } adm_state; + struct { bool num_ostreams_present; bool max_instreams_present; uint16_t num_ostreams_value; uint16_t max_instreams_value; } sctp_init;
+ /* Used internally by "listen" VTY node to figure out if "no shutdown" + * was done explicitly, in order to avoid automatic xUA Server + * reconfiguring/restart at go_parent(). + * Can be dropped in the future once we make sure everybody uses + * "[no] shutdown" explicitly in cfg files. */ + bool explicit_shutdown_state_by_vty_since_node_enter; + /*! The underlaying transport protocol (one of IPPROTO_*) */ int trans_proto; } cfg; @@ -64,7 +75,9 @@ uint16_t local_port, const char *local_host);
int -ss7_xua_server_bind(struct osmo_xua_server *xs); +ss7_xua_server_restart(struct osmo_xua_server *oxs); +int +ss7_xua_server_restart_after_reconfigure(struct osmo_xua_server *oxs);
int ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host); diff --git a/src/ss7_xua_srv_vty.c b/src/ss7_xua_srv_vty.c index 37a9212..8e4ba48 100644 --- a/src/ss7_xua_srv_vty.c +++ b/src/ss7_xua_srv_vty.c @@ -84,6 +84,9 @@ ss7_xua_server_set_local_hosts(xs, NULL, 0); }
+ /* Reset value, will be checked at osmo_ss7_vty_go_parent() */ + xs->cfg.explicit_shutdown_state_by_vty_since_node_enter = false; + vty->node = L_CS7_XUA_NODE; vty->index = xs; return CMD_SUCCESS; @@ -274,6 +277,38 @@ return CMD_SUCCESS; }
+DEFUN_ATTR(xua_shutdown, xua_shutdown_cmd, + "shutdown", + "Terminates transport (SCTP, TCP) listening socket\n", + CMD_ATTR_NODE_EXIT) +{ + struct osmo_xua_server *oxs = vty->index; + + LOGPOXS(oxs, DLSS7, LOGL_NOTICE, "Applying Adm State change: '%sshutdown' -> 'shutdown'\n", + oxs->cfg.adm_state.shutdown ? "" : "no "); + + oxs->cfg.explicit_shutdown_state_by_vty_since_node_enter = true; + oxs->cfg.adm_state.shutdown = true; + ss7_xua_server_restart_after_reconfigure(oxs); + return CMD_SUCCESS; +} + +DEFUN_ATTR(xua_no_shutdown, xua_no_shutdown_cmd, + "no shutdown", + NO_STR "Terminates transport (SCTP, TCP) listening socket\n", + CMD_ATTR_NODE_EXIT) +{ + struct osmo_xua_server *oxs = vty->index; + + LOGPOXS(oxs, DLSS7, LOGL_NOTICE, "Applying Adm State change: '%sshutdown' -> 'no shutdown'\n", + oxs->cfg.adm_state.shutdown ? "" : "no "); + + oxs->cfg.explicit_shutdown_state_by_vty_since_node_enter = true; + oxs->cfg.adm_state.shutdown = false; + ss7_xua_server_restart_after_reconfigure(oxs); + return CMD_SUCCESS; +} + void ss7_vty_write_one_oxs(struct vty *vty, struct osmo_xua_server *xs) { int i; @@ -299,6 +334,8 @@ 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); + + vty_out(vty, " %sshutdown%s", xs->cfg.adm_state.shutdown ? "" : "no ", VTY_NEWLINE); }
static void vty_dump_xua_server(struct vty *vty, struct osmo_xua_server *xs) @@ -386,10 +423,29 @@ { struct osmo_xua_server *oxs = vty->index;
- /* If no local addr was set, or erased after _create(): */ - ss7_xua_server_set_default_local_hosts(oxs); - if (ss7_xua_server_bind(oxs) < 0) - vty_out(vty, "%% Unable to bind xUA server to IP(s)%s", VTY_NEWLINE); + if (oxs->cfg.explicit_shutdown_state_by_vty_since_node_enter) { + /* Interactive VTY, inform of new behavior upon use of new '[no] shutdown' commands: */ + if (vty->type != VTY_FILE) + vty_out(vty, "%% NOTE: Skipping automatic restart of VTY node 'listen' " + "since an explicit '[no] shutdown' command was entered%s", + VTY_NEWLINE); + oxs->cfg.explicit_shutdown_state_by_vty_since_node_enter = false; + } else if (vty->type == VTY_FILE) { + /* Make sure config reading is backward compatible by starting the xUA server if no explicit 'no shutdown' is read: */ + vty_out(vty, + "%% VTY node 'listen' without a '[no] shutdown' command at the end is deprecated, " + "please make sure you update your cfg file for future compatibility.%s", + VTY_NEWLINE); + if (ss7_xua_server_restart_after_reconfigure(oxs) < 0) + vty_out(vty, "%% Unable to bind xUA server to IP(s)%s", VTY_NEWLINE); + } else { + /* Interactive VTY without '[no] shutdown' explicit cmd, remind the user that we are no + * longer automatically restarting the xUA server when going out of the "asp" node: */ + vty_out(vty, + "%% NOTE: Make sure to use '[no] shutdown' command in 'listen' node " + "in order to restart the ASP for new configs to be applied.%s", + VTY_NEWLINE); + } vty->node = L_CS7_NODE; vty->index = oxs->inst;
@@ -416,4 +472,6 @@ 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); + install_lib_element(L_CS7_XUA_NODE, &xua_shutdown_cmd); + install_lib_element(L_CS7_XUA_NODE, &xua_no_shutdown_cmd); } diff --git a/tests/vty/osmo_stp_route_prio.vty b/tests/vty/osmo_stp_route_prio.vty index 6a4ac08..54c9475 100644 --- a/tests/vty/osmo_stp_route_prio.vty +++ b/tests/vty/osmo_stp_route_prio.vty @@ -71,6 +71,7 @@ local-ip 127.0.0.1 local-ip ::1 accept-asp-connections dynamic-permitted + no shutdown end
OsmoSTP(config-cs7)# route-table system diff --git a/tests/vty/osmo_stp_test.vty b/tests/vty/osmo_stp_test.vty index 167a1a0..fdcdc26 100644 --- a/tests/vty/osmo_stp_test.vty +++ b/tests/vty/osmo_stp_test.vty @@ -435,6 +435,8 @@ accept-asp-connections (pre-configured|dynamic-permitted) sctp-param init (num-ostreams|max-instreams) <0-65535> no sctp-param init (num-ostreams|max-instreams) + shutdown + no shutdown ...
OsmoSTP(config-cs7-listen)# ? @@ -454,6 +456,7 @@ ...
OsmoSTP(config-cs7-listen)# exit +% NOTE: Make sure to use '[no] shutdown' command in 'listen' node in order to restart the ASP for new configs to be applied. OsmoSTP(config-cs7)# as my-ass m3ua OsmoSTP(config-cs7-as)# list ... @@ -711,6 +714,7 @@ local-ip 127.0.0.1 local-ip ::1 accept-asp-connections dynamic-permitted + no shutdown sccp-address foo routing-indicator PC point-code 1.2.3 diff --git a/tests/vty/vty_test_runner.py b/tests/vty/vty_test_runner.py index bad989e..3f25439 100755 --- a/tests/vty/vty_test_runner.py +++ b/tests/vty/vty_test_runner.py @@ -257,7 +257,8 @@ self.assertTrue(self.vty.verify("qos-class 5",[''])) else: self.assertTrue(self.vty.verify("init-ip-dscp 23",["% 'init-ip-dscp' command is deprecated, use 'qos-class' instead"])) - self.assertTrue(self.vty.verify("exit",[''])) + self.assertTrue(self.vty.verify("no shutdown",[''])) + self.assertTrue(self.vty.verify("exit",["% NOTE: Skipping automatic restart of VTY node 'listen' since an explicit '[no] shutdown' command was entered"])) self.assertTrue(self.vty.verify("asp asp-srv-m3ua 2906 2905 m3ua",[''])) self.assertTrue(self.vty.verify("local-ip 127.0.0.1",[''])) self.assertTrue(self.vty.verify("remote-ip 127.0.0.2",['']))