pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/34511?usp=email )
Change subject: sccplite: Support multiple MGW in MGW pool ...................................................................... sccplite: Support multiple MGW in MGW pool Before this patch, the MGW was selected at startup, and the MGCP data was always forwarded to that same MGW. If several MGW were configured in the MGW pool, then osmo-bsc would select any of those from the pool, and start configured the BTS-side connection on an endpoint in that MGW. However, when the MSC submitted the MGCP encapsulated in IPA to the BSC, the BSC would always forward the MGCP message to that same MGW selected at startup. As a result, multiple MGWs configured with osmo-bsc using SCCPlite was broken. This commit fixes support for multiple MGWs by looking up the already selected MGW (to setup the BTS-side conn on the endpoint), based on the CIC (MGCP Endpoint) which was provided by the MSC upon AssignReq. Related: OS#6189 Depends: libosmocore.git Change-Id Iee361d740845257fa62c9093e30e8079fa933827 Depends: osmo-mgw.git Change-Id I18d7bdf650c0ec87ae16ed4944aed9f495400137 Change-Id: Ia106a21b7692eb5b2ac3b5ac2b358bedbc3b9da6 --- M TODO-RELEASE M src/osmo-bsc/osmo_bsc_mgcp.c M src/osmo-bsc/osmo_bsc_msc.c 3 files changed, 144 insertions(+), 19 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/11/34511/1 diff --git a/TODO-RELEASE b/TODO-RELEASE index d0852fc..7a7ec22 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 +libosmocore > 1.9.0 working (compiling) OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL diff --git a/src/osmo-bsc/osmo_bsc_mgcp.c b/src/osmo-bsc/osmo_bsc_mgcp.c index 1b8e089..de11f44 100644 --- a/src/osmo-bsc/osmo_bsc_mgcp.c +++ b/src/osmo-bsc/osmo_bsc_mgcp.c @@ -2,6 +2,7 @@ * SCCPlite MGCP handling * * (C) 2018 by Harald Welte <lafo...@gnumonks.org> + * (C) 2023 by sysmocom s.f.m.c. GmbH <i...@sysmocom.de> * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -19,6 +20,15 @@ * */ +#include <string.h> + +#include <osmocom/core/utils.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/socket.h> +#include <osmocom/core/sockaddr_str.h> +#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> +#include <osmocom/mgcp_client/mgcp_client.h> + #include <osmocom/bsc/bsc_msc_data.h> #include <osmocom/bsc/osmo_bsc.h> #include <osmocom/bsc/gsm_data.h> @@ -46,22 +56,121 @@ return osmo_msc_data_find(bsc_gsmnet, msc_nr); } +/* negative on error, filled buf size upon success */ +static int parse_local_endpoint_name(char *buf, size_t buf_len, const char *data) +{ + char line[1024]; + char *epstart, *sep; + const char *start = data; + char *eol = strpbrk(start, "\r\n"); + if (!eol) + return -1; + + if (eol - start > sizeof(line)) + return -1; + memcpy(line, start, eol - start); + line[eol - start] = '\0'; + + if (!(epstart = strchr(line, ' '))) + return -1; + epstart++; + /* epstart now points to trans */ + + if (!(epstart = strchr(epstart, ' '))) + return -1; + epstart++; + /* epstart now points to endpoint */ + if (!(sep = strchr(epstart, '@'))) + return -1; + if (sep - epstart >= buf_len) + return -1; + + *sep = '\0'; + osmo_strlcpy(buf, epstart, buf_len); + return 0; +} + /* We received an IPA-encapsulated MGCP message from a MSC. Transfers msg ownership. */ int bsc_sccplite_rx_mgcp(struct osmo_ss7_asp *asp, struct msgb *msg) { struct bsc_msc_data *msc; + struct gsm_subscriber_connection *conn; + char rcv_ep_local_name[1024]; + struct osmo_sockaddr_str osa_str = {}; + struct osmo_sockaddr osa = {}; + socklen_t dest_len; + struct mgcp_client *mgcp_cli = NULL; int rc; LOGP(DMSC, LOGL_NOTICE, "%s: Received IPA-encapsulated MGCP: %s\n", osmo_ss7_asp_get_name(asp), msg->l2h); - msc = msc_from_asp(asp); - if (msc) { - /* we don't have a write queue here as we simply expect the socket buffers - * to be large enough to deal with whatever small/infrequent MGCP messages */ - rc = send(msc->mgcp_ipa.ofd.fd, msgb_l2(msg), msgb_l2len(msg), 0); - } else - rc = 0; + msc = msc_from_asp(asp); + if (!msc) { + rc = 0; + goto free_msg_ret; + } + + rc = parse_local_endpoint_name(rcv_ep_local_name, sizeof(rcv_ep_local_name), (const char *)msg->l2h); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "(%s:) Received IPA-encapsulated MGCP: Failed to parse CIC\n", + osmo_ss7_asp_get_name(asp)); + goto free_msg_ret; + } + + /* Lookup which conn attached to the MSC holds an MGW endpoint the same + * Endpoint Number as the one provided in the MGCP msg we received from + * MSC. Sine CIC are unique per MSC, that's the same MGW in the pool + * where we have to forward the MGCP message. */ + llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { + const char *ep_local_name; + if (conn->sccp.msc != msc) + continue; /* Only conns belonging to this MSC */ + if (!conn->user_plane.mgw_endpoint) + continue; + ep_local_name = osmo_mgcpc_ep_local_name(conn->user_plane.mgw_endpoint); + LOGPFSMSL(conn->fi, DMSC, LOGL_NOTICE, "ep_local_name='%s' vs rcv_ep_local_name='%s'\n", ep_local_name, rcv_ep_local_name); + if (!ep_local_name) + continue; + if (strcmp(ep_local_name, rcv_ep_local_name) != 0) + continue; + mgcp_cli = osmo_mgcpc_ep_client(conn->user_plane.mgw_endpoint); + if (!mgcp_cli) + continue; + break; + } + + if (!mgcp_cli) { + LOGP(DMSC, LOGL_ERROR, "(%s:) Received IPA-encapsulated MGCP: Failed to find associated MGW\n", + osmo_ss7_asp_get_name(asp)); + rc = 0; + goto free_msg_ret; + } + + rc = osmo_sockaddr_str_from_str(&osa_str, mgcp_client_remote_addr_str(mgcp_cli), + mgcp_client_remote_port(mgcp_cli)); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "(%s:) Received IPA-encapsulated MGCP: Failed to parse MGCP address %s:%u\n", + osmo_ss7_asp_get_name(asp), mgcp_client_remote_addr_str(mgcp_cli), mgcp_client_remote_port(mgcp_cli)); + goto free_msg_ret; + } + + LOGP(DMSC, LOGL_NOTICE, "%s: Forwarding IPA-encapsulated MGCP to MGW at " OSMO_SOCKADDR_STR_FMT "\n", + osmo_ss7_asp_get_name(asp), OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL(&osa_str)); + + rc = osmo_sockaddr_str_to_sockaddr(&osa_str, &osa.u.sas); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "(%s:) Received IPA-encapsulated MGCP: Failed to parse MGCP address " OSMO_SOCKADDR_STR_FMT "\n", + osmo_ss7_asp_get_name(asp), OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL(&osa_str)); + goto free_msg_ret; + } + dest_len = osmo_sockaddr_size(&osa); + + /* we don't have a write queue here as we simply expect the socket buffers + * to be large enough to deal with whatever small/infrequent MGCP messages */ + rc = sendto(msc->mgcp_ipa.ofd.fd, msgb_l2(msg), msgb_l2len(msg), 0, &osa.u.sa, dest_len); + +free_msg_ret: msgb_free(msg); return rc; } diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c index dfba2de..2425592 100644 --- a/src/osmo-bsc/osmo_bsc_msc.c +++ b/src/osmo-bsc/osmo_bsc_msc.c @@ -376,26 +376,15 @@ int osmo_bsc_msc_init(struct bsc_msc_data *msc) { - struct gsm_network *net = msc->network; - struct mgcp_client *mgcp_cli; int rc; /* Everything below refers to SCCP-Lite MSC connections only. */ if (msc_is_aoip(msc)) return 0; - /* Note: MGW is preselected here at startup, which means currently - * osmo-bsc configured for SCCPLite doesn't support MGW pools with more - * than 1 MGW. - */ - mgcp_cli = mgcp_client_pool_get(net->mgw.mgw_pool); - OSMO_ASSERT(mgcp_cli); rc = osmo_sock_init2_ofd(&msc->mgcp_ipa.ofd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, msc->mgcp_ipa.local_addr, msc->mgcp_ipa.local_port, - mgcp_client_remote_addr_str(mgcp_cli), - mgcp_client_remote_port(mgcp_cli), - OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT); - mgcp_client_pool_put(mgcp_cli); + NULL, 0, OSMO_SOCK_F_BIND); if (rc < 0) { LOGP(DMSC, LOGL_ERROR, "msc %u: Could not create/connect/bind MGCP proxy socket: %d\n", msc->nr, rc); -- To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/34511?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bsc Gerrit-Branch: master Gerrit-Change-Id: Ia106a21b7692eb5b2ac3b5ac2b358bedbc3b9da6 Gerrit-Change-Number: 34511 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-MessageType: newchange