mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 21:13:44 +00:00
sgsn: Add gsm0408_gprs_access_cancelled
This function is called to delete an established MM context silently without invoking a detach procedure. It is called when a subscriber is cancelled by the HLR. This generally happens, when an MS has moved to another routing area and has to use another SGSN. Sponsored-by: On-Waves ehf
This commit is contained in:
committed by
Holger Hans Peter Freyther
parent
be2c8d9358
commit
98647ca0ef
@@ -15,6 +15,7 @@ int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
|
|||||||
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg);
|
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg);
|
||||||
void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);
|
void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);
|
||||||
void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx);
|
void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx);
|
||||||
|
void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx);
|
||||||
|
|
||||||
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
|
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
|
||||||
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
||||||
|
|||||||
@@ -756,6 +756,33 @@ void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *ctx)
|
||||||
|
{
|
||||||
|
switch (ctx->mm_state) {
|
||||||
|
#if 0
|
||||||
|
case GMM_COMMON_PROC_INIT:
|
||||||
|
LOGP(DMM, LOGL_NOTICE,
|
||||||
|
"Cancelled, rejecting ATTACH REQUEST, IMSI=%s\n",
|
||||||
|
ctx->imsi);
|
||||||
|
gsm48_tx_gmm_att_rej(ctx, GMM_CAUSE_IMPL_DETACHED);
|
||||||
|
break;
|
||||||
|
case GMM_REGISTERED_NORMAL:
|
||||||
|
case GMM_REGISTERED_SUSPENDED:
|
||||||
|
LOGP(DMM, LOGL_NOTICE,
|
||||||
|
"Cancelled, detaching, IMSI=%s\n",
|
||||||
|
ctx->imsi);
|
||||||
|
gsm48_tx_gmm_detach_req(
|
||||||
|
ctx, GPRS_DET_T_MT_REATT_NOTREQ, GMM_CAUSE_IMPL_DETACHED);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
LOGP(DMM, LOGL_INFO,
|
||||||
|
"Cancelled, deleting context, IMSI=%s\n",
|
||||||
|
ctx->imsi);
|
||||||
|
}
|
||||||
|
mm_ctx_cleanup_free(ctx, "access cancelled");
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse Chapter 9.4.13 Identity Response */
|
/* Parse Chapter 9.4.13 Identity Response */
|
||||||
static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg)
|
static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -184,7 +184,10 @@ void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
|
|||||||
gsm0408_gprs_access_granted(mmctx);
|
gsm0408_gprs_access_granted(mmctx);
|
||||||
break;
|
break;
|
||||||
case SGSN_AUTH_REJECTED:
|
case SGSN_AUTH_REJECTED:
|
||||||
gsm0408_gprs_access_denied(mmctx);
|
if (subscr && (subscr->flags & GPRS_SUBSCRIBER_CANCELLED) != 0)
|
||||||
|
gsm0408_gprs_access_cancelled(mmctx);
|
||||||
|
else
|
||||||
|
gsm0408_gprs_access_denied(mmctx);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -733,6 +733,122 @@ static void test_gmm_reject(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test cancellation of attached MM contexts
|
||||||
|
*/
|
||||||
|
static void test_gmm_cancel(void)
|
||||||
|
{
|
||||||
|
struct gprs_ra_id raid = { 0, };
|
||||||
|
struct sgsn_mm_ctx *ctx = NULL;
|
||||||
|
struct sgsn_mm_ctx *ictx;
|
||||||
|
uint32_t ptmsi1;
|
||||||
|
uint32_t foreign_tlli;
|
||||||
|
uint32_t local_tlli = 0;
|
||||||
|
struct gprs_llc_lle *lle;
|
||||||
|
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
|
||||||
|
|
||||||
|
/* DTAP - Attach Request */
|
||||||
|
/* The P-TMSI is not known by the SGSN */
|
||||||
|
static const unsigned char attach_req[] = {
|
||||||
|
0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
|
||||||
|
0xfb, 0xc5, 0x46, 0x79, 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 - Identity Response IMEI */
|
||||||
|
static const unsigned char ident_resp_imei[] = {
|
||||||
|
0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
|
||||||
|
0x56
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DTAP - Identity Response IMSI */
|
||||||
|
static const unsigned char ident_resp_imsi[] = {
|
||||||
|
0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
|
||||||
|
0x54
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DTAP - Attach Complete */
|
||||||
|
static const unsigned char attach_compl[] = {
|
||||||
|
0x08, 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("Testing cancellation\n");
|
||||||
|
|
||||||
|
sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
|
||||||
|
|
||||||
|
/* reset the PRNG used by sgsn_alloc_ptmsi */
|
||||||
|
srand(1);
|
||||||
|
|
||||||
|
ptmsi1 = sgsn_alloc_ptmsi();
|
||||||
|
OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
|
||||||
|
|
||||||
|
/* reset the PRNG, so that the same P-TMSI sequence will be generated
|
||||||
|
* again */
|
||||||
|
srand(1);
|
||||||
|
|
||||||
|
foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
|
||||||
|
|
||||||
|
/* Create a LLE/LLME */
|
||||||
|
OSMO_ASSERT(count(gprs_llme_list()) == 0);
|
||||||
|
lle = gprs_lle_get_or_create(foreign_tlli, 3);
|
||||||
|
OSMO_ASSERT(count(gprs_llme_list()) == 1);
|
||||||
|
|
||||||
|
/* inject the attach request */
|
||||||
|
send_0408_message(lle->llme, foreign_tlli,
|
||||||
|
attach_req, ARRAY_SIZE(attach_req));
|
||||||
|
|
||||||
|
ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
|
||||||
|
OSMO_ASSERT(ctx != NULL);
|
||||||
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
||||||
|
|
||||||
|
/* we expect an identity request (IMEI) */
|
||||||
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
||||||
|
|
||||||
|
/* inject the identity response (IMEI) */
|
||||||
|
send_0408_message(ctx->llme, foreign_tlli,
|
||||||
|
ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
|
||||||
|
|
||||||
|
/* we expect an identity request (IMSI) */
|
||||||
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
||||||
|
|
||||||
|
/* inject the identity response (IMSI) */
|
||||||
|
send_0408_message(ctx->llme, foreign_tlli,
|
||||||
|
ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
|
||||||
|
|
||||||
|
/* check that the MM context has not been removed due to a failed
|
||||||
|
* authorization */
|
||||||
|
OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
|
||||||
|
|
||||||
|
OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
|
||||||
|
|
||||||
|
/* we expect an attach accept/reject */
|
||||||
|
OSMO_ASSERT(sgsn_tx_counter == 1);
|
||||||
|
|
||||||
|
/* this has been randomly assigned by the SGSN */
|
||||||
|
local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
|
||||||
|
|
||||||
|
/* inject the attach complete */
|
||||||
|
send_0408_message(ctx->llme, local_tlli,
|
||||||
|
attach_compl, ARRAY_SIZE(attach_compl));
|
||||||
|
|
||||||
|
OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
|
||||||
|
|
||||||
|
/* we don't expect a response */
|
||||||
|
OSMO_ASSERT(sgsn_tx_counter == 0);
|
||||||
|
|
||||||
|
/* cancel */
|
||||||
|
gsm0408_gprs_access_cancelled(ctx);
|
||||||
|
|
||||||
|
/* verify that things are gone */
|
||||||
|
OSMO_ASSERT(count(gprs_llme_list()) == 0);
|
||||||
|
ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
|
||||||
|
OSMO_ASSERT(!ictx);
|
||||||
|
|
||||||
|
sgsn->cfg.auth_policy = saved_auth_policy;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test the dynamic allocation of P-TMSIs
|
* Test the dynamic allocation of P-TMSIs
|
||||||
*/
|
*/
|
||||||
@@ -997,6 +1113,7 @@ int main(int argc, char **argv)
|
|||||||
test_gmm_attach_acl();
|
test_gmm_attach_acl();
|
||||||
test_gmm_attach_subscr();
|
test_gmm_attach_subscr();
|
||||||
test_gmm_reject();
|
test_gmm_reject();
|
||||||
|
test_gmm_cancel();
|
||||||
test_gmm_ptmsi_allocation();
|
test_gmm_ptmsi_allocation();
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Testing GMM reject
|
|||||||
- Routing Area Update Request (valid)
|
- Routing Area Update Request (valid)
|
||||||
- Routing Area Update Request (invalid type)
|
- Routing Area Update Request (invalid type)
|
||||||
- Routing Area Update Request (invalid CAP length)
|
- Routing Area Update Request (invalid CAP length)
|
||||||
|
Testing cancellation
|
||||||
Testing P-TMSI allocation
|
Testing P-TMSI allocation
|
||||||
- sgsn_alloc_ptmsi
|
- sgsn_alloc_ptmsi
|
||||||
- Repeated Attach Request
|
- Repeated Attach Request
|
||||||
|
|||||||
Reference in New Issue
Block a user