TLLI problems and proposed solution

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/OpenBSC@lists.osmocom.org/.

Holger Hans Peter Freyther holger at freyther.de
Tue Jul 30 07:20:38 UTC 2013


On Tue, Jul 30, 2013 at 08:03:49AM +0800, Harald Welte wrote:
> 
> Sure, go ahead. that's what I meant by 'be brave' :)

The engineer in me.. used git gui blame on the file and I found the commit
that added the foreign tlli lookup.


commit f0901f0067e363c0ced6254db1b45a9771640412
Author: Harald Welte <laforge at gnumonks.org>
Date:   Sun Dec 26 10:39:26 2010 +0100

    [SGSN] Fix processing of RA Update Request regarding TLLI
    
    In case we get a RA UPD REQ on a new cell (both served by the same
    SGSN), the LLC stack should not allocate a ne LLE/LLME, as the latter
    would reset the V(u)sent / V(u)recv to zero and make the MS discard
    our responses.
    
    Instead, whenever the LLC stack sees a foreign TLLI, it should always
    convert it to the local TLLI before doing any lookup for a LLE/LLME.


I had to move some code around but what I essentialy do is.

1.) I do the lookup based on the tlli...
2.) if the tlli is foreign.. I convert it and make another lookup
3.) I create the LLME on the fly or return NULL

Or shall we do this... "oh we know this subscriber already" at a
higher level in GMM? E.g. notice that it is a routing area update...
and then free the new llme and do a tlli assignment for the foreign
tlli?


diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index c3bd9d2..b637acb 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -36,6 +36,54 @@
 #include <openbsc/crc24.h>
 #include <openbsc/sgsn.h>
 
+enum gprs_llc_cmd {
+	GPRS_LLC_NULL,
+	GPRS_LLC_RR,
+	GPRS_LLC_ACK,
+	GPRS_LLC_RNR,
+	GPRS_LLC_SACK,
+	GPRS_LLC_DM,
+	GPRS_LLC_DISC,
+	GPRS_LLC_UA,
+	GPRS_LLC_SABM,
+	GPRS_LLC_FRMR,
+	GPRS_LLC_XID,
+	GPRS_LLC_UI,
+};
+
+static const struct value_string llc_cmd_strs[] = {
+	{ GPRS_LLC_NULL,	"NULL" },
+	{ GPRS_LLC_RR,		"RR" },
+	{ GPRS_LLC_ACK,		"ACK" },
+	{ GPRS_LLC_RNR,		"RNR" },
+	{ GPRS_LLC_SACK,	"SACK" },
+	{ GPRS_LLC_DM,		"DM" },
+	{ GPRS_LLC_DISC,	"DISC" },
+	{ GPRS_LLC_UA,		"UA" },
+	{ GPRS_LLC_SABM,	"SABM" },
+	{ GPRS_LLC_FRMR,	"FRMR" },
+	{ GPRS_LLC_XID,		"XID" },
+	{ GPRS_LLC_UI,		"UI" },
+	{ 0, NULL }
+};
+
+struct gprs_llc_hdr_parsed {
+	uint8_t sapi;
+	uint8_t is_cmd:1,
+		 ack_req:1,
+		 is_encrypted:1;
+	uint32_t seq_rx;
+	uint32_t seq_tx;
+	uint32_t fcs;
+	uint32_t fcs_calc;
+	uint8_t *data;
+	uint16_t data_len;
+	uint16_t crc_length;
+	enum gprs_llc_cmd cmd;
+};
+
+static struct gprs_llc_llme *llme_alloc(uint32_t tlli);
+
 /* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU
  * to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */
 static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
@@ -162,6 +210,43 @@ static struct gprs_llc_lle *lle_by_tlli_sapi(const uint32_t tlli, uint8_t sapi)
 	return NULL;
 }
 
+/* lookup LLC Entity for RX based on DLCI (TLLI+SAPI tuple) */
+static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli,
+					uint8_t sapi, enum gprs_llc_cmd cmd)
+{
+	struct gprs_llc_lle *lle;
+
+	/* We already know about this TLLI */
+	lle = lle_by_tlli_sapi(tlli, sapi);
+	if (lle)
+		return lle;
+
+	/* Maybe it is a routing area update but we already know this sapi? */
+	if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
+		lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
+		if (lle)
+			return lle;
+	}
+
+	/* 7.2.1.1 LLC belonging to unassigned TLLI+SAPI shall be discarded,
+	 * except UID and XID frames with SAPI=1 */
+	if (sapi == GPRS_SAPI_GMM &&
+		    (cmd == GPRS_LLC_XID || cmd == GPRS_LLC_UI)) {
+		struct gprs_llc_llme *llme;
+		/* FIXME: don't use the TLLI but the 0xFFFF unassigned? */
+		llme = llme_alloc(tlli);
+		LOGP(DLLC, LOGL_DEBUG, "LLC RX: unknown TLLI 0x%08x, "
+			"creating LLME on the fly\n", tlli);
+		lle = &llme->lle[sapi];
+		return lle;
+	}
+	
+	LOGP(DLLC, LOGL_NOTICE,
+		"unknown TLLI(0x%08x)/SAPI(%d): Silently dropping\n",
+		tlli, sapi);
+	return NULL;
+}
+
 static void lle_init(struct gprs_llc_llme *llme, uint8_t sapi)
 {
 	struct gprs_llc_lle *lle = &llme->lle[sapi];
@@ -201,52 +286,6 @@ static void llme_free(struct gprs_llc_llme *llme)
 	talloc_free(llme);
 }
 
-enum gprs_llc_cmd {
-	GPRS_LLC_NULL,
-	GPRS_LLC_RR,
-	GPRS_LLC_ACK,
-	GPRS_LLC_RNR,
-	GPRS_LLC_SACK,
-	GPRS_LLC_DM,
-	GPRS_LLC_DISC,
-	GPRS_LLC_UA,
-	GPRS_LLC_SABM,
-	GPRS_LLC_FRMR,
-	GPRS_LLC_XID,
-	GPRS_LLC_UI,
-};
-
-static const struct value_string llc_cmd_strs[] = {
-	{ GPRS_LLC_NULL,	"NULL" },
-	{ GPRS_LLC_RR,		"RR" },
-	{ GPRS_LLC_ACK,		"ACK" },
-	{ GPRS_LLC_RNR,		"RNR" },
-	{ GPRS_LLC_SACK,	"SACK" },
-	{ GPRS_LLC_DM,		"DM" },
-	{ GPRS_LLC_DISC,	"DISC" },
-	{ GPRS_LLC_UA,		"UA" },
-	{ GPRS_LLC_SABM,	"SABM" },
-	{ GPRS_LLC_FRMR,	"FRMR" },
-	{ GPRS_LLC_XID,		"XID" },
-	{ GPRS_LLC_UI,		"UI" },
-	{ 0, NULL }
-};
-
-struct gprs_llc_hdr_parsed {
-	uint8_t sapi;
-	uint8_t is_cmd:1,
-		 ack_req:1,
-		 is_encrypted:1;
-	uint32_t seq_rx;
-	uint32_t seq_tx;
-	uint32_t fcs;
-	uint32_t fcs_calc;
-	uint8_t *data;
-	uint16_t data_len;
-	uint16_t crc_length;
-	enum gprs_llc_cmd cmd;
-};
-
 #define LLC_ALLOC_SIZE 16384
 #define UI_HDR_LEN	3
 #define N202		4
@@ -770,25 +809,9 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
 	}
 
 	/* find the LLC Entity for this TLLI+SAPI tuple */
-	lle = lle_by_tlli_sapi(msgb_tlli(msg), llhp.sapi);
-
-	/* 7.2.1.1 LLC belonging to unassigned TLLI+SAPI shall be discarded,
-	 * except UID and XID frames with SAPI=1 */
-	if (!lle) {
-		if (llhp.sapi == GPRS_SAPI_GMM &&
-		    (llhp.cmd == GPRS_LLC_XID || llhp.cmd == GPRS_LLC_UI)) {
-			struct gprs_llc_llme *llme;
-			/* FIXME: don't use the TLLI but the 0xFFFF unassigned? */
-			llme = llme_alloc(msgb_tlli(msg));
-			LOGP(DLLC, LOGL_DEBUG, "LLC RX: unknown TLLI 0x%08x, "
-				"creating LLME on the fly\n", msgb_tlli(msg));
-			lle = &llme->lle[llhp.sapi];
-		} else {
-			LOGP(DLLC, LOGL_NOTICE,
-				"unknown TLLI/SAPI: Silently dropping\n");
-			return 0;
-		}
-	}
+	lle = lle_for_rx_by_tlli_sapi(msgb_tlli(msg), llhp.sapi, llhp.cmd);
+	if (!lle)
+		return 0;
 
 	/* decrypt information field + FCS, if needed! */
 	if (llhp.is_encrypted) {




More information about the OpenBSC mailing list