pespin has submitted this change. (
https://gerrit.osmocom.org/c/osmo-msc/+/29782 )
Change subject: Introduce support for libosmo-mgcp-client MGW pooling
......................................................................
Introduce support for libosmo-mgcp-client MGW pooling
Large RAN installations may benefit from distributing the RTP voice
stream load over multiple media gateways.
libosmo-mgcp-client supports MGW pooling since version 1.8.0 (more than
one year ago). OsmoBSC has already been making use of it since then (see
osmo-bsc.git 8d22e6870637ed6d392a8a77aeaebc51b23a8a50); lets use this
feature in osmo-msc too.
This commit is also part of a series of patches cleaning up
libosmo-mgcp-client and slowly getting rid of the old non-mgw-pooled VTY
configuration, in order to keep only 1 way to configure
libosmo-mgcp-client through VTY.
Related: SYS#5091
Related: SYS#5987
Change-Id: I7670ba56fe989706579224a364595fdd4b4708ff
---
M doc/examples/osmo-msc/osmo-msc.cfg
M doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
M doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
M doc/manuals/chapters/running.adoc
M include/osmocom/msc/gsm_data.h
M include/osmocom/msc/vty.h
M src/libmsc/call_leg.c
M src/libmsc/msc_vty.c
M src/osmo-msc/msc_main.c
M tests/msc_vlr/msc_vlr_tests.c
M tests/test_nodes.vty
11 files changed, 97 insertions(+), 26 deletions(-)
Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, but someone else must approve
osmith: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
diff --git a/doc/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg
index 83b2c6f..2b0d98d 100644
--- a/doc/examples/osmo-msc/osmo-msc.cfg
+++ b/doc/examples/osmo-msc/osmo-msc.cfg
@@ -12,10 +12,11 @@
encryption a5 0
rrlp mode none
mm info 1
+ mgw 0
+ mgw remote-ip 127.0.0.1
+ mgw remote-port 2427
+ mgw local-port 2728
msc
- mgw remote-ip 127.0.0.1
- mgw remote-port 2427
- mgw local-port 2728
assign-tmsi
auth-tuple-max-reuse-count 3
auth-tuple-reuse-on-error 1
diff --git a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
index d949ef9..d014edd 100644
--- a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
+++ b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
@@ -12,6 +12,10 @@
encryption a5 0
rrlp mode none
mm info 1
+ mgw 0
+ mgw remote-ip 127.0.0.1
+ mgw remote-port 2427
+ mgw local-port 2728
cs7 instance 0
point-code 0.23.1
asp asp-clnt-OsmoMSC-A-Iu 2905 0 m3ua
@@ -21,7 +25,4 @@
msc
cs7-instance-a 0
cs7-instance-iu 0
- mgw remote-ip 127.0.0.1
- mgw remote-port 2427
- mgw local-port 2728
assign-tmsi
diff --git a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
index cb1157d..62c9270 100644
--- a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
+++ b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
@@ -12,6 +12,10 @@
encryption a5 0
rrlp mode none
mm info 1
+ mgw 0
+ mgw remote-ip 127.0.0.1
+ mgw remote-port 2427
+ mgw local-port 2728
cs7 instance 0
point-code 0.23.1
asp asp-clnt-OsmoMSC-A 2905 0 m3ua
@@ -23,7 +27,4 @@
msc
cs7-instance-a 0
cs7-instance-iu 1
- mgw remote-ip 127.0.0.1
- mgw remote-port 2427
- mgw local-port 2728
assign-tmsi
diff --git a/doc/manuals/chapters/running.adoc b/doc/manuals/chapters/running.adoc
index 8665395..4556e01 100644
--- a/doc/manuals/chapters/running.adoc
+++ b/doc/manuals/chapters/running.adoc
@@ -149,11 +149,23 @@
Here is an example configuration for a remote MGW:
----
-msc
- mgw remote-ip 10.9.8.7
- mgw remote-port 2427
- mgw reset-endpoint rtpbridge/* <1>
+network
+ mgw 0
+ mgw remote-ip 10.9.8.7
+ mgw remote-port 2427
+ mgw reset-endpoint rtpbridge/* <1>
----
<1> The 'reset-endpoint' setting instructs the OsmoMGW to send a
wildcarded
DLCX to the media gateway. This helps to clear lingering calls from the
media gateway when the OsmoMSC is restarted.
+
+[NOTE]
+====
+Previous versions of OsmoMSC (1.9.0 and below) didn't have the 'mgw' VTY node
and
+hence didn't support the MGW pooling feature. Therefore, historically the MGW
+related commands where placed under the `msc` VTY node. The MGW related commands
+under the `msc` VTY are still parsed and used but its use is deprecated and
+hence discouraged in favour of the new `mgw` node. Writing the config to a file
+from within OsmoMSC will automatically convert the config to use the new `mgw`
+node.
+====
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index 43944e7..1cf6820 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -16,6 +16,7 @@
#include <osmocom/crypt/utran_cipher.h>
#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/mgcp_client/mgcp_client_pool.h>
#include <osmocom/msc/msc_common.h>
#include <osmocom/msc/neighbor_ident.h>
@@ -216,7 +217,9 @@
struct {
struct osmo_tdef *tdefs;
struct mgcp_client_conf conf;
- struct mgcp_client *client;
+ /* MGW pool, also includes the single MGCP client as fallback if no
+ * pool is configured. */
+ struct mgcp_client_pool *mgw_pool;
} mgw;
struct {
diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h
index 1e13846..11d9ed1 100644
--- a/include/osmocom/msc/vty.h
+++ b/include/osmocom/msc/vty.h
@@ -17,6 +17,7 @@
enum bsc_vty_node {
GSMNET_NODE = _LAST_OSMOVTY_NODE + 1,
+ MGW_NODE,
SUBSCR_NODE,
MSC_NODE,
MNCC_INT_NODE,
diff --git a/src/libmsc/call_leg.c b/src/libmsc/call_leg.c
index e890f75..f8a75c4 100644
--- a/src/libmsc/call_leg.c
+++ b/src/libmsc/call_leg.c
@@ -122,7 +122,13 @@
static void call_leg_mgw_endpoint_gone(struct call_leg *cl)
{
+ struct mgcp_client *mgcp_client;
int i;
+
+ /* Put MGCP client back into MGW pool */
+ mgcp_client = osmo_mgcpc_ep_client(cl->mgw_endpoint);
+ mgcp_client_pool_put(mgcp_client);
+
cl->mgw_endpoint = NULL;
for (i = 0; i < ARRAY_SIZE(cl->rtp); i++) {
if (!cl->rtp[i])
@@ -275,10 +281,17 @@
if (cl->rtp[dir])
return 0;
- if (!cl->mgw_endpoint)
+ if (!cl->mgw_endpoint) {
+ struct mgcp_client *mgcp_client = mgcp_client_pool_get(gsmnet->mgw.mgw_pool);
+ if (!mgcp_client) {
+ LOG_CALL_LEG(cl, LOGL_ERROR,
+ "cannot ensure MGW endpoint -- no MGW configured, check
configuration!\n");
+ return -ENODEV;
+ }
cl->mgw_endpoint = osmo_mgcpc_ep_alloc(cl->fi, CALL_LEG_EV_MGW_ENDPOINT_GONE,
- gsmnet->mgw.client, gsmnet->mgw.tdefs, cl->fi->id,
- "%s", mgcp_client_rtpbridge_wildcard(gsmnet->mgw.client));
+ mgcp_client, gsmnet->mgw.tdefs, cl->fi->id,
+ "%s", mgcp_client_rtpbridge_wildcard(mgcp_client));
+ }
if (!cl->mgw_endpoint) {
LOG_CALL_LEG(cl, LOGL_ERROR, "failed to setup MGW endpoint\n");
return -EIO;
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index be05a95..357b975 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -2033,6 +2033,8 @@
install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
install_element(GSMNET_NODE, &cfg_net_call_wait_cmd);
install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd);
+ mgcp_client_pool_vty_init(GSMNET_NODE, MGW_NODE, " ",
msc_network->mgw.mgw_pool);
+
install_element(CONFIG_NODE, &cfg_msc_cmd);
install_node(&msc_node, config_write_msc);
@@ -2066,7 +2068,9 @@
/* Timer configuration commands (generic osmo_tdef API) */
osmo_tdef_vty_groups_init(MSC_NODE, msc_tdef_group);
+ /* Deprecated: Old MGCP config without pooling support in MSC node: */
mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
+
#ifdef BUILD_IU
ranap_iu_vty_init(MSC_NODE, (enum
ranap_nsap_addr_enc*)&msc_network->iu.rab_assign_addr_enc);
#endif
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index 9cc4120..c6514c2 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -256,6 +256,7 @@
MSC_HLR_REMOTE_IP_DEFAULT);
net->gsup_server_port = MSC_HLR_REMOTE_PORT_DEFAULT;
+ net->mgw.mgw_pool = mgcp_client_pool_alloc(net);
mgcp_client_conf_init(&net->mgw.conf);
net->call_waiting = true;
net->lcls_permitted = false;
@@ -546,6 +547,41 @@
extern void *tall_call_ctx;
extern void *tall_trans_ctx;
+static int msc_mgw_setup(void)
+{
+ struct mgcp_client *mgcp_client_single;
+ unsigned int pool_members_initalized;
+
+ /* Initialize MGW pool. This initalizes and connects all MGCP clients that are currently
configured in
+ * the pool. Adding additional MGCP clients to the pool is possible but the user has to
configure and
+ * (re)connect them manually from the VTY. */
+ pool_members_initalized = mgcp_client_pool_connect(msc_network->mgw.mgw_pool);
+ if (pool_members_initalized) {
+ LOGP(DMSC, LOGL_NOTICE,
+ "MGW pool with %u pool members configured, (ignoring MGW configuration in VTY
node 'msc').\n",
+ pool_members_initalized);
+ return 0;
+ }
+
+ /* Initialize and connect a single MGCP client. This MGCP client will appear as the one
and only pool
+ * member if there is no MGW pool configured. */
+ LOGP(DMSC, LOGL_NOTICE, "No MGW pool configured, using MGW configuration in VTY
node 'msc'\n");
+ mgcp_client_single = mgcp_client_init(msc_network, &msc_network->mgw.conf);
+ if (!mgcp_client_single) {
+ LOGP(DMSC, LOGL_ERROR, "MGW (single) client initalization failed\n");
+ return -EINVAL;
+ }
+ if (mgcp_client_connect(mgcp_client_single)) {
+ LOGP(DMSC, LOGL_ERROR, "MGW (single) connect failed at (%s:%u)\n",
+ msc_network->mgw.conf.remote_addr,
+ msc_network->mgw.conf.remote_port);
+ return -EINVAL;
+ }
+ mgcp_client_pool_register_single(msc_network->mgw.mgw_pool, mgcp_client_single);
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
int rc;
@@ -705,13 +741,8 @@
if (sms_queue_start(msc_network) != 0)
return -1;
- msc_network->mgw.client = mgcp_client_init(
- msc_network, &msc_network->mgw.conf);
-
- if (mgcp_client_connect(msc_network->mgw.client)) {
- fprintf(stderr, "MGCPGW connect failed\n");
+ if (msc_mgw_setup() != 0)
return 7;
- }
if (ss7_setup(tall_msc_ctx, &sccp_a, &sccp_iu)) {
fprintf(stderr, "Setting up SCCP client failed.\n");
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index 378f84a..3ef94f2 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -1136,6 +1136,7 @@
struct gsm_network *test_net(void *ctx)
{
struct gsm_network *net = gsm_network_init(ctx, mncc_recv);
+ struct mgcp_client *client;
net->gsup_server_addr_str = talloc_strdup(net, "no_gsup_server");
net->gsup_server_port = 0;
@@ -1172,8 +1173,9 @@
net->mgw.tdefs = g_mgw_tdefs;
mgcp_client_conf_init(&net->mgw.conf);
net->mgw.tdefs = g_mgw_tdefs;
- net->mgw.client = mgcp_client_init(net, &net->mgw.conf);
-
+ net->mgw.mgw_pool = mgcp_client_pool_alloc(net);
+ client = mgcp_client_init(net, &net->mgw.conf);
+ mgcp_client_pool_register_single(net->mgw.mgw_pool, client);
return net;
}
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index 0c9e360..400bc7d 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -27,6 +27,8 @@
no timezone
call-waiting
no call-waiting
+ mgw <0-255>
+ no mgw <0-255>
OsmoMSC(config-net)# encryption?
encryption Encryption options
@@ -152,6 +154,7 @@
authentication optional
rrlp mode none
mm info 1
+...
msc
mncc guard-timeout 180
ncss guard-timeout 30
@@ -160,7 +163,6 @@
...
auth-tuple-max-reuse-count 3
auth-tuple-reuse-on-error 1
-...
mncc-int
default-codec tch-f fr
default-codec tch-h hr
--
To view, visit
https://gerrit.osmocom.org/c/osmo-msc/+/29782
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Change-Id: I7670ba56fe989706579224a364595fdd4b4708ff
Gerrit-Change-Number: 29782
Gerrit-PatchSet: 11
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged