aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);