[PATCH] openbsc[master]: IuPS: osmo-sgsn: add core IuPS impl, call iu_init()

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 Aug 22 12:36:06 UTC 2016


Review at  https://gerrit.osmocom.org/729

IuPS: osmo-sgsn: add core IuPS impl, call iu_init()

Add:

* gsm0408_gprs_rcvmsg_iu()
* sgsn_mm_ctx_by_ue_ctx()
* sgsn_mm_ctx_alloc_iu()
* sgsn_ranap_iu_event()
* sgsn_ranap_rab_ass_resp()

Call iu_init() from sgsn_main.c.

Add asn_debug impl ("extern" from libasn1c).

osmo-sgsn build: add libiu and libasn1c, libosmo-sigtran, libosmo-ranap

Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5
---
M openbsc/include/openbsc/gprs_gmm.h
M openbsc/include/openbsc/gprs_sgsn.h
M openbsc/src/gprs/Makefile.am
M openbsc/src/gprs/gprs_gmm.c
M openbsc/src/gprs/gprs_sgsn.c
M openbsc/src/gprs/sgsn_libgtp.c
M openbsc/src/gprs/sgsn_main.c
7 files changed, 233 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/29/729/1

diff --git a/openbsc/include/openbsc/gprs_gmm.h b/openbsc/include/openbsc/gprs_gmm.h
index 8a3ffea..28467d7 100644
--- a/openbsc/include/openbsc/gprs_gmm.h
+++ b/openbsc/include/openbsc/gprs_gmm.h
@@ -14,6 +14,8 @@
 
 int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
 			   bool drop_cipherable);
+int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
+			   uint16_t *sai);
 int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
 int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
 				       struct gprs_llc_llme *llme);
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index b0dd75f..18cbab8 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -226,6 +226,7 @@
 					const struct gprs_ra_id *raid);
 struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
 struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
 
 /* look-up by matching TLLI and P-TMSI (think twice before using this) */
 struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
@@ -234,6 +235,8 @@
 /* Allocate a new SGSN MM context */
 struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
 					const struct gprs_ra_id *raid);
+struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx);
+
 void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
 
 struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am
index 6dc7e16..cc135f7 100644
--- a/openbsc/src/gprs/Makefile.am
+++ b/openbsc/src/gprs/Makefile.am
@@ -3,6 +3,10 @@
 	$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
 	$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
 	$(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS)
+if BUILD_IU
+AM_CFLAGS += $(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS)
+endif
+
 OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
 	    $(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
 
@@ -30,9 +34,15 @@
 			sgsn_cdr.c sgsn_ares.c \
 			oap.c oap_messages.c
 osmo_sgsn_LDADD = 	\
-			$(top_builddir)/src/libcommon/libcommon.a \
-			-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
+			$(top_builddir)/src/libcommon/libcommon.a
+if BUILD_IU
+osmo_sgsn_LDADD +=	$(top_builddir)/src/libiu/libiu.a
+endif
+osmo_sgsn_LDADD +=	-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
 			$(LIBCRYPTO_LIBS) -lrt
+if BUILD_IU
+osmo_sgsn_LDADD +=	$(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS)
+endif
 
 osmo_gtphub_SOURCES =	gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \
 			gtphub_vty.c sgsn_ares.c gprs_utils.c
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 1a030fb..e67ee10 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -33,6 +33,8 @@
 
 #include <openssl/rand.h>
 
+#include "bscconfig.h"
+
 #include <openbsc/db.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/gsm/tlv.h>
@@ -44,6 +46,10 @@
 #include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
 
 #include <osmocom/gprs/gprs_bssgp.h>
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/ranap_ies_defs.h>
+#endif
 
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
@@ -57,6 +63,10 @@
 #include <openbsc/gprs_utils.h>
 #include <openbsc/sgsn.h>
 #include <openbsc/signal.h>
+
+#ifdef BUILD_IU
+#include <openbsc/iu.h>
+#endif
 
 #include <pdp.h>
 
@@ -96,6 +106,45 @@
 };
 
 static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
+
+#ifdef BUILD_IU
+int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies);
+int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data)
+{
+	struct sgsn_mm_ctx *mm;
+	int rc = -1;
+
+	mm = sgsn_mm_ctx_by_ue_ctx(ctx);
+	if (!mm) {
+		LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type);
+		return rc;
+	}
+
+	switch (type) {
+	case IU_EVENT_RAB_ASSIGN:
+		rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data);
+		break;
+	case IU_EVENT_IU_RELEASE:
+		/* fall thru */
+	case IU_EVENT_LINK_INVALIDATED:
+		/* Clean up ue_conn_ctx here */
+		LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
+		rc = 0;
+		break;
+	case IU_EVENT_SECURITY_MODE_COMPLETE:
+		/* Continue authentication here */
+		mm->iu.ue_ctx->integrity_active = 1;
+		rc = gsm48_gmm_authorize(mm);
+		break;
+	default:
+		LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type);
+		rc = -1;
+		break;
+	}
+	return rc;
+}
+#endif
+
 
 /* Our implementation, should be kept in SGSN */
 
@@ -2191,6 +2240,45 @@
 	return rc;
 }
 
+/* Main entry point for incoming 04.08 GPRS messages from Iu */
+int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
+			   uint16_t *sai)
+{
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+	struct sgsn_mm_ctx *mmctx;
+	int rc = -EINVAL;
+
+	mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst);
+	if (mmctx) {
+		rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
+		if (ra_id)
+			memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra));
+	}
+
+	/* MMCTX can be NULL */
+
+	switch (pdisc) {
+	case GSM48_PDISC_MM_GPRS:
+		rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false);
+#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?"
+		break;
+	case GSM48_PDISC_SM_GPRS:
+		rc = gsm0408_rcv_gsm(mmctx, msg, NULL);
+		break;
+	default:
+		LOGMMCTXP(LOGL_NOTICE, mmctx,
+			"Unknown GSM 04.08 discriminator 0x%02x: %s\n",
+			pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
+		/* FIXME: return status message */
+		break;
+	}
+
+	/* MMCTX can be invalid */
+
+	return rc;
+}
+
 /* Main entry point for incoming 04.08 GPRS messages from Gb */
 int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
 			   bool drop_cipherable)
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index 147facf..4036025 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -39,6 +39,7 @@
 #include <openbsc/gprs_utils.h>
 #include <openbsc/signal.h>
 #include "openbsc/gprs_llc.h"
+#include <openbsc/iu.h>
 
 #include <pdp.h>
 
@@ -124,6 +125,20 @@
 
 void sgsn_rate_ctr_init() {
 	sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0);
+}
+
+/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
+{
+	struct sgsn_mm_ctx *ctx;
+
+	llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
+		if (ctx->ran_type == MM_CTX_T_UTRAN_Iu
+		    && uectx == ctx->iu.ue_ctx)
+			return ctx;
+	}
+
+	return NULL;
 }
 
 /* look-up a SGSN MM context based on TLLI + RAI */
@@ -214,6 +229,32 @@
 	return ctx;
 }
 
+/* Allocate a new SGSN MM context */
+struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
+{
+	struct sgsn_mm_ctx *ctx;
+
+	ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
+	if (!ctx)
+		return NULL;
+
+	ctx->ran_type = MM_CTX_T_UTRAN_Iu;
+	ctx->iu.ue_ctx = uectx;
+	ctx->mm_state = GMM_DEREGISTERED;
+	ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
+	ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0);
+
+	/* Need to get RAID from IU conn */
+	ctx->ra = ctx->iu.ue_ctx->ra_id;
+
+	INIT_LLIST_HEAD(&ctx->pdp_list);
+
+	llist_add(&ctx->list, &sgsn_mm_ctxts);
+
+	return ctx;
+}
+
+
 /* this is a hard _free_ function, it doesn't clean up the PDP contexts
  * in libgtp! */
 static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c
index be7637a..4a14cf6 100644
--- a/openbsc/src/gprs/sgsn_libgtp.c
+++ b/openbsc/src/gprs/sgsn_libgtp.c
@@ -34,6 +34,8 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#include "bscconfig.h"
+
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/select.h>
 #include <osmocom/core/rate_ctr.h>
@@ -47,6 +49,11 @@
 #include <openbsc/gprs_sgsn.h>
 #include <openbsc/gprs_gmm.h>
 #include <openbsc/gsm_subscriber.h>
+
+#ifdef BUILD_IU
+#include <openbsc/iu.h>
+#include <osmocom/ranap/ranap_ies_defs.h>
+#endif
 
 #include <gtp.h>
 #include <pdp.h>
@@ -218,7 +225,10 @@
 	memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
 		sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
 
-	/* SGSN address for user plane */
+	/* SGSN address for user plane
+	 * Default to the control plane addr for now. If we are connected to a
+	 * hnbgw via IuPS we'll need to send a PDP context update with the
+	 * correct IP address after the RAB Assignment is complete */
 	pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr);
 	memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
 		sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
@@ -383,6 +393,72 @@
 	return EOF;
 }
 
+#ifdef BUILD_IU
+/* Callback for RAB assignment response */
+int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies)
+{
+	uint8_t rab_id;
+	bool require_pdp_update = false;
+	struct sgsn_pdp_ctx *pdp = NULL;
+	RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem;
+
+	rab_id = item->rAB_ID.buf[0];
+
+	pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id);
+	if (!pdp) {
+		LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id);
+		return -1;
+	}
+
+	if (item->transportLayerAddress) {
+		LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf,
+								     item->transportLayerAddress->size));
+		switch (item->transportLayerAddress->size) {
+		case 7:
+			/* It must be IPv4 inside a X213 NSAP */
+			memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4);
+			break;
+		case 4:
+			/* It must be a raw IPv4 address */
+			memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4);
+			break;
+		case 16:
+			/* TODO: It must be a raw IPv6 address */
+		case 19:
+			/* TODO: It must be IPv6 inside a X213 NSAP */
+		default:
+			LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown "
+				"transport layer address size %u\n",
+				item->transportLayerAddress->size);
+			return -1;
+		}
+		require_pdp_update = true;
+	}
+
+	/* The TEI on the RNC side might have changed, too */
+	if (item->iuTransportAssociation &&
+	    item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI &&
+	    item->iuTransportAssociation->choice.gTP_TEI.buf &&
+	    item->iuTransportAssociation->choice.gTP_TEI.size >= 4) {
+		uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf);
+		LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n",
+			pdp->lib->teid_own, tei);
+		pdp->lib->teid_own = tei;
+		require_pdp_update = true;
+	}
+
+	if (require_pdp_update)
+		gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
+
+	if (pdp->state != PDP_STATE_CR_CONF) {
+		send_act_pdp_cont_acc(pdp);
+		pdp->state = PDP_STATE_CR_CONF;
+	}
+	return 0;
+
+}
+#endif
+
 /* Confirmation of a PDP Context Delete */
 static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
 {
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 52fc985..18adde5 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -56,6 +56,8 @@
 #include <openbsc/sgsn.h>
 #include <openbsc/gprs_llc.h>
 #include <openbsc/gprs_gmm.h>
+#include <openbsc/iu.h>
+
 #include <osmocom/ctrl/control_if.h>
 #include <osmocom/ctrl/ports.h>
 
@@ -300,6 +302,9 @@
 	.num_cat = ARRAY_SIZE(gprs_categories),
 };
 
+int asn_debug;
+
+int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data);
 
 int main(int argc, char **argv)
 {
@@ -417,6 +422,11 @@
 		}
 	}
 
+	asn_debug = 0;
+#ifdef BUILD_IU
+	iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event);
+#endif
+
 	if (daemonize) {
 		rc = osmo_daemonize();
 		if (rc < 0) {

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I469ae6ca9ef254d04ee0d2d79bdd65aebcd027b5
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: neels_test_account <neels at hofmeyr.de>



More information about the gerrit-log mailing list