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
diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c
index 35479fb..ef0cc23 100644
--- a/src/gprs/gprs_sgsn.c
+++ b/src/gprs/gprs_sgsn.c
@@ -444,7 +444,8 @@
 
 	/* 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 @@
 		lib->priv = NULL;
 	}
 
-	if (pdp->destroy_ggsn)
-		sgsn_ggsn_ctx_free(pdp->ggsn);
 	talloc_free(pdp);
 }
 
@@ -702,9 +701,10 @@
 
 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 @@
 	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)