sgsn: Add sgsn_mm_ctx_cleanup_free for safe shutdown

Currently the MM context cleanup code is distributed over several
functions. sgsn_mm_ctx_free not only frees data structure but also
eventually stops the timer and does the subscriber clean-up.
mm_ctx_cleanup_free (gprs_gmm.c) cleans up the PDP contexts and
unassign the TLLI.

This commit moves the cleanup code from both functions into a new
unifying function sgsn_mm_ctx_cleanup_free that cares about the
clean-up of all related sub-systems.

Sponsored-by: On-Waves ehf
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 03773a6..abda327 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -181,34 +181,14 @@
 	msgb_nsei(msg) = mm->nsei;
 }
 
-static void delete_pdp_contexts(struct sgsn_mm_ctx *ctx, const char *log_text)
-{
-	struct sgsn_pdp_ctx *pdp, *pdp2;
-
-	/* delete all existing PDP contexts for this MS */
-	llist_for_each_entry_safe(pdp, pdp2, &ctx->pdp_list, list) {
-		LOGMMCTXP(LOGL_NOTICE, ctx,
-			  "Dropping PDP context for NSAPI=%u due to %s\n",
-			  pdp->nsapi, log_text);
-		sgsn_pdp_ctx_terminate(pdp);
-	}
-}
-
 static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text)
 {
-	struct gprs_llc_llme *llme = ctx->llme;
-	uint32_t tlli = ctx->tlli;
+	LOGMMCTXP(LOGL_INFO, ctx, "Cleaning MM context due to %s\n", log_text);
 
 	/* Mark MM state as deregistered */
 	ctx->mm_state = GMM_DEREGISTERED;
 
-	delete_pdp_contexts(ctx, log_text);
-
-	sgsn_mm_ctx_free(ctx);
-	ctx = NULL;
-
-	/* TLLI unassignment, must be called after sgsn_mm_ctx_free */
-	gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
+	sgsn_mm_ctx_cleanup_free(ctx);
 }
 
 /* Chapter 9.4.18 */