lists.osmocom.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

gerrit-log

Thread Start a new thread
Download
Threads by month
  • ----- 2026 -----
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
gerrit-log@lists.osmocom.org

June 2023

  • 1 participants
  • 2480 discussions
[M] Change in osmo-hnbgw[master]: cnpool: split up context_map_find_or_create_by_rua_ctx_id()
by neels 01 Jun '23

01 Jun '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33127 ) Change subject: cnpool: split up context_map_find_or_create_by_rua_ctx_id() ...................................................................... cnpool: split up context_map_find_or_create_by_rua_ctx_id() Have separate find, alloc, set_cnlink functions instead of all in one. For CN pooling, I need these operations to be separate: - we need to decode the RANAP and L3 PDU only if no existing context_map was found (see I373d665c9684b607207f68094188eab63209db51 ). - while decoding RANAP and L3 PDU, and while deciding which cnlink to use, I already want to use the logging context of LOG_MAP(). So I want to allocate a map first, and connect it to the selected cnlink later. Related: SYS#6412 Change-Id: Ifc5242547260154eb5aecd3a9d9c2aac8419e8db --- M include/osmocom/hnbgw/context_map.h M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw_rua.c 3 files changed, 100 insertions(+), 39 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/27/33127/1 diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index fe9d3e0..55d96ea 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -136,8 +136,9 @@ enum hnbgw_context_map_state map_rua_get_state(struct hnbgw_context_map *map); enum hnbgw_context_map_state map_sccp_get_state(struct hnbgw_context_map *map); -struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, - bool is_ps); +struct hnbgw_context_map *context_map_find_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps); +struct hnbgw_context_map *context_map_alloc(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps); +int context_map_set_cnlink(struct hnbgw_context_map *map, struct hnbgw_cnlink *cnlink_selected); void map_rua_fsm_alloc(struct hnbgw_context_map *map); void map_sccp_fsm_alloc(struct hnbgw_context_map *map); diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index cdc526b..13aae0e 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -53,13 +53,9 @@ } /* Map from a HNB + ContextID to the SCCP-side Connection ID */ -struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, - bool is_ps) +struct hnbgw_context_map *context_map_find_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps) { struct hnbgw_context_map *map; - uint32_t new_scu_conn_id; - struct hnbgw_cnlink *cnlink; - struct hnbgw_sccp_user *hsu; llist_for_each_entry(map, &hnb->map_list, hnb_list) { if (map->is_ps != is_ps) @@ -77,51 +73,58 @@ /* Already exists */ return map; } + return NULL; +} - /* Does not exist yet, create a new hnbgw_context_map. */ +struct hnbgw_context_map *context_map_alloc(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps) +{ + struct hnbgw_context_map *map; - /* From the RANAP/RUA input, determine which cnlink to use */ - cnlink = hnbgw_cnlink_select(is_ps); - if (!cnlink) { - LOGHNB(hnb, DMAIN, LOGL_ERROR, "Failed to select CN link\n"); - return NULL; - } - - /* Allocate new SCCP conn id on the SCCP instance the cnlink is on. */ - hsu = cnlink->hnbgw_sccp_user; - if (!hsu) { - LOGHNB(hnb, DMAIN, LOGL_ERROR, "Cannot allocate context map: No SCCP instance for CN link %s\n", - cnlink->name); - return NULL; - } - - new_scu_conn_id = osmo_sccp_instance_next_conn_id(hsu->ss7->sccp); - if (new_scu_conn_id < 0) { - LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate SCCP conn ID on %s\n", hsu->name); - return NULL; - } - - /* allocate a new map entry. */ + /* allocate a new map entry now, so we have logging context */ map = talloc_zero(hnb, struct hnbgw_context_map); - map->cnlink = cnlink; map->hnb_ctx = hnb; map->rua_ctx_id = rua_ctx_id; map->is_ps = is_ps; - map->scu_conn_id = new_scu_conn_id; INIT_LLIST_HEAD(&map->ps_rab_ass); INIT_LLIST_HEAD(&map->ps_rabs); map_rua_fsm_alloc(map); - map_sccp_fsm_alloc(map); llist_add_tail(&map->hnb_list, &hnb->map_list); - llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink->map_list); + + LOG_MAP(map, DRUA, LOGL_INFO, "New RUA CTX\n"); + return map; +} + +int context_map_set_cnlink(struct hnbgw_context_map *map, struct hnbgw_cnlink *cnlink_selected) +{ + int new_scu_conn_id; + struct hnbgw_sccp_user *hsu; + + /* Allocate new SCCP conn id on the SCCP instance the cnlink is on. */ + hsu = cnlink_selected->hnbgw_sccp_user; + if (!hsu) { + LOG_MAP(map, DCN, LOGL_ERROR, "Cannot map RUA context to SCCP: No SCCP instance for CN link %s\n", + cnlink_selected->name); + return -EIO; + } + + new_scu_conn_id = osmo_sccp_instance_next_conn_id(hsu->ss7->sccp); + if (new_scu_conn_id < 0) { + LOG_MAP(map, DCN, LOGL_ERROR, "Unable to allocate SCCP conn ID on %s\n", hsu->name); + return new_scu_conn_id; + } + + map->cnlink = cnlink_selected; + map->scu_conn_id = new_scu_conn_id; + llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink_selected->map_list); + hash_add(hsu->hnbgw_context_map_by_conn_id, &map->hnbgw_sccp_user_entry, new_scu_conn_id); - LOG_MAP(map, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %u <-> SCU Conn ID %s/%u\n", - rua_ctx_id, hsu->name, new_scu_conn_id); + LOG_MAP(map, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %u <-> SCU Conn ID %u to %s on %s\n", + map->rua_ctx_id, new_scu_conn_id, cnlink_selected->name, hsu->name); - return map; + return 0; } int _map_rua_dispatch(struct hnbgw_context_map *map, uint32_t event, struct msgb *ranap_msg, diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c index 8157cfc..abda5ea 100644 --- a/src/osmo-hnbgw/hnbgw_rua.c +++ b/src/osmo-hnbgw/hnbgw_rua.c @@ -33,7 +33,7 @@ #include "asn1helpers.h" -#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_cn.h> #include <osmocom/hnbgw/hnbgw_ranap.h> #include <osmocom/rua/rua_common.h> #include <osmocom/rua/rua_ies_defs.h> @@ -189,6 +189,44 @@ return get_value_string(rua_procedure_code_names, val); } +static struct hnbgw_context_map *find_or_create_context_map(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps, + struct msgb *ranap_msg) +{ + struct hnbgw_context_map *map; + struct hnbgw_cnlink *cnlink; + + map = context_map_find_by_rua_ctx_id(hnb, rua_ctx_id, is_ps); + if (map) { + /* Already established SCCP link. Continue to use that. */ + return map; + } + + /* Establish a new context map. From the RUA Connect, extract a mobile identity, if any, and select a CN link + * based on an NRI found in the mobile identity, if any. */ + + /* Allocate a map for logging context */ + map = context_map_alloc(hnb, rua_ctx_id, is_ps); + OSMO_ASSERT(map); + + /* FUTURE: extract mobile identity and store in map-> */ + + cnlink = hnbgw_cnlink_select(map); + if (!cnlink) { + LOG_MAP(map, DCN, LOGL_ERROR, "Failed to select %s link\n", is_ps ? "IuPS" : "IuCS"); + context_map_free(map); + return NULL; + } + + if (context_map_set_cnlink(map, cnlink)) { + LOG_MAP(map, DCN, LOGL_ERROR, "Failed to establish link to %s\n", cnlink->name); + context_map_free(map); + return NULL; + } + + LOG_MAP(map, DCN, LOGL_INFO, "establishing SCCP link: selected %s\n", cnlink->name); + return map; +} + /* dispatch a RUA connection-oriented message received from a HNB to a context mapping's RUA FSM, so that it is * forwarded to the CN via SCCP connection-oriented messages. * Connectionless messages are handled in hnbgw_ranap_rx() instead, not here. */ @@ -224,7 +262,7 @@ memcpy(ranap_msg->l2h, data, len); } - map = context_map_find_or_create_by_rua_ctx_id(hnb, context_id, is_ps); + map = find_or_create_context_map(hnb, context_id, is_ps, ranap_msg); if (!map) { LOGHNB(hnb, DRUA, LOGL_ERROR, "Failed to create context map for %s: rx RUA %s with %u bytes RANAP data\n", -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33127 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Ifc5242547260154eb5aecd3a9d9c2aac8419e8db Gerrit-Change-Number: 33127 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
[L] Change in osmo-hnbgw[master]: cnpool: make NRI mappings VTY configurable
by neels 01 Jun '23

01 Jun '23
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/33130 ) Change subject: cnpool: make NRI mappings VTY configurable ...................................................................... cnpool: make NRI mappings VTY configurable Implement only the VTY configuration part, applying NRI to select CN links follows in I66fba27cfbe6e2b27ee3443718846ecfbbd8a974. Use the osmo_nri_ranges API to manage each cnlink's NRI ranges by VTY configuration. Analogous to osmo-bsc MSC pooling: make NRI mappings VTY configurable 4099f1db504c401e3d7211d9761b034d62d15f7c I6c251f2744d7be26fc4ad74adefc96a6a3fe08b0 plus vty: fix doc: default value for 'nri bitlen' f15d236e3eee8e7cbdc184d401f33b062d1b1aac I8af840a4589f47eaca6bf10e37e0859f9ae53dfa Related: SYS#6412 Change-Id: Ifb87e01e5971962e5cfe5e127871af4a67806de1 --- M include/osmocom/hnbgw/hnbgw.h M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_vty.c M tests/Makefile.am M tests/cnpool.vty A tests/nri_cfg.vty 7 files changed, 786 insertions(+), 19 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/30/33130/1 diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 14552fb..cc32f93 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -101,9 +101,8 @@ /* User provided configuration for struct hnbgw_cnpool. */ struct hnbgw_cnpool_cfg { - /* FUTURE: This will be added here shortly: - * - global NRI config: bitlen and NULL-NRI. - */ + uint8_t nri_bitlen; + struct osmo_nri_ranges *null_nri_ranges; }; /* User provided configuration for struct hnbgw_cnlink. */ @@ -112,9 +111,7 @@ * use. */ char *remote_addr_name; - /* FUTURE: This will be added here shortly: - * - per peer NRI config: NRI ranges assigned to this peer. - */ + struct osmo_nri_ranges *nri_ranges; }; /* Collection of CN peers to distribute UE connections across. MSCs for DOMAIN_CS, SGSNs for DOMAIN_PS. */ @@ -134,9 +131,10 @@ /* List of struct hnbgw_cnlink */ struct llist_head cnlinks; - /* FUTURE: This will be added here shortly: - * - round robin state for new conns - */ + unsigned int round_robin_next_nr; + /* Emergency calls potentially select a different set of MSCs, so to not mess up the normal round-robin + * behavior, emergency calls need a separate round-robin counter. */ + unsigned int round_robin_next_emerg_nr; }; /* A CN peer, like 'msc 0' or 'sgsn 23' */ @@ -163,6 +161,9 @@ /* linked list of hnbgw_context_map */ struct llist_head map_list; + + bool allow_attach; + bool allow_emerg; }; #define LOG_CNLINK(CNLINK, SUBSYS, LEVEL, FMT, ARGS...) \ diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index 205c683..0d64adf 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -24,6 +24,8 @@ #include <osmocom/vty/vty.h> +#include <osmocom/gsm/gsm23236.h> + #include <osmocom/netif/stream.h> #include "config.h" @@ -67,9 +69,8 @@ .peer_name = "msc", .default_remote_pc = DEFAULT_PC_MSC, .vty = { - /* FUTURE: This will be added here shortly: - * - defaults for global NRI config: bitlen and NULL-NRI. - */ + .nri_bitlen = OSMO_NRI_BITLEN_DEFAULT, + .null_nri_ranges = osmo_nri_ranges_alloc(g_hnbgw), }, }; INIT_LLIST_HEAD(&g_hnbgw->sccp.cnpool_iucs.cnlinks); @@ -80,9 +81,8 @@ .peer_name = "sgsn", .default_remote_pc = DEFAULT_PC_SGSN, .vty = { - /* FUTURE: This will be added here shortly: - * - defaults for global NRI config: bitlen and NULL-NRI. - */ + .nri_bitlen = OSMO_NRI_BITLEN_DEFAULT, + .null_nri_ranges = osmo_nri_ranges_alloc(g_hnbgw), }, }; INIT_LLIST_HEAD(&g_hnbgw->sccp.cnpool_iups.cnlinks); diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index d829718..9dc2016 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -27,6 +27,8 @@ #include <osmocom/core/utils.h> #include <osmocom/core/timer.h> +#include <osmocom/gsm/gsm23236.h> + #include <osmocom/sigtran/protocol/m3ua.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/sccp_helpers.h> @@ -453,12 +455,26 @@ void hnbgw_cnpool_apply_cfg(struct hnbgw_cnpool *cnpool) { - cnpool->use = cnpool->vty; + struct osmo_nri_range *r; + + cnpool->use.nri_bitlen = cnpool->vty.nri_bitlen; + + osmo_nri_ranges_free(cnpool->use.null_nri_ranges); + cnpool->use.null_nri_ranges = osmo_nri_ranges_alloc(g_hnbgw); + llist_for_each_entry(r, &cnpool->vty.null_nri_ranges->entries, entry) + osmo_nri_ranges_add(cnpool->use.null_nri_ranges, r); } static void hnbgw_cnlink_cfg_copy(struct hnbgw_cnlink *cnlink) { + struct osmo_nri_range *r; + osmo_talloc_replace_string(cnlink, &cnlink->use.remote_addr_name, cnlink->vty.remote_addr_name); + + osmo_nri_ranges_free(cnlink->use.nri_ranges); + cnlink->use.nri_ranges = osmo_nri_ranges_alloc(cnlink); + llist_for_each_entry(r, &cnlink->vty.nri_ranges->entries, entry) + osmo_nri_ranges_add(cnlink->use.nri_ranges, r); } static bool hnbgw_cnlink_sccp_cfg_changed(struct hnbgw_cnlink *cnlink) @@ -636,7 +652,9 @@ .nr = nr, .vty = { /* VTY config defaults for the new cnlink */ + .nri_ranges = osmo_nri_ranges_alloc(cnlink), }, + .allow_attach = true, }; INIT_LLIST_HEAD(&cnlink->map_list); diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 206db4f..3404a3f 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -26,6 +26,8 @@ #include <osmocom/vty/command.h> #include <osmocom/vty/tdef_vty.h> +#include <osmocom/gsm/gsm23236.h> + #include <osmocom/hnbgw/vty.h> #include <osmocom/hnbgw/hnbgw.h> @@ -346,6 +348,69 @@ return CMD_WARNING; } +#define NRI_STR "Mapping of Network Resource Indicators to this CN peer, for CN pooling\n" +#define NULL_NRI_STR "Define NULL-NRI values that cause re-assignment of an MS to a different CN peer, for CN pooling.\n" +#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \ + "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \ + " first value; if omitted, apply only the first value.\n" +#define NRI_ARGS_TO_STR_FMT "%s%s%s" +#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : "" + +#define NRI_WARN(CNLINK, FORMAT, args...) do { \ + vty_out(vty, "%% Warning: %s %d: " FORMAT "%s", CNLINK->pool->peer_name, CNLINK->nr, ##args, \ + VTY_NEWLINE); \ + LOGP(DCN, LOGL_ERROR, "%s %d: " FORMAT "\n", CNLINK->pool->peer_name, CNLINK->nr, ##args); \ + } while (0) + + +/* hnbgw/iucs/nri ... AND hnbgw/iups/nri ... */ +DEFUN(cfg_hnbgw_cnpool_nri_bitlen, + cfg_hnbgw_cnpool_nri_bitlen_cmd, + "nri bitlen <1-15>", + NRI_STR + "Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet).\n" + "bit count (default: " OSMO_STRINGIFY_VAL(OSMO_NRI_BITLEN_DEFAULT) ")\n") +{ + struct hnbgw_cnpool *cnpool = vty->index; + cnpool->vty.nri_bitlen = atoi(argv[0]); + return CMD_SUCCESS; +} + +/* hnbgw/iucs/nri ... AND hnbgw/iups/nri ... */ +DEFUN(cfg_hnbgw_cnpool_nri_null_add, cfg_hnbgw_cnpool_nri_null_add_cmd, + "nri null add <0-32767> [<0-32767>]", + NRI_STR NULL_NRI_STR "Add NULL-NRI value (or range)\n" + NRI_FIRST_LAST_STR) +{ + int rc; + const char *message; + struct hnbgw_cnpool *cnpool = vty->index; + rc = osmo_nri_ranges_vty_add(&message, NULL, cnpool->vty.null_nri_ranges, argc, argv, cnpool->vty.nri_bitlen); + if (message) + vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + if (rc < 0) + return CMD_WARNING; + return CMD_SUCCESS; +} + +/* hnbgw/iucs/nri ... AND hnbgw/iups/nri ... */ +DEFUN(cfg_hnbgw_cnpool_nri_null_del, cfg_hnbgw_cnpool_nri_null_del_cmd, + "nri null del <0-32767> [<0-32767>]", + NRI_STR NULL_NRI_STR "Remove NRI value or range from the NRI mapping for this CN link\n" + NRI_FIRST_LAST_STR) +{ + int rc; + const char *message; + struct hnbgw_cnpool *cnpool = vty->index; + rc = osmo_nri_ranges_vty_del(&message, NULL, cnpool->vty.null_nri_ranges, argc, argv); + if (message) + vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv), + VTY_NEWLINE); + if (rc < 0) + return CMD_WARNING; + return CMD_SUCCESS; +} + /* Legacy from when there was only one IuCS and one IuPS peer. Instead, there are now 'msc 123' / 'sgsn 123' sub nodes. * To yield legacy behavior, set the first cnlink config in this pool ('msc 0' / 'sgsn 0'). */ DEFUN_DEPRECATED(cfg_hnbgw_cnpool_remote_addr, @@ -436,6 +501,217 @@ return CMD_SUCCESS; } +DEFUN_ATTR(cfg_cnlink_nri_add, cfg_cnlink_nri_add_cmd, + "nri add <0-32767> [<0-32767>]", + NRI_STR "Add NRI value or range to the NRI mapping for this CN link\n" + NRI_FIRST_LAST_STR, + CMD_ATTR_IMMEDIATE) +{ + struct hnbgw_cnlink *cnlink = vty->index; + struct hnbgw_cnlink *other_cnlink; + bool before; + int rc; + const char *message; + struct osmo_nri_range added_range; + + rc = osmo_nri_ranges_vty_add(&message, &added_range, cnlink->vty.nri_ranges, argc, argv, cnlink->pool->vty.nri_bitlen); + if (message) { + NRI_WARN(cnlink, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; + + /* Issue a warning about NRI range overlaps (but still allow them). + * Overlapping ranges will map to whichever CN link comes fist in the llist, + * which is not necessarily in the order of increasing cnlink->nr. */ + before = true; + llist_for_each_entry(other_cnlink, &cnlink->pool->cnlinks, entry) { + if (other_cnlink == cnlink) { + before = false; + continue; + } + if (osmo_nri_range_overlaps_ranges(&added_range, other_cnlink->vty.nri_ranges)) { + NRI_WARN(cnlink, "NRI range [%d..%d] overlaps between %s %d and %s %d." + " For overlaps, %s %d has higher priority than %s %d", + added_range.first, added_range.last, cnlink->pool->peer_name, cnlink->nr, + other_cnlink->pool->peer_name, other_cnlink->nr, + (before ? other_cnlink : cnlink)->pool->peer_name, + (before ? other_cnlink : cnlink)->nr, + (before ? cnlink : other_cnlink)->pool->peer_name, + (before ? cnlink : other_cnlink)->nr); + } + } + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_cnlink_nri_del, cfg_cnlink_nri_del_cmd, + "nri del <0-32767> [<0-32767>]", + NRI_STR "Remove NRI value or range from the NRI mapping for this CN link\n" + NRI_FIRST_LAST_STR, + CMD_ATTR_IMMEDIATE) +{ + struct hnbgw_cnlink *cnlink = vty->index; + int rc; + const char *message; + + rc = osmo_nri_ranges_vty_del(&message, NULL, cnlink->vty.nri_ranges, argc, argv); + if (message) { + NRI_WARN(cnlink, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_cnlink_allow_attach, cfg_cnlink_allow_attach_cmd, + "allow-attach", + "Allow this CN link to attach new subscribers (default).\n", + CMD_ATTR_IMMEDIATE) +{ + struct hnbgw_cnlink *cnlink = vty->index; + cnlink->allow_attach = true; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_cnlink_no_allow_attach, cfg_cnlink_no_allow_attach_cmd, + "no allow-attach", + NO_STR + "Do not assign new subscribers to this CN link." + " Useful if an CN link in an CN link pool is configured to off-load subscribers." + " The CN link will still be operational for already IMSI-Attached subscribers," + " but the NAS node selection function will skip this CN link for new subscribers\n", + CMD_ATTR_IMMEDIATE) +{ + struct hnbgw_cnlink *cnlink = vty->index; + cnlink->allow_attach = false; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_cnlink_allow_emerg, + cfg_cnlink_allow_emerg_cmd, + "allow-emergency", + "Allow CM ServiceRequests with type emergency on this CN link\n", + CMD_ATTR_IMMEDIATE) +{ + struct hnbgw_cnlink *cnlink = vty->index; + cnlink->allow_emerg = true; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_cnlink_no_allow_emerg, + cfg_cnlink_no_allow_emerg_cmd, + "no allow-emergency", + NO_STR + "Do not serve CM ServiceRequests with type emergency on this CN link\n", + CMD_ATTR_IMMEDIATE) +{ + struct hnbgw_cnlink *cnlink = vty->index; + cnlink->allow_emerg = false; + return CMD_SUCCESS; +} + +static void cnlink_write_nri(struct vty *vty, struct hnbgw_cnlink *cnlink, bool verbose) +{ + struct osmo_nri_range *r; + + if (verbose) { + vty_out(vty, "%s %d%s", cnlink->pool->peer_name, cnlink->nr, VTY_NEWLINE); + if (llist_empty(&cnlink->vty.nri_ranges->entries)) { + vty_out(vty, " %% no NRI mappings%s", VTY_NEWLINE); + return; + } + } + + llist_for_each_entry(r, &cnlink->vty.nri_ranges->entries, entry) { + if (osmo_nri_range_validate(r, 255)) + vty_out(vty, " %% INVALID RANGE:"); + vty_out(vty, " nri add %d", r->first); + if (r->first != r->last) + vty_out(vty, " %d", r->last); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (!cnlink->allow_attach) + vty_out(vty, " no allow-attach%s", VTY_NEWLINE); + if (cnlink->allow_emerg) + vty_out(vty, " allow-emergency%s", VTY_NEWLINE); +} + +DEFUN(cfg_cnlink_show_nri, cfg_cnlink_show_nri_cmd, + "show nri", + SHOW_STR NRI_STR) +{ + struct hnbgw_cnlink *cnlink = vty->index; + cnlink_write_nri(vty, cnlink, true); + return CMD_SUCCESS; +} + +void cnlinks_write_nri(struct vty *vty, struct hnbgw_cnpool *cnpool, bool verbose) +{ + struct hnbgw_cnlink *cnlink; + llist_for_each_entry(cnlink, &cnpool->cnlinks, entry) + cnlink_write_nri(vty, cnlink, verbose); +} + +void cnpool_write_nri(struct vty *vty, struct hnbgw_cnpool *cnpool, bool verbose) +{ + struct osmo_nri_range *r; + + if (verbose) + vty_out(vty, " %s%s", cnpool->pool_name, VTY_NEWLINE); + + if (verbose || cnpool->vty.nri_bitlen != OSMO_NRI_BITLEN_DEFAULT) + vty_out(vty, " nri bitlen %u%s", cnpool->vty.nri_bitlen, VTY_NEWLINE); + + llist_for_each_entry(r, &cnpool->vty.null_nri_ranges->entries, entry) { + vty_out(vty, " nri null add %d", r->first); + if (r->first != r->last) + vty_out(vty, " %d", r->last); + vty_out(vty, "%s", VTY_NEWLINE); + } + if (verbose && llist_empty(&cnpool->vty.null_nri_ranges->entries)) + vty_out(vty, " %% No NULL-NRI entries%s", VTY_NEWLINE); +} + +DEFUN(show_nri, show_nri_cmd, + "show nri", + SHOW_STR NRI_STR) +{ + /* hnbgw + * iucs + * nri null add ... + */ + vty_out(vty, "hnbgw%s", VTY_NEWLINE); + cnpool_write_nri(vty, &g_hnbgw->sccp.cnpool_iucs, true); + cnpool_write_nri(vty, &g_hnbgw->sccp.cnpool_iups, true); + + /* msc 0 + * nri add ... + */ + cnlinks_write_nri(vty, &g_hnbgw->sccp.cnpool_iucs, true); + cnlinks_write_nri(vty, &g_hnbgw->sccp.cnpool_iups, true); + return CMD_SUCCESS; +} + +/* Hidden since it exists only for use by ttcn3 tests */ +DEFUN_HIDDEN(cnpool_roundrobin_next, cnpool_roundrobin_next_cmd, + "cnpool roundrobin next (msc|sgsn) " CNLINK_NR_RANGE, + "CN pooling: load balancing across multiple CN links.\n" + "Adjust current state of the CN link round-robin algorithm (for testing).\n" + "Set the CN link nr to direct the next new subscriber to (for testing).\n" + "Set next MSC or next SGSN number\n" + "CN link number, as in the config file; if the number does not exist," + " the round-robin continues to the next valid number.\n") +{ + struct hnbgw_cnpool *cnpool; + if (!strcmp("msc", argv[0])) + cnpool = &g_hnbgw->sccp.cnpool_iucs; + else + cnpool = &g_hnbgw->sccp.cnpool_iups; + cnpool->round_robin_next_nr = atoi(argv[1]); + return CMD_SUCCESS; +} + #define APPLY_STR "Immediately use configuration modified via telnet VTY, and restart components as needed.\n" #define SCCP_RESTART_STR \ " If 'remote-addr' changed, related SCCP links will be restarted, possibly dropping active UE contexts." @@ -518,6 +794,21 @@ #endif /* ENABLE_PFCP */ +/* hnbgw + * iucs } this part + * foo } + */ +static void _config_write_cnpool(struct vty *vty, struct hnbgw_cnpool *cnpool) +{ + if (cnpool->vty.nri_bitlen == OSMO_NRI_BITLEN_DEFAULT + && llist_empty(&cnpool->vty.null_nri_ranges->entries)) + return; + + vty_out(vty, " %s%s", cnpool->pool_name, VTY_NEWLINE); + + cnpool_write_nri(vty, cnpool, false); +} + static int config_write_hnbgw(struct vty *vty) { vty_out(vty, "hnbgw%s", VTY_NEWLINE); @@ -528,6 +819,9 @@ VTY_NEWLINE); osmo_tdef_vty_groups_write(vty, " "); + _config_write_cnpool(vty, &g_hnbgw->sccp.cnpool_iucs); + _config_write_cnpool(vty, &g_hnbgw->sccp.cnpool_iups); + return CMD_SUCCESS; } @@ -565,7 +859,7 @@ vty_out(vty, "%s %d%s", cnpool->peer_name, cnlink->nr, VTY_NEWLINE); if (cnlink->vty.remote_addr_name) vty_out(vty, " remote-addr %s%s", cnlink->vty.remote_addr_name, VTY_NEWLINE); - /* FUTURE: NRI config */ + cnlink_write_nri(vty, cnlink, false); } } @@ -597,7 +891,14 @@ static void install_cnlink_elements(int node) { install_element(node, &cfg_cnlink_remote_addr_cmd); + install_element(node, &cfg_cnlink_nri_add_cmd); + install_element(node, &cfg_cnlink_nri_del_cmd); + install_element(node, &cfg_cnlink_show_nri_cmd); install_element(node, &cfg_cnlink_apply_sccp_cmd); + install_element(node, &cfg_cnlink_allow_attach_cmd); + install_element(node, &cfg_cnlink_no_allow_attach_cmd); + install_element(node, &cfg_cnlink_allow_emerg_cmd); + install_element(node, &cfg_cnlink_no_allow_emerg_cmd); } void hnbgw_vty_init(void) @@ -618,9 +919,15 @@ install_element(HNBGW_NODE, &cfg_hnbgw_iucs_cmd); install_node(&iucs_node, NULL); + install_element(IUCS_NODE, &cfg_hnbgw_cnpool_nri_bitlen_cmd); + install_element(IUCS_NODE, &cfg_hnbgw_cnpool_nri_null_add_cmd); + install_element(IUCS_NODE, &cfg_hnbgw_cnpool_nri_null_del_cmd); install_element(HNBGW_NODE, &cfg_hnbgw_iups_cmd); install_node(&iups_node, NULL); + install_element(IUPS_NODE, &cfg_hnbgw_cnpool_nri_bitlen_cmd); + install_element(IUPS_NODE, &cfg_hnbgw_cnpool_nri_null_add_cmd); + install_element(IUPS_NODE, &cfg_hnbgw_cnpool_nri_null_del_cmd); /* deprecated: 'remote-addr' outside of 'msc 123' redirects to 'msc 0' / same for 'sgsn' */ install_element(IUCS_NODE, &cfg_hnbgw_cnpool_remote_addr_cmd); @@ -647,6 +954,8 @@ install_element(PFCP_NODE, &cfg_pfcp_remote_addr_cmd); #endif + osmo_tdef_vty_groups_init(HNBGW_NODE, hnbgw_tdef_group); + install_element(CONFIG_NODE, &cfg_msc_nr_cmd); install_node(&msc_node, config_write_msc); install_cnlink_elements(MSC_NODE); @@ -658,5 +967,6 @@ /* global 'apply sccp' command. There are two more on MSC_NODE and SGSN_NODE from install_cnlink_elements(). */ install_element(CONFIG_NODE, &cfg_config_apply_sccp_cmd); - osmo_tdef_vty_groups_init(HNBGW_NODE, hnbgw_tdef_group); + install_element_ve(&show_nri_cmd); + install_element(ENABLE_NODE, &cnpool_roundrobin_next_cmd); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 62fb6c6..f34d9a0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,7 +25,7 @@ $(srcdir)/package.m4 \ $(TESTSUITE) \ osmo-hnbgw-vty-test.cfg \ - osmo-hnbgw.vty \ + $(srcdir)/*.vty \ $(srcdir)/config/*.cfg \ $(srcdir)/config/*.vty \ $(srcdir)/config/run_tests.sh \ diff --git a/tests/cnpool.vty b/tests/cnpool.vty index 6b57122..9745306 100644 --- a/tests/cnpool.vty +++ b/tests/cnpool.vty @@ -2,6 +2,17 @@ OsmoHNBGW# configure terminal OsmoHNBGW(config)# ### cnpool doc strings +OsmoHNBGW(config)# list +... + apply sccp +... + +OsmoHNBGW(config)# apply? + apply Immediately use configuration modified via telnet VTY, and restart components as needed. + +OsmoHNBGW(config)# apply ? + sccp For telnet VTY: apply all SCCP and NRI config changes made to any CN pools and CN links in the running osmo-hnbgw process. If 'remote-addr' changed, related SCCP links will be restarted, possibly dropping active UE contexts. This is run implicitly on program startup, only useful to apply changes made later via telnet VTY. + OsmoHNBGW(config)# hnbgw OsmoHNBGW(config-hnbgw)# list ... @@ -13,6 +24,79 @@ OsmoHNBGW(config-hnbgw)# iups? iups Configure IuPS options +OsmoHNBGW(config-hnbgw)# iucs + +OsmoHNBGW(config-hnbgw-iucs)# list +... + nri bitlen <1-15> + nri null add <0-32767> [<0-32767>] + nri null del <0-32767> [<0-32767>] +... + +OsmoHNBGW(config-hnbgw-iucs)# nri? + nri Mapping of Network Resource Indicators to this CN peer, for CN pooling + +OsmoHNBGW(config-hnbgw-iucs)# nri ? + bitlen Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet). + null Define NULL-NRI values that cause re-assignment of an MS to a different CN peer, for CN pooling. + +OsmoHNBGW(config-hnbgw-iucs)# nri bitlen ? + <1-15> bit count (default: 10) + +OsmoHNBGW(config-hnbgw-iucs)# nri null ? + add Add NULL-NRI value (or range) + del Remove NRI value or range from the NRI mapping for this CN link + +OsmoHNBGW(config-hnbgw-iucs)# nri null add ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. + +OsmoHNBGW(config-hnbgw-iucs)# nri null add 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iucs)# nri null del ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. + +OsmoHNBGW(config-hnbgw-iucs)# nri null del 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iucs)# exit + +OsmoHNBGW(config-hnbgw)# iups + +OsmoHNBGW(config-hnbgw-iups)# list +... + nri bitlen <1-15> + nri null add <0-32767> [<0-32767>] + nri null del <0-32767> [<0-32767>] +... + +OsmoHNBGW(config-hnbgw-iups)# nri? + nri Mapping of Network Resource Indicators to this CN peer, for CN pooling + +OsmoHNBGW(config-hnbgw-iups)# nri ? + bitlen Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet). + null Define NULL-NRI values that cause re-assignment of an MS to a different CN peer, for CN pooling. + +OsmoHNBGW(config-hnbgw-iups)# nri bitlen ? + <1-15> bit count (default: 10) + +OsmoHNBGW(config-hnbgw-iups)# nri null ? + add Add NULL-NRI value (or range) + del Remove NRI value or range from the NRI mapping for this CN link + +OsmoHNBGW(config-hnbgw-iups)# nri null add ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. + +OsmoHNBGW(config-hnbgw-iups)# nri null add 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iups)# nri null del ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. + +OsmoHNBGW(config-hnbgw-iups)# nri null del 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iups)# exit OsmoHNBGW(config-hnbgw)# exit OsmoHNBGW(config)# msc? @@ -37,7 +121,14 @@ OsmoHNBGW(config-msc)# list ... remote-addr NAME + nri add <0-32767> [<0-32767>] + nri del <0-32767> [<0-32767>] + show nri apply sccp + allow-attach + no allow-attach + allow-emergency + no allow-emergency ... OsmoHNBGW(config-msc)# remote-addr? @@ -45,11 +136,25 @@ OsmoHNBGW(config-msc)# remote-addr ? NAME SCCP address book entry name (see 'cs7 instance' / 'sccp-address') +OsmoHNBGW(config-msc)# show nri? + nri Mapping of Network Resource Indicators to this CN peer, for CN pooling + OsmoHNBGW(config-msc)# apply? apply Immediately use configuration modified via telnet VTY, and restart components as needed. + OsmoHNBGW(config-msc)# apply ? sccp For telnet VTY: apply SCCP and NRI config changes made to this CN link in the running osmo-hnbgw process. If 'remote-addr' changed, related SCCP links will be restarted, possibly dropping active UE contexts. This is run implicitly on program startup, only useful to apply changes made later via telnet VTY. +OsmoHNBGW(config-msc)# allow-attach? + allow-attach Allow this CN link to attach new subscribers (default). + +OsmoHNBGW(config-msc)# allow-emergency? + allow-emergency Allow CM ServiceRequests with type emergency on this CN link + +OsmoHNBGW(config-msc)# no ? + allow-attach Do not assign new subscribers to this CN link. Useful if an CN link in an CN link pool is configured to off-load subscribers. The CN link will still be operational for already IMSI-Attached subscribers, but the NAS node selection function will skip this CN link for new subscribers + allow-emergency Do not serve CM ServiceRequests with type emergency on this CN link + OsmoHNBGW(config-msc)# exit OsmoHNBGW(config)# sgsn 1 @@ -57,7 +162,14 @@ OsmoHNBGW(config-sgsn)# list ... remote-addr NAME + nri add <0-32767> [<0-32767>] + nri del <0-32767> [<0-32767>] + show nri apply sccp + allow-attach + no allow-attach + allow-emergency + no allow-emergency ... OsmoHNBGW(config-sgsn)# remote-addr? @@ -65,11 +177,25 @@ OsmoHNBGW(config-sgsn)# remote-addr ? NAME SCCP address book entry name (see 'cs7 instance' / 'sccp-address') +OsmoHNBGW(config-sgsn)# show nri? + nri Mapping of Network Resource Indicators to this CN peer, for CN pooling + OsmoHNBGW(config-sgsn)# apply? apply Immediately use configuration modified via telnet VTY, and restart components as needed. + OsmoHNBGW(config-sgsn)# apply ? sccp For telnet VTY: apply SCCP and NRI config changes made to this CN link in the running osmo-hnbgw process. If 'remote-addr' changed, related SCCP links will be restarted, possibly dropping active UE contexts. This is run implicitly on program startup, only useful to apply changes made later via telnet VTY. +OsmoHNBGW(config-sgsn)# allow-attach? + allow-attach Allow this CN link to attach new subscribers (default). + +OsmoHNBGW(config-sgsn)# allow-emergency? + allow-emergency Allow CM ServiceRequests with type emergency on this CN link + +OsmoHNBGW(config-sgsn)# no ? + allow-attach Do not assign new subscribers to this CN link. Useful if an CN link in an CN link pool is configured to off-load subscribers. The CN link will still be operational for already IMSI-Attached subscribers, but the NAS node selection function will skip this CN link for new subscribers + allow-emergency Do not serve CM ServiceRequests with type emergency on this CN link + OsmoHNBGW(config-sgsn)# exit OsmoHNBGW(config)# ### Just by entering the nodes above, 'msc 1' and 'sgsn 1' now exist @@ -85,10 +211,12 @@ OsmoHNBGW(config)# msc 2 OsmoHNBGW(config-msc)# remote-addr addr-msc2 +OsmoHNBGW(config-msc)# no allow-attach OsmoHNBGW(config-msc)# exit OsmoHNBGW(config)# msc 3 OsmoHNBGW(config-msc)# remote-addr addr-msc3 +OsmoHNBGW(config-msc)# allow-emergency OsmoHNBGW(config-msc)# exit OsmoHNBGW(config)# sgsn 2 @@ -105,8 +233,10 @@ msc 1 msc 2 remote-addr addr-msc2 + no allow-attach msc 3 remote-addr addr-msc3 + allow-emergency sgsn 0 sgsn 1 sgsn 2 @@ -116,8 +246,12 @@ ... OsmoHNBGW(config)# ### Re-entering existing nodes works (does not create new ones) +OsmoHNBGW(config)# msc 2 +OsmoHNBGW(config-msc)# allow-attach +OsmoHNBGW(config-msc)# exit OsmoHNBGW(config)# msc 3 OsmoHNBGW(config-msc)# remote-addr addr-msc4 +OsmoHNBGW(config-msc)# no allow-emergency OsmoHNBGW(config-msc)# exit OsmoHNBGW(config)# sgsn 2 OsmoHNBGW(config-sgsn)# remote-addr addr-sgsn4 diff --git a/tests/nri_cfg.vty b/tests/nri_cfg.vty new file mode 100644 index 0000000..e8a820b --- /dev/null +++ b/tests/nri_cfg.vty @@ -0,0 +1,279 @@ +OsmoHNBGW> show nri +hnbgw + iucs + nri bitlen 10 + % No NULL-NRI entries + iups + nri bitlen 10 + % No NULL-NRI entries +msc 0 + % no NRI mappings +sgsn 0 + % no NRI mappings + +OsmoHNBGW> enable +OsmoHNBGW# configure terminal + +OsmoHNBGW(config)# msc 0 + +OsmoHNBGW(config-msc)# list +... + nri add <0-32767> [<0-32767>] + nri del <0-32767> [<0-32767>] + show nri +... +OsmoHNBGW(config-msc)# nri ? + add Add NRI value or range to the NRI mapping for this CN link + del Remove NRI value or range from the NRI mapping for this CN link +OsmoHNBGW(config-msc)# nri add ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. +OsmoHNBGW(config-msc)# nri add 23 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-msc)# nri add 23 +OsmoHNBGW(config-msc)# nri add 256 511 +OsmoHNBGW(config-msc)# nri add 100 200 +OsmoHNBGW(config-msc)# nri add 1024 1024 +% Warning: msc 0: Warning: NRI range surpasses current NRI bitlen: 1024..1024 +OsmoHNBGW(config-msc)# show nri +msc 0 + nri add 23 + nri add 100 200 + nri add 256 511 + nri add 1024 +OsmoHNBGW(config-msc)# exit + +OsmoHNBGW(config)# ### Do msc 2 first, to see that the order of mscs in the internal list is not determined by the msc->nr, +OsmoHNBGW(config)# ### and whichever was configured first gets higher priority for overlaps. + +OsmoHNBGW(config)# msc 2 +OsmoHNBGW(config-msc)# nri add 200 300 +% Warning: msc 2: NRI range [200..300] overlaps between msc 2 and msc 0. For overlaps, msc 0 has higher priority than msc 2 +OsmoHNBGW(config-msc)# nri add 1024 1025 +% Warning: msc 2: Warning: NRI range surpasses current NRI bitlen: 1024..1025 +% Warning: msc 2: NRI range [1024..1025] overlaps between msc 2 and msc 0. For overlaps, msc 0 has higher priority than msc 2 +OsmoHNBGW(config-msc)# exit + +OsmoHNBGW(config)# msc 1 +OsmoHNBGW(config-msc)# nri add 42 +OsmoHNBGW(config-msc)# nri add 512 767 +OsmoHNBGW(config-msc)# nri add 200 300 +% Warning: msc 1: NRI range [200..300] overlaps between msc 1 and msc 0. For overlaps, msc 0 has higher priority than msc 1 +% Warning: msc 1: NRI range [200..300] overlaps between msc 1 and msc 2. For overlaps, msc 2 has higher priority than msc 1 +OsmoHNBGW(config-msc)# nri add 1024 1025 +% Warning: msc 1: Warning: NRI range surpasses current NRI bitlen: 1024..1025 +% Warning: msc 1: NRI range [1024..1025] overlaps between msc 1 and msc 0. For overlaps, msc 0 has higher priority than msc 1 +% Warning: msc 1: NRI range [1024..1025] overlaps between msc 1 and msc 2. For overlaps, msc 2 has higher priority than msc 1 +OsmoHNBGW(config-msc)# show nri +msc 1 + nri add 42 + nri add 200 300 + nri add 512 767 + nri add 1024 1025 +OsmoHNBGW(config-msc)# exit + +OsmoHNBGW(config)# do show nri +hnbgw + iucs + nri bitlen 10 + % No NULL-NRI entries + iups + nri bitlen 10 + % No NULL-NRI entries +msc 0 + nri add 23 + nri add 100 200 + nri add 256 511 + nri add 1024 +msc 2 + nri add 200 300 + nri add 1024 1025 +msc 1 + nri add 42 + nri add 200 300 + nri add 512 767 + nri add 1024 1025 +sgsn 0 + % no NRI mappings + +OsmoHNBGW(config)# ### msc and sgsn have separate scopes of NRI, i.e. overlaps are no problem +OsmoHNBGW(config)# sgsn 0 +OsmoHNBGW(config-sgsn)# nri add 0 1023 +OsmoHNBGW(config-sgsn)# show nri +sgsn 0 + nri add 0 1023 +OsmoHNBGW(config-sgsn)# exit + +OsmoHNBGW(config)# ### NULL-NRI config +OsmoHNBGW(config)# hnbgw +OsmoHNBGW(config-hnbgw)# iucs + +OsmoHNBGW(config-hnbgw-iucs)# list +... + nri bitlen <1-15> + nri null add <0-32767> [<0-32767>] + nri null del <0-32767> [<0-32767>] +... + +OsmoHNBGW(config-hnbgw-iucs)# nri ? + bitlen Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet). + null Define NULL-NRI values that cause re-assignment of an MS to a different CN peer, for CN pooling. + +OsmoHNBGW(config-hnbgw-iucs)# nri bitlen ? + <1-15> bit count (default: 10) + +OsmoHNBGW(config-hnbgw-iucs)# nri bitlen 11 +OsmoHNBGW(config-hnbgw-iucs)# show running-config +... +hnbgw +... + iucs +... + nri bitlen 11 +... + +OsmoHNBGW(config-hnbgw-iucs)# nri null ? + add Add NULL-NRI value (or range) + del Remove NRI value or range from the NRI mapping for this CN link + +OsmoHNBGW(config-hnbgw-iucs)# nri null add ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. +OsmoHNBGW(config-hnbgw-iucs)# nri null add 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iucs)# nri null del ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. +OsmoHNBGW(config-hnbgw-iucs)# nri null del 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iucs)# exit + +OsmoHNBGW(config-hnbgw)# iups + +OsmoHNBGW(config-hnbgw-iups)# list +... + nri bitlen <1-15> + nri null add <0-32767> [<0-32767>] + nri null del <0-32767> [<0-32767>] +... + +OsmoHNBGW(config-hnbgw-iups)# nri ? + bitlen Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet). + null Define NULL-NRI values that cause re-assignment of an MS to a different CN peer, for CN pooling. + +OsmoHNBGW(config-hnbgw-iups)# nri bitlen ? + <1-15> bit count (default: 10) + +OsmoHNBGW(config-hnbgw-iups)# nri bitlen 9 +OsmoHNBGW(config-hnbgw-iups)# show running-config +... +hnbgw +... + iups +... + nri bitlen 9 +... + +OsmoHNBGW(config-hnbgw-iups)# nri null ? + add Add NULL-NRI value (or range) + del Remove NRI value or range from the NRI mapping for this CN link + +OsmoHNBGW(config-hnbgw-iups)# nri null add ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. +OsmoHNBGW(config-hnbgw-iups)# nri null add 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iups)# nri null del ? + <0-32767> First value of the NRI value range, should not surpass the configured 'nri bitlen'. +OsmoHNBGW(config-hnbgw-iups)# nri null del 0 ? + [<0-32767>] Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the first value; if omitted, apply only the first value. + +OsmoHNBGW(config-hnbgw-iups)# exit + +OsmoHNBGW(config-hnbgw)# exit + +OsmoHNBGW(config)# msc 0 +OsmoHNBGW(config-msc)# nri del 0 10000 +OsmoHNBGW(config-msc)# exit +OsmoHNBGW(config)# msc 1 +OsmoHNBGW(config-msc)# nri del 0 10000 +OsmoHNBGW(config-msc)# exit +OsmoHNBGW(config)# msc 2 +OsmoHNBGW(config-msc)# nri del 0 10000 +OsmoHNBGW(config-msc)# exit +OsmoHNBGW(config)# do show nri +hnbgw + iucs + nri bitlen 11 + % No NULL-NRI entries + iups + nri bitlen 9 + % No NULL-NRI entries +msc 0 + % no NRI mappings +msc 2 + % no NRI mappings +msc 1 + % no NRI mappings +sgsn 0 + nri add 0 1023 + +OsmoHNBGW(config)# msc 0 +OsmoHNBGW(config-msc)# nri add 0 1000 +OsmoHNBGW(config-msc)# show nri +msc 0 + nri add 0 1000 +OsmoHNBGW(config-msc)# nri del 23 +OsmoHNBGW(config-msc)# nri del 200 300 +OsmoHNBGW(config-msc)# nri del 1000 2000 +OsmoHNBGW(config-msc)# show nri +msc 0 + nri add 0 22 + nri add 24 199 + nri add 301 999 +OsmoHNBGW(config-msc)# nri add 23 +OsmoHNBGW(config-msc)# show nri +msc 0 + nri add 0 199 + nri add 301 999 +OsmoHNBGW(config-msc)# nri add 200 300 +OsmoHNBGW(config-msc)# show nri +msc 0 + nri add 0 999 +OsmoHNBGW(config-msc)# nri add 1000 +OsmoHNBGW(config-msc)# show nri +msc 0 + nri add 0 1000 + +OsmoHNBGW(config-msc)# show running-config +... ! no allow-attach +OsmoHNBGW(config-msc)# no allow-attach +OsmoHNBGW(config-msc)# show running-config +... +msc 0 +... + nri add 0 1000 + no allow-attach +... ! no allow-attach +OsmoHNBGW(config-msc)# exit +OsmoHNBGW(config)# sgsn 1 +OsmoHNBGW(config-sgsn)# no allow-attach +OsmoHNBGW(config-sgsn)# show running-config +... +msc 0 +... + nri add 0 1000 + no allow-attach +... ! no allow-attach +sgsn 1 +... + no allow-attach +... + +OsmoHNBGW(config-sgsn)# allow-attach +OsmoHNBGW(config-sgsn)# exit +OsmoHNBGW(config)# msc 0 +OsmoHNBGW(config-msc)# allow-attach +OsmoHNBGW(config-msc)# show running-config +... ! no allow-attach +OsmoHNBGW(config-msc)# exit -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/33130 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Ifb87e01e5971962e5cfe5e127871af4a67806de1 Gerrit-Change-Number: 33130 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: newchange
1 0
0 0
[M] Change in osmo-hnbgw[master]: add separate cfg file only for VTY tests
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32990 ) Change subject: add separate cfg file only for VTY tests ...................................................................... add separate cfg file only for VTY tests Instead of doc/examples/osmo-hnbgw.cfg, use a separate location tests/osmo-hnbgw-vty-test.cfg for VTY transcript tests, and add a bunch of SCCP address book entries that upcoming VTY tests will use. Declaring address book entries within transcript tests is possible, but cluttered with node 'exit' and VTY prompts -- these addresses are much easier to read and maintain in form of a cfg file. First user of these address book entries will be cnpool.vty in I5479eded786ec26062d49403a8be12967f113cdb Related: SYS#6412 Change-Id: Idcdf0e8660e8180fbe02282bc94e623ff89e848a --- M tests/Makefile.am A tests/osmo-hnbgw-vty-test.cfg 2 files changed, 63 insertions(+), 1 deletion(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved diff --git a/tests/Makefile.am b/tests/Makefile.am index 0225d7e..58d6592 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,6 +24,7 @@ testsuite.at \ $(srcdir)/package.m4 \ $(TESTSUITE) \ + osmo-hnbgw-vty-test.cfg \ osmo-hnbgw.vty \ $(NULL) @@ -53,7 +54,7 @@ osmo_verify_transcript_vty.py -v \ -n OsmoHNBGW -p 4261 \ -r "$(top_builddir)/src/osmo-hnbgw/osmo-hnbgw \ - -c $(top_srcdir)/doc/examples/osmo-hnbgw/osmo-hnbgw.cfg" \ + -c $(srcdir)/osmo-hnbgw-vty-test.cfg" \ $(U) $(srcdir)/$(VTY_TEST) check-local: atconfig $(TESTSUITE) diff --git a/tests/osmo-hnbgw-vty-test.cfg b/tests/osmo-hnbgw-vty-test.cfg new file mode 100644 index 0000000..6f9c0b6 --- /dev/null +++ b/tests/osmo-hnbgw-vty-test.cfg @@ -0,0 +1,40 @@ +log stderr + logging filter all 1 + logging color 1 + logging print level 1 + logging print category 1 + logging print category-hex 0 + logging print file basename last + logging print extended-timestamp 1 + logging level set-all notice + +# Define some cs7 address book entries to play with +cs7 instance 0 + sccp-address addr-msc0 + point-code 0.1.0 + sccp-address addr-msc2 + point-code 0.1.2 + sccp-address addr-sgsn3 + point-code 0.2.3 + sccp-address addr-sgsn4 + point-code 0.2.4 + +cs7 instance 1 + sccp-address addr-sgsn0 + point-code 1.2.0 + sccp-address addr-sgsn2 + point-code 1.2.2 + sccp-address addr-msc3 + point-code 1.1.3 + sccp-address addr-msc4 + point-code 1.1.4 + +hnbgw + iuh + local-ip 0.0.0.0 + hnbap-allow-tmsi 1 + mgw 0 + remote-ip 127.0.0.1 + local-port 2729 + remote-port 2427 + reset-endpoint rtpbridge/* -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32990 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Idcdf0e8660e8180fbe02282bc94e623ff89e848a Gerrit-Change-Number: 32990 Gerrit-PatchSet: 2 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmo-hnbgw[master]: charts: add sccp.dot
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32322 ) ( 2 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: charts: add sccp.dot ...................................................................... charts: add sccp.dot Show current use of SCCP and SS7 by osmo-hnbgw, which is about to change (along with this chart). Related: SYS#6422 Change-Id: I109948758de998326a5e9f0dcdc84d5f11dfba02 --- M doc/charts/Makefile.am A doc/charts/sccp.dot 2 files changed, 51 insertions(+), 0 deletions(-) Approvals: msuraev: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified diff --git a/doc/charts/Makefile.am b/doc/charts/Makefile.am index 52b111f..3ffcfc8 100644 --- a/doc/charts/Makefile.am +++ b/doc/charts/Makefile.am @@ -4,6 +4,7 @@ dot: \ $(builddir)/hnbgw_context_map_fsm.png \ + $(builddir)/sccp.png \ $(NULL) $(builddir)/%.png: $(srcdir)/%.msc diff --git a/doc/charts/sccp.dot b/doc/charts/sccp.dot new file mode 100644 index 0000000..9c04c35 --- /dev/null +++ b/doc/charts/sccp.dot @@ -0,0 +1,37 @@ +digraph G { +rankdir=TB +labelloc=t; label="SCCP/SS7 use in OsmoHNBGW" + + subgraph cluster_ss0 { + label="" + ss0 [label="cs7 instance 0\n local pc: 1.1.1"] + ss0ab [label="address book"] + ss0 -> ss0ab + + msc0a [label="2.2.2"] + sgsn0a [label="3.3.3"] + ss0ab -> msc0a,sgsn0a + } + + iucs_addr [label=".iucs_addr -> 2.2.2"] + iups_addr [label=".iups_addr -> 3.3.3"] + msc0a -> iucs_addr [dir=back] + sgsn0a -> iups_addr [dir=back] + cnlink [label="hnbgw_cnlink (singleton)\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; + ss0 -> cnlink [dir=back] + + cs0 [label="UE CS conn\n hnbgw_context_map"] + cs1 [label="UE CS conn\n hnbgw_context_map"] + ps0 [label="UE PS conn\n hnbgw_context_map"] + ps1 [label="UE PS conn\n hnbgw_context_map"] + cnlink -> cs0,cs1,ps0,ps1 + iucs_addr -> cs0,cs1 [style=dotted,dir=none] + iups_addr -> ps0,ps1 [style=dotted,dir=none] + + subgraph cluster_hnbgw { + label="global hnb_gw" + cnlink + iucs_addr + iups_addr + } +} -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32322 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I109948758de998326a5e9f0dcdc84d5f11dfba02 Gerrit-Change-Number: 32322 Gerrit-PatchSet: 4 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: msuraev <msuraev(a)sysmocom.de> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[L] Change in osmo-hnbgw[master]: add startup config tests
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32991 ) Change subject: add startup config tests ...................................................................... add startup config tests Get a handle on how osmo-hnbgw currently auto-configures itself, by running vty tests with a couple of config files that have various levels of omitted config items that are to be auto-configured. These tests serve to ensure continuity and compatibility by upcoming cnpool patches. They will show how the configuration changes / doesn't change in all the right ways. Uncover one bug in osmo-hnbgw: local point-code setting is discarded by osmo-hnbgw startup when there are no SCCP address book entries in use. The error is fixed as side effect of an upcoming patch: Iea1824f1c586723d989c80a909bae16bd2866e08 Related: SYS#6412 Change-Id: Ic8bb30e1dd73753c2ff255566382e241918414f7 --- M tests/Makefile.am A tests/config/defaults.cfg A tests/config/defaults.vty A tests/config/one_cs7.cfg A tests/config/one_cs7.vty A tests/config/one_cs7_with_addrs.cfg A tests/config/one_cs7_with_addrs.vty A tests/config/one_cs7_with_iucs_addr.cfg A tests/config/one_cs7_with_iucs_addr.vty A tests/config/one_cs7_with_iups_addr.cfg A tests/config/one_cs7_with_iups_addr.vty A tests/config/run_tests.sh 12 files changed, 266 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve laforge: Looks good to me, but someone else must approve neels: Looks good to me, approved diff --git a/tests/Makefile.am b/tests/Makefile.am index 58d6592..62fb6c6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,6 +26,9 @@ $(TESTSUITE) \ osmo-hnbgw-vty-test.cfg \ osmo-hnbgw.vty \ + $(srcdir)/config/*.cfg \ + $(srcdir)/config/*.vty \ + $(srcdir)/config/run_tests.sh \ $(NULL) TESTSUITE = $(srcdir)/testsuite @@ -37,6 +40,7 @@ if ENABLE_EXT_TESTS python-tests: $(MAKE) vty-test + $(MAKE) config-tests osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v else @@ -57,6 +61,13 @@ -c $(srcdir)/osmo-hnbgw-vty-test.cfg" \ $(U) $(srcdir)/$(VTY_TEST) +# Test each config/*.cfg file with the corresponding config/*.vty transcript test. +# Each config test runs an osmo-hnbgw process to talk to, so they must not run concurrently. +# To prevent 'make -j N' from running these tests in parallel, call a script with a linear for-loop. +.PHONY: config-tests +config-tests: + $(srcdir)/config/run_tests.sh "$(top_builddir)/src/osmo-hnbgw/osmo-hnbgw" "$(srcdir)/config/" $U + check-local: atconfig $(TESTSUITE) $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) $(MAKE) $(AM_MAKEFLAGS) python-tests diff --git a/tests/config/defaults.cfg b/tests/config/defaults.cfg new file mode 100644 index 0000000..b4e37fb --- /dev/null +++ b/tests/config/defaults.cfg @@ -0,0 +1 @@ +# configure nothing, to get purely the implicit default config diff --git a/tests/config/defaults.vty b/tests/config/defaults.vty new file mode 100644 index 0000000..282c080 --- /dev/null +++ b/tests/config/defaults.vty @@ -0,0 +1,31 @@ +OsmoHNBGW> ### Config file was empty, everything we see here is the default auto configuration + +OsmoHNBGW> enable + +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 0.23.5 + asp asp-clnt-OsmoHNBGW 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-OsmoHNBGW m3ua + asp asp-clnt-OsmoHNBGW + routing-key 0 0.23.5 + +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuPS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 0.23.5 +hnbgw + rnc-id 23 + log-prefix hnb-id + iuh + mgw 0 +... diff --git a/tests/config/one_cs7.cfg b/tests/config/one_cs7.cfg new file mode 100644 index 0000000..83862d8 --- /dev/null +++ b/tests/config/one_cs7.cfg @@ -0,0 +1,3 @@ +# auto-configuration will pick up cs7 instance 0. Configure only the local point-code. +cs7 instance 0 + point-code 1.1.1 diff --git a/tests/config/one_cs7.vty b/tests/config/one_cs7.vty new file mode 100644 index 0000000..7011c83 --- /dev/null +++ b/tests/config/one_cs7.vty @@ -0,0 +1,28 @@ +OsmoHNBGW> enable + +OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5 +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 0.23.5 + asp asp-clnt-OsmoHNBGW 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-OsmoHNBGW m3ua + asp asp-clnt-OsmoHNBGW + routing-key 0 0.23.5 + +OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5 +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuPS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + +OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5 +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 0.23.5 +hnbgw +... diff --git a/tests/config/one_cs7_with_addrs.cfg b/tests/config/one_cs7_with_addrs.cfg new file mode 100644 index 0000000..0369bd4 --- /dev/null +++ b/tests/config/one_cs7_with_addrs.cfg @@ -0,0 +1,12 @@ +# explicitly point at cs7 instance 0 via two address book entries for CS and PS. Leave ASP and AS to auto-configuration. +cs7 instance 0 + point-code 1.1.1 + sccp-address my-msc + point-code 1.2.3 + sccp-address my-sgsn + point-code 1.4.2 +hnbgw + iucs + remote-addr my-msc + iups + remote-addr my-sgsn diff --git a/tests/config/one_cs7_with_addrs.vty b/tests/config/one_cs7_with_addrs.vty new file mode 100644 index 0000000..59b1b76 --- /dev/null +++ b/tests/config/one_cs7_with_addrs.vty @@ -0,0 +1,46 @@ +OsmoHNBGW> enable + +OsmoHNBGW# ### ASP and AS were auto-configured +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 1.1.1 + asp asp-clnt-OsmoHNBGW 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-OsmoHNBGW m3ua + asp asp-clnt-OsmoHNBGW + routing-key 0 1.1.1 + sccp-address my-msc + routing-indicator PC + point-code 1.2.3 + sccp-address my-sgsn + routing-indicator PC + point-code 1.4.2 + +OsmoHNBGW# ### IuCS and IuPS were explicitly pointed to specific remote point-codes, using cs7 instance 0 addresses +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc:RI=SSN_PC,PC=1.2.3,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn:RI=SSN_PC,PC=1.4.2,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 1.1.1 + sccp-address my-msc + routing-indicator PC + point-code 1.2.3 + sccp-address my-sgsn + routing-indicator PC + point-code 1.4.2 +hnbgw + rnc-id 23 + log-prefix hnb-id + iuh + iucs + remote-addr my-msc + iups + remote-addr my-sgsn +... diff --git a/tests/config/one_cs7_with_iucs_addr.cfg b/tests/config/one_cs7_with_iucs_addr.cfg new file mode 100644 index 0000000..9e0207e --- /dev/null +++ b/tests/config/one_cs7_with_iucs_addr.cfg @@ -0,0 +1,8 @@ +# only set an explicit remote address for IuCS, let IuPS be auto-configured +cs7 instance 0 + point-code 1.1.1 + sccp-address my-msc + point-code 1.2.3 +hnbgw + iucs + remote-addr my-msc diff --git a/tests/config/one_cs7_with_iucs_addr.vty b/tests/config/one_cs7_with_iucs_addr.vty new file mode 100644 index 0000000..2e57ea1 --- /dev/null +++ b/tests/config/one_cs7_with_iucs_addr.vty @@ -0,0 +1,37 @@ +OsmoHNBGW> enable + +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 1.1.1 + asp asp-clnt-OsmoHNBGW 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-OsmoHNBGW m3ua + asp asp-clnt-OsmoHNBGW + routing-key 0 1.1.1 + sccp-address my-msc + routing-indicator PC + point-code 1.2.3 + +OsmoHNBGW# ### only IuCS was configured to go to remote-PC = 1.2.3, IuPS auto-configured to remote-PC = 0.23.4 +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc:RI=SSN_PC,PC=1.2.3,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 1.1.1 + sccp-address my-msc + routing-indicator PC + point-code 1.2.3 +hnbgw + rnc-id 23 + log-prefix hnb-id + iuh + iucs + remote-addr my-msc +... diff --git a/tests/config/one_cs7_with_iups_addr.cfg b/tests/config/one_cs7_with_iups_addr.cfg new file mode 100644 index 0000000..96e7afa --- /dev/null +++ b/tests/config/one_cs7_with_iups_addr.cfg @@ -0,0 +1,8 @@ +# only set an explicit remote address for IuPS, let IuCS be auto-configured +cs7 instance 0 + point-code 1.1.1 + sccp-address my-sgsn + point-code 1.4.2 +hnbgw + iups + remote-addr my-sgsn diff --git a/tests/config/one_cs7_with_iups_addr.vty b/tests/config/one_cs7_with_iups_addr.vty new file mode 100644 index 0000000..1e4346f --- /dev/null +++ b/tests/config/one_cs7_with_iups_addr.vty @@ -0,0 +1,37 @@ +OsmoHNBGW> enable + +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 1.1.1 + asp asp-clnt-OsmoHNBGW 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-OsmoHNBGW m3ua + asp asp-clnt-OsmoHNBGW + routing-key 0 1.1.1 + sccp-address my-sgsn + routing-indicator PC + point-code 1.4.2 + +OsmoHNBGW# ### only IuPS was configured to go to remote-PC = 1.4.2, IuCS auto-configured to remote-PC = 0.23.1 +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn:RI=SSN_PC,PC=1.4.2,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 1.1.1 + sccp-address my-sgsn + routing-indicator PC + point-code 1.4.2 +hnbgw + rnc-id 23 + log-prefix hnb-id + iuh + iups + remote-addr my-sgsn +... diff --git a/tests/config/run_tests.sh b/tests/config/run_tests.sh new file mode 100755 index 0000000..3177df9 --- /dev/null +++ b/tests/config/run_tests.sh @@ -0,0 +1,21 @@ +#!/bin/sh +osmo_hnbgw="$1" +tests_src="$2" +shift +shift + +if [ ! -x "$osmo_hnbgw" ]; then + echo "there seems to be no osmo-hnbgw executable at '$osmo_hnbgw'" + exit 1 +fi + +if [ ! -d "$tests_src" ]; then + echo "there seems to be no tests source dir at '$tests_src'" + exit 1 +fi + +set -e +for dot_vty in "$tests_src"/*.vty; do + dot_cfg="$(echo $dot_vty | sed 's/\.vty$/.cfg/')" + osmo_verify_transcript_vty.py -v -n OsmoHNBGW -p 4261 -r "$osmo_hnbgw -c $dot_cfg" "$dot_vty" $@ +done -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32991 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Ic8bb30e1dd73753c2ff255566382e241918414f7 Gerrit-Change-Number: 32991 Gerrit-PatchSet: 5 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[L] Change in osmo-hnbgw[master]: cnpool: allow separate cs7 for IuPS and IuCS
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323 ) Change subject: cnpool: allow separate cs7 for IuPS and IuCS ...................................................................... cnpool: allow separate cs7 for IuPS and IuCS Prepare for CN pooling; allow using separate SS7 instances for IuCS and IuPS. New struct hnbgw_sccp_user describes a RANAP SCCP user, one per cs7. Limit struct hnbgw_cnlink to describing a CN peer, using whichever SCCP instance that is indicated by hnbgw_sccp_user. Chart sccp.dot shows the changes made. Related: SYS#6412 Change-Id: Iea1824f1c586723d989c80a909bae16bd2866e08 --- M doc/charts/sccp.dot M include/osmocom/hnbgw/context_map.h M include/osmocom/hnbgw/hnbgw.h M include/osmocom/hnbgw/hnbgw_cn.h M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/context_map_sccp.c M src/osmo-hnbgw/hnbgw.c M src/osmo-hnbgw/hnbgw_cn.c M src/osmo-hnbgw/hnbgw_rua.c M src/osmo-hnbgw/hnbgw_vty.c M src/osmo-hnbgw/osmo_hnbgw_main.c M tests/config/defaults.vty M tests/config/one_cs7.vty M tests/config/one_cs7_with_addrs.vty M tests/config/one_cs7_with_iucs_addr.vty M tests/config/one_cs7_with_iups_addr.vty A tests/config/two_cs7.cfg A tests/config/two_cs7.vty A tests/config/two_cs7_with_addrs.cfg A tests/config/two_cs7_with_addrs.vty 20 files changed, 674 insertions(+), 298 deletions(-) Approvals: Jenkins Builder: Verified neels: Looks good to me, approved diff --git a/doc/charts/sccp.dot b/doc/charts/sccp.dot index 9c04c35..ed11ab9 100644 --- a/doc/charts/sccp.dot +++ b/doc/charts/sccp.dot @@ -9,29 +9,50 @@ ss0 -> ss0ab msc0a [label="2.2.2"] - sgsn0a [label="3.3.3"] - ss0ab -> msc0a,sgsn0a + ss0ab -> msc0a } - iucs_addr [label=".iucs_addr -> 2.2.2"] - iups_addr [label=".iups_addr -> 3.3.3"] - msc0a -> iucs_addr [dir=back] - sgsn0a -> iups_addr [dir=back] - cnlink [label="hnbgw_cnlink (singleton)\n .osmo_sccp_instance\n .osmo_ss7_user SSN: RANAP"]; - ss0 -> cnlink [dir=back] + sccp0 [label="hnbgw_sccp_user for '0'\n .osmo_ss7_instance 0\n .osmo_sccp_user SSN: RANAP\n PC: ss7 primary = 1.1.1"]; + ss0 -> sccp0 [dir=back] + + msc0 [label="hnbgw_cnlink for IuCS\n .remote_addr -> 2.2.2"] + sccp0 -> msc0 [dir=back] + msc0a -> msc0 [dir=back] cs0 [label="UE CS conn\n hnbgw_context_map"] cs1 [label="UE CS conn\n hnbgw_context_map"] + msc0 -> cs0,cs1 + + subgraph cluster_ss1 { + label="" + ss1 [label="cs7 instance 1\n local pc: 4.4.4"] + ss1ab [label="address book"] + ss1 -> ss1ab + + sgsn0a [label="3.3.3"] + ss1ab -> sgsn0a + } + + sccp1 [label="hnbgw_sccp_user for '1'\n .osmo_ss7_instance 1\n .osmo_sccp_user SSN: RANAP\n PC: ss7 primary = 4.4.4"]; + ss1 -> sccp1 [dir=back] + + sgsn0 [label="hnbgw_cnlink for IuPS\n .remote_addr -> 3.3.3"] + sccp1 -> sgsn0 [dir=back] + sgsn0a -> sgsn0 [dir=back] + ps0 [label="UE PS conn\n hnbgw_context_map"] ps1 [label="UE PS conn\n hnbgw_context_map"] - cnlink -> cs0,cs1,ps0,ps1 - iucs_addr -> cs0,cs1 [style=dotted,dir=none] - iups_addr -> ps0,ps1 [style=dotted,dir=none] + sgsn0 -> ps0,ps1 + + subgraph cluster_sccp_inst { + label="global sccp.users (llist)" + sccp0 + sccp1 + } subgraph cluster_hnbgw { - label="global hnb_gw" - cnlink - iucs_addr - iups_addr + label="global hnbgw" + msc0 + sgsn0 } } diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index 9320ce0..fe9d3e0 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -74,11 +74,14 @@ struct hnbgw_context_map { /* entry in the per-CN list of mappings */ - struct llist_head cn_list; + struct llist_head hnbgw_cnlink_entry; /* entry in the per-HNB list of mappings. If hnb_ctx == NULL, then this llist entry has been llist_del()eted and * must not be used. */ struct llist_head hnb_list; + /* entry in the per-SCCP-conn-id hashtable */ + struct hlist_node hnbgw_sccp_user_entry; + /* Pointer to HNB for this map, to transceive RUA. If the HNB has disconnected without releasing the RUA * context, this is NULL. */ struct hnb_context *hnb_ctx; @@ -88,7 +91,7 @@ struct osmo_fsm_inst *rua_fi; /* Pointer to CN, to transceive SCCP. */ - struct hnbgw_cnlink *cn_link; + struct hnbgw_cnlink *cnlink; /* SCCP User SAP connection ID used in SCCP messages to/from the cn_link. */ uint32_t scu_conn_id; /* FSM handling the SCCP state for scu_conn_id. */ @@ -133,17 +136,12 @@ enum hnbgw_context_map_state map_rua_get_state(struct hnbgw_context_map *map); enum hnbgw_context_map_state map_sccp_get_state(struct hnbgw_context_map *map); -struct hnbgw_context_map * -context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id, - bool is_ps, - struct hnbgw_cnlink *cn_if_new); +struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, + bool is_ps); void map_rua_fsm_alloc(struct hnbgw_context_map *map); void map_sccp_fsm_alloc(struct hnbgw_context_map *map); -struct hnbgw_context_map * -context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id); - void context_map_hnb_released(struct hnbgw_context_map *map); #define map_rua_dispatch(MAP, EVENT, MSGB) \ diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 6570bdf..7e6bda7 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -2,11 +2,14 @@ #include <osmocom/core/select.h> #include <osmocom/core/linuxlist.h> +#include <osmocom/core/hashtable.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/timer.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/ctrl/control_if.h> +#include <osmocom/ranap/RANAP_CN-DomainIndicator.h> + #define DEBUG #include <osmocom/core/logging.h> @@ -29,6 +32,9 @@ #define LOGHNB(HNB_CTX, ss, lvl, fmt, args ...) \ LOGP(ss, lvl, "(%s) " fmt, hnb_context_name(HNB_CTX), ## args) +#define DOMAIN_CS RANAP_CN_DomainIndicator_cs_domain +#define DOMAIN_PS RANAP_CN_DomainIndicator_ps_domain + enum hnb_ctrl_node { CTRL_NODE_HNB = _LAST_CTRL_NODE, _LAST_CTRL_NODE_HNB @@ -40,6 +46,10 @@ #define HNBGW_IUCS_REMOTE_IP_DEFAULT "127.0.0.1" #define HNBGW_IUPS_REMOTE_IP_DEFAULT "127.0.0.1" +#define DEFAULT_PC_HNBGW ((23 << 3) + 5) +#define DEFAULT_PC_MSC ((23 << 3) + 1) +#define DEFAULT_PC_SGSN ((23 << 3) + 4) + /* 25.467 Section 7.1 */ #define IUH_DEFAULT_SCTP_PORT 29169 #define RNA_DEFAULT_SCTP_PORT 25471 @@ -61,17 +71,79 @@ uint32_t cid; /*!< Cell ID */ }; -struct hnbgw_cnlink { - struct llist_head list; +/* osmo-hnbgw keeps a single hnbgw_sccp_user per osmo_sccp_instance, for the local point-code and SSN == RANAP. + * This relates the (opaque) osmo_sccp_user to osmo-hnbgw's per-ss7 state. */ +struct hnbgw_sccp_user { + /* entry in g_hnbgw->sccp.users */ + struct llist_head entry; - /* reference to the SCCP User SAP by which we communicate */ - struct osmo_sccp_instance *sccp; + /* logging context */ + char *name; + + /* Which 'cs7 instance' is this for? Below sccp_user is registered at the osmo_sccp_instance ss7->sccp. */ + struct osmo_ss7_instance *ss7; + + /* Local address: cs7 instance's primary PC if present, else the default HNBGW PC; with SSN == RANAP. */ + struct osmo_sccp_addr local_addr; + + /* osmo_sccp API state for above local address on above ss7 instance. */ struct osmo_sccp_user *sccp_user; + /* Fast access to the hnbgw_context_map responsible for a given SCCP conn_id of the ss7->sccp instance. + * hlist_node: hnbgw_context_map->hnbgw_sccp_user_entry. */ + DECLARE_HASHTABLE(hnbgw_context_map_by_conn_id, 6); +}; + +#define LOG_HSI(HNBGW_SCCP_INST, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "(%s) " FMT, (HNBGW_SCCP_INST) ? (HNBGW_SCCP_INST)->name : "null", ##ARGS) + +/* A CN peer, like MSC or SGSN. */ +struct hnbgw_cnlink { + /* To print in logging/VTY */ + char *name; + + /* IuCS or IuPS? */ + RANAP_CN_DomainIndicator_t domain; + + /* cs7 address book entry to indicate both the remote point-code of the peer, as well as which cs7 instance to + * use. */ + const char *remote_addr_name; + + /* Copy of the address pointed at by remote_addr_name. */ + struct osmo_sccp_addr remote_addr; + + /* The SCCP instance for the cs7 instance indicated by remote_addr_name. (Multiple hnbgw_cnlinks may use the + * same hnbgw_sccp_user -- there is exactly one hnbgw_sccp_user per configured cs7 instance.) */ + struct hnbgw_sccp_user *hnbgw_sccp_user; + /* linked list of hnbgw_context_map */ struct llist_head map_list; }; +#define LOG_CNLINK(CNLINK, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "(%s) " FMT, (CNLINK) ? (CNLINK)->name : "null", ##ARGS) + +static inline bool cnlink_is_cs(const struct hnbgw_cnlink *cnlink) +{ + return cnlink && cnlink->domain == DOMAIN_CS; +} + +static inline bool cnlink_is_ps(const struct hnbgw_cnlink *cnlink) +{ + return cnlink && cnlink->domain == DOMAIN_PS; +} + +static inline struct osmo_sccp_instance *cnlink_sccp(const struct hnbgw_cnlink *cnlink) +{ + if (!cnlink) + return NULL; + if (!cnlink->hnbgw_sccp_user) + return NULL; + if (!cnlink->hnbgw_sccp_user->ss7) + return NULL; + return cnlink->hnbgw_sccp_user->ss7->sccp; +} + /* The lifecycle of the hnb_context object is the same as its conn */ struct hnb_context { /*! Entry in HNB-global list of HNB */ @@ -139,11 +211,11 @@ struct ctrl_handle *ctrl; /* currently active CN links for CS and PS */ struct { - struct osmo_sccp_instance *client; - struct hnbgw_cnlink *cnlink; - struct osmo_sccp_addr local_addr; - struct osmo_sccp_addr iucs_remote_addr; - struct osmo_sccp_addr iups_remote_addr; + /* List of hnbgw_sccp_user */ + struct llist_head users; + /* FUTURE: cnlink_iucs, cnlink_iups will be replaced with llist cnpool. */ + struct hnbgw_cnlink *cnlink_iucs; + struct hnbgw_cnlink *cnlink_iups; } sccp; /* MGW pool, also includes the single MGCP client as fallback if no * pool is configured. */ diff --git a/include/osmocom/hnbgw/hnbgw_cn.h b/include/osmocom/hnbgw/hnbgw_cn.h index 5711c5e..a684c98 100644 --- a/include/osmocom/hnbgw/hnbgw_cn.h +++ b/include/osmocom/hnbgw/hnbgw_cn.h @@ -2,6 +2,12 @@ #include <osmocom/hnbgw/hnbgw.h> -int hnbgw_cnlink_init(const char *stp_host, uint16_t stp_port, const char *local_ip); +struct hnbgw_cnlink *hnbgw_cnlink_alloc(const char *remote_addr_name, RANAP_CN_DomainIndicator_t domain); const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(bool is_ps); + +struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu, + const struct osmo_sccp_addr *remote_addr); +struct hnbgw_cnlink *hnbgw_cnlink_select(bool is_ps); + +char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr); diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index f8d0ecf..cdc526b 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -28,7 +28,7 @@ #include <osmocom/sigtran/sccp_helpers.h> -#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_cn.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbgw/mgw_fsm.h> #include <osmocom/hnbgw/ps_rab_ass_fsm.h> @@ -53,16 +53,16 @@ } /* Map from a HNB + ContextID to the SCCP-side Connection ID */ -struct hnbgw_context_map * -context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id, - bool is_ps, - struct hnbgw_cnlink *cn_if_new) +struct hnbgw_context_map *context_map_find_or_create_by_rua_ctx_id(struct hnb_context *hnb, uint32_t rua_ctx_id, + bool is_ps) { struct hnbgw_context_map *map; uint32_t new_scu_conn_id; + struct hnbgw_cnlink *cnlink; + struct hnbgw_sccp_user *hsu; llist_for_each_entry(map, &hnb->map_list, hnb_list) { - if (map->cn_link != cn_if_new) + if (map->is_ps != is_ps) continue; /* Matching on RUA context id -- only match for RUA context that has not been disconnected yet. If an @@ -71,24 +71,39 @@ if (!map_rua_is_active(map)) continue; - if (map->rua_ctx_id == rua_ctx_id - && map->is_ps == is_ps) { - return map; - } + if (map->rua_ctx_id != rua_ctx_id) + continue; + + /* Already exists */ + return map; } - new_scu_conn_id = osmo_sccp_instance_next_conn_id(map->cn_link->sccp); - if (new_scu_conn_id < 0) { - LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate CN connection ID\n"); + /* Does not exist yet, create a new hnbgw_context_map. */ + + /* From the RANAP/RUA input, determine which cnlink to use */ + cnlink = hnbgw_cnlink_select(is_ps); + if (!cnlink) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Failed to select CN link\n"); return NULL; } - LOGHNB(hnb, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %p/%u <-> SCU Conn ID %p/%u\n", - hnb, rua_ctx_id, cn_if_new, new_scu_conn_id); + /* Allocate new SCCP conn id on the SCCP instance the cnlink is on. */ + hsu = cnlink->hnbgw_sccp_user; + if (!hsu) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Cannot allocate context map: No SCCP instance for CN link %s\n", + cnlink->name); + return NULL; + } + + new_scu_conn_id = osmo_sccp_instance_next_conn_id(hsu->ss7->sccp); + if (new_scu_conn_id < 0) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate SCCP conn ID on %s\n", hsu->name); + return NULL; + } /* allocate a new map entry. */ map = talloc_zero(hnb, struct hnbgw_context_map); - map->cn_link = cn_if_new; + map->cnlink = cnlink; map->hnb_ctx = hnb; map->rua_ctx_id = rua_ctx_id; map->is_ps = is_ps; @@ -99,9 +114,12 @@ map_rua_fsm_alloc(map); map_sccp_fsm_alloc(map); - /* put it into both lists */ llist_add_tail(&map->hnb_list, &hnb->map_list); - llist_add_tail(&map->cn_list, &cn_if_new->map_list); + llist_add_tail(&map->hnbgw_cnlink_entry, &cnlink->map_list); + hash_add(hsu->hnbgw_context_map_by_conn_id, &map->hnbgw_sccp_user_entry, new_scu_conn_id); + + LOG_MAP(map, DMAIN, LOGL_INFO, "Creating new Mapping RUA CTX %u <-> SCU Conn ID %s/%u\n", + rua_ctx_id, hsu->name, new_scu_conn_id); return map; } @@ -133,30 +151,6 @@ return msg && msgb_l2(msg) ? msgb_l2len(msg) : 0; } -/* Map from a CN + Connection ID to HNB + Context ID */ -struct hnbgw_context_map * -context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id) -{ - struct hnbgw_context_map *map; - - llist_for_each_entry(map, &cn->map_list, cn_list) { - /* Matching on SCCP conn id -- only match for SCCP conn that has not been disconnected yet. If an - * inactive context map for an scu_conn_id is still around, we may have two entries for the same - * scu_conn_id around at the same time. That should only stay until its RUA side is done releasing. */ - if (!map_sccp_is_active(map)) - continue; - - if (map->scu_conn_id == scu_conn_id) { - return map; - } - } - /* we don't allocate new mappings in the CN->HNB - * direction, as the RUA=SCCP=SUA connections are always - * established from HNB towards CN. */ - LOGP(DMAIN, LOGL_NOTICE, "Unable to resolve map for CN " "connection ID %p/%u\n", cn, scu_conn_id); - return NULL; -} - void context_map_hnb_released(struct hnbgw_context_map *map) { /* When a HNB disconnects from RUA, the hnb_context will be freed. This hnbgw_context_map was allocated as a @@ -199,8 +193,10 @@ hnbgw_gtpmap_release(map); #endif - if (map->cn_link) - llist_del(&map->cn_list); + if (map->cnlink) { + llist_del(&map->hnbgw_cnlink_entry); + hash_del(&map->hnbgw_sccp_user_entry); + } if (map->hnb_ctx) llist_del(&map->hnb_list); diff --git a/src/osmo-hnbgw/context_map_sccp.c b/src/osmo-hnbgw/context_map_sccp.c index 3de8215..00b24f2 100644 --- a/src/osmo-hnbgw/context_map_sccp.c +++ b/src/osmo-hnbgw/context_map_sccp.c @@ -124,6 +124,11 @@ struct osmo_scu_prim *prim; int rc; + if (!map->cnlink || !map->cnlink->hnbgw_sccp_user) { + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Connection Request: no CN link\n"); + return -1; + } + if (!ranap_msg) { /* prepare a msgb to send an empty N-Connect prim (but this should never happen in practice) */ ranap_msg = hnbgw_ranap_msg_alloc("SCCP-CR-empty"); @@ -132,13 +137,13 @@ prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, ranap_msg); prim->u.connect.called_addr = *hnbgw_cn_get_remote_addr(map->is_ps); - prim->u.connect.calling_addr = g_hnbgw->sccp.local_addr; + prim->u.connect.calling_addr = map->cnlink->hnbgw_sccp_user->local_addr; prim->u.connect.sccp_class = 2; prim->u.connect.conn_id = map->scu_conn_id; - rc = osmo_sccp_user_sap_down_nofree(map->cn_link->sccp_user, &prim->oph); + rc = osmo_sccp_user_sap_down_nofree(map->cnlink->hnbgw_sccp_user->sccp_user, &prim->oph); if (rc) - LOGPFSML(fi, LOGL_ERROR, "Failed to forward SCCP Connectoin Request to CN\n"); + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Connection Request to CN\n"); return rc; } @@ -151,20 +156,31 @@ if (!msg_has_l2_data(ranap_msg)) return 0; + if (!map->cnlink || !map->cnlink->hnbgw_sccp_user) { + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Data Form 1: no CN link\n"); + return -1; + } + prim = (struct osmo_scu_prim *)msgb_push(ranap_msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, ranap_msg); prim->u.data.conn_id = map->scu_conn_id; - rc = osmo_sccp_user_sap_down_nofree(map->cn_link->sccp_user, &prim->oph); + rc = osmo_sccp_user_sap_down_nofree(map->cnlink->hnbgw_sccp_user->sccp_user, &prim->oph); if (rc) - LOGPFSML(fi, LOGL_ERROR, "Failed to forward SCCP Data Form 1 to CN\n"); + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP Data Form 1 to CN\n"); return rc; } static int tx_sccp_rlsd(struct osmo_fsm_inst *fi) { struct hnbgw_context_map *map = fi->priv; - return osmo_sccp_tx_disconn(map->cn_link->sccp_user, map->scu_conn_id, NULL, 0); + + if (!map->cnlink || !map->cnlink->hnbgw_sccp_user) { + LOGPFSML(fi, LOGL_ERROR, "Failed to send SCCP RLSD: no CN link\n"); + return -1; + } + + return osmo_sccp_tx_disconn(map->cnlink->hnbgw_sccp_user->sccp_user, map->scu_conn_id, NULL, 0); } static int destruct_ranap_ran_rx_co_ies(ranap_message *ranap_message_p) @@ -468,7 +484,7 @@ /* send SCCP RLSD. libosmo-sigtran/sccp_scoc.c will do the SCCP connection cleanup. * (It will repeatedly send SCCP RLSD until the peer responded with SCCP RLC, or until the * sccp_connection->t_int timer expires, and the sccp_connection is freed.) */ - if (map->cn_link && map->cn_link->sccp_user) + if (map->cnlink) tx_sccp_rlsd(fi); map_sccp_fsm_state_chg(MAP_SCCP_ST_DISCONNECTED); return 0; diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c index 6bf7b3f..b07dbc7 100644 --- a/src/osmo-hnbgw/hnbgw.c +++ b/src/osmo-hnbgw/hnbgw.c @@ -51,6 +51,7 @@ g_hnbgw->next_ue_ctx_id = 23; INIT_LLIST_HEAD(&g_hnbgw->hnb_list); INIT_LLIST_HEAD(&g_hnbgw->ue_list); + INIT_LLIST_HEAD(&g_hnbgw->sccp.users); g_hnbgw->mgw_pool = mgcp_client_pool_alloc(g_hnbgw); g_hnbgw->config.mgcp_client = talloc_zero(g_hnbgw, struct mgcp_client_conf); diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index 33ec0f6..0175498 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -33,6 +33,7 @@ #include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/hnbgw_rua.h> +#include <osmocom/hnbgw/hnbgw_cn.h> #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/ranap_msg_factory.h> #include <osmocom/hnbgw/context_map.h> @@ -47,33 +48,47 @@ .choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure, }; - LOGP(DRANAP, LOGL_NOTICE, "Tx RESET to %s %s\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(g_hnbgw->sccp.cnlink->sccp, remote_addr)); + if (!cnlink) + return -1; - msg = ranap_new_msg_reset(domain, &cause); + if (!cnlink->hnbgw_sccp_user) { + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET: no CN link\n"); + return -1; + } - return osmo_sccp_tx_unitdata_msg(g_hnbgw->sccp.cnlink->sccp_user, - &g_hnbgw->sccp.local_addr, - remote_addr, + LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET to %s %s\n", + cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(cnlink->hnbgw_sccp_user->sccp, &cnlink->remote_addr)); + + msg = ranap_new_msg_reset(cnlink->domain, &cause); + + return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, + &cnlink->local_addr, + &cnlink->remote_addr, msg); } #endif -static int transmit_reset_ack(RANAP_CN_DomainIndicator_t domain, - const struct osmo_sccp_addr *remote_addr) +static int transmit_reset_ack(struct hnbgw_cnlink *cnlink) { struct msgb *msg; + struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink); - LOGP(DRANAP, LOGL_NOTICE, "Tx RESET ACK to %s %s\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(g_hnbgw->sccp.cnlink->sccp, remote_addr)); + if (!sccp) { + LOG_CNLINK(cnlink, DRANAP, LOGL_ERROR, "cannot send RANAP RESET ACK: no CN link\n"); + return -1; + } - msg = ranap_new_msg_reset_ack(domain, NULL); + LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Tx RANAP RESET ACK %s %s --> %s\n", + cnlink_is_cs(cnlink) ? "IuCS" : "IuPS", + cnlink_sccp_addr_to_str(cnlink, &cnlink->hnbgw_sccp_user->local_addr), + cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr)); - return osmo_sccp_tx_unitdata_msg(g_hnbgw->sccp.cnlink->sccp_user, - &g_hnbgw->sccp.local_addr, - remote_addr, + msg = ranap_new_msg_reset_ack(cnlink->domain, NULL); + + return osmo_sccp_tx_unitdata_msg(cnlink->hnbgw_sccp_user->sccp_user, + &cnlink->hnbgw_sccp_user->local_addr, + &cnlink->remote_addr, msg); } @@ -93,16 +108,16 @@ domain = ies.cN_DomainIndicator; ranap_free_reseties(&ies); - LOGP(DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr)); + LOG_CNLINK(cnlink, DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n", + domain == DOMAIN_CS ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr)); /* FIXME: actually reset connections, if any */ - if (transmit_reset_ack(domain, &unitdata->calling_addr)) + if (transmit_reset_ack(cnlink)) LOGP(DRANAP, LOGL_ERROR, "Error: cannot send RESET ACK to %s %s\n", - domain == RANAP_CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", - osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr)); + domain == DOMAIN_CS ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(cnlink_sccp(cnlink), &unitdata->calling_addr)); return rc; } @@ -246,101 +261,94 @@ return rc; } -static bool pc_and_ssn_match(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b) +static struct hnbgw_cnlink *cnlink_from_addr(struct hnbgw_sccp_user *hsu, const struct osmo_sccp_addr *calling_addr, + const struct osmo_prim_hdr *oph) { - return (a == b) - || ((a->pc == b->pc) - && (a->ssn == b->ssn)); + struct hnbgw_cnlink *cnlink = NULL; + cnlink = hnbgw_cnlink_find_by_addr(hsu, calling_addr); + if (!cnlink) { + LOG_HSI(hsu, DRANAP, LOGL_ERROR, "Rx from unknown SCCP peer: %s: %s\n", + osmo_sccp_inst_addr_name(hsu->ss7->sccp, calling_addr), + osmo_scu_prim_hdr_name_c(OTC_SELECT, oph)); + return NULL; + } + return cnlink; } -static int classify_cn_remote_addr(const struct osmo_sccp_addr *cn_remote_addr, - bool *is_ps) +static struct hnbgw_context_map *map_from_conn_id(struct hnbgw_sccp_user *hsu, uint32_t conn_id, + const struct osmo_prim_hdr *oph) { - if (pc_and_ssn_match(cn_remote_addr, &g_hnbgw->sccp.iucs_remote_addr)) { - if (is_ps) - *is_ps = false; - return 0; - } - if (pc_and_ssn_match(cn_remote_addr, &g_hnbgw->sccp.iups_remote_addr)) { - if (is_ps) - *is_ps = true; - return 0; - } - LOGP(DMAIN, LOGL_ERROR, "Unexpected remote address, matches neither CS nor PS address: %s\n", - osmo_sccp_addr_dump(cn_remote_addr)); - return -1; + struct hnbgw_context_map *map; + hash_for_each_possible(hsu->hnbgw_context_map_by_conn_id, map, hnbgw_sccp_user_entry, conn_id) + return map; + LOGP(DRANAP, LOGL_ERROR, "Rx for unknown SCCP connection ID: %u: %s\n", + conn_id, osmo_scu_prim_hdr_name_c(OTC_SELECT, oph)); + return NULL; } -static int handle_cn_unitdata(struct hnbgw_cnlink *cnlink, +static int handle_cn_unitdata(struct hnbgw_sccp_user *hsu, const struct osmo_scu_unitdata_param *param, struct osmo_prim_hdr *oph) { + struct hnbgw_cnlink *cnlink = cnlink_from_addr(hsu, &param->calling_addr, oph); + if (!cnlink) + return -ENOENT; + if (param->called_addr.ssn != OSMO_SCCP_SSN_RANAP) { LOGP(DMAIN, LOGL_NOTICE, "N-UNITDATA.ind for unknown SSN %u\n", param->called_addr.ssn); return -1; } - if (classify_cn_remote_addr(&param->calling_addr, NULL) < 0) - return -1; - return handle_cn_ranap(cnlink, param, msgb_l2(oph->msg), msgb_l2len(oph->msg)); } -static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink, +static int handle_cn_conn_conf(struct hnbgw_sccp_user *hsu, const struct osmo_scu_connect_param *param, struct osmo_prim_hdr *oph) { - struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(g_hnbgw->sccp.client); struct hnbgw_context_map *map; + map = map_from_conn_id(hsu, param->conn_id, oph); + if (!map || !map->cnlink) + return -ENOENT; + LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() conn_id=%d, addrs: called=%s calling=%s responding=%s\n", param->conn_id, - osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->called_addr), - osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->calling_addr), - osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->responding_addr)); - - map = context_map_by_cn(cnlink, param->conn_id); - if (!map) { - /* We have no such SCCP connection. Ignore. */ - return 0; - } + cnlink_sccp_addr_to_str(map->cnlink, &param->called_addr), + cnlink_sccp_addr_to_str(map->cnlink, &param->calling_addr), + cnlink_sccp_addr_to_str(map->cnlink, &param->responding_addr)); map_sccp_dispatch(map, MAP_SCCP_EV_RX_CONNECTION_CONFIRM, oph->msg); return 0; } -static int handle_cn_data_ind(struct hnbgw_cnlink *cnlink, +static int handle_cn_data_ind(struct hnbgw_sccp_user *hsu, const struct osmo_scu_data_param *param, struct osmo_prim_hdr *oph) { struct hnbgw_context_map *map; - map = context_map_by_cn(cnlink, param->conn_id); - if (!map) { - /* We have no such SCCP connection. Ignore. */ - return 0; - } + map = map_from_conn_id(hsu, param->conn_id, oph); + if (!map || !map->cnlink) + return -ENOENT; return map_sccp_dispatch(map, MAP_SCCP_EV_RX_DATA_INDICATION, oph->msg); } -static int handle_cn_disc_ind(struct hnbgw_cnlink *cnlink, +static int handle_cn_disc_ind(struct hnbgw_sccp_user *hsu, const struct osmo_scu_disconn_param *param, struct osmo_prim_hdr *oph) { struct hnbgw_context_map *map; - LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%d originator=%d\n", - param->conn_id, param->originator); - LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() responding_addr=%s\n", - inet_ntoa(param->responding_addr.ip.v4)); + map = map_from_conn_id(hsu, param->conn_id, oph); + if (!map || !map->cnlink) + return -ENOENT; - map = context_map_by_cn(cnlink, param->conn_id); - if (!map) { - /* We have no connection. Ignore. */ - return 0; - } + LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%u responding_addr=%s\n", + param->conn_id, + cnlink_sccp_addr_to_str(map->cnlink, &param->responding_addr)); return map_sccp_dispatch(map, MAP_SCCP_EV_RX_RELEASED, oph->msg); } @@ -349,7 +357,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx) { struct osmo_sccp_user *scu = ctx; - struct hnbgw_cnlink *cnlink; + struct hnbgw_sccp_user *hsu; struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; int rc = 0; @@ -362,10 +370,10 @@ return -1; } - cnlink = osmo_sccp_user_get_priv(scu); - if (!cnlink) { + hsu = osmo_sccp_user_get_priv(scu); + if (!hsu) { LOGP(DMAIN, LOGL_ERROR, - "sccp_sap_up(): NULL hnbgw_cnlink, cannot send prim (sap %u prim %u op %d)\n", + "sccp_sap_up(): NULL hnbgw_sccp_user, cannot send prim (sap %u prim %u op %d)\n", oph->sap, oph->primitive, oph->operation); return -1; } @@ -374,16 +382,16 @@ switch (OSMO_PRIM_HDR(oph)) { case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - rc = handle_cn_unitdata(cnlink, &prim->u.unitdata, oph); + rc = handle_cn_unitdata(hsu, &prim->u.unitdata, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - rc = handle_cn_conn_conf(cnlink, &prim->u.connect, oph); + rc = handle_cn_conn_conf(hsu, &prim->u.connect, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - rc = handle_cn_data_ind(cnlink, &prim->u.data, oph); + rc = handle_cn_data_ind(hsu, &prim->u.data, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): - rc = handle_cn_disc_ind(cnlink, &prim->u.disconnect, oph); + rc = handle_cn_disc_ind(hsu, &prim->u.disconnect, oph); break; case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION): LOGP(DMAIN, LOGL_DEBUG, "Ignoring prim %s from SCCP USER SAP\n", @@ -412,8 +420,6 @@ const char *addr_name, const char *label, uint32_t default_pc) { - struct osmo_ss7_instance *ss7_tmp; - if (!addr_name) { osmo_sccp_make_addr_pc_ssn(dest, default_pc, OSMO_SCCP_SSN_RANAP); LOGP(DMAIN, LOGL_INFO, "%s remote addr not configured, using default: %s\n", label, @@ -421,21 +427,13 @@ return 0; } - ss7_tmp = osmo_sccp_addr_by_name(dest, addr_name); - if (!ss7_tmp) { + *ss7 = osmo_sccp_addr_by_name(dest, addr_name); + if (!*ss7) { LOGP(DMAIN, LOGL_ERROR, "%s remote addr: no such SCCP address book entry: '%s'\n", - label, addr_name); + 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)) { @@ -449,74 +447,197 @@ return 0; } -int hnbgw_cnlink_init(const char *stp_host, uint16_t stp_port, const char *local_ip) +/* If not present yet, set up all of osmo_ss7_instance, osmo_sccp_instance and hnbgw_sccp_user for the given cnlink. + * The cs7 instance nr to use is determined by cnlink->remote_addr_name, or cs7 instance 0 if that is not present. + * Set cnlink->hnbgw_sccp_user to the new SCCP instance. Return 0 on success, negative on error. */ +int cnlink_ensure_sccp(struct hnbgw_cnlink *cnlink) { - struct hnbgw_cnlink *cnlink; - struct osmo_ss7_instance *ss7; + struct osmo_ss7_instance *ss7 = NULL; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *sccp_user; uint32_t local_pc; + struct hnbgw_sccp_user *hsu; - OSMO_ASSERT(!g_hnbgw->sccp.client); - OSMO_ASSERT(!g_hnbgw->sccp.cnlink); + /* If a hnbgw_sccp_user has already been set up, use that. */ + if (cnlink->hnbgw_sccp_user) { + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "SCCP instance already set up, using %s\n", + cnlink->hnbgw_sccp_user->name); + return 0; + } + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "no SCCP instance selected yet\n"); - ss7 = NULL; - if (resolve_addr_name(&g_hnbgw->sccp.iucs_remote_addr, &ss7, - g_hnbgw->config.iucs_remote_addr_name, "IuCS", (23 << 3) + 1)) - return -1; - if (resolve_addr_name(&g_hnbgw->sccp.iups_remote_addr, &ss7, - g_hnbgw->config.iups_remote_addr_name, "IuPS", (23 << 3) + 4)) - return -1; + /* Figure out which cs7 instance to use. If cnlink->remote_addr_name is set, it points to an address book entry + * in a specific cs7 instance. If it is not set, leave ss7 == NULL to use cs7 instance 0. */ + if (cnlink->remote_addr_name) { + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "resolving 'remote-addr %s'\n", cnlink->remote_addr_name); + if (resolve_addr_name(&cnlink->remote_addr, &ss7, cnlink->remote_addr_name, cnlink->name, + DEFAULT_PC_HNBGW)) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "cannot initialize SCCP: there is no SCCP address named '%s'\n", + cnlink->remote_addr_name); + return -ENOENT; + } + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "remote-addr is '%s', using cs7 instance %u\n", + cnlink->remote_addr_name, ss7->cfg.id); + } else { + /* If no address is configured, use the default remote CN address, according to legacy behavior. */ + uint32_t remote_pc; + switch (cnlink->domain) { + case DOMAIN_CS: + remote_pc = DEFAULT_PC_MSC; + break; + case DOMAIN_PS: + remote_pc = DEFAULT_PC_SGSN; + break; + default: + return -EINVAL; + } + osmo_sccp_make_addr_pc_ssn(&cnlink->remote_addr, remote_pc, OSMO_SCCP_SSN_RANAP); + } + + /* If no 'cs7 instance' has been selected by the address, see if there already is a cs7 0 we can use by default. + * If it doesn't exist, it will get created by osmo_sccp_simple_client_on_ss7_id(). */ if (!ss7) { - LOGP(DRANAP, LOGL_NOTICE, "No cs7 instance configured for IuCS nor IuPS," - " creating default instance\n"); - ss7 = osmo_ss7_instance_find_or_create(g_hnbgw, 0); - if (!ss7) - return -1; - ss7->cfg.primary_pc = (23 << 3) + 5; + ss7 = osmo_ss7_instance_find(0); + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "Using default 'cs7 instance 0' (%s)\n", ss7 ? "already exists" : "will create"); } - 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); + if (ss7) { + /* Has another cnlink already set up an SCCP instance for this ss7? */ + llist_for_each_entry(hsu, &g_hnbgw->sccp.users, entry) { + if (hsu->ss7 != ss7) + continue; + cnlink->hnbgw_sccp_user = hsu; + LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "using existing SCCP instance %s on cs7 instance %u\n", + hsu->name, ss7->cfg.id); + return 0; + } + /* else cnlink->hnbgw_sccp_user stays NULL and is set up below. */ + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "cs7 instance %u has no SCCP instance yet\n", ss7->cfg.id); + + /* All SCCP instances should originate from this function. So if there is no hnbgw_sccp_user for the cs7 + * instance, then the cs7 instance should not have an SCCP instance yet. */ + OSMO_ASSERT(!ss7->sccp); + } + + /* No SCCP instance yet for this ss7. Create it. If no address name is given that resolves to a + * particular cs7 instance above, use 'cs7 instance 0'. */ + sccp = osmo_sccp_simple_client_on_ss7_id(g_hnbgw, ss7 ? ss7->cfg.id : 0, cnlink->name, DEFAULT_PC_HNBGW, + OSMO_SS7_ASP_PROT_M3UA, 0, "localhost", -1, "localhost"); + if (!sccp) { + LOG_CNLINK(cnlink, DCN, LOGL_ERROR, "Failed to configure 'cs7 instance %u'\n", ss7->cfg.id); return -1; } - local_pc = ss7->cfg.primary_pc; + ss7 = osmo_sccp_get_ss7(sccp); + LOG_CNLINK(cnlink, DCN, LOGL_NOTICE, "created SCCP instance on cs7 instance %u\n", ss7->cfg.id); - osmo_sccp_make_addr_pc_ssn(&g_hnbgw->sccp.local_addr, local_pc, OSMO_SCCP_SSN_RANAP); - LOGP(DRANAP, LOGL_NOTICE, "Local SCCP addr: %s\n", osmo_sccp_addr_name(ss7, &g_hnbgw->sccp.local_addr)); + /* Bind the SCCP user, using the cs7 instance's default point-code if one is configured, or osmo-hnbgw's default + * local PC. */ + if (osmo_ss7_pc_is_valid(ss7->cfg.primary_pc)) + local_pc = ss7->cfg.primary_pc; + else + local_pc = DEFAULT_PC_HNBGW; - g_hnbgw->sccp.client = osmo_sccp_simple_client_on_ss7_id(g_hnbgw, ss7->cfg.id, "OsmoHNBGW", - local_pc, OSMO_SS7_ASP_PROT_M3UA, - 0, local_ip, stp_port, stp_host); - if (!g_hnbgw->sccp.client) { - LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP Client\n"); - return -1; - } + LOG_CNLINK(cnlink, DCN, LOGL_DEBUG, "binding OsmoHNBGW user to cs7 instance %u, local PC %u = %s\n", + ss7->cfg.id, local_pc, osmo_ss7_pointcode_print(ss7, local_pc)); - cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink); - INIT_LLIST_HEAD(&cnlink->map_list); - - cnlink->sccp_user = osmo_sccp_user_bind_pc(g_hnbgw->sccp.client, "OsmoHNBGW", sccp_sap_up, - OSMO_SCCP_SSN_RANAP, g_hnbgw->sccp.local_addr.pc); - if (!cnlink->sccp_user) { + sccp_user = osmo_sccp_user_bind_pc(sccp, "OsmoHNBGW", sccp_sap_up, OSMO_SCCP_SSN_RANAP, local_pc); + if (!sccp_user) { LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP User\n"); return -1; } - LOGP(DRANAP, LOGL_NOTICE, "Remote SCCP addr: IuCS: %s\n", - osmo_sccp_addr_name(ss7, &g_hnbgw->sccp.iucs_remote_addr)); - LOGP(DRANAP, LOGL_NOTICE, "Remote SCCP addr: IuPS: %s\n", - osmo_sccp_addr_name(ss7, &g_hnbgw->sccp.iups_remote_addr)); + hsu = talloc_zero(cnlink, struct hnbgw_sccp_user); + *hsu = (struct hnbgw_sccp_user){ + .name = talloc_asprintf(hsu, "cs7-%u.sccp", ss7->cfg.id), + .ss7 = ss7, + .sccp_user = sccp_user, + }; + osmo_sccp_make_addr_pc_ssn(&hsu->local_addr, local_pc, OSMO_SCCP_SSN_RANAP); + hash_init(hsu->hnbgw_context_map_by_conn_id); + osmo_sccp_user_set_priv(sccp_user, hsu); - /* In sccp_sap_up() we expect the cnlink in the user's priv. */ - osmo_sccp_user_set_priv(cnlink->sccp_user, cnlink); + llist_add_tail(&hsu->entry, &g_hnbgw->sccp.users); - g_hnbgw->sccp.cnlink = cnlink; - + cnlink->hnbgw_sccp_user = hsu; return 0; } +struct hnbgw_cnlink *hnbgw_cnlink_alloc(const char *remote_addr_name, RANAP_CN_DomainIndicator_t domain) +{ + struct hnbgw_cnlink *cnlink; + + cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink); + *cnlink = (struct hnbgw_cnlink){ + .name = (domain == DOMAIN_CS ? "msc-0" : "sgsn-0"), + .domain = domain, + .remote_addr_name = talloc_strdup(cnlink, remote_addr_name), + }; + + INIT_LLIST_HEAD(&cnlink->map_list); + + if (cnlink_ensure_sccp(cnlink)) { + /* error logging already in cnlink_ensure_sccp() */ + talloc_free(cnlink); + return NULL; + } + + switch (domain) { + case DOMAIN_CS: + OSMO_ASSERT(!g_hnbgw->sccp.cnlink_iucs); + g_hnbgw->sccp.cnlink_iucs = cnlink; + break; + case DOMAIN_PS: + OSMO_ASSERT(!g_hnbgw->sccp.cnlink_iups); + g_hnbgw->sccp.cnlink_iups = cnlink; + break; + default: + OSMO_ASSERT(false); + } + + return cnlink; +} + const struct osmo_sccp_addr *hnbgw_cn_get_remote_addr(bool is_ps) { - return is_ps ? &g_hnbgw->sccp.iups_remote_addr : &g_hnbgw->sccp.iucs_remote_addr; + struct hnbgw_cnlink *cnlink = is_ps ? g_hnbgw->sccp.cnlink_iups : g_hnbgw->sccp.cnlink_iucs; + if (!cnlink) + return NULL; + return &cnlink->remote_addr; +} + +static bool cnlink_matches(const struct hnbgw_cnlink *cnlink, const struct hnbgw_sccp_user *hsu, const struct osmo_sccp_addr *remote_addr) +{ + if (cnlink->hnbgw_sccp_user != hsu) + return false; + if (osmo_sccp_addr_cmp(&cnlink->remote_addr, remote_addr, OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC)) + return false; + return true; +} +struct hnbgw_cnlink *hnbgw_cnlink_find_by_addr(const struct hnbgw_sccp_user *hsu, + const struct osmo_sccp_addr *remote_addr) +{ + /* FUTURE: loop over llist g_hnb_gw->sccp.cnpool */ + if (cnlink_matches(g_hnbgw->sccp.cnlink_iucs, hsu, remote_addr)) + return g_hnbgw->sccp.cnlink_iucs; + if (cnlink_matches(g_hnbgw->sccp.cnlink_iups, hsu, remote_addr)) + return g_hnbgw->sccp.cnlink_iups; + return NULL; +} + +struct hnbgw_cnlink *hnbgw_cnlink_select(bool is_ps) +{ + /* FUTURE: soon we will pick one of many configurable CN peers from a pool. There will be more input arguments + * (MI, or TMSI, or NRI decoded from RANAP) and this function will do round robin for new subscribers. */ + if (is_ps) + return g_hnbgw->sccp.cnlink_iups; + return g_hnbgw->sccp.cnlink_iucs; +} + +char *cnlink_sccp_addr_to_str(struct hnbgw_cnlink *cnlink, const struct osmo_sccp_addr *addr) +{ + struct osmo_sccp_instance *sccp = cnlink_sccp(cnlink); + if (!sccp) + return osmo_sccp_addr_dump(addr); + return osmo_sccp_inst_addr_to_str_c(OTC_SELECT, sccp, addr); } diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c index 2e03e01..8157cfc 100644 --- a/src/osmo-hnbgw/hnbgw_rua.c +++ b/src/osmo-hnbgw/hnbgw_rua.c @@ -200,7 +200,6 @@ { struct msgb *ranap_msg = NULL; struct hnbgw_context_map *map = NULL; - struct hnbgw_cnlink *cn = g_hnbgw->sccp.cnlink; bool is_ps; switch (cN_DomainIndicator) { @@ -215,11 +214,6 @@ return -1; } - if (!cn) { - LOGHNB(hnb, DRUA, LOGL_NOTICE, "CN=NULL, discarding message\n"); - return 0; - } - /* If there is RANAP data, include it in the msgb. In RUA there is always data in practice, but theoretically it * could be an empty Connect or Disconnect. */ if (data && len) { @@ -230,8 +224,13 @@ memcpy(ranap_msg->l2h, data, len); } - map = context_map_alloc_by_hnb(hnb, context_id, is_ps, cn); - OSMO_ASSERT(map); + map = context_map_find_or_create_by_rua_ctx_id(hnb, context_id, is_ps); + if (!map) { + LOGHNB(hnb, DRUA, LOGL_ERROR, + "Failed to create context map for %s: rx RUA %s with %u bytes RANAP data\n", + is_ps ? "IuPS" : "IuCS", rua_procedure_code_name(rua_procedure), data ? len : 0); + return -1; + } LOG_MAP(map, DRUA, LOGL_DEBUG, "rx RUA %s with %u bytes RANAP data\n", rua_procedure_code_name(rua_procedure), data ? len : 0); diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 47db695..c1ff268 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -29,6 +29,7 @@ #include <osmocom/hnbgw/vty.h> #include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_cn.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbgw/tdefs.h> #include <osmocom/sigtran/protocol/sua.h> @@ -108,36 +109,51 @@ return vty->node; } +static void _show_cnlink(struct vty *vty, struct hnbgw_cnlink *cnlink) +{ + struct osmo_ss7_route *rt; + struct osmo_ss7_instance *ss7; + + if (!cnlink) { + vty_out(vty, "NULL%s", VTY_NEWLINE); + return; + } + + if (!cnlink->hnbgw_sccp_user) { + vty_out(vty, "no SCCP state%s", VTY_NEWLINE); + return; + } + + ss7 = cnlink->hnbgw_sccp_user->ss7; + if (!ss7) { + vty_out(vty, "no cs7 instance%s", VTY_NEWLINE); + return; + } + + if (!cnlink->hnbgw_sccp_user->sccp_user) { + vty_out(vty, "no SCCP user%s", VTY_NEWLINE); + return; + } + + vty_out(vty, "%s <->", + osmo_sccp_user_name(cnlink->hnbgw_sccp_user->sccp_user)); + vty_out(vty, " %s%s%s%s", + cnlink->remote_addr_name ? : "", + cnlink->remote_addr_name ? "=" : "", + cnlink_sccp_addr_to_str(cnlink, &cnlink->remote_addr), + VTY_NEWLINE); + + rt = osmo_ss7_route_lookup(ss7, cnlink->remote_addr.pc); + vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE); +} + DEFUN(show_cnlink, show_cnlink_cmd, "show cnlink", SHOW_STR "Display information on core network link\n") { - struct osmo_ss7_route *rt; - struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(g_hnbgw->sccp.client); -#define GUARD(STR) \ - STR ? STR : "", \ - STR ? ":" : "" - - vty_out(vty, "IuCS: %s <->", - osmo_sccp_user_name(g_hnbgw->sccp.cnlink->sccp_user)); - vty_out(vty, " %s%s%s%s", - GUARD(g_hnbgw->config.iucs_remote_addr_name), - osmo_sccp_inst_addr_name(g_hnbgw->sccp.client, &g_hnbgw->sccp.iucs_remote_addr), - VTY_NEWLINE); - - rt = osmo_ss7_route_lookup(ss7, g_hnbgw->sccp.iucs_remote_addr.pc); - vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE); - - vty_out(vty, "IuPS: %s <->", - osmo_sccp_user_name(g_hnbgw->sccp.cnlink->sccp_user)); - vty_out(vty, " %s%s%s%s", - GUARD(g_hnbgw->config.iups_remote_addr_name), - osmo_sccp_inst_addr_name(g_hnbgw->sccp.client, &g_hnbgw->sccp.iups_remote_addr), - VTY_NEWLINE); - - rt = osmo_ss7_route_lookup(ss7, g_hnbgw->sccp.iups_remote_addr.pc); - vty_out(vty, " SS7 route: %s%s", osmo_ss7_route_name(rt, true), VTY_NEWLINE); - -#undef GUARD + vty_out(vty, "IuCS: "); + _show_cnlink(vty, g_hnbgw->sccp.cnlink_iucs); + vty_out(vty, "IuPS: "); + _show_cnlink(vty, g_hnbgw->sccp.cnlink_iups); return CMD_SUCCESS; } diff --git a/src/osmo-hnbgw/osmo_hnbgw_main.c b/src/osmo-hnbgw/osmo_hnbgw_main.c index 28ff42a..4994b1f 100644 --- a/src/osmo-hnbgw/osmo_hnbgw_main.c +++ b/src/osmo-hnbgw/osmo_hnbgw_main.c @@ -259,11 +259,13 @@ ranap_set_log_area(DRANAP); - rc = hnbgw_cnlink_init("localhost", M3UA_PORT, "localhost"); - if (rc < 0) { + if (!hnbgw_cnlink_alloc(g_hnbgw->config.iucs_remote_addr_name, DOMAIN_CS) + || !hnbgw_cnlink_alloc(g_hnbgw->config.iups_remote_addr_name, DOMAIN_PS)) { LOGP(DMAIN, LOGL_ERROR, "Failed to initialize SCCP link to CN\n"); exit(1); } + OSMO_ASSERT(g_hnbgw->sccp.cnlink_iucs); + OSMO_ASSERT(g_hnbgw->sccp.cnlink_iups); LOGP(DHNBAP, LOGL_NOTICE, "Using RNC-Id %u\n", g_hnbgw->config.rnc_id); diff --git a/tests/config/defaults.vty b/tests/config/defaults.vty index 282c080..35119b1 100644 --- a/tests/config/defaults.vty +++ b/tests/config/defaults.vty @@ -5,19 +5,19 @@ OsmoHNBGW# show cs7 config cs7 instance 0 point-code 0.23.5 - asp asp-clnt-OsmoHNBGW 2905 0 m3ua + asp asp-clnt-msc-0 2905 0 m3ua local-ip localhost remote-ip localhost sctp-role client - as as-clnt-OsmoHNBGW m3ua - asp asp-clnt-OsmoHNBGW + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 routing-key 0 0.23.5 OsmoHNBGW# show cnlink IuCS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 IuPS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 OsmoHNBGW# show running-config ... diff --git a/tests/config/one_cs7.vty b/tests/config/one_cs7.vty index 7011c83..7196ef8 100644 --- a/tests/config/one_cs7.vty +++ b/tests/config/one_cs7.vty @@ -1,28 +1,25 @@ OsmoHNBGW> enable -OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5 OsmoHNBGW# show cs7 config cs7 instance 0 - point-code 0.23.5 - asp asp-clnt-OsmoHNBGW 2905 0 m3ua + point-code 1.1.1 + asp asp-clnt-msc-0 2905 0 m3ua local-ip localhost remote-ip localhost sctp-role client - as as-clnt-OsmoHNBGW m3ua - asp asp-clnt-OsmoHNBGW - routing-key 0 0.23.5 + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 + routing-key 0 1.1.1 -OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5 OsmoHNBGW# show cnlink -IuCS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW -IuPS: OsmoHNBGW:RI=SSN_PC,PC=0.23.5,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 -OsmoHNBGW# ### ERROR: 'one_cs7.cfg' sets 'cs7 instance 0' / 'point-code 1.1.1', but osmo-hnbgw uses 0.23.5 OsmoHNBGW# show running-config ... cs7 instance 0 - point-code 0.23.5 + point-code 1.1.1 hnbgw ... diff --git a/tests/config/one_cs7_with_addrs.vty b/tests/config/one_cs7_with_addrs.vty index 59b1b76..2975ade 100644 --- a/tests/config/one_cs7_with_addrs.vty +++ b/tests/config/one_cs7_with_addrs.vty @@ -4,12 +4,12 @@ OsmoHNBGW# show cs7 config cs7 instance 0 point-code 1.1.1 - asp asp-clnt-OsmoHNBGW 2905 0 m3ua + asp asp-clnt-msc-0 2905 0 m3ua local-ip localhost remote-ip localhost sctp-role client - as as-clnt-OsmoHNBGW m3ua - asp asp-clnt-OsmoHNBGW + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 routing-key 0 1.1.1 sccp-address my-msc routing-indicator PC @@ -20,10 +20,10 @@ OsmoHNBGW# ### IuCS and IuPS were explicitly pointed to specific remote point-codes, using cs7 instance 0 addresses OsmoHNBGW# show cnlink -IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc:RI=SSN_PC,PC=1.2.3,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW -IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn:RI=SSN_PC,PC=1.4.2,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc=RI=SSN_PC,PC=1.2.3,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn=RI=SSN_PC,PC=1.4.2,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 OsmoHNBGW# show running-config ... diff --git a/tests/config/one_cs7_with_iucs_addr.vty b/tests/config/one_cs7_with_iucs_addr.vty index 2e57ea1..7fc4ed1 100644 --- a/tests/config/one_cs7_with_iucs_addr.vty +++ b/tests/config/one_cs7_with_iucs_addr.vty @@ -3,12 +3,12 @@ OsmoHNBGW# show cs7 config cs7 instance 0 point-code 1.1.1 - asp asp-clnt-OsmoHNBGW 2905 0 m3ua + asp asp-clnt-msc-0 2905 0 m3ua local-ip localhost remote-ip localhost sctp-role client - as as-clnt-OsmoHNBGW m3ua - asp asp-clnt-OsmoHNBGW + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 routing-key 0 1.1.1 sccp-address my-msc routing-indicator PC @@ -16,10 +16,10 @@ OsmoHNBGW# ### only IuCS was configured to go to remote-PC = 1.2.3, IuPS auto-configured to remote-PC = 0.23.4 OsmoHNBGW# show cnlink -IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc:RI=SSN_PC,PC=1.2.3,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc=RI=SSN_PC,PC=1.2.3,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 OsmoHNBGW# show running-config ... diff --git a/tests/config/one_cs7_with_iups_addr.vty b/tests/config/one_cs7_with_iups_addr.vty index 1e4346f..bd5f261 100644 --- a/tests/config/one_cs7_with_iups_addr.vty +++ b/tests/config/one_cs7_with_iups_addr.vty @@ -3,12 +3,12 @@ OsmoHNBGW# show cs7 config cs7 instance 0 point-code 1.1.1 - asp asp-clnt-OsmoHNBGW 2905 0 m3ua + asp asp-clnt-msc-0 2905 0 m3ua local-ip localhost remote-ip localhost sctp-role client - as as-clnt-OsmoHNBGW m3ua - asp asp-clnt-OsmoHNBGW + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 routing-key 0 1.1.1 sccp-address my-sgsn routing-indicator PC @@ -17,9 +17,9 @@ OsmoHNBGW# ### only IuPS was configured to go to remote-PC = 1.4.2, IuCS auto-configured to remote-PC = 0.23.1 OsmoHNBGW# show cnlink IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW -IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn:RI=SSN_PC,PC=1.4.2,SSN=RANAP - SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-OsmoHNBGW proto=m3ua ASP asp-clnt-OsmoHNBGW + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-sgsn=RI=SSN_PC,PC=1.4.2,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 OsmoHNBGW# show running-config ... diff --git a/tests/config/two_cs7.cfg b/tests/config/two_cs7.cfg new file mode 100644 index 0000000..9f5eba0 --- /dev/null +++ b/tests/config/two_cs7.cfg @@ -0,0 +1,7 @@ +# there are two cs7 instances, but auto-configuration will only use instance 0. + +cs7 instance 0 + point-code 1.1.1 + +cs7 instance 1 + point-code 2.2.2 diff --git a/tests/config/two_cs7.vty b/tests/config/two_cs7.vty new file mode 100644 index 0000000..3d337fa --- /dev/null +++ b/tests/config/two_cs7.vty @@ -0,0 +1,31 @@ +OsmoHNBGW> enable + +OsmoHNBGW# ### there are two cs7 instances, but auto-configuration has only set up ASP and AS in instance 0. +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 1.1.1 + asp asp-clnt-msc-0 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 + routing-key 0 1.1.1 +cs7 instance 1 + point-code 2.2.2 + +OsmoHNBGW# ### there are two cs7 instances, but auto-configuration will only use SCCP of instance 0 with local-PC = 1.1.1 +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.1,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 +IuPS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> RI=SSN_PC,PC=0.23.4,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 + +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 1.1.1 +cs7 instance 1 + point-code 2.2.2 +hnbgw +... diff --git a/tests/config/two_cs7_with_addrs.cfg b/tests/config/two_cs7_with_addrs.cfg new file mode 100644 index 0000000..57f13e3 --- /dev/null +++ b/tests/config/two_cs7_with_addrs.cfg @@ -0,0 +1,17 @@ +# two cs7 instances, both will be auto-configured for ASP and AS because address book entries point at both. + +cs7 instance 0 + point-code 1.1.1 + sccp-address my-msc + point-code 1.2.3 + +cs7 instance 1 + point-code 2.2.2 + sccp-address my-sgsn + point-code 2.4.2 + +hnbgw + iucs + remote-addr my-msc + iups + remote-addr my-sgsn diff --git a/tests/config/two_cs7_with_addrs.vty b/tests/config/two_cs7_with_addrs.vty new file mode 100644 index 0000000..59240d1 --- /dev/null +++ b/tests/config/two_cs7_with_addrs.vty @@ -0,0 +1,57 @@ +OsmoHNBGW> enable + +OsmoHNBGW# ### two cs7 instances, both have been auto-configured for ASP and AS because address book entries point at both. +OsmoHNBGW# show cs7 config +cs7 instance 0 + point-code 1.1.1 + asp asp-clnt-msc-0 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-msc-0 m3ua + asp asp-clnt-msc-0 + routing-key 0 1.1.1 + sccp-address my-msc + routing-indicator PC + point-code 1.2.3 +cs7 instance 1 + point-code 2.2.2 + asp asp-clnt-sgsn-0 2905 0 m3ua + local-ip localhost + remote-ip localhost + sctp-role client + as as-clnt-sgsn-0 m3ua + asp asp-clnt-sgsn-0 + routing-key 0 2.2.2 + sccp-address my-sgsn + routing-indicator PC + point-code 2.4.2 + +OsmoHNBGW# ### IuCS on instance 0 with local-PC = 1.1.1, IuPS on instance 1 with local-PC = 2.2.2 +OsmoHNBGW# show cnlink +IuCS: OsmoHNBGW:RI=SSN_PC,PC=1.1.1,SSN=RANAP <-> my-msc=RI=SSN_PC,PC=1.2.3,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-msc-0 proto=m3ua ASP asp-clnt-msc-0 +IuPS: OsmoHNBGW:RI=SSN_PC,PC=2.2.2,SSN=RANAP <-> my-sgsn=RI=SSN_PC,PC=2.4.2,SSN=RANAP + SS7 route: pc=0=0.0.0 mask=0x0=0.0.0 via AS as-clnt-sgsn-0 proto=m3ua ASP asp-clnt-sgsn-0 + +OsmoHNBGW# show running-config +... +cs7 instance 0 + point-code 1.1.1 + sccp-address my-msc + routing-indicator PC + point-code 1.2.3 +cs7 instance 1 + point-code 2.2.2 + sccp-address my-sgsn + routing-indicator PC + point-code 2.4.2 +hnbgw + rnc-id 23 + log-prefix hnb-id + iuh + iucs + remote-addr my-msc + iups + remote-addr my-sgsn +... -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Iea1824f1c586723d989c80a909bae16bd2866e08 Gerrit-Change-Number: 32323 Gerrit-PatchSet: 9 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-CC: msuraev <msuraev(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[S] Change in osmo-hnbgw[master]: add doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32989 ) Change subject: add doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg ...................................................................... add doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg We have not a single example yet showing point code and SCCP address configuration. Add this example, which will also show how the config file syntax changes while introducing CN pooling in upcoming patches. Related: SYS#6412 Change-Id: I42c3b434a7339cc3efb27b43c893cfb734de9ca4 --- M contrib/osmo-hnbgw.spec.in M debian/osmo-hnbgw.install A doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg 3 files changed, 43 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, but someone else must approve neels: Looks good to me, approved diff --git a/contrib/osmo-hnbgw.spec.in b/contrib/osmo-hnbgw.spec.in index f2cb6dc..8428ce8 100644 --- a/contrib/osmo-hnbgw.spec.in +++ b/contrib/osmo-hnbgw.spec.in @@ -92,6 +92,7 @@ %dir %{_docdir}/%{name}/examples %dir %{_docdir}/%{name}/examples/osmo-hnbgw %{_docdir}/%{name}/examples/osmo-hnbgw/osmo-hnbgw.cfg +%{_docdir}/%{name}/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg %{_docdir}/%{name}/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg %dir %{_sysconfdir}/osmocom %config(noreplace) %{_sysconfdir}/osmocom/osmo-hnbgw.cfg diff --git a/debian/osmo-hnbgw.install b/debian/osmo-hnbgw.install index daf1f1a..c2449b6 100644 --- a/debian/osmo-hnbgw.install +++ b/debian/osmo-hnbgw.install @@ -3,3 +3,4 @@ usr/bin/osmo-hnbgw usr/share/doc/osmo-hnbgw/examples/osmo-hnbgw/osmo-hnbgw.cfg usr/share/doc/osmo-hnbgw/examples usr/share/doc/osmo-hnbgw/examples/osmo-hnbgw/osmo-hnbgw-pfcp.cfg usr/share/doc/osmo-hnbgw/examples +usr/share/doc/osmo-hnbgw/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg usr/share/doc/osmo-hnbgw/examples diff --git a/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg b/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg new file mode 100644 index 0000000..5e78947 --- /dev/null +++ b/doc/examples/osmo-hnbgw/osmo-hnbgw-cs7.cfg @@ -0,0 +1,27 @@ +cs7 instance 0 + point-code 0.3.0 + asp asp-clnt-hnbgw-0 2905 0 m3ua + remote-ip 127.0.0.1 + sccp-address my-msc + point-code 1.2.3 + sccp-address my-sgsn + point-code 1.4.2 + +hnbgw + iuh + local-ip 0.0.0.0 + hnbap-allow-tmsi 1 + iucs + remote-addr my-msc + iups + remote-addr my-sgsn + +log stderr + logging filter all 1 + logging color 1 + logging print level 1 + logging print category 1 + logging print category-hex 0 + logging print file basename last + logging print extended-timestamp 1 + logging level set-all notice -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32989 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I42c3b434a7339cc3efb27b43c893cfb734de9ca4 Gerrit-Change-Number: 32989 Gerrit-PatchSet: 2 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmo-hnbgw[master]: use new osmo_sccp_instance_next_conn_id()
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32987 ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: use new osmo_sccp_instance_next_conn_id() ...................................................................... use new osmo_sccp_instance_next_conn_id() Change-Id: I0fc6e486ce5d68b06d0bc9869292f082ec7a67f0 --- M include/osmocom/hnbgw/hnbgw.h M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnbgw_cn.c 3 files changed, 11 insertions(+), 44 deletions(-) Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index e67a86a..6570bdf 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -67,7 +67,6 @@ /* reference to the SCCP User SAP by which we communicate */ struct osmo_sccp_instance *sccp; struct osmo_sccp_user *sccp_user; - uint32_t next_conn_id; /* linked list of hnbgw_context_map */ struct llist_head map_list; diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index f610087..f8d0ecf 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -52,47 +52,6 @@ return MAP_S_CONNECTING; } -/* is a given SCCP USER SAP Connection ID in use for a given CN link? */ -static int cn_id_in_use(struct hnbgw_cnlink *cn, uint32_t id) -{ - struct hnbgw_context_map *map; - - llist_for_each_entry(map, &cn->map_list, cn_list) { - if (map->scu_conn_id == id) - return 1; - } - return 0; -} - -/* try to allocate a new SCCP User SAP Connection ID */ -static int alloc_cn_conn_id(struct hnbgw_cnlink *cn, uint32_t *id_out) -{ - uint32_t i; - uint32_t id; - - /* SUA: RFC3868 sec 3.10.4: - * The source reference number is a 4 octet long integer. - * This is allocated by the source SUA instance. - * M3UA/SCCP: ITU-T Q.713 sec 3.3: - * The "source local reference" parameter field is a three-octet field containing a - * reference number which is generated and used by the local node to identify the - * connection section after the connection section is set up. - * The coding "all ones" is reserved for future use. - * Hence, let's simply use 24 bit ids to fit all link types (excluding 0x00ffffff). - */ - - for (i = 0; i < 0x00ffffff; i++) { - id = cn->next_conn_id++; - if (cn->next_conn_id == 0x00ffffff) - cn->next_conn_id = 0; - if (!cn_id_in_use(cn, id)) { - *id_out = id; - return 1; - } - } - return -1; -} - /* Map from a HNB + ContextID to the SCCP-side Connection ID */ struct hnbgw_context_map * context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id, @@ -118,7 +77,8 @@ } } - if (alloc_cn_conn_id(cn_if_new, &new_scu_conn_id) < 0) { + new_scu_conn_id = osmo_sccp_instance_next_conn_id(map->cn_link->sccp); + if (new_scu_conn_id < 0) { LOGHNB(hnb, DMAIN, LOGL_ERROR, "Unable to allocate CN connection ID\n"); return NULL; } diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c index d9e35af..33ec0f6 100644 --- a/src/osmo-hnbgw/hnbgw_cn.c +++ b/src/osmo-hnbgw/hnbgw_cn.c @@ -495,7 +495,6 @@ cnlink = talloc_zero(g_hnbgw, struct hnbgw_cnlink); INIT_LLIST_HEAD(&cnlink->map_list); - cnlink->next_conn_id = 1000; cnlink->sccp_user = osmo_sccp_user_bind_pc(g_hnbgw->sccp.client, "OsmoHNBGW", sccp_sap_up, OSMO_SCCP_SSN_RANAP, g_hnbgw->sccp.local_addr.pc); -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32987 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I0fc6e486ce5d68b06d0bc9869292f082ec7a67f0 Gerrit-Change-Number: 32987 Gerrit-PatchSet: 2 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[M] Change in osmo-hnbgw[master]: immediately SCCP RLSD on HNB re-register
by neels 01 Jun '23

01 Jun '23
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32915 ) Change subject: immediately SCCP RLSD on HNB re-register ...................................................................... immediately SCCP RLSD on HNB re-register The RUA side may disconnect a) gracefully (RUA Disconnect with RANAP IU Release Complete) or b) by detecting that the HNB is gone / has restarted For a), the SCCP side waits for a RLSD from the CN that follows the IU Release Complete. For b), we so far also wait for a RLSD from CN, which will never come, and only after a timeout send an SCCP RLSD to the CN. Instead, for b), immediately send an SCCP RLSD. To distinguish between the graceful release (a) and the disruptive release (b), add new state MAP_RUA_ST_DISRUPTED on the RUA side, and add new event MAP_SCCP_EV_RAN_LINK_LOST for the SCCP side. Any non-graceful disconnect of RUA enters ST_DISRUPTED. disrupted_onenter() dispatches EV_RAN_LINK_LOST to SCCP, and SCCP directly sends RLSD to the CN without timeout. These changes are also shown in doc/charts/hnbgw_context_map.msc. Change-Id: I4e78617ad39bb73fe92097c8a1a8069da6a7f6a1 --- M doc/charts/hnbgw_context_map.msc M include/osmocom/hnbgw/context_map.h M src/osmo-hnbgw/context_map_rua.c M src/osmo-hnbgw/context_map_sccp.c 4 files changed, 95 insertions(+), 15 deletions(-) Approvals: pespin: Looks good to me, but someone else must approve Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve neels: Looks good to me, approved diff --git a/doc/charts/hnbgw_context_map.msc b/doc/charts/hnbgw_context_map.msc index 7a4da55..d287d89 100644 --- a/doc/charts/hnbgw_context_map.msc +++ b/doc/charts/hnbgw_context_map.msc @@ -65,7 +65,7 @@ sccp abox sccp [label="MAP_SCCP_ST_DISCONNECTED"]; rua <= sccp [label="MAP_RUA_EV_CN_DISC"]; hnb <= rua [label="RUA Disconnect"]; - rua abox rua [label="MAP_RUA_ST_DISCONNECTED"]; + rua abox rua [label="MAP_RUA_ST_DISRUPTED"]; rua rbox sccp [label="map_check_released()"]; rua rbox sccp [label="hnbgw_context_map_free()"]; @@ -81,10 +81,10 @@ --- [label="Ungraceful release from HNB"]; hnb -x rua [label="link loss"]; rua rbox rua [label="MAP_RUA_EV_HNB_LINK_LOST"]; - rua => sccp [label="MAP_SCCP_EV_RAN_DISC"]; + rua abox rua [label="MAP_RUA_ST_DISRUPTED"]; + rua => sccp [label="MAP_SCCP_EV_RAN_LINK_LOST"]; sccp => cn [label="SCCP Released"]; sccp abox sccp [label="MAP_SCCP_ST_DISCONNECTED"]; - rua abox rua [label="MAP_RUA_ST_DISCONNECTED"]; rua rbox sccp [label="map_check_released()"]; rua rbox sccp [label="hnbgw_context_map_free()"]; @@ -98,10 +98,8 @@ rua rbox rua [label="MAP_RUA_EV_HNB_LINK_LOST"]; hnb <= rua [label="RUA Disconnect"]; hnb note rua [label="TODO: does it make sense to send\nRUA Disconnect per context when HNB is/was gone?\nOr has the HNB implicitly discarded these?"]; - rua abox rua [label="MAP_RUA_ST_DISCONNECTED"]; - rua => sccp [label="MAP_SCCP_EV_RAN_DISC\nfrom map_rua_disconnected_onenter()"]; - sccp abox sccp [label="MAP_SCCP_ST_WAIT_RLSD"]; - rua => sccp [label="MAP_SCCP_EV_RAN_DISC\nto skip waiting for SCCP Released from CN"]; + rua abox rua [label="MAP_RUA_ST_DISRUPTED"]; + rua => sccp [label="MAP_SCCP_EV_RAN_LINK_LOST\nfrom map_rua_disrupted_onenter()"]; sccp => cn [label="SCCP Released"]; sccp abox sccp [label="MAP_SCCP_ST_DISCONNECTED"]; rua rbox sccp [label="map_check_released()"]; diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index a2e76c3..9320ce0 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -51,6 +51,8 @@ * CN should have received an Iu-ReleaseComplete with or before this, give CN a chance to send an SCCP RLSD; * after a timeout we will send a non-standard RLSD to the CN instead. */ MAP_SCCP_EV_RAN_DISC, + /* The RAN released ungracefully. We will directly disconnect the SCCP connection, too. */ + MAP_SCCP_EV_RAN_LINK_LOST, /* Receiving an SCCP RLSD from CN, or libosmo-sigtran tells us about SCCP connection timeout. All done. */ MAP_SCCP_EV_RX_RELEASED, }; diff --git a/src/osmo-hnbgw/context_map_rua.c b/src/osmo-hnbgw/context_map_rua.c index f50f711..9e8f028 100644 --- a/src/osmo-hnbgw/context_map_rua.c +++ b/src/osmo-hnbgw/context_map_rua.c @@ -41,6 +41,7 @@ MAP_RUA_ST_INIT, MAP_RUA_ST_CONNECTED, MAP_RUA_ST_DISCONNECTED, + MAP_RUA_ST_DISRUPTED, }; static const struct value_string map_rua_fsm_event_names[] = { @@ -58,6 +59,7 @@ static const struct osmo_tdef_state_timeout map_rua_fsm_timeouts[32] = { [MAP_RUA_ST_INIT] = { .T = -31 }, [MAP_RUA_ST_DISCONNECTED] = { .T = -31 }, + [MAP_RUA_ST_DISRUPTED] = { .T = -31 }, }; /* Transition to a state, using the T timer defined in map_rua_fsm_timeouts. @@ -93,6 +95,7 @@ return MAP_S_ACTIVE; default: case MAP_RUA_ST_DISCONNECTED: + case MAP_RUA_ST_DISRUPTED: return MAP_S_DISCONNECTING; } } @@ -103,6 +106,7 @@ return false; switch (map->rua_fi->state) { case MAP_RUA_ST_DISCONNECTED: + case MAP_RUA_ST_DISRUPTED: return false; default: return true; @@ -114,10 +118,11 @@ /* Return 1 to terminate FSM instance, 0 to keep running */ switch (fi->state) { default: - map_rua_fsm_state_chg(MAP_RUA_ST_DISCONNECTED); + map_rua_fsm_state_chg(MAP_RUA_ST_DISRUPTED); return 0; case MAP_RUA_ST_DISCONNECTED: + case MAP_RUA_ST_DISRUPTED: return 1; } } @@ -210,8 +215,6 @@ return; case MAP_RUA_EV_RX_DISCONNECT: - case MAP_RUA_EV_CN_DISC: - case MAP_RUA_EV_HNB_LINK_LOST: /* Unlikely that SCCP is active, but let the SCCP FSM decide about that. */ handle_rx_rua(fi, ranap_msg); /* There is a reason to shut down this RUA connection. Super unlikely, we haven't even processed the @@ -220,6 +223,11 @@ map_rua_fsm_state_chg(MAP_RUA_ST_DISCONNECTED); break; + case MAP_RUA_EV_CN_DISC: + case MAP_RUA_EV_HNB_LINK_LOST: + map_rua_fsm_state_chg(MAP_RUA_ST_DISRUPTED); + break; + default: OSMO_ASSERT(false); } @@ -276,14 +284,14 @@ case MAP_RUA_EV_HNB_LINK_LOST: /* The HNB is gone. Cannot gracefully cleanup the RUA connection, just be gone. */ - map_rua_fsm_state_chg(MAP_RUA_ST_DISCONNECTED); + map_rua_fsm_state_chg(MAP_RUA_ST_DISRUPTED); return; case MAP_RUA_EV_CN_DISC: /* There is a disruptive reason to shut down this RUA connection, HNB is still there */ OSMO_ASSERT(data == NULL); map_rua_tx_disconnect(fi); - map_rua_fsm_state_chg(MAP_RUA_ST_DISCONNECTED); + map_rua_fsm_state_chg(MAP_RUA_ST_DISRUPTED); return; default: @@ -291,23 +299,35 @@ } } -static void map_rua_disconnected_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +static void map_rua_free_if_done(struct hnbgw_context_map *map, uint32_t sccp_event) { - struct hnbgw_context_map *map = fi->priv; /* From RUA's POV, we can now free the hnbgw_context_map. * If SCCP is still active, tell it to disconnect -- in that case the SCCP side will call context_map_free(). * If SCCP is no longer active, free this map. */ if (map_sccp_is_active(map)) - map_sccp_dispatch(map, MAP_SCCP_EV_RAN_DISC, NULL); + map_sccp_dispatch(map, sccp_event, NULL); else context_map_free(map); } +static void map_rua_disconnected_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct hnbgw_context_map *map = fi->priv; + map_rua_free_if_done(map, MAP_SCCP_EV_RAN_DISC); +} + static void map_rua_disconnected_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct msgb *ranap_msg = data; if (msg_has_l2_data(ranap_msg)) LOGPFSML(fi, LOGL_ERROR, "RUA not connected, cannot dispatch RANAP message\n"); + /* Ignore all events. */ +} + +static void map_rua_disrupted_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct hnbgw_context_map *map = fi->priv; + map_rua_free_if_done(map, MAP_SCCP_EV_RAN_LINK_LOST); } void map_rua_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) @@ -331,6 +351,7 @@ | S(MAP_RUA_ST_INIT) | S(MAP_RUA_ST_CONNECTED) | S(MAP_RUA_ST_DISCONNECTED) + | S(MAP_RUA_ST_DISRUPTED) , .action = map_rua_init_action, }, @@ -345,6 +366,7 @@ , .out_state_mask = 0 | S(MAP_RUA_ST_DISCONNECTED) + | S(MAP_RUA_ST_DISRUPTED) , .action = map_rua_connected_action, }, @@ -357,6 +379,16 @@ .onenter = map_rua_disconnected_onenter, .action = map_rua_disconnected_action, }, + [MAP_RUA_ST_DISRUPTED] = { + .name = "disrupted", + .in_event_mask = 0 + | S(MAP_RUA_EV_CN_DISC) + | S(MAP_RUA_EV_HNB_LINK_LOST) + , + .onenter = map_rua_disrupted_onenter, + /* same as MAP_RUA_ST_DISCONNECTED: */ + .action = map_rua_disconnected_action, + }, }; static struct osmo_fsm map_rua_fsm = { diff --git a/src/osmo-hnbgw/context_map_sccp.c b/src/osmo-hnbgw/context_map_sccp.c index 132d03e..3de8215 100644 --- a/src/osmo-hnbgw/context_map_sccp.c +++ b/src/osmo-hnbgw/context_map_sccp.c @@ -52,6 +52,7 @@ OSMO_VALUE_STRING(MAP_SCCP_EV_RX_DATA_INDICATION), OSMO_VALUE_STRING(MAP_SCCP_EV_TX_DATA_REQUEST), OSMO_VALUE_STRING(MAP_SCCP_EV_RAN_DISC), + OSMO_VALUE_STRING(MAP_SCCP_EV_RAN_LINK_LOST), OSMO_VALUE_STRING(MAP_SCCP_EV_RX_RELEASED), {} }; @@ -262,6 +263,7 @@ map_sccp_fsm_state_chg(MAP_SCCP_ST_WAIT_CC); return; + case MAP_SCCP_EV_RAN_LINK_LOST: case MAP_SCCP_EV_RAN_DISC: /* No CR has been sent yet, just go to disconnected state. */ if (msg_has_l2_data(ranap_msg)) @@ -297,6 +299,7 @@ LOGPFSML(fi, LOGL_ERROR, "Connection not yet confirmed, cannot forward RANAP to CN\n"); return; + case MAP_SCCP_EV_RAN_LINK_LOST: case MAP_SCCP_EV_RAN_DISC: /* RUA connection was terminated. First wait for the CC before releasing the SCCP conn. */ if (msg_has_l2_data(ranap_msg)) @@ -351,6 +354,16 @@ tx_sccp_df1(fi, ranap_msg); return; + case MAP_SCCP_EV_RAN_LINK_LOST: + /* RUA has disconnected ungracefully, so there is no Iu Release that told the CN to disconnect. + * Disconnect on the SCCP layer, ungracefully. */ + /* There won't be any ranap_msg, but if a caller wants to dispatch a msg, forward it before + * disconnecting. */ + tx_sccp_df1(fi, ranap_msg); + tx_sccp_rlsd(fi); + map_sccp_fsm_state_chg(MAP_SCCP_ST_DISCONNECTED); + return; + case MAP_SCCP_EV_RX_RELEASED: /* The CN sends an N-Disconnect (SCCP Released) out of the usual sequence. Not what we expected, but * handle it. */ @@ -480,6 +493,7 @@ .in_event_mask = 0 | S(MAP_SCCP_EV_TX_DATA_REQUEST) | S(MAP_SCCP_EV_RAN_DISC) + | S(MAP_SCCP_EV_RAN_LINK_LOST) | S(MAP_SCCP_EV_RX_RELEASED) , .out_state_mask = 0 @@ -495,6 +509,7 @@ | S(MAP_SCCP_EV_RX_CONNECTION_CONFIRM) | S(MAP_SCCP_EV_TX_DATA_REQUEST) | S(MAP_SCCP_EV_RAN_DISC) + | S(MAP_SCCP_EV_RAN_LINK_LOST) | S(MAP_SCCP_EV_RX_RELEASED) , .out_state_mask = 0 @@ -509,6 +524,7 @@ | S(MAP_SCCP_EV_RX_DATA_INDICATION) | S(MAP_SCCP_EV_TX_DATA_REQUEST) | S(MAP_SCCP_EV_RAN_DISC) + | S(MAP_SCCP_EV_RAN_LINK_LOST) | S(MAP_SCCP_EV_RX_RELEASED) | S(MAP_SCCP_EV_RX_CONNECTION_CONFIRM) , @@ -526,6 +542,7 @@ | S(MAP_SCCP_EV_RX_DATA_INDICATION) | S(MAP_SCCP_EV_TX_DATA_REQUEST) | S(MAP_SCCP_EV_RAN_DISC) + | S(MAP_SCCP_EV_RAN_LINK_LOST) | S(MAP_SCCP_EV_RX_CONNECTION_CONFIRM) , .out_state_mask = 0 @@ -539,6 +556,7 @@ .in_event_mask = 0 | S(MAP_SCCP_EV_TX_DATA_REQUEST) | S(MAP_SCCP_EV_RAN_DISC) + | S(MAP_SCCP_EV_RAN_LINK_LOST) , .onenter = map_sccp_disconnected_onenter, .action = map_sccp_disconnected_action, -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32915 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: I4e78617ad39bb73fe92097c8a1a8069da6a7f6a1 Gerrit-Change-Number: 32915 Gerrit-PatchSet: 4 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: merged
1 0
0 0
[L] Change in osmo-hnbgw[master]: cnpool: allow separate cs7 for IuPS and IuCS
by neels 01 Jun '23

01 Jun '23
Attention is currently required from: pespin, msuraev. neels has posted comments on this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323 ) Change subject: cnpool: allow separate cs7 for IuPS and IuCS ...................................................................... Patch Set 9: (1 comment) File include/osmocom/hnbgw/hnbgw.h: https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323/comment/6cdf28d1_c7d76de4 PS8, Line 133: if (!cnlink->hnbgw_sccp_user) > In places where it's established to be safe i can just use cnlink->hnbgw_sccp_usser->ss7->sccp direc […] (in patch Ifc5242547260154eb5aecd3a9d9c2aac8419e8db it will be more obvious that there can be a hnbgw_context_map without a cnlink yet...) -- To view, visit https://gerrit.osmocom.org/c/osmo-hnbgw/+/32323 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnbgw Gerrit-Branch: master Gerrit-Change-Id: Iea1824f1c586723d989c80a909bae16bd2866e08 Gerrit-Change-Number: 32323 Gerrit-PatchSet: 9 Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge(a)osmocom.org> Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de> Gerrit-Reviewer: pespin <pespin(a)sysmocom.de> Gerrit-CC: msuraev <msuraev(a)sysmocom.de> Gerrit-Attention: pespin <pespin(a)sysmocom.de> Gerrit-Attention: msuraev <msuraev(a)sysmocom.de> Gerrit-Comment-Date: Thu, 01 Jun 2023 00:10:35 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: neels <nhofmeyr(a)sysmocom.de> Comment-In-Reply-To: pespin <pespin(a)sysmocom.de> Gerrit-MessageType: comment
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 245
  • 246
  • 247
  • 248
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.