aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorDaniel Willmann <dwillmann@sysmocom.de>2017-12-21 12:37:35 +0100
committerDaniel Willmann <dwillmann@sysmocom.de>2018-01-30 18:59:28 +0100
commit120a01a33ae41d090f7f50f990c742bf445329c5 (patch)
tree66b9367090c1ade91855d49ac34fb1e4f5c5739b /openbsc
parent8aef4862af7787ec363c348be28437c8dbf25c71 (diff)
osmo-bsc_nat: Implement MSC-side nat of SCCP connection
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/bsc_nat_sccp.h1
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c8
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat.c6
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_vty.c3
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_sccp.c29
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_ussd.c5
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c6
7 files changed, 42 insertions, 16 deletions
diff --git a/openbsc/include/openbsc/bsc_nat_sccp.h b/openbsc/include/openbsc/bsc_nat_sccp.h
index 8d7e52b8c..c16108e4c 100644
--- a/openbsc/include/openbsc/bsc_nat_sccp.h
+++ b/openbsc/include/openbsc/bsc_nat_sccp.h
@@ -79,6 +79,7 @@ struct nat_sccp_connection {
struct sccp_source_reference bsc_patched_ref; /* local ref of the nat to MSC */
struct sccp_source_reference msc_real_ref; /* local ref of the MSC to nat */
+ struct sccp_source_reference msc_patched_ref; /* local ref of the nat to BSC */
int has_msc_ref;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
index 81bdf4686..1229d5750 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_mgcp_utils.c
@@ -217,8 +217,8 @@ int bsc_mgcp_assign_patch(struct nat_sccp_connection *con, struct msgb *msg)
LOGP(DNAT, LOGL_ERROR,
"Endpoint %d was assigned to 0x%x and now 0x%x\n",
endp,
- sccp_src_ref_to_int(&mcon->patched_ref),
- sccp_src_ref_to_int(&con->patched_ref));
+ sccp_src_ref_to_int(&mcon->bsc_patched_ref),
+ sccp_src_ref_to_int(&con->bsc_patched_ref));
bsc_mgcp_dlcx(mcon);
}
}
@@ -338,8 +338,8 @@ static void remember_pending_dlcx(struct nat_sccp_connection *con, uint32_t tran
/* take the endpoint here */
endp = &con->mgcp_conf->trunk.endpoints[con->msc_endp];
- stats->remote_ref = con->remote_ref;
- stats->src_ref = con->patched_ref;
+ stats->remote_ref = con->msc_real_ref;
+ stats->src_ref = con->bsc_patched_ref;
stats->ci = endp->ci;
stats->bts_rtp_port = endp->bts_end.rtp_port;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index 8bce839be..d153d6183 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -298,7 +298,7 @@ static void nat_send_rlsd_bsc(struct nat_sccp_connection *conn)
rel->type = SCCP_MSG_TYPE_RLSD;
rel->release_cause = SCCP_RELEASE_CAUSE_SCCP_FAILURE;
rel->destination_local_reference = conn->bsc_real_ref;
- rel->source_local_reference = conn->msc_real_ref;
+ rel->source_local_reference = conn->msc_patched_ref;
bsc_write(conn->bsc, msg, IPAC_PROTO_SCCP);
}
@@ -502,7 +502,7 @@ static void bsc_send_con_release(struct bsc_connection *bsc,
nat_send_clrc_bsc(con);
- rlsd = sccp_create_rlsd(&con->msc_real_ref, &con->bsc_real_ref,
+ rlsd = sccp_create_rlsd(&con->msc_patched_ref, &con->bsc_real_ref,
SCCP_RELEASE_CAUSE_END_USER_ORIGINATED);
if (!rlsd) {
LOGP(DNAT, LOGL_ERROR, "Failed to allocate RLSD for the BSC.\n");
@@ -547,7 +547,7 @@ static void bsc_send_con_refuse(struct bsc_connection *bsc,
con->filter_state.con_type = FLT_CON_TYPE_LOCAL_REJECT;
con->con_local = NAT_CON_END_LOCAL;
con->has_msc_ref = 1;
- con->msc_real_ref = con->bsc_patched_ref;
+ con->msc_real_ref = con->msc_patched_ref;
/* 1. create a confirmation */
cc = sccp_create_cc(&con->msc_real_ref, &con->bsc_real_ref);
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
index 20cacdb77..f18098210 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -221,12 +221,13 @@ DEFUN(show_sccp, show_sccp_cmd, "show sccp connections",
vty_out(vty, "Listing all open SCCP connections%s", VTY_NEWLINE);
llist_for_each_entry(con, &_nat->sccp_connections, list_entry) {
- vty_out(vty, "For BSC Nr: %d BSC ref: 0x%x; MUX ref: 0x%x; Network has ref: %d ref: 0x%x MSC/BSC mux: 0x%x/0x%x type: %s%s",
+ vty_out(vty, "For BSC Nr: %d BSC ref: 0x%x; MUX ref: 0x%x; Network has ref: %d ref: 0x%x; MUX ref: 0x%x; MSC/BSC mux: 0x%x/0x%x type: %s%s",
con->bsc->cfg ? con->bsc->cfg->nr : -1,
sccp_src_ref_to_int(&con->bsc_real_ref),
sccp_src_ref_to_int(&con->bsc_patched_ref),
con->has_msc_ref,
sccp_src_ref_to_int(&con->msc_real_ref),
+ sccp_src_ref_to_int(&con->msc_patched_ref),
con->msc_endp, con->bsc_endp,
bsc_con_type_to_string(con->filter_state.con_type),
VTY_NEWLINE);
diff --git a/openbsc/src/osmo-bsc_nat/bsc_sccp.c b/openbsc/src/osmo-bsc_nat/bsc_sccp.c
index b5da6e353..26b3cefbd 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_sccp.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_sccp.c
@@ -43,10 +43,12 @@ static int equal(struct sccp_source_reference *ref1, struct sccp_source_referenc
static int sccp_ref_is_free(struct sccp_source_reference *ref, struct bsc_nat *nat)
{
struct nat_sccp_connection *conn;
-
+#warning "We could have two lists - one for msc and one for bsc side..."
llist_for_each_entry(conn, &nat->sccp_connections, list_entry) {
if (equal(ref, &conn->bsc_patched_ref))
return -1;
+ if (memcmp(ref, &conn->msc_patched_ref, sizeof(*ref)) == 0)
+ return -1;
}
return 0;
@@ -103,6 +105,12 @@ struct nat_sccp_connection *create_sccp_src_ref(struct bsc_connection *bsc,
llist_del(&conn->list_entry);
talloc_free(conn);
return NULL;
+ }
+ if (assign_src_local_reference(&conn->msc_patched_ref, bsc->nat) != 0) {
+ bsc_mgcp_dlcx(conn);
+ llist_del(&conn->list_entry);
+ talloc_free(conn);
+ return NULL;
} else {
clock_gettime(CLOCK_MONOTONIC, &conn->creation_time);
bsc_mgcp_dlcx(conn);
@@ -126,6 +134,12 @@ struct nat_sccp_connection *create_sccp_src_ref(struct bsc_connection *bsc,
return NULL;
}
+ if (assign_src_local_reference(&conn->msc_patched_ref, bsc->nat) != 0) {
+ LOGP(DNAT, LOGL_ERROR, "Failed to assign a ref.\n");
+ talloc_free(conn);
+ return NULL;
+ }
+
bsc_mgcp_init(conn);
llist_add_tail(&conn->list_entry, &bsc->nat->sccp_connections);
rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_SCCP_CONN]);
@@ -147,6 +161,7 @@ int update_sccp_src_ref(struct nat_sccp_connection *sccp, struct bsc_nat_parsed
sccp->msc_real_ref = *parsed->src_local_ref;
sccp->has_msc_ref = 1;
+ *parsed->src_local_ref = sccp->msc_patched_ref;
LOGP(DNAT, LOGL_DEBUG, "Updating 0x%x to remote 0x%x on %p\n",
sccp_src_ref_to_int(&sccp->bsc_patched_ref),
sccp_src_ref_to_int(&sccp->msc_real_ref), sccp->bsc);
@@ -192,6 +207,8 @@ struct nat_sccp_connection *patch_sccp_src_ref_to_bsc(struct msgb *msg,
/* Change the dest address to the real one */
*parsed->dest_local_ref = conn->bsc_real_ref;
+ if (parsed->src_local_ref && conn->has_msc_ref)
+ *parsed->src_local_ref = conn->msc_patched_ref;
return conn;
}
@@ -215,15 +232,21 @@ struct nat_sccp_connection *patch_sccp_src_ref_to_msc(struct msgb *msg,
llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) {
if (conn->bsc != bsc)
continue;
-
+#warning "Do we need to patch the other ref in these ifs as well?"
if (parsed->src_local_ref) {
if (equal(parsed->src_local_ref, &conn->bsc_real_ref)) {
*parsed->src_local_ref = conn->bsc_patched_ref;
+ if (parsed->dest_local_ref)
+ *parsed->dest_local_ref = conn->msc_real_ref;
return conn;
}
} else if (parsed->dest_local_ref) {
- if (equal(parsed->dest_local_ref, &conn->msc_real_ref))
+ if (equal(parsed->dest_local_ref, &conn->msc_patched_ref)) {
+ *parsed->dest_local_ref = conn->msc_real_ref;
+ if (parsed->src_local_ref)
+ *parsed->src_local_ref = conn->bsc_patched_ref;
return conn;
+ }
} else {
LOGP(DNAT, LOGL_ERROR, "Header has neither loc/dst ref.\n");
return NULL;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
index 0ba63270d..7a96232f0 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
@@ -348,8 +348,9 @@ static int forward_ussd(struct nat_sccp_connection *con, const struct ussd_reque
state = (struct ipac_msgt_sccp_state *) msgb_put(msg, sizeof(*state));
state->trans_id = req->transaction_id;
state->invoke_id = req->invoke_id;
- memcpy(&state->src_ref, &con->remote_ref, sizeof(con->remote_ref));
- memcpy(&state->dst_ref, &con->real_ref, sizeof(con->real_ref));
+#warning "Check if msc_real_ref should be used here"
+ memcpy(&state->src_ref, &con->msc_real_ref, sizeof(con->msc_real_ref));
+ memcpy(&state->dst_ref, &con->bsc_real_ref, sizeof(con->bsc_real_ref));
memcpy(state->imsi, con->filter_state.imsi, strlen(con->filter_state.imsi));
/* add additional tag/values */
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 15666387f..869553095 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -330,7 +330,7 @@ static void test_contrack()
con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
if (con_found != NULL) {
printf("Con should not exist realref(%u)\n",
- sccp_src_ref_to_int(&con_found->real_ref));
+ sccp_src_ref_to_int(&con_found->bsc_real_ref));
abort();
}
rc_con = create_sccp_src_ref(con, parsed);
@@ -412,8 +412,8 @@ static void test_contrack()
/* verify that it is gone */
if (con_found != NULL) {
- printf("Con should not exist real_ref(%u)\n",
- sccp_src_ref_to_int(&con_found->real_ref));
+ printf("Con should not exist bsc_real_ref(%u)\n",
+ sccp_src_ref_to_int(&con_found->bsc_real_ref));
abort();
}
talloc_free(parsed);