From 0f3a27a5838097f1c919f25a6fe96dea408ee7fa Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 28 Oct 2014 09:47:03 +0100 Subject: sgsn: Unassign the LLME after GMM Status without mmctx Currently the LLME is not deleted when a GMM Status message is received for which a mmctx cannot be found. This can fill the LLME list with unneeded entries. This patch adds code to unassign the LLME in that case. Ticket: OW#1324 Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gprs_gmm.c | 6 +++++- openbsc/tests/sgsn/sgsn_test.c | 39 +++++++++++++++++++++++++++++++++++++++ openbsc/tests/sgsn/sgsn_test.ok | 1 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index c8ad98cbe..a5f9b782a 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -1111,8 +1111,12 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ) { LOGP(DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n"); /* 4.7.10 */ - if (gh->msg_type == GSM48_MT_GMM_STATUS) + if (gh->msg_type == GSM48_MT_GMM_STATUS) { + /* TLLI unassignment */ + gprs_llgmm_assign(llme, llme->tlli, 0xffffffff, + GPRS_ALGO_GEA0, NULL); return 0; + } gprs_llgmm_reset(llme); diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 05d1ee0ef..6762ef883 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -256,6 +256,44 @@ static void test_gmm_detach_no_mmctx(void) OSMO_ASSERT(count(gprs_llme_list()) == 0); } +/* + * Test that a GMM Status will remove the associated LLME if there is no MMCTX. + */ +static void test_gmm_status_no_mmctx(void) +{ + struct gprs_llc_lle *lle; + uint32_t local_tlli; + struct msgb *msg; + int sgsn_tx_counter_old; + + printf("Testing GMM Status (no MMCTX)\n"); + + /* DTAP - GMM Status, protocol error */ + static const unsigned char gmm_status[] = { + 0x08, 0x20, 0x6f + }; + + /* Create an LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); + lle = gprs_lle_get_or_create(local_tlli, 3); + + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the detach */ + sgsn_tx_counter_old = sgsn_tx_counter; + msg = create_msg(gmm_status, ARRAY_SIZE(gmm_status)); + msgb_tlli(msg) = local_tlli; + gsm0408_gprs_rcvmsg(msg, lle->llme); + msgb_free(msg); + + /* verify that no message has been sent by the SGSN */ + OSMO_ASSERT(sgsn_tx_counter_old == sgsn_tx_counter); + + /* verify that the LLME is gone */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); +} + static struct log_info_cat gprs_categories[] = { [DMM] = { .name = "DMM", @@ -321,6 +359,7 @@ int main(int argc, char **argv) test_gmm_detach(); test_gmm_detach_power_off(); test_gmm_detach_no_mmctx(); + test_gmm_status_no_mmctx(); printf("Done\n"); return 0; } diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok index bca2b4bc4..ea5b0fadd 100644 --- a/openbsc/tests/sgsn/sgsn_test.ok +++ b/openbsc/tests/sgsn/sgsn_test.ok @@ -2,4 +2,5 @@ Testing LLME allocations Testing GMM detach Testing GMM detach (power off) Testing GMM detach (no MMCTX) +Testing GMM Status (no MMCTX) Done -- cgit v1.2.3