SGSN: Avoid duplicate MM contexts in case MS and SGSN disagree on P-TMSI

This commit is contained in:
Harald Welte
2010-12-24 23:07:18 +01:00
parent a9b473a3c2
commit c728eeaf9b
3 changed files with 31 additions and 0 deletions

View File

@@ -119,6 +119,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
/* Allocate a new SGSN MM context */ /* Allocate a new SGSN MM context */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
const struct gprs_ra_id *raid); const struct gprs_ra_id *raid);
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm);
enum pdp_ctx_state { enum pdp_ctx_state {

View File

@@ -594,6 +594,19 @@ static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg)
/* we already have a mm context with current TLLI, but no /* we already have a mm context with current TLLI, but no
* P-TMSI / IMSI yet. What we now need to do is to fill * P-TMSI / IMSI yet. What we now need to do is to fill
* this initial context with data from the HLR */ * this initial context with data from the HLR */
if (strlen(ctx->imsi) == 0) {
/* Check if we already have a MM context for this IMSI */
struct sgsn_mm_ctx *ictx;
ictx = sgsn_mm_ctx_by_imsi(mi_string);
if (ictx) {
DEBUGP(DMM, "Deleting old MM Context for same IMSI ",
"p_tmsi_old=0x%08x, p_tmsi_new=0x%08x\n",
ictx->p_tmsi, ctx->p_tmsi);
gprs_llgmm_assign(ictx->llme, ictx->tlli,
0xffffffff, GPRS_ALGO_GEA0, NULL);
sgsn_mm_ctx_free(ictx);
}
}
strncpy(ctx->imsi, mi_string, sizeof(ctx->imei)); strncpy(ctx->imsi, mi_string, sizeof(ctx->imei));
break; break;
case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEI:
@@ -704,6 +717,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
if (!ctx) if (!ctx)
ctx = sgsn_mm_ctx_by_ptmsi(tmsi); ctx = sgsn_mm_ctx_by_ptmsi(tmsi);
if (!ctx) { if (!ctx) {
/* Allocate a context as most of our code expects one.
* Context will not have an IMSI ultil ID RESP is received */
ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id); ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id);
ctx->p_tmsi = tmsi; ctx->p_tmsi = tmsi;
} }

View File

@@ -173,6 +173,21 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return ctx; return ctx;
} }
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
{
struct sgsn_pdp_ctx *pdp, *pdp2;
/* Unlink from global list of MM contexts */
llist_del(&mm->list);
/* Free all PDP contexts */
llist_for_each_entry_safe(pdp, pdp2, &mm->pdp_list, list)
sgsn_pdp_ctx_free(pdp);
rate_ctr_group_free(mm->ctrg);
talloc_free(mm);
}
/* look up PDP context by MM context and NSAPI */ /* look up PDP context by MM context and NSAPI */
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm, struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,