diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2018-07-13 16:37:22 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2018-07-16 15:17:06 +0200 |
commit | a733a50931c4836fbda30f40d853bfab98441e98 (patch) | |
tree | d66e1207d8b180116753428a164c1edf490d6fe5 /src/gprs/gprs_sgsn.c | |
parent | 89895b027d57d2352afb56bdfef72c3e106168d6 (diff) |
sgsn: Don't attempt to delete GTP pdp ctx if GGSN was restarted
Scenario and behaviour before this commit:
- Received Echo Reply from GGSN has incremented RestartCounter
- func sgsn_ggsn_ctx_drop_all_pdp() is called to dettach all pdp ctx
from GGSN and request the MS to deact all related ctx.
- DEACT ACCEPT is received from MS, and then it tries to send DEL PDP CTX
to GGSN, expecting to receive a Confirmation and only then freeing the
pdp ctx.
The problem is that since the initial cause of triggering was a GGSN
restart, the GGSN doesn't know anything about that pdp ctx anymore, so
it's not useful sending it. We can instead dettach the GGSN and libgtp
ref at drop_all_pdp() time and then when we receive DEACT ACCEPT from MS
we can free the pdp ctx directly.
Change-Id: I1c74098e181552c218e152bf4ac5035cea770428
Diffstat (limited to 'src/gprs/gprs_sgsn.c')
-rw-r--r-- | src/gprs/gprs_sgsn.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c index 35479fb02..ef0cc23da 100644 --- a/src/gprs/gprs_sgsn.c +++ b/src/gprs/gprs_sgsn.c @@ -444,7 +444,8 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp) /* Detach from MM context */ pdp_ctx_detach_mm_ctx(pdp); - sgsn_delete_pdp_ctx(pdp); + if (pdp->ggsn) + sgsn_delete_pdp_ctx(pdp); } /* @@ -479,8 +480,6 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp) lib->priv = NULL; } - if (pdp->destroy_ggsn) - sgsn_ggsn_ctx_free(pdp->ggsn); talloc_free(pdp); } @@ -702,9 +701,10 @@ failed: static void drop_one_pdp(struct sgsn_pdp_ctx *pdp) { - if (pdp->mm->gmm_state == GMM_REGISTERED_NORMAL) + if (pdp->mm->gmm_state == GMM_REGISTERED_NORMAL) { gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL, true); - else { + sgsn_ggsn_ctx_remove_pdp(pdp->ggsn, pdp); + } else { /* FIXME: GPRS paging in case MS is SUSPENDED */ LOGPDPCTXP(LOGL_NOTICE, pdp, "Hard-dropping PDP ctx due to GGSN " "recovery\n"); @@ -739,6 +739,13 @@ void sgsn_ggsn_ctx_remove_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pd llist_del(&pdp->ggsn_list); if (llist_empty(&ggc->pdp_list) && osmo_timer_pending(&ggc->echo_timer)) osmo_timer_del(&ggc->echo_timer); + if (pdp->destroy_ggsn) + sgsn_ggsn_ctx_free(pdp->ggsn); + pdp->ggsn = NULL; + /* Drop references to libgtp since the conn is down */ + if (pdp->lib) + pdp_freepdp(pdp->lib); + pdp->lib = NULL; } void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) |