pespin has uploaded this change for review. ( 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
Change-Id: I7670ba56fe989706579224a364595fdd4b4708ff --- 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 6 files changed, 61 insertions(+), 12 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/82/29782/1
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..5fd8bec 100644 --- a/include/osmocom/msc/vty.h +++ b/include/osmocom/msc/vty.h @@ -25,6 +25,7 @@ HLR_NODE, CFG_SGS_NODE, SMSC_NODE, + MGW_NODE, };
int bsc_vty_init_extra(void); diff --git a/src/libmsc/call_leg.c b/src/libmsc/call_leg.c index e890f75..3408d36 100644 --- a/src/libmsc/call_leg.c +++ b/src/libmsc/call_leg.c @@ -17,6 +17,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ +#include <asm-generic/errno-base.h> #include <osmocom/core/fsm.h> #include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
@@ -275,10 +276,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..16d9d07 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; + + /* Initalize 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; }