diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hnbgw.c | 22 | ||||
-rw-r--r-- | src/hnbgw_cn.c | 99 | ||||
-rw-r--r-- | src/hnbgw_rua.c | 4 | ||||
-rw-r--r-- | src/hnbgw_vty.c | 74 |
4 files changed, 111 insertions, 88 deletions
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); |