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 <nhofm...@sysmocom.de> Gerrit-MessageType: newchange