aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-07-31 13:13:24 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-08-09 15:30:14 +0200
commitecbdc5cb06ef7f61c6f4cdb4e1fd84a05ec0407d (patch)
treed37d0f16ebc34830066550a29afd1e3c62e6471e
parent5e0292a6412a04eeed9e0aff3f56bd8d4f353346 (diff)
make point codes configurable by SCCP address book
In the vty config, use the SCCP address book to configure the local and remote SCCP addresses. Add VTY commands to set the remote SCCP addresses by name, derive the ss7 instance from these addresses: cs7 instance 1 point-code 0.23.0 sccp-address msc point-code 0.0.1 sccp-address sgsn point-code 0.0.2 hnbgw iucs remote-addr msc iups remote-addr sgsn Enforce that both IuCS and IuPS use the same ss7 instance. In the future, we may add the feature to use two separate instances. Depends: libosmo-sccp I75c67d289693f1c2a049ac61cf2b2097d6e5687d, Ie1aedd7894acd69ddc887cd65a8a0df4b888838c, I85b46269dbe7909e52873ace3f720f6292a4516c Change-Id: I33a7ba11eb7c2d9a5dc74d10fb0cf04bf664477b
-rw-r--r--include/osmocom/iuh/hnbgw.h12
-rw-r--r--include/osmocom/iuh/hnbgw_cn.h3
-rw-r--r--src/hnbgw.c22
-rw-r--r--src/hnbgw_cn.c99
-rw-r--r--src/hnbgw_rua.c4
-rw-r--r--src/hnbgw_vty.c74
6 files changed, 117 insertions, 97 deletions
diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h
index db22d97..58bdab4 100644
--- a/include/osmocom/iuh/hnbgw.h
+++ b/include/osmocom/iuh/hnbgw.h
@@ -116,10 +116,8 @@ struct hnb_gw {
/*! The UDP port where we receive multiplexed CS user
* plane traffic from HNBs */
uint16_t iuh_cs_mux_port;
- const char *iucs_remote_ip;
- uint16_t iucs_remote_port;
- const char *iups_remote_ip;
- uint16_t iups_remote_port;
+ const char *iucs_remote_addr_name;
+ const char *iups_remote_addr_name;
uint16_t rnc_id;
bool hnbap_allow_tmsi;
} config;
@@ -134,11 +132,11 @@ struct hnb_gw {
/* currently active CN links for CS and PS */
struct {
- struct osmo_sccp_instance *instance;
+ struct osmo_sccp_instance *client;
struct hnbgw_cnlink *cnlink;
struct osmo_sccp_addr local_addr;
- struct osmo_sccp_addr remote_addr_cs;
- struct osmo_sccp_addr remote_addr_ps;
+ struct osmo_sccp_addr iucs_remote_addr;
+ struct osmo_sccp_addr iups_remote_addr;
} sccp;
};
diff --git a/include/osmocom/iuh/hnbgw_cn.h b/include/osmocom/iuh/hnbgw_cn.h
index 93123f2..2e61d82 100644
--- a/include/osmocom/iuh/hnbgw_cn.h
+++ b/include/osmocom/iuh/hnbgw_cn.h
@@ -2,5 +2,4 @@
#include <osmocom/iuh/hnbgw.h>
-int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port,
- const char *local_ip, uint32_t local_pc);
+int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port, const char *local_ip);
diff --git a/src/hnbgw.c b/src/hnbgw.c
index 5d9f87b..c9fdd53 100644
--- a/src/hnbgw.c
+++ b/src/hnbgw.c
@@ -79,14 +79,6 @@ static struct hnb_gw *hnb_gw_create(void *ctx)
gw->config.iuh_local_ip = talloc_strdup(gw, HNBGW_LOCAL_IP_DEFAULT);
gw->config.iuh_local_port = IUH_DEFAULT_SCTP_PORT;
- gw->config.iucs_remote_ip = talloc_strdup(gw,
- HNBGW_IUCS_REMOTE_IP_DEFAULT);
- gw->config.iucs_remote_port = M3UA_PORT;
-
- gw->config.iups_remote_ip = talloc_strdup(gw,
- HNBGW_IUPS_REMOTE_IP_DEFAULT);
- gw->config.iups_remote_port = M3UA_PORT;
-
gw->next_ue_ctx_id = 23;
INIT_LLIST_HEAD(&gw->hnb_list);
INIT_LLIST_HEAD(&gw->ue_list);
@@ -465,6 +457,7 @@ int main(int argc, char **argv)
vty_info.copyright = osmo_hnbgw_copyright;
vty_init(&vty_info);
+ osmo_ss7_vty_init_asp(tall_hnb_ctx);
hnbgw_vty_init(g_hnb_gw, tall_hnb_ctx);
logging_vty_add_cmds(&hnbgw_log_info);
@@ -501,24 +494,13 @@ int main(int argc, char **argv)
ranap_set_log_area(DRANAP);
- OSMO_ASSERT(g_hnb_gw->config.iucs_remote_ip);
rc = hnbgw_cnlink_init(g_hnb_gw,
- g_hnb_gw->config.iucs_remote_ip,
- g_hnb_gw->config.iucs_remote_port,
- "127.0.0.5" /* FIXME: configurable */,
- 23 /* FIXME: configurable */);
+ "127.0.0.1", M3UA_PORT, "127.0.0.5" /* FIXME: configurable */);
if (rc < 0) {
LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n");
exit(1);
}
- osmo_sccp_make_addr_pc_ssn(&g_hnb_gw->sccp.remote_addr_cs,
- 1 /* FIXME: configurable */,
- OSMO_SCCP_SSN_RANAP);
- osmo_sccp_make_addr_pc_ssn(&g_hnb_gw->sccp.remote_addr_ps,
- 2 /* FIXME: configurable */,
- OSMO_SCCP_SSN_RANAP);
-
OSMO_ASSERT(g_hnb_gw->config.iuh_local_ip);
LOGP(DMAIN, LOGL_NOTICE, "Listening for Iuh at %s %d\n",
g_hnb_gw->config.iuh_local_ip,
diff --git a/src/hnbgw_cn.c b/src/hnbgw_cn.c
index e967260..4aa3422 100644
--- a/src/hnbgw_cn.c
+++ b/src/hnbgw_cn.c
@@ -63,8 +63,8 @@ static void cnlink_trafc_cb(void *data)
{
struct hnb_gw *gw = data;
- transmit_rst(gw, RANAP_CN_DomainIndicator_cs_domain, &gw->sccp.remote_addr_cs);
- transmit_rst(gw, RANAP_CN_DomainIndicator_ps_domain, &gw->sccp.remote_addr_ps);
+ transmit_rst(gw, RANAP_CN_DomainIndicator_cs_domain, &gw->sccp.iucs_remote_addr);
+ transmit_rst(gw, RANAP_CN_DomainIndicator_ps_domain, &gw->sccp.iups_remote_addr);
hnbgw_cnlink_change_state(gw->sccp.cnlink, CNLINK_S_EST_RST_TX_WAIT_ACK);
/* The spec states that we should abandon after a configurable
* number of times. We decide to simply continue trying */
@@ -251,12 +251,12 @@ static int classify_cn_remote_addr(const struct hnb_gw *gw,
const struct osmo_sccp_addr *cn_remote_addr,
bool *is_ps)
{
- if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.remote_addr_cs)) {
+ if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.iucs_remote_addr)) {
if (is_ps)
*is_ps = false;
return 0;
}
- if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.remote_addr_ps)) {
+ if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.iups_remote_addr)) {
if (is_ps)
*is_ps = true;
return 0;
@@ -401,27 +401,90 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx)
return 0;
}
-int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port,
- const char *local_ip, uint32_t local_pc)
+static bool addr_has_pc_and_ssn(const struct osmo_sccp_addr *addr)
+{
+ if (!(addr->presence & OSMO_SCCP_ADDR_T_SSN))
+ return false;
+ if (!(addr->presence & OSMO_SCCP_ADDR_T_PC))
+ return false;
+ return true;
+}
+
+static int resolve_addr_name(struct osmo_sccp_addr *dest, struct osmo_ss7_instance **ss7,
+ const char *addr_name, const char *label)
+{
+ struct osmo_ss7_instance *ss7_tmp;
+
+ if (!addr_name) {
+ LOGP(DMAIN, LOGL_ERROR, "Missing config: %s remote-addr\n", label);
+ return -1;
+ }
+
+ ss7_tmp = osmo_sccp_addr_by_name(dest, addr_name);
+ if (!ss7_tmp) {
+ LOGP(DMAIN, LOGL_ERROR, "%s remote addr: no such SCCP address book entry: '%s'\n",
+ label, addr_name);
+ return -1;
+ }
+
+ if (*ss7 && (*ss7 != ss7_tmp)) {
+ LOGP(DMAIN, LOGL_ERROR, "IuCS and IuPS cannot be served from separate CS7 instances,"
+ " cs7 instance %d != %d\n", (*ss7)->cfg.id, ss7_tmp->cfg.id);
+ return -1;
+ }
+
+ *ss7 = ss7_tmp;
+
+ osmo_sccp_addr_set_ssn(dest, OSMO_SCCP_SSN_RANAP);
+
+ if (!addr_has_pc_and_ssn(dest)) {
+ LOGP(DMAIN, LOGL_ERROR, "Invalid/incomplete %s remote-addr: %s\n",
+ label, osmo_sccp_addr_name(dest));
+ return -1;
+ }
+
+ LOGP(DRANAP, LOGL_NOTICE, "Remote %s SCCP addr: %s\n",
+ label, osmo_sccp_addr_name(*ss7, dest));
+ return 0;
+}
+
+int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port, const char *local_ip)
{
struct hnbgw_cnlink *cnlink;
+ struct osmo_ss7_instance *ss7;
+ uint32_t local_pc;
int rc;
- OSMO_ASSERT(!gw->sccp.instance);
+ OSMO_ASSERT(!gw->sccp.client);
OSMO_ASSERT(!gw->sccp.cnlink);
- gw->sccp.instance = osmo_sccp_simple_client(gw, "OsmoHNBGW", local_pc,
- OSMO_SS7_ASP_PROT_M3UA, 0, local_ip,
- stp_port, stp_host);
- if (!gw->sccp.instance) {
- LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP Instance\n");
+ ss7 = NULL;
+ if (resolve_addr_name(&gw->sccp.iucs_remote_addr, &ss7,
+ gw->config.iucs_remote_addr_name, "IuCS"))
+ return -1;
+ if (resolve_addr_name(&gw->sccp.iups_remote_addr, &ss7,
+ gw->config.iups_remote_addr_name, "IuPS"))
+ return -1;
+
+ if (!osmo_ss7_pc_is_valid(ss7->cfg.primary_pc)) {
+ LOGP(DMAIN, LOGL_ERROR, "IuCS/IuPS uplink cannot be setup: CS7 instance %d has no point-code set\n",
+ ss7->cfg.id);
return -1;
}
+ local_pc = ss7->cfg.primary_pc;
- LOGP(DRUA, LOGL_DEBUG, "SCCP uplink to STP: %s %u\n", stp_host, stp_port);
+ osmo_sccp_make_addr_pc_ssn(&gw->sccp.local_addr, local_pc, OSMO_SCCP_SSN_RANAP);
- osmo_sccp_make_addr_pc_ssn(&gw->sccp.local_addr, local_pc,
- OSMO_SCCP_SSN_RANAP);
+ LOGP(DRANAP, LOGL_NOTICE, "M3UA uplink to STP: %s %u\n", stp_host, stp_port);
+ LOGP(DRANAP, LOGL_NOTICE, "Local SCCP addr: %s\n", osmo_sccp_addr_name(ss7, &gw->sccp.local_addr));
+
+ gw->sccp.client = osmo_sccp_simple_client_on_ss7_id(gw, ss7->cfg.id, "OsmoHNBGW",
+ local_pc, OSMO_SS7_ASP_PROT_M3UA,
+ 0, local_ip, stp_port, stp_host);
+ if (!gw->sccp.client) {
+ LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP Client\n");
+ return -1;
+ }
cnlink = talloc_zero(gw, struct hnbgw_cnlink);
cnlink->gw = gw;
@@ -430,10 +493,8 @@ int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port
cnlink->T_RafC.data = gw;
cnlink->next_conn_id = 1000;
- cnlink->sccp_user = osmo_sccp_user_bind_pc(gw->sccp.instance,
- "OsmoHNBGW",
- sccp_sap_up, OSMO_SCCP_SSN_RANAP,
- gw->sccp.local_addr.pc);
+ cnlink->sccp_user = osmo_sccp_user_bind_pc(gw->sccp.client, "OsmoHNBGW", sccp_sap_up,
+ OSMO_SCCP_SSN_RANAP, gw->sccp.local_addr.pc);
if (!cnlink->sccp_user) {
LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP User\n");
return -1;
diff --git a/src/hnbgw_rua.c b/src/hnbgw_rua.c
index b610437..95979f5 100644
--- a/src/hnbgw_rua.c
+++ b/src/hnbgw_rua.c
@@ -188,11 +188,11 @@ static int rua_to_scu(struct hnb_context *hnb,
switch (cN_DomainIndicator) {
case RUA_CN_DomainIndicator_cs_domain:
- remote_addr = &hnb->gw->sccp.remote_addr_cs;
+ remote_addr = &hnb->gw->sccp.iucs_remote_addr;
is_ps = false;
break;
case RUA_CN_DomainIndicator_ps_domain:
- remote_addr = &hnb->gw->sccp.remote_addr_ps;
+ remote_addr = &hnb->gw->sccp.iups_remote_addr;
is_ps = true;
break;
default:
diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c
index 59871da..ddea578 100644
--- a/src/hnbgw_vty.c
+++ b/src/hnbgw_vty.c
@@ -90,7 +90,6 @@ int hnbgw_vty_go_parent(struct vty *vty)
vty->node = HNBGW_NODE;
vty->index = NULL;
break;
- default:
case HNBGW_NODE:
vty->node = CONFIG_NODE;
vty->index = NULL;
@@ -99,6 +98,9 @@ int hnbgw_vty_go_parent(struct vty *vty)
vty->node = ENABLE_NODE;
vty->index = NULL;
break;
+ default:
+ osmo_ss7_vty_go_parent(vty);
+ break;
}
return vty->node;
@@ -182,37 +184,23 @@ DEFUN(cfg_hnbgw_iuh_hnbap_allow_tmsi, cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_hnbgw_iucs_remote_ip, cfg_hnbgw_iucs_remote_ip_cmd, "remote-ip A.B.C.D",
- "Address to establish IuCS core network link to\n"
- "Remote IuCS IP address (default: " HNBGW_IUCS_REMOTE_IP_DEFAULT ")")
+DEFUN(cfg_hnbgw_iucs_remote_addr,
+ cfg_hnbgw_iucs_remote_addr_cmd,
+ "remote-addr NAME",
+ "SCCP address to send IuCS to (MSC)\n"
+ "SCCP address book entry name (see 'cs7-instance')\n")
{
- talloc_free((void*)g_hnb_gw->config.iucs_remote_ip);
- g_hnb_gw->config.iucs_remote_ip = talloc_strdup(tall_hnb_ctx, argv[0]);
+ g_hnb_gw->config.iucs_remote_addr_name = talloc_strdup(g_hnb_gw, argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_hnbgw_iucs_remote_port, cfg_hnbgw_iucs_remote_port_cmd, "remote-port <1-65535>",
- "Remote port to establish IuCS core network link to\n"
- "Remote IuCS port (default: 14001)")
+DEFUN(cfg_hnbgw_iups_remote_addr,
+ cfg_hnbgw_iups_remote_addr_cmd,
+ "remote-addr NAME",
+ "SCCP address to send IuPS to (SGSN)\n"
+ "SCCP address book entry name (see 'cs7-instance')\n")
{
- g_hnb_gw->config.iucs_remote_port = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_hnbgw_iups_remote_ip, cfg_hnbgw_iups_remote_ip_cmd, "remote-ip A.B.C.D",
- "Address to establish IuPS core network link to\n"
- "Remote IuPS IP address (default: " HNBGW_IUPS_REMOTE_IP_DEFAULT ")")
-{
- talloc_free((void*)g_hnb_gw->config.iups_remote_ip);
- g_hnb_gw->config.iups_remote_ip = talloc_strdup(tall_hnb_ctx, argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_hnbgw_iups_remote_port, cfg_hnbgw_iups_remote_port_cmd, "remote-port <1-65535>",
- "Remote port to establish IuPS core network link to\n"
- "Remote IuPS port (default: 14001)")
-{
- g_hnb_gw->config.iups_remote_port = atoi(argv[0]);
+ g_hnb_gw->config.iups_remote_addr_name = talloc_strdup(g_hnb_gw, argv[0]);
return CMD_SUCCESS;
}
@@ -248,15 +236,12 @@ static int config_write_hnbgw_iucs(struct vty *vty)
const char *addr;
uint16_t port;
- vty_out(vty, " iucs%s", VTY_NEWLINE);
-
- addr = g_hnb_gw->config.iucs_remote_ip;
- if (addr && (strcmp(addr, HNBGW_IUCS_REMOTE_IP_DEFAULT) != 0))
- vty_out(vty, " remote-ip %s%s", addr, VTY_NEWLINE);
+ if (!g_hnb_gw->config.iucs_remote_addr_name)
+ return CMD_SUCCESS;
- port = g_hnb_gw->config.iucs_remote_port;
- if (port && port != SUA_PORT)
- vty_out(vty, " remote-port %u%s", port, VTY_NEWLINE);
+ vty_out(vty, " iucs%s", VTY_NEWLINE);
+ vty_out(vty, " remote-addr %s%s", g_hnb_gw->config.iucs_remote_addr_name,
+ VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -266,15 +251,12 @@ static int config_write_hnbgw_iups(struct vty *vty)
const char *addr;
uint16_t port;
- vty_out(vty, " iups%s", VTY_NEWLINE);
-
- addr = g_hnb_gw->config.iups_remote_ip;
- if (addr && (strcmp(addr, HNBGW_IUPS_REMOTE_IP_DEFAULT) != 0))
- vty_out(vty, " remote-ip %s%s", addr, VTY_NEWLINE);
+ if (!g_hnb_gw->config.iups_remote_addr_name)
+ return CMD_SUCCESS;
- port = g_hnb_gw->config.iups_remote_port;
- if (port && port != SUA_PORT)
- vty_out(vty, " remote-port %u%s", port, VTY_NEWLINE);
+ vty_out(vty, " iups%s", VTY_NEWLINE);
+ vty_out(vty, " remote-addr %s%s", g_hnb_gw->config.iups_remote_addr_name,
+ VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -300,15 +282,13 @@ void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx)
install_node(&iucs_node, config_write_hnbgw_iucs);
vty_install_default(IUCS_NODE);
- install_element(IUCS_NODE, &cfg_hnbgw_iucs_remote_ip_cmd);
- install_element(IUCS_NODE, &cfg_hnbgw_iucs_remote_port_cmd);
+ install_element(IUCS_NODE, &cfg_hnbgw_iucs_remote_addr_cmd);
install_element(HNBGW_NODE, &cfg_hnbgw_iups_cmd);
install_node(&iups_node, config_write_hnbgw_iups);
vty_install_default(IUPS_NODE);
- install_element(IUPS_NODE, &cfg_hnbgw_iups_remote_ip_cmd);
- install_element(IUPS_NODE, &cfg_hnbgw_iups_remote_port_cmd);
+ install_element(IUPS_NODE, &cfg_hnbgw_iups_remote_addr_cmd);
install_element_ve(&show_hnb_cmd);
install_element_ve(&show_ue_cmd);