aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-11-05 14:54:56 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-04-16 09:17:21 +0200
commitc327187259d74cf260c977f165963778de4bedb1 (patch)
tree1072aaa6f04f075261636f964e1ecb314a402fee /openbsc
parent77956aa034a7ac5ddfdf91c7341d3bf82cb07367 (diff)
nat: Make it possible to send MGCP messages through the IPA multiplex
Instead of handling MGCP through the UDP socket, read and write messages through the ipa connection to the MSC.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/bsc_nat.h4
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c82
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat.c11
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_vty.c17
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c6
5 files changed, 105 insertions, 15 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 1698fa47f..4baaa8280 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -270,6 +270,7 @@ struct bsc_nat {
struct mgcp_config *mgcp_cfg;
uint8_t mgcp_msg[4096];
int mgcp_length;
+ int mgcp_ipa;
/* msc things */
struct llist_head dests;
@@ -463,6 +464,9 @@ struct bsc_nat_barr_entry {
int bsc_nat_barr_adapt(void *ctx, struct rb_root *rbtree, const struct osmo_config_list *);
int bsc_nat_barr_find(struct rb_root *root, const char *imsi, int *cm, int *lu);
+void bsc_nat_send_mgcp_to_msc(struct bsc_nat *bsc_nat, struct msgb *msg);
+void bsc_nat_handle_mgcp(struct bsc_nat *bsc, struct msgb *msg);
+
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port);
void bsc_nat_ctrl_del_pending(struct bsc_cmd_list *pending);
int bsc_nat_handle_ctrlif_msg(struct bsc_connection *bsc, struct msgb *msg);
diff --git a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
index 1436ebd35..480a8f6d1 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
@@ -62,7 +62,7 @@
#include <errno.h>
#include <unistd.h>
-static void mgcp_queue_for_call_agent(struct bsc_nat *nat, struct msgb *output)
+static void send_direct(struct bsc_nat *nat, struct msgb *output)
{
if (osmo_wqueue_enqueue(&nat->mgcp_cfg->gw_fd, output) != 0) {
LOGP(DMGCP, LOGL_ERROR, "Failed to queue MGCP msg.\n");
@@ -70,6 +70,14 @@ static void mgcp_queue_for_call_agent(struct bsc_nat *nat, struct msgb *output)
}
}
+static void mgcp_queue_for_call_agent(struct bsc_nat *nat, struct msgb *output)
+{
+ if (nat->mgcp_ipa)
+ bsc_nat_send_mgcp_to_msc(nat, output);
+ else
+ send_direct(nat, output);
+}
+
int bsc_mgcp_nr_multiplexes(int max_endpoints)
{
int div = max_endpoints / 32;
@@ -656,6 +664,38 @@ copy:
return output;
}
+/*
+ * This comes from the MSC and we will now parse it. The caller needs
+ * to free the msgb.
+ */
+void bsc_nat_handle_mgcp(struct bsc_nat *nat, struct msgb *msg)
+{
+ struct msgb *resp;
+
+ if (!nat->mgcp_ipa) {
+ LOGP(DMGCP, LOGL_ERROR, "MGCP message not allowed on IPA.\n");
+ return;
+ }
+
+ if (msgb_l2len(msg) > sizeof(nat->mgcp_msg) - 1) {
+ LOGP(DMGCP, LOGL_ERROR, "MGCP msg too big for handling.\n");
+ return;
+ }
+
+ memcpy(nat->mgcp_msg, msg->l2h, msgb_l2len(msg));
+ nat->mgcp_length = msgb_l2len(msg);
+ nat->mgcp_msg[nat->mgcp_length] = '\0';
+
+ /* now handle the message */
+ resp = mgcp_handle_message(nat->mgcp_cfg, msg);
+
+ /* we do have a direct answer... e.g. AUEP */
+ if (resp)
+ mgcp_queue_for_call_agent(nat, resp);
+
+ return;
+}
+
static int mgcp_do_read(struct osmo_fd *fd)
{
struct bsc_nat *nat;
@@ -705,21 +745,10 @@ static int mgcp_do_write(struct osmo_fd *bfd, struct msgb *msg)
return rc;
}
-int bsc_mgcp_nat_init(struct bsc_nat *nat)
+static int init_mgcp_socket(struct bsc_nat *nat, struct mgcp_config *cfg)
{
- int on;
struct sockaddr_in addr;
- struct mgcp_config *cfg = nat->mgcp_cfg;
-
- if (!cfg->call_agent_addr) {
- LOGP(DMGCP, LOGL_ERROR, "The BSC nat requires the call agent ip to be set.\n");
- return -1;
- }
-
- if (cfg->bts_ip) {
- LOGP(DMGCP, LOGL_ERROR, "Do not set the BTS ip for the nat.\n");
- return -1;
- }
+ int on;
cfg->gw_fd.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
if (cfg->gw_fd.bfd.fd < 0) {
@@ -765,6 +794,31 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat)
return -1;
}
+ return 0;
+}
+
+int bsc_mgcp_nat_init(struct bsc_nat *nat)
+{
+ struct mgcp_config *cfg = nat->mgcp_cfg;
+
+ if (!cfg->call_agent_addr) {
+ LOGP(DMGCP, LOGL_ERROR, "The BSC nat requires the call agent ip to be set.\n");
+ return -1;
+ }
+
+ if (cfg->bts_ip) {
+ LOGP(DMGCP, LOGL_ERROR, "Do not set the BTS ip for the nat.\n");
+ return -1;
+ }
+
+ /* initialize the MGCP socket */
+ if (!nat->mgcp_ipa) {
+ int rc = init_mgcp_socket(nat, cfg);
+ if (rc != 0)
+ return rc;
+ }
+
+
/* some more MGCP config handling */
cfg->data = nat;
cfg->policy_cb = bsc_mgcp_policy_cb;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index 792d33c23..e70f54952 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -333,6 +333,12 @@ static void send_mgcp_reset(struct bsc_connection *bsc)
bsc_write_mgcp(bsc, mgcp_reset, sizeof mgcp_reset - 1);
}
+void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
+{
+ ipaccess_prepend_header(msg, IPAC_PROTO_MGCP_OLD);
+ queue_for_msc(nat->msc_con, msg);
+}
+
/*
* Below is the handling of messages coming
* from the MSC and need to be forwarded to
@@ -820,8 +826,11 @@ static int ipaccess_msc_read_cb(struct osmo_fd *bfd)
initialize_msc_if_needed(msc_con);
else if (msg->l2h[0] == IPAC_MSGT_ID_GET)
send_id_get_response(msc_con);
- } else if (hh->proto == IPAC_PROTO_SCCP)
+ } else if (hh->proto == IPAC_PROTO_SCCP) {
forward_sccp_to_bts(msc_con, msg);
+ } else if (hh->proto == IPAC_PROTO_MGCP_OLD) {
+ bsc_nat_handle_mgcp(nat, msg);
+ }
msgb_free(msg);
return 0;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
index 7bbc89059..32e5106ae 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -143,6 +143,8 @@ static int config_write_nat(struct vty *vty)
write_acc_lst(vty, lst);
llist_for_each_entry(pgroup, &_nat->paging_groups, entry)
write_pgroup_lst(vty, pgroup);
+ if (_nat->mgcp_ipa)
+ vty_out(vty, " mgcp-through-msc-ipa%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -657,6 +659,20 @@ DEFUN(cfg_nat_ussd_local,
return CMD_SUCCESS;
}
+DEFUN(cfg_nat_mgcp_ipa,
+ cfg_nat_mgcp_ipa_cmd,
+ "mgcp-through-msc-ipa",
+ "This needs to be set at start. Handle MGCP messages through "
+ "the IPA protocol and not through the UDP socket.\n")
+{
+ if (_nat->mgcp_cfg->data)
+ vty_out(vty,
+ "%%the setting will not be applied right now.%s",
+ VTY_NEWLINE);
+ _nat->mgcp_ipa = 1;
+ return CMD_SUCCESS;
+}
+
/* per BSC configuration */
DEFUN(cfg_bsc, cfg_bsc_cmd, "bsc BSC_NR",
"BSC configuration\n" "Identifier of the BSC\n")
@@ -1086,6 +1102,7 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_element(NAT_NODE, &cfg_nat_ussd_query_cmd);
install_element(NAT_NODE, &cfg_nat_ussd_token_cmd);
install_element(NAT_NODE, &cfg_nat_ussd_local_cmd);
+ install_element(NAT_NODE, &cfg_nat_mgcp_ipa_cmd);
/* access-list */
install_element(NAT_NODE, &cfg_lst_imsi_allow_cmd);
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 66b4ff5a7..3b5c24e36 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -1242,3 +1242,9 @@ int main(int argc, char **argv)
printf("Testing execution completed.\n");
return 0;
}
+
+/* stub */
+void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
+{
+ abort();
+}