aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-04-08 10:24:57 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-04-08 10:24:57 +0200
commit6cb97bdebe5503d9fd7487d7f57c4c9e3d87b4c5 (patch)
treee36fc93ebc04e9efb74b6781658ca62f083c4065
parent8c3694a2824b674ce4653c013d1f79e019e3be8d (diff)
nat: Attempt to have a single BSC write method
This method currently prepends the IPA header and sends the data. In the future we might be able to use SCTP for it. We have to remove the IPA header from the static messages for that to work. This code is untested.
-rw-r--r--openbsc/include/openbsc/bsc_nat.h4
-rw-r--r--openbsc/src/nat/bsc_mgcp_utils.c2
-rw-r--r--openbsc/src/nat/bsc_nat.c38
-rw-r--r--openbsc/src/nat/bsc_nat_utils.c6
4 files changed, 26 insertions, 24 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index d3cd4626c..62e3c52e4 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -196,7 +196,6 @@ struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat
/**
* MGCP/Audio handling
*/
-int bsc_write_mgcp_msg(struct bsc_connection *bsc, struct msgb *msg);
int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
void bsc_mgcp_clear(struct sccp_connections *);
@@ -212,4 +211,7 @@ void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
int bsc_mgcp_extract_ci(const char *resp);
+
+int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
+
#endif
diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c
index 81465cae9..a273af46d 100644
--- a/openbsc/src/nat/bsc_mgcp_utils.c
+++ b/openbsc/src/nat/bsc_mgcp_utils.c
@@ -177,7 +177,7 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
mgcp_free_endp(mgcp_endp);
}
- bsc_write_mgcp_msg(bsc_con, bsc_msg);
+ bsc_write(bsc_con, bsc_msg, NAT_IPAC_PROTO_MGCP);
return MGCP_POLICY_DEFER;
}
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index f44cb139f..e521516d8 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -58,7 +58,7 @@ static struct bsc_fd bsc_listen;
static struct bsc_nat *nat;
-static void bsc_send_data(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
+static void bsc_send_data(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length, int);
static void remove_bsc_connection(struct bsc_connection *connection);
static void msc_send_reset(struct bsc_msc_connection *con);
@@ -93,28 +93,27 @@ int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
static void send_reset_ack(struct bsc_connection *bsc)
{
static const u_int8_t gsm_reset_ack[] = {
- 0x00, 0x13, 0xfd,
0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
0x00, 0x01, 0x31,
};
- bsc_send_data(bsc, gsm_reset_ack, sizeof(gsm_reset_ack));
+ bsc_send_data(bsc, gsm_reset_ack, sizeof(gsm_reset_ack), IPAC_PROTO_SCCP);
}
static void send_id_ack(struct bsc_connection *bsc)
{
static const u_int8_t id_ack[] = {
- 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK
+ IPAC_MSGT_ID_ACK
};
- bsc_send_data(bsc, id_ack, sizeof(id_ack));
+ bsc_send_data(bsc, id_ack, sizeof(id_ack), IPAC_PROTO_IPACCESS);
}
static void send_id_req(struct bsc_connection *bsc)
{
static const u_int8_t id_req[] = {
- 0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
+ IPAC_MSGT_ID_GET,
0x01, IPAC_IDTAG_UNIT,
0x01, IPAC_IDTAG_MACADDR,
0x01, IPAC_IDTAG_LOCATION1,
@@ -125,7 +124,7 @@ static void send_id_req(struct bsc_connection *bsc)
0x01, IPAC_IDTAG_SERNR,
};
- bsc_send_data(bsc, id_req, sizeof(id_req));
+ bsc_send_data(bsc, id_req, sizeof(id_req), IPAC_PROTO_IPACCESS);
}
static void nat_send_rlsd(struct sccp_connections *conn)
@@ -180,27 +179,25 @@ static void initialize_msc_if_needed()
/*
* Currently we are lacking refcounting so we need to copy each message.
*/
-static void bsc_send_data(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length)
+static void bsc_send_data(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length, int proto)
{
struct msgb *msg;
- if (length > 4096) {
+ if (length > 4096 - 128) {
LOGP(DINP, LOGL_ERROR, "Can not send message of that size.\n");
return;
}
- msg = msgb_alloc(4096, "to-bsc");
+ msg = msgb_alloc_headroom(4096, 128, "to-bsc");
if (!msg) {
LOGP(DINP, LOGL_ERROR, "Failed to allocate memory for BSC msg.\n");
return;
}
- msgb_put(msg, length);
+ msg->l2h = msgb_put(msg, length);
memcpy(msg->data, data, length);
- if (write_queue_enqueue(&bsc->write_queue, msg) != 0) {
- LOGP(DINP, LOGL_ERROR, "Failed to enqueue the write.\n");
- msgb_free(msg);
- }
+
+ bsc_write(bsc, msg, proto);
}
static int forward_sccp_to_bts(struct msgb *msg)
@@ -208,6 +205,7 @@ static int forward_sccp_to_bts(struct msgb *msg)
struct sccp_connections *con;
struct bsc_connection *bsc;
struct bsc_nat_parsed *parsed;
+ int proto;
/* filter, drop, patch the message? */
parsed = bsc_nat_parse(msg);
@@ -219,8 +217,10 @@ static int forward_sccp_to_bts(struct msgb *msg)
if (bsc_nat_filter_ipa(DIR_BSC, msg, parsed))
goto exit;
+ proto = parsed->ipa_proto;
+
/* Route and modify the SCCP packet */
- if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
+ if (proto == IPAC_PROTO_SCCP) {
switch (parsed->sccp_type) {
case SCCP_MSG_TYPE_UDT:
/* forward UDT messages to every BSC */
@@ -266,7 +266,7 @@ static int forward_sccp_to_bts(struct msgb *msg)
return -1;
}
- bsc_send_data(con->bsc, msg->data, msg->len);
+ bsc_send_data(con->bsc, msg->l2h, msgb_l2len(msg), proto);
return 0;
send_to_all:
@@ -278,7 +278,7 @@ send_to_all:
if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) {
bsc = bsc_nat_find_bsc(nat, msg);
if (bsc)
- bsc_send_data(bsc, msg->data, msg->len);
+ bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto);
else
LOGP(DNAT, LOGL_ERROR, "Could not determine BSC for paging.\n");
@@ -289,7 +289,7 @@ send_to_all:
if (!bsc->authenticated)
continue;
- bsc_send_data(bsc, msg->data, msg->len);
+ bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto);
}
exit:
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index 24b4e1f00..85f72cfad 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -146,13 +146,13 @@ int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned in
msg->l3h = msgb_put(msg, length);
memcpy(msg->l3h, data, length);
- return bsc_write_mgcp_msg(bsc, msg);
+ return bsc_write(bsc, msg, NAT_IPAC_PROTO_MGCP);
}
-int bsc_write_mgcp_msg(struct bsc_connection *bsc, struct msgb *msg)
+int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int proto)
{
/* prepend the header */
- ipaccess_prepend_header(msg, NAT_IPAC_PROTO_MGCP);
+ ipaccess_prepend_header(msg, proto);
if (write_queue_enqueue(&bsc->write_queue, msg) != 0) {
LOGP(DINP, LOGL_ERROR, "Failed to enqueue the write.\n");