summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-04-02 11:58:17 +0200
committerHarald Welte <laforge@gnumonks.org>2017-04-07 17:29:58 +0200
commit0931531ea8e28d59e403fed6dab1b31ec7aca601 (patch)
treec44e0d8846be3f1ed3bc09887ff06f89881e1879
parente2a0070e231a9ee1e49a7eff540abff0a78a5820 (diff)
WIP: Add IPA/SCCPlite stackinglaforge/sigtran-ipa
-rw-r--r--include/osmocom/sigtran/osmo_ss7.h1
-rw-r--r--src/osmo_ss7.c138
-rw-r--r--src/sccp_scrc.c4
3 files changed, 134 insertions, 9 deletions
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index d765ae0..c7f1069 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -248,6 +248,7 @@ enum osmo_ss7_asp_protocol {
OSMO_SS7_ASP_PROT_NONE,
OSMO_SS7_ASP_PROT_SUA,
OSMO_SS7_ASP_PROT_M3UA,
+ OSMO_SS7_ASP_PROT_IPA,
_NUM_OSMO_SS7_ASP_PROT
};
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index 8ec099a..fc92251 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -40,6 +40,7 @@
#include <osmocom/core/socket.h>
#include <osmocom/netif/stream.h>
+#include <osmocom/netif/ipa.h>
#include "sccp_internal.h"
#include "xua_internal.h"
@@ -66,12 +67,25 @@ struct value_string osmo_ss7_asp_protocol_vals[] = {
{ OSMO_SS7_ASP_PROT_NONE, "none" },
{ OSMO_SS7_ASP_PROT_SUA, "sua" },
{ OSMO_SS7_ASP_PROT_M3UA, "m3ua" },
+ { OSMO_SS7_ASP_PROT_IPA, "ipa" },
{ 0, NULL }
};
#define LOGSS7(inst, level, fmt, args ...) \
LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args)
+static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto)
+{
+ switch (proto) {
+ case OSMO_SS7_ASP_PROT_IPA:
+ return IPPROTO_TCP;
+ case OSMO_SS7_ASP_PROT_SUA:
+ case OSMO_SS7_ASP_PROT_M3UA:
+ default:
+ return IPPROTO_SCTP;
+ }
+}
+
/***********************************************************************
* SS7 Point Code Parsing / Printing
@@ -770,7 +784,8 @@ osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name,
as->cfg.proto = proto;
as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE;
as->cfg.recovery_timeout_msec = 2000;
- as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
+ if (proto != OSMO_SS7_ASP_PROT_IPA)
+ as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
llist_add_tail(&as->list, &inst->as_list);
}
@@ -1004,6 +1019,7 @@ void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp)
}
static int xua_cli_read_cb(struct osmo_stream_cli *conn);
+static int ipa_cli_read_cb(struct osmo_stream_cli *conn);
static int xua_cli_connect_cb(struct osmo_stream_cli *cli);
int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp)
@@ -1031,10 +1047,13 @@ int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp)
}
osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host);
osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port);
- osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP);
+ osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto));
osmo_stream_cli_set_reconnect_timeout(asp->client, 5);
osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb);
- osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb);
+ if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
+ osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb);
+ else
+ osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb);
osmo_stream_cli_set_data(asp->client, asp);
rc = osmo_stream_cli_open2(asp->client, 1);
if (rc < 0) {
@@ -1061,7 +1080,8 @@ int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp)
/* (re)start the ASP FSM */
if (asp->fi)
osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL);
- asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG);
+ if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
+ asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG);
return 0;
}
@@ -1146,6 +1166,64 @@ static void log_sctp_notification(struct osmo_ss7_asp *asp, const char *pfx,
}
}
+static int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg)
+{
+ struct osmo_mtp_prim *omp;
+
+ /* FIXME: pull the IPA header */
+
+ /* Generate an MTP-TRANSFER.ind and hand it into the MTP core
+ * so it can dispatch it to SCCP */
+ omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp));
+ osmo_prim_init(&omp->oph, MTP_SAP_USER,
+ OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION, msg);
+ omp->u.transfer.opc = 0;
+ omp->u.transfer.dpc = 0;
+ omp->u.transfer.sio = MTP_SI_SCCP;
+ omp->u.transfer.sls = 0;
+
+ return osmo_ss7_mtp_to_user(asp->inst, omp);
+}
+
+/* netif code tells us we can read something from the socket */
+static int ipa_srv_conn_cb(struct osmo_stream_srv *conn)
+{
+ struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
+ struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn);
+ struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx");
+ int rc;
+
+ if (!msg)
+ return -ENOMEM;
+
+ /* read xUA message from socket and process it */
+ rc = osmo_stream_srv_recv(conn, msg);
+ LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): recvmsg() returned %d\n",
+ __func__, rc);
+ if (rc < 0) {
+ osmo_stream_srv_destroy(conn);
+ goto out;
+ } else if (rc == 0) {
+ osmo_stream_srv_destroy(conn);
+ goto out;
+ }
+ if (osmo_ipa_process_msg(msg) < 0) {
+ LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n");
+ osmo_stream_srv_destroy(conn);
+ goto out;
+ }
+ msg->dst = asp;
+
+ /* Handle IPA PING, PONG and ID_ACK messages */
+ if (osmo_ipa_rcvmsg_base(msg, ofd, 1))
+ return 0;
+
+ rc = ipa_rx_msg(asp, msg);
+out:
+ msgb_free(msg);
+ return rc;
+}
+
/* netif code tells us we can read something from the socket */
static int xua_srv_conn_cb(struct osmo_stream_srv *conn)
{
@@ -1230,6 +1308,40 @@ static int xua_cli_connect_cb(struct osmo_stream_cli *cli)
return 0;
}
+/* read call-back for IPA/SCCPlite socket */
+static int ipa_cli_read_cb(struct osmo_stream_cli *conn)
+{
+ struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn);
+ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn);
+ struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "IPA Client Rx");
+ int rc;
+
+ if (!msg)
+ return -ENOMEM;
+
+ rc = osmo_stream_cli_recv(conn, msg);
+ if (rc <= 0) {
+ LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot receive message\n");
+ osmo_stream_cli_reconnect(conn);
+ goto out;
+ }
+ if (osmo_ipa_process_msg(msg) < 0) {
+ LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n");
+ osmo_stream_cli_reconnect(conn);
+ goto out;
+ }
+
+ /* Handle IPA PING, PONG and ID_ACK messages */
+ if (osmo_ipa_rcvmsg_base(msg, ofd, 0))
+ return 0;
+
+ msg->dst = asp;
+ rc = ipa_rx_msg(asp, msg);
+out:
+ msgb_free(msg);
+ return rc;
+}
+
static int xua_cli_read_cb(struct osmo_stream_cli *conn)
{
struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn);
@@ -1322,9 +1434,15 @@ static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd)
LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n",
sock_name);
- srv = osmo_stream_srv_create(oxs, link, fd,
- xua_srv_conn_cb,
- xua_srv_conn_closed_cb, NULL);
+ if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) {
+ srv = osmo_stream_srv_create(oxs, link, fd,
+ ipa_srv_conn_cb,
+ xua_srv_conn_closed_cb, NULL);
+ } else {
+ srv = osmo_stream_srv_create(oxs, link, fd,
+ xua_srv_conn_cb,
+ xua_srv_conn_closed_cb, NULL);
+ }
if (!srv) {
LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server "
"for SCTP connection\n", sock_name);
@@ -1372,6 +1490,10 @@ int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg)
case OSMO_SS7_ASP_PROT_M3UA:
msgb_sctp_ppid(msg) = M3UA_PPID;
break;
+ case OSMO_SS7_ASP_PROT_IPA:
+ /* do we really want to do this here? */
+ osmo_ipa_msg_push_header(msg, FIXME);
+ break;
default:
OSMO_ASSERT(0);
}
@@ -1434,7 +1556,7 @@ osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_pro
osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host);
osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port);
- osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP);
+ osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto));
rc = osmo_stream_srv_link_open(oxs->server);
if (rc < 0) {
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c
index 0ab25cb..2511dfe 100644
--- a/src/sccp_scrc.c
+++ b/src/sccp_scrc.c
@@ -142,6 +142,7 @@ static int gen_mtp_transfer_req_xua(struct osmo_sccp_instance *inst,
case OSMO_SS7_ASP_PROT_SUA:
return sua_tx_xua_as(as, xua);
case OSMO_SS7_ASP_PROT_M3UA:
+ case OSMO_SS7_ASP_PROT_IPA:
return sua2sccp_tx_m3ua(inst, xua);
default:
LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for "
@@ -295,7 +296,8 @@ static int scrc_node_6(struct osmo_sccp_instance *inst,
const struct osmo_sccp_addr *called)
{
struct osmo_sccp_user *scu;
-
+ /* it is not really clear that called->pc will be set to
+ * anything here, in the case of a SSN-only CalledAddr */
scu = sccp_user_find(inst, called->ssn, called->pc);
/* Is subsystem equipped? */