neels has uploaded this change for review.

View Change

UE state leak: when HNB re-registers, discard previous UE state

User reports show leaked UE contexts over time, in a scenario where HNB
regularly disconnect and reconnect.

So far, when we receive a HNB REGISTER REQ, we log as "duplicated" and
continue to use the hnb_context unchanged. But it seems obvious that a
HNB that registers does not expect any UE state to remain. It will
obviously not tear down UE contexts (HNBAP or RUA) that have been
established before the HNB REGISTER REQUEST. These hence remain in
osmo-hnbgw indefinitely.

When receiving a HNB REGISTER REQUEST, release all its previous UE
state. Allow the HNB to register with a clean slate.

The aim is to alleviate the observed build-up of apparently orphaned UE
contexts, in order to avoid gradual memory exhaustion.

Related: SYS#6297
Change-Id: I7fa8a04cc3b2dfba263bda5b410961c77fbed332
---
M include/osmocom/hnbgw/hnbgw.h
M src/osmo-hnbgw/hnbgw.c
M src/osmo-hnbgw/hnbgw_hnbap.c
3 files changed, 21 insertions(+), 7 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/93/31293/1
diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h
index 8adefea..ed18ca4 100644
--- a/include/osmocom/hnbgw/hnbgw.h
+++ b/include/osmocom/hnbgw/hnbgw.h
@@ -188,6 +188,7 @@

struct hnb_context *hnb_context_alloc(struct hnb_gw *gw, struct osmo_stream_srv_link *link, int new_fd);
void hnb_context_release(struct hnb_context *ctx);
+void hnb_context_release_ue_state(struct hnb_context *ctx);

void hnbgw_vty_init(struct hnb_gw *gw, void *tall_ctx);
int hnbgw_vty_go_parent(struct vty *vty);
diff --git a/src/osmo-hnbgw/hnbgw.c b/src/osmo-hnbgw/hnbgw.c
index 5dba1e3..3a6879e 100644
--- a/src/osmo-hnbgw/hnbgw.c
+++ b/src/osmo-hnbgw/hnbgw.c
@@ -395,15 +395,10 @@
return umts_cell_id_name(&ctx->id);
}

-void hnb_context_release(struct hnb_context *ctx)
+void hnb_context_release_ue_state(struct hnb_context *ctx)
{
struct hnbgw_context_map *map, *map2;

- LOGHNB(ctx, DMAIN, LOGL_INFO, "Releasing HNB context\n");
-
- /* remove from the list of HNB contexts */
- llist_del(&ctx->list);
-
/* deactivate all context maps */
llist_for_each_entry_safe(map, map2, &ctx->map_list, hnb_list) {
/* remove it from list, as HNB context will soon be
@@ -414,6 +409,16 @@
context_map_deactivate(map);
}
ue_context_free_by_hnb(ctx->gw, ctx);
+}
+
+void hnb_context_release(struct hnb_context *ctx)
+{
+ LOGHNB(ctx, DMAIN, LOGL_INFO, "Releasing HNB context\n");
+
+ /* remove from the list of HNB contexts */
+ llist_del(&ctx->list);
+
+ hnb_context_release_ue_state(ctx);

if (ctx->conn) { /* we own a conn, we must free it: */
LOGHNB(ctx, DMAIN, LOGL_INFO, "Closing HNB SCTP connection %s\n",
diff --git a/src/osmo-hnbgw/hnbgw_hnbap.c b/src/osmo-hnbgw/hnbgw_hnbap.c
index 4aefe2b..19ebd38 100644
--- a/src/osmo-hnbgw/hnbgw_hnbap.c
+++ b/src/osmo-hnbgw/hnbgw_hnbap.c
@@ -467,7 +467,15 @@

LOGHNB(ctx, DHNBAP, LOGL_DEBUG, "HNB-REGISTER-REQ %s MCC=%u,MNC=%u,LAC=%u,RAC=%u,SAC=%u,CID=%u from %s%s\n",
ctx->identity_info, ctx->id.mcc, ctx->id.mnc, ctx->id.lac, ctx->id.rac, ctx->id.sac, ctx->id.cid,
- name, ctx->hnb_registered ? " (duplicated)" : "");
+ name, ctx->hnb_registered ? " (re-connecting)" : "");
+
+ if (ctx->hnb_registered) {
+ /* The HNB is already registered, and we are seeing a new HNB Register Request. The HNB has restarted
+ * without us noticing. Clearly, the HNB does not expect any UE state to be active here, so discard any
+ * UE contexts and SCCP connections associated with this HNB. */
+ LOGHNB(ctx, DHNBAP, LOGL_NOTICE, "HNB reconnecting, discarding all previous UE state\n");
+ hnb_context_release_ue_state(ctx);
+ }

ctx->hnb_registered = true;


To view, visit change 31293. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: I7fa8a04cc3b2dfba263bda5b410961c77fbed332
Gerrit-Change-Number: 31293
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr@sysmocom.de>
Gerrit-MessageType: newchange