From 1330478aa508ddaf2b0045d7b3acd97665712aac Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 4 Jan 2016 18:43:37 +0100 Subject: sgsn/test: Add test case test_gmm_routing_areas This test add different cases of routing area changes. Sponsored-by: On-Waves ehf --- openbsc/tests/sgsn/sgsn_test.c | 347 ++++++++++++++++++++++++++++++++++++++++ openbsc/tests/sgsn/sgsn_test.ok | 8 + 2 files changed, 355 insertions(+) diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 2098972bd..d27b755db 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1805,6 +1805,352 @@ static void test_gmm_ptmsi_allocation(void) cleanup_test(); } +/* + * Test changing of routing areas + */ +static void test_gmm_routing_areas(void) +{ + struct gprs_ra_id raid1 = {332, 112, 16464, 96}; + struct gprs_ra_id raid2 = {332, 112, 16464, 97}; + struct sgsn_mm_ctx *ctx = NULL; + struct sgsn_mm_ctx *ictx; + uint32_t ptmsi1; + uint32_t received_ptmsi; + uint32_t ms_tlli = 0; + struct gprs_llc_lle *lle; + const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; + + /* DTAP - Attach Request (IMSI 12131415161718) */ + static const unsigned char attach_req[] = { + 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, + 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, + 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, + 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, + 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, + 0x00, + }; + + /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */ + static const unsigned char attach_req2[] = { + 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, + 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19, + 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, + 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, + 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, + 0x00, + }; + + /* DTAP - Identity Response IMEI */ + static const unsigned char ident_resp_imei[] = { + 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, + 0x56 + }; + + /* DTAP - Attach Complete */ + static const unsigned char attach_compl[] = { + 0x08, 0x03 + }; + + /* DTAP - Routing Area Update Request (coming from RA 1) */ + static const unsigned char ra_upd_req1[] = { + 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, + 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, + 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, + 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, + 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, + 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, + 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 + }; + + /* DTAP - Routing Area Update Request (coming from RA 2) */ + static const unsigned char ra_upd_req2[] = { + 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, + 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, + 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, + 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, + 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, + 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, + 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 + }; + + /* DTAP - Routing Area Update Request (coming from RA other) */ + /* raid_other = {443, 223, 16464, 98}; */ + static const unsigned char ra_upd_req_other[] = { + 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50, + 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, + 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, + 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, + 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, + 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, + 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 + }; + + /* DTAP - Routing Area Update Complete */ + static const unsigned char ra_upd_complete[] = { + 0x08, 0x0a + }; + + /* DTAP - Detach Request (MO) */ + /* normal detach, power_off = 1 */ + static const unsigned char detach_req[] = { + 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, + 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb + }; + + sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN; + + printf("Testing routing area changes\n"); + + /* reset the PRNG used by sgsn_alloc_ptmsi */ + srand(1); + + ptmsi1 = GSM_RESERVED_TMSI; + + printf(" - Attach Request (RA 1)\n"); + + ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM); + + /* Create a LLE/LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + lle = gprs_lle_get_or_create(ms_tlli, 3); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the attach request */ + send_0408_message(lle->llme, ms_tlli, &raid1, + attach_req, ARRAY_SIZE(attach_req)); + + ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1); + OSMO_ASSERT(ctx != NULL); + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + + /* we expect an identity request (IMEI) */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ); + OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); + + /* inject the identity response (IMEI) */ + send_0408_message(ctx->llme, ms_tlli, &raid1, + ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); + + /* check that the MM context has not been removed due to a failed + * authorization */ + OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1)); + + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + + /* we expect an attach accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); + OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the attach complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + send_0408_message(ctx->llme, ms_tlli, &raid1, + attach_compl, ARRAY_SIZE(attach_compl)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + + printf(" - RA Update Request (RA 1 -> RA 1)\n"); + + /* inject the RA update request */ + send_0408_message(ctx->llme, ms_tlli, &raid1, + ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); + + /* we expect an RA update accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); + // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); + + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + OSMO_ASSERT(ctx->p_tmsi != ptmsi1); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the RA update complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + send_0408_message(ctx->llme, ms_tlli, &raid1, + ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + OSMO_ASSERT(ctx->tlli == ms_tlli); + + + printf(" - RA Update Request (RA 1 -> RA 2)\n"); + + /* inject the RA update request */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN); + + /* It is coming from RA 1 => ra_upd_req1 */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); + + /* we expect an RA update reject (and a LLC XID RESET) */ + OSMO_ASSERT(sgsn_tx_counter == 2); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ); + /* this has killed the LLE/LLME */ + + printf(" - Attach Request (RA 2)\n"); + + /* Create a LLE/LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 1); + lle = gprs_lle_get_or_create(ms_tlli, 3); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the attach request */ + send_0408_message(lle->llme, ms_tlli, &raid2, + attach_req2, ARRAY_SIZE(attach_req2)); + + ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ctx != NULL); + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + + /* we expect an attach accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the attach complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ictx != NULL); + OSMO_ASSERT(ictx == ctx); + + send_0408_message(ctx->llme, ms_tlli, &raid2, + attach_compl, ARRAY_SIZE(attach_compl)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + + printf(" - RA Update Request (RA other -> RA 2)\n"); + + /* inject the RA update request */ + ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN); + + /* It is coming from RA 1 => ra_upd_req1 */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other)); + + /* we expect an RA update reject (and a LLC XID RESET) */ + OSMO_ASSERT(sgsn_tx_counter == 2); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ); + /* this has killed the LLE/LLME */ + + printf(" - Attach Request (RA 2)\n"); + + /* Create a LLE/LLME */ + OSMO_ASSERT(count(gprs_llme_list()) == 1); + lle = gprs_lle_get_or_create(ms_tlli, 3); + OSMO_ASSERT(count(gprs_llme_list()) == 1); + + /* inject the attach request */ + send_0408_message(lle->llme, ms_tlli, &raid2, + attach_req2, ARRAY_SIZE(attach_req2)); + + ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ctx != NULL); + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + + /* we expect an attach accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the attach complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(ictx != NULL); + OSMO_ASSERT(ictx == ctx); + + send_0408_message(ctx->llme, ms_tlli, &raid2, + attach_compl, ARRAY_SIZE(attach_compl)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + + printf(" - RA Update Request (RA 2 -> RA 2)\n"); + + /* inject the RA update request */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_req2, ARRAY_SIZE(ra_upd_req2)); + + /* we expect an RA update accept */ + OSMO_ASSERT(sgsn_tx_counter == 1); + OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); + + OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT); + OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); + OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); + OSMO_ASSERT(ctx->p_tmsi != ptmsi1); + + received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); + OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); + ptmsi1 = received_ptmsi; + + /* inject the RA update complete */ + ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); + send_0408_message(ctx->llme, ms_tlli, &raid2, + ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); + + /* we don't expect a response */ + OSMO_ASSERT(sgsn_tx_counter == 0); + + OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL); + OSMO_ASSERT(ctx->p_tmsi_old == 0); + OSMO_ASSERT(ctx->p_tmsi == ptmsi1); + OSMO_ASSERT(ctx->tlli == ms_tlli); + + + /* inject the detach */ + send_0408_message(ctx->llme, ms_tlli, &raid2, + detach_req, ARRAY_SIZE(detach_req)); + + /* verify that things are gone */ + OSMO_ASSERT(count(gprs_llme_list()) == 0); + ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); + OSMO_ASSERT(!ictx); + + sgsn->cfg.auth_policy = saved_auth_policy; + + cleanup_test(); +} + static void test_apn_matching(void) { struct apn_ctx *actx, *actxs[9]; @@ -2129,6 +2475,7 @@ int main(int argc, char **argv) test_gmm_reject(); test_gmm_cancel(); test_gmm_ptmsi_allocation(); + test_gmm_routing_areas(); test_apn_matching(); test_ggsn_selection(); printf("Done\n"); diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok index 7913a3914..5b8fc40d2 100644 --- a/openbsc/tests/sgsn/sgsn_test.ok +++ b/openbsc/tests/sgsn/sgsn_test.ok @@ -25,6 +25,14 @@ Testing P-TMSI allocation - sgsn_alloc_ptmsi - Repeated Attach Request - Repeated RA Update Request +Testing routing area changes + - Attach Request (RA 1) + - RA Update Request (RA 1 -> RA 1) + - RA Update Request (RA 1 -> RA 2) + - Attach Request (RA 2) + - RA Update Request (RA other -> RA 2) + - Attach Request (RA 2) + - RA Update Request (RA 2 -> RA 2) Testing APN matching Testing GGSN selection Done -- cgit v1.2.3