[PATCH] osmo-iuh[master]: hnbap: accept UE Register Requests with TMSI and pTMSI

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Mon Sep 26 00:21:27 UTC 2016


Hello Harald Welte, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/910

to look at the new patch set (#2).

hnbap: accept UE Register Requests with TMSI and pTMSI

Add the option to allow UE Register Requests with a TMSI identity.
Add VTY command to enable this option, 'hnbap-allow-tmsi'.
Add hnbgw_tx_ue_register_acc_tmsi().

HNBGW so far keeps track of UEs that have registered, with their IMSI. When a
UE registers with only a TMSI, we obviously can't store an IMSI. However, since
we're so far never *using* the list of UEs in osmo-hnbgw, we might as well just
accept the TMSI registration and carry on as usual. All that is needed for
proper operation is a valid UE context.

This is aimed at the ip.access nano3G femto cell, as it apparently feeds
whichever identification the UE sends through to HNBAP (TMSI+LAI, pTMSI+RAI),
instead of an IMSI as expected. So far this caused failures and the need to
make the UE clear its TMSI (wait several minutes or attempt to subscribe to a
different network), so that UE registration switched back to IMSI. When simply
accepting the TMSI in osmo-hngw, no problems are apparent in our current code
state.

For example, a Samsung Galaxy S4 seems to send a UE_Identity_PR_tMSILAI (CS
identity), and a GT-I9100 seems to send a UE_Identity_PR_pTMSIRAI (PS identity)
upon first registration to the network.

Recording the IMSI in hnbgw: we could use the subscriber list during paging, to
page a UE on only its last seen HNB. On the other hand, it doesn't hurt to
anyway always page to all HNBs connected to osmo-hnbgw. The paging procedure
does include a page-to-all-HNBs in case the first HNB paging fails. But we must
be aware that UEs that register by TMSI will simply not have an IMSI recorded
in the list of UE contexts, so a lookup based on IMSI may fail.

Patch-by: Harald Welte <laforge at gnumonks.org>, me
Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589
---
M include/osmocom/iuh/hnbgw.h
M src/hnbgw_hnbap.c
M src/hnbgw_vty.c
3 files changed, 130 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/10/910/2

diff --git a/include/osmocom/iuh/hnbgw.h b/include/osmocom/iuh/hnbgw.h
index bee7fb6..dfe287c 100644
--- a/include/osmocom/iuh/hnbgw.h
+++ b/include/osmocom/iuh/hnbgw.h
@@ -117,6 +117,7 @@
 		 * plane traffic from HNBs */
 		uint16_t iuh_cs_mux_port;
 		uint16_t rnc_id;
+		bool hnbap_allow_tmsi;
 	} config;
 	/*! SCTP listen socket for incoming connections */
 	struct osmo_stream_srv_link *iuh;
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 78f4692..59150c9 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -244,6 +244,108 @@
 	return hnbgw_hnbap_tx(hnb, msg);
 }
 
+static int hnbgw_tx_ue_register_acc_tmsi(struct hnb_context *hnb, UE_Identity_t *ue_id)
+{
+	UERegisterAccept_t accept_out;
+	UERegisterAcceptIEs_t accept;
+	struct msgb *msg;
+	uint32_t ctx_id;
+	uint32_t tmsi = 0;
+	struct ue_context *ue;
+	int rc;
+
+	memset(&accept, 0, sizeof(accept));
+	accept.uE_Identity.present = ue_id->present;
+
+	switch (ue_id->present) {
+	case UE_Identity_PR_tMSILAI:
+		BIT_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.tMSI,
+				   ue_id->choice.tMSILAI.tMSI.buf,
+				   ue_id->choice.tMSILAI.tMSI.size * 8
+				   - ue_id->choice.tMSILAI.tMSI.bits_unused);
+		tmsi = *(uint32_t*)accept.uE_Identity.choice.tMSILAI.tMSI.buf;
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.pLMNID,
+				     ue_id->choice.tMSILAI.lAI.pLMNID.buf,
+				     ue_id->choice.tMSILAI.lAI.pLMNID.size);
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.tMSILAI.lAI.lAC,
+				     ue_id->choice.tMSILAI.lAI.lAC.buf,
+				     ue_id->choice.tMSILAI.lAI.lAC.size);
+		break;
+
+	case UE_Identity_PR_pTMSIRAI:
+		BIT_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.pTMSI,
+				   ue_id->choice.pTMSIRAI.pTMSI.buf,
+				   ue_id->choice.pTMSIRAI.pTMSI.size * 8
+				   - ue_id->choice.pTMSIRAI.pTMSI.bits_unused);
+		tmsi = *(uint32_t*)accept.uE_Identity.choice.pTMSIRAI.pTMSI.buf;
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.buf,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.pLMNID.size);
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.lAC.buf,
+				     ue_id->choice.pTMSIRAI.rAI.lAI.lAC.size);
+		OCTET_STRING_fromBuf(&accept.uE_Identity.choice.pTMSIRAI.rAI.rAC,
+				     ue_id->choice.pTMSIRAI.rAI.rAC.buf,
+				     ue_id->choice.pTMSIRAI.rAI.rAC.size);
+		break;
+
+	default:
+		LOGP(DHNBAP, LOGL_ERROR, "Unsupportedccept UE ID (present=%d)\n",
+			ue_id->present);
+		return -1;
+	}
+
+	tmsi = ntohl(tmsi);
+	LOGP(DHNBAP, LOGL_DEBUG, "HNBAP register with TMSI %x\n",
+	     tmsi);
+
+	ue = ue_context_by_tmsi(hnb->gw, tmsi);
+	if (!ue)
+		ue = ue_context_alloc(hnb, NULL, tmsi);
+
+	asn1_u24_to_bitstring(&accept.context_ID, &ctx_id, ue->context_id);
+
+	memset(&accept_out, 0, sizeof(accept_out));
+	rc = hnbap_encode_ueregisteraccepties(&accept_out, &accept);
+	if (rc < 0)
+		return rc;
+
+	msg = hnbap_generate_successful_outcome(ProcedureCode_id_UERegister,
+						Criticality_reject,
+						&asn_DEF_UERegisterAccept,
+						&accept_out);
+
+	switch (ue_id->present) {
+	case UE_Identity_PR_tMSILAI:
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING,
+					      &accept.uE_Identity.choice.tMSILAI.tMSI);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.tMSILAI.lAI.pLMNID);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.tMSILAI.lAI.lAC);
+		break;
+
+	case UE_Identity_PR_pTMSIRAI:
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BIT_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.pTMSI);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.pLMNID);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.rAI.lAI.lAC);
+		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OCTET_STRING,
+					      &accept.uE_Identity.choice.pTMSIRAI.rAI.rAC);
+		break;
+
+	default:
+		/* should never happen after above switch() */
+		break;
+	}
+
+	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UERegisterAccept, &accept_out);
+
+	return hnbgw_hnbap_tx(hnb, msg);
+}
+
 static int hnbgw_rx_hnb_deregister(struct hnb_context *ctx, ANY_t *in)
 {
 	HNBDe_RegisterIEs_t ies;
@@ -313,11 +415,19 @@
 		ranap_bcd_decode(imsi, sizeof(imsi), ies.uE_Identity.choice.iMSIESN.iMSIDS41.buf,
 			      ies.uE_Identity.choice.iMSIESN.iMSIDS41.size);
 		break;
+	case UE_Identity_PR_tMSILAI:
+	case UE_Identity_PR_pTMSIRAI:
+		if (ctx->gw->config.hnbap_allow_tmsi)
+			rc = hnbgw_tx_ue_register_acc_tmsi(ctx, &ies.uE_Identity);
+		else
+			rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity);
+		/* all has been handled by TMSI, skip the IMSI code below */
+		hnbap_free_ueregisterrequesties(&ies);
+		return rc;
 	default:
-		LOGP(DHNBAP, LOGL_NOTICE, "UE-REGISTER-REQ without IMSI\n");
-		/* TODO: this is probably a TMSI registration. Store TMSIs
-		 * and look them up to accept UE Registration. */
-		rc = hnbgw_tx_ue_register_rej_tmsi(ctx, &ies.uE_Identity);
+		LOGP(DHNBAP, LOGL_NOTICE,
+		     "UE-REGISTER-REQ with unsupported UE Id type %d\n",
+		     ies.uE_Identity.present);
 		hnbap_free_ueregisterrequesties(&ies);
 		return rc;
 	}
diff --git a/src/hnbgw_vty.c b/src/hnbgw_vty.c
index 2e3d1e9..d6fad64 100644
--- a/src/hnbgw_vty.c
+++ b/src/hnbgw_vty.c
@@ -114,6 +114,16 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_hnbgw_iuh_hnbap_allow_tmsi, cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd,
+      "hnbap-allow-tmsi (0|1)",
+      "Allow HNBAP UE Register messages with TMSI or PTMSI identity\n"
+      "Only accept IMSI identity, reject TMSI or PTMSI\n"
+      "Accept IMSI, TMSI or PTMSI as UE identity\n")
+{
+	g_hnb_gw->config.hnbap_allow_tmsi = (*argv[0] == '1');
+	return CMD_SUCCESS;
+}
+
 static int config_write_hnbgw(struct vty *vty)
 {
 	vty_out(vty, "hnbgw%s", VTY_NEWLINE);
@@ -130,6 +140,9 @@
 	if (addr && (strcmp(addr, HNBGW_IUH_BIND_ADDR_DEFAULT) != 0))
 		vty_out(vty, "  bind %s%s", addr, VTY_NEWLINE);
 
+	if (g_hnb_gw->config.hnbap_allow_tmsi)
+		vty_out(vty, "  hnbap-allow-tmsi 1%s", VTY_NEWLINE);
+
 	return CMD_SUCCESS;
 }
 
@@ -145,7 +158,9 @@
 	install_element(HNBGW_NODE, &cfg_hnbgw_iuh_cmd);
 	install_node(&iuh_node, config_write_hnbgw_iuh);
 	vty_install_default(IUH_NODE);
+
 	install_element(IUH_NODE, &cfg_hnbgw_iuh_bind_cmd);
+	install_element(IUH_NODE, &cfg_hnbgw_iuh_hnbap_allow_tmsi_cmd);
 
 	install_element_ve(&show_hnb_cmd);
 	install_element_ve(&show_ue_cmd);

-- 
To view, visit https://gerrit.osmocom.org/910
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I87bc1aa3e85815ded7ac1dbdca48f1680b468589
Gerrit-PatchSet: 2
Gerrit-Project: osmo-iuh
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list