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