aboutsummaryrefslogtreecommitdiffstats
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
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.
-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();
+}