pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-sgsn/+/30891 )

Change subject: Move sgsn_pdp_ctx to its own file pdpctx.{c,h}
......................................................................

Move sgsn_pdp_ctx to its own file pdpctx.{c,h}

This further shrinks the mess in gprs_sgsn.h, and allows to easily see
layer violations (like pdpctx.c requiring llc.h)

Change-Id: Iad4da06efee7d8514ff48423bdaebc0f26413cc1
---
M include/osmocom/sgsn/Makefile.am
M include/osmocom/sgsn/gprs_sgsn.h
A include/osmocom/sgsn/pdpctx.h
M src/sgsn/Makefile.am
M src/sgsn/gprs_gmm.c
M src/sgsn/gprs_mm_state_iu_fsm.c
M src/sgsn/gprs_ranap.c
M src/sgsn/gprs_sgsn.c
M src/sgsn/gprs_sm.c
M src/sgsn/gtp_ggsn.c
A src/sgsn/pdpctx.c
M src/sgsn/sgsn_cdr.c
M src/sgsn/sgsn_ctrl.c
M src/sgsn/sgsn_libgtp.c
M src/sgsn/sgsn_vty.c
M tests/sgsn/Makefile.am
16 files changed, 270 insertions(+), 193 deletions(-)

Approvals:
  Jenkins Builder: Verified
  dexter: Looks good to me, but someone else must approve
  daniel: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve



diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am
index 4d43c6d..a3bc218 100644
--- a/include/osmocom/sgsn/Makefile.am
+++ b/include/osmocom/sgsn/Makefile.am
@@ -26,6 +26,7 @@
        gtphub.h \
        gtp_ggsn.h \
        gtp_mme.h \
+       pdpctx.h \
        sgsn.h \
        sgsn_rim.h \
        signal.h \
diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index 8aaabfd..3fdf45d 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -23,6 +23,7 @@
 struct ctrl_handle;
 struct gprs_subscr;
 struct sgsn_ggsn_ctx;
+struct sgsn_pdp_ctx;

 enum gsm48_gsm_cause;

@@ -40,13 +41,6 @@
        GMM_CTR_RA_UPDATE,
 };

-enum gprs_pdp_ctx {
-       PDP_CTR_PKTS_UDATA_IN,
-       PDP_CTR_PKTS_UDATA_OUT,
-       PDP_CTR_BYTES_UDATA_IN,
-       PDP_CTR_BYTES_UDATA_OUT,
-};
-
 enum gprs_t3350_mode {
        GMM_T3350_MODE_NONE,
        GMM_T3350_MODE_ATT,
@@ -291,64 +285,6 @@
                                                enum gsm48_gsm_cause *gsm_cause,
                                                char *apn_str);

-enum pdp_ctx_state {
-       PDP_STATE_NONE,
-       PDP_STATE_CR_REQ,
-       PDP_STATE_CR_CONF,
-
-       /* 04.08 / Figure 6.2 / 6.1.2.2 */
-       PDP_STATE_INACT_PEND,
-       PDP_STATE_INACTIVE = PDP_STATE_NONE,
-};
-
-enum pdp_type {
-       PDP_TYPE_NONE,
-       PDP_TYPE_ETSI_PPP,
-       PDP_TYPE_IANA_IPv4,
-       PDP_TYPE_IANA_IPv6,
-};
-
-struct sgsn_pdp_ctx {
-       struct llist_head       list;   /* list_head for mmctx->pdp_list */
-       struct llist_head       g_list; /* list_head for global list */
-       struct sgsn_mm_ctx      *mm;    /* back pointer to MM CTX */
-       int                     destroy_ggsn; /* destroy it on destruction */
-       struct sgsn_ggsn_ctx    *ggsn;  /* which GGSN serves this PDP */
-       struct llist_head       ggsn_list;      /* list_head for ggsn->pdp_list 
*/
-       struct rate_ctr_group   *ctrg;
-
-       //unsigned int          id;
-       struct pdp_t            *lib;   /* pointer to libgtp PDP ctx */
-       enum pdp_ctx_state      state;
-       enum pdp_type           type;
-       uint32_t                address;
-       char                    *apn_subscribed;
-       //char                  *apn_used;
-       uint16_t                nsapi;  /* SNDCP */
-       uint16_t                sapi;   /* LLC */
-       uint8_t                 ti;     /* transaction identifier */
-       int                     vplmn_allowed;
-       uint32_t                qos_profile_subscr;
-       //uint32_t              qos_profile_req;
-       //uint32_t              qos_profile_neg;
-       uint8_t                 radio_prio;
-       //uint32_t              charging_id;
-
-       struct osmo_timer_list  timer;
-       unsigned int            T;              /* Txxxx number */
-       unsigned int            num_T_exp;      /* number of consecutive T 
expirations */
-
-       struct osmo_timer_list  cdr_timer;      /* CDR record wird timer */
-       struct timespec         cdr_start;      /* The start of the CDR */
-       uint64_t                cdr_bytes_in;
-       uint64_t                cdr_bytes_out;
-       uint32_t                cdr_charging_id;
-};
-
-#define LOGPDPCTXP(level, pdp, fmt, args...) \
-       LOGP(DGPRS, level, "PDP(%s/%u) " \
-            fmt, (pdp)->mm ? (pdp)->mm->imsi : "---", (pdp)->ti, ## args)
-
 /* look up PDP context by MM context and NSAPI */
 struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,
                                           uint8_t nsapi);
@@ -356,19 +292,10 @@
 struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
                                         uint8_t tid);

-struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
-                                       struct sgsn_ggsn_ctx *ggsn,
-                                       uint8_t nsapi);
-void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp);
-void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
-
 extern struct llist_head sgsn_mm_ctxts;
-extern struct llist_head sgsn_pdp_ctxts;

 uint32_t sgsn_alloc_ptmsi(void);

-char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len, bool return_ipv6);
-
 /*
  * ctrl interface related work
  */
diff --git a/include/osmocom/sgsn/pdpctx.h b/include/osmocom/sgsn/pdpctx.h
new file mode 100644
index 0000000..1e982af
--- /dev/null
+++ b/include/osmocom/sgsn/pdpctx.h
@@ -0,0 +1,96 @@
+#pragma once
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <inttypes.h>
+
+#include <osmocom/core/timer.h>
+#include <osmocom/core/rate_ctr.h>
+
+#include <osmocom/gsm/gsm48.h>
+
+#include <osmocom/crypt/gprs_cipher.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
+#include <osmocom/crypt/auth.h>
+
+#include <osmocom/sgsn/apn.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
+
+struct sgsn_mm_ctx;
+struct sgsn_ggsn_ctx;
+
+enum gprs_pdp_ctx {
+       PDP_CTR_PKTS_UDATA_IN,
+       PDP_CTR_PKTS_UDATA_OUT,
+       PDP_CTR_BYTES_UDATA_IN,
+       PDP_CTR_BYTES_UDATA_OUT,
+};
+
+enum pdp_ctx_state {
+       PDP_STATE_NONE,
+       PDP_STATE_CR_REQ,
+       PDP_STATE_CR_CONF,
+
+       /* 04.08 / Figure 6.2 / 6.1.2.2 */
+       PDP_STATE_INACT_PEND,
+       PDP_STATE_INACTIVE = PDP_STATE_NONE,
+};
+
+enum pdp_type {
+       PDP_TYPE_NONE,
+       PDP_TYPE_ETSI_PPP,
+       PDP_TYPE_IANA_IPv4,
+       PDP_TYPE_IANA_IPv6,
+};
+
+struct sgsn_pdp_ctx {
+       struct llist_head       list;   /* list_head for mmctx->pdp_list */
+       struct llist_head       g_list; /* list_head for global list */
+       struct sgsn_mm_ctx      *mm;    /* back pointer to MM CTX */
+       int                     destroy_ggsn; /* destroy it on destruction */
+       struct sgsn_ggsn_ctx    *ggsn;  /* which GGSN serves this PDP */
+       struct llist_head       ggsn_list;      /* list_head for ggsn->pdp_list 
*/
+       struct rate_ctr_group   *ctrg;
+
+       //unsigned int          id;
+       struct pdp_t            *lib;   /* pointer to libgtp PDP ctx */
+       enum pdp_ctx_state      state;
+       enum pdp_type           type;
+       uint32_t                address;
+       char                    *apn_subscribed;
+       //char                  *apn_used;
+       uint16_t                nsapi;  /* SNDCP */
+       uint16_t                sapi;   /* LLC */
+       uint8_t                 ti;     /* transaction identifier */
+       int                     vplmn_allowed;
+       uint32_t                qos_profile_subscr;
+       //uint32_t              qos_profile_req;
+       //uint32_t              qos_profile_neg;
+       uint8_t                 radio_prio;
+       //uint32_t              charging_id;
+
+       struct osmo_timer_list  timer;
+       unsigned int            T;              /* Txxxx number */
+       unsigned int            num_T_exp;      /* number of consecutive T 
expirations */
+
+       struct osmo_timer_list  cdr_timer;      /* CDR record wird timer */
+       struct timespec         cdr_start;      /* The start of the CDR */
+       uint64_t                cdr_bytes_in;
+       uint64_t                cdr_bytes_out;
+       uint32_t                cdr_charging_id;
+};
+
+#define LOGPDPCTXP(level, pdp, fmt, args...) \
+       LOGP(DGPRS, level, "PDP(%s/%u) " \
+            fmt, (pdp)->mm ? (pdp)->mm->imsi : "---", (pdp)->ti, ## args)
+
+struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
+                                       struct sgsn_ggsn_ctx *ggsn,
+                                       uint8_t nsapi);
+void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp);
+void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
+
+extern struct llist_head sgsn_pdp_ctxts;
+
+char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len, bool return_ipv6);
+
diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am
index ba752ad..75f9608 100644
--- a/src/sgsn/Makefile.am
+++ b/src/sgsn/Makefile.am
@@ -62,6 +62,7 @@
        sgsn_libgtp.c \
        gprs_llc.c \
        gprs_llc_vty.c \
+       pdpctx.c \
        sgsn_ctrl.c \
        sgsn_auth.c \
        gprs_subscriber.c \
diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c
index b12102e..2630db9 100644
--- a/src/sgsn/gprs_gmm.c
+++ b/src/sgsn/gprs_gmm.c
@@ -62,6 +62,7 @@
 #include <osmocom/sgsn/gprs_ranap.h>
 #include <osmocom/sgsn/gprs_sm.h>
 #include <osmocom/sgsn/gtp.h>
+#include <osmocom/sgsn/pdpctx.h>

 #include <pdp.h>

diff --git a/src/sgsn/gprs_mm_state_iu_fsm.c b/src/sgsn/gprs_mm_state_iu_fsm.c
index d0e9ffc..597507c 100644
--- a/src/sgsn/gprs_mm_state_iu_fsm.c
+++ b/src/sgsn/gprs_mm_state_iu_fsm.c
@@ -30,6 +30,7 @@
 #include <osmocom/sgsn/sgsn.h>
 #include <osmocom/sgsn/gprs_ranap.h>
 #include <osmocom/sgsn/gtp.h>
+#include <osmocom/sgsn/pdpctx.h>

 #define X(s) (1 << (s))

diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
index af1a61c..245de4b 100644
--- a/src/sgsn/gprs_ranap.c
+++ b/src/sgsn/gprs_ranap.c
@@ -39,6 +39,7 @@
 #include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
 #include <osmocom/sgsn/gtp_ggsn.h>
 #include <osmocom/sgsn/gtp.h>
+#include <osmocom/sgsn/pdpctx.h>

 /* Send RAB activation requests for all PDP contexts */
 void activate_pdp_rabs(struct sgsn_mm_ctx *ctx)
diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c
index c911b6a..9d2ed7d 100644
--- a/src/sgsn/gprs_sgsn.c
+++ b/src/sgsn/gprs_sgsn.c
@@ -52,6 +52,7 @@
 #include <osmocom/sgsn/gprs_sndcp.h>
 #include <osmocom/sgsn/gtp_ggsn.h>
 #include <osmocom/sgsn/gtp.h>
+#include <osmocom/sgsn/pdpctx.h>

 #include <pdp.h>

@@ -64,7 +65,6 @@
 extern struct osmo_tdef sgsn_T_defs[];

 LLIST_HEAD(sgsn_mm_ctxts);
-LLIST_HEAD(sgsn_pdp_ctxts);

 const struct value_string sgsn_ran_type_names[] = {
        { MM_CTX_T_GERAN_Gb, "GPRS/EDGE via Gb" },
@@ -97,21 +97,6 @@
        .class_id = OSMO_STATS_CLASS_SUBSCRIBER,
 };

-static const struct rate_ctr_desc pdpctx_ctr_description[] = {
-       { "udata:packets:in",   "User Data  Messages ( In)" },
-       { "udata:packets:out",  "User Data  Messages (Out)" },
-       { "udata:bytes:in",     "User Data  Bytes    ( In)" },
-       { "udata:bytes:out",    "User Data  Bytes    (Out)" },
-};
-
-static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
-       .group_name_prefix = "sgsn:pdpctx",
-       .group_description = "SGSN PDP Context Statistics",
-       .num_ctr = ARRAY_SIZE(pdpctx_ctr_description),
-       .ctr_desc = pdpctx_ctr_description,
-       .class_id = OSMO_STATS_CLASS_SUBSCRIBER,
-};
-
 static const struct rate_ctr_desc sgsn_ctr_description[] = {
        { "llc:dl_bytes", "Count sent LLC bytes before giving it to the bssgp 
layer" },
        { "llc:ul_bytes", "Count successful received LLC bytes (encrypt & fcs 
correct)" },
@@ -429,109 +414,6 @@
        return NULL;
 }

-/* you don't want to use this directly, call sgsn_create_pdp_ctx() */
-struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
-                                       struct sgsn_ggsn_ctx *ggsn,
-                                       uint8_t nsapi)
-{
-       struct sgsn_pdp_ctx *pdp;
-
-       pdp = sgsn_pdp_ctx_by_nsapi(mm, nsapi);
-       if (pdp)
-               return NULL;
-
-       pdp = talloc_zero(tall_sgsn_ctx, struct sgsn_pdp_ctx);
-       if (!pdp)
-               return NULL;
-
-       pdp->mm = mm;
-       pdp->ggsn = ggsn;
-       pdp->nsapi = nsapi;
-       pdp->ctrg = rate_ctr_group_alloc(pdp, &pdpctx_ctrg_desc, nsapi);
-       if (!pdp->ctrg) {
-               LOGPDPCTXP(LOGL_ERROR, pdp, "Error allocation counter group\n");
-               talloc_free(pdp);
-               return NULL;
-       }
-       llist_add(&pdp->list, &mm->pdp_list);
-       sgsn_ggsn_ctx_add_pdp(pdp->ggsn, pdp);
-       llist_add(&pdp->g_list, &sgsn_pdp_ctxts);
-
-       return pdp;
-}
-
-/*
- * This function will not trigger any GSM DEACT PDP ACK messages, so you
- * probably want to call sgsn_delete_pdp_ctx() instead if the connection
- * isn't detached already.
- */
-void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
-{
-       struct sgsn_signal_data sig_data;
-
-       OSMO_ASSERT(pdp->mm != NULL);
-
-       /* There might still be pending callbacks in libgtp. So the parts of
-        * this object relevant to GTP need to remain intact in this case. */
-
-       LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n");
-
-       if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
-               /* Force the deactivation of the SNDCP layer */
-               if (pdp->mm->gb.llme)
-                       
sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
-       }
-
-       memset(&sig_data, 0, sizeof(sig_data));
-       sig_data.pdp = pdp;
-       osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data);
-
-       /* Detach from MM context */
-       pdp_ctx_detach_mm_ctx(pdp);
-       if (pdp->ggsn)
-               sgsn_delete_pdp_ctx(pdp);
-}
-
-/*
- * Don't call this function directly unless you know what you are doing.
- * In normal conditions use sgsn_delete_pdp_ctx and in unspecified or
- * implementation dependent abnormal ones sgsn_pdp_ctx_terminate.
- */
-void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
-{
-       struct sgsn_signal_data sig_data;
-
-       memset(&sig_data, 0, sizeof(sig_data));
-       sig_data.pdp = pdp;
-       osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_FREE, &sig_data);
-
-       if (osmo_timer_pending(&pdp->timer)) {
-               LOGPDPCTXP(LOGL_ERROR, pdp, "Freeing PDP ctx with timer %u 
pending\n", pdp->T);
-               osmo_timer_del(&pdp->timer);
-       }
-
-       rate_ctr_group_free(pdp->ctrg);
-       if (pdp->mm)
-               llist_del(&pdp->list);
-       if (pdp->ggsn)
-               sgsn_ggsn_ctx_remove_pdp(pdp->ggsn, pdp);
-       llist_del(&pdp->g_list);
-
-       /* _if_ we still have a library handle, at least set it to NULL
-        * to avoid any dereferences of the now-deleted PDP context from
-        * sgsn_libgtp:cb_data_ind() */
-       if (pdp->lib) {
-               struct pdp_t *lib = pdp->lib;
-               LOGPDPCTXP(LOGL_NOTICE, pdp, "freeing PDP context that still "
-                    "has a libgtp handle attached to it, this shouldn't "
-                    "happen!\n");
-               osmo_generate_backtrace();
-               lib->priv = NULL;
-       }
-
-       talloc_free(pdp);
-}
-
 uint32_t sgsn_alloc_ptmsi(void)
 {
        struct sgsn_mm_ctx *mm;
diff --git a/src/sgsn/gprs_sm.c b/src/sgsn/gprs_sm.c
index 3177a70..9a66e0a 100644
--- a/src/sgsn/gprs_sm.c
+++ b/src/sgsn/gprs_sm.c
@@ -43,6 +43,7 @@
 #include <osmocom/sgsn/gprs_sndcp.h>
 #include <osmocom/sgsn/gprs_ranap.h>
 #include <osmocom/sgsn/gtp.h>
+#include <osmocom/sgsn/pdpctx.h>

 /* 3GPP TS 04.08 sec 6.1.3.4.3(.a) "Abnormal cases" */
 #define T339X_MAX_RETRANS 4
diff --git a/src/sgsn/gtp_ggsn.c b/src/sgsn/gtp_ggsn.c
index b43fb25..7cc65f8 100644
--- a/src/sgsn/gtp_ggsn.c
+++ b/src/sgsn/gtp_ggsn.c
@@ -34,6 +34,7 @@
 #include <osmocom/sgsn/debug.h>
 #include <osmocom/sgsn/gprs_gmm_fsm.h>
 #include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/pdpctx.h>

 void sgsn_ggsn_ctx_check_echo_timer(struct sgsn_ggsn_ctx *ggc)
 {
diff --git a/src/sgsn/pdpctx.c b/src/sgsn/pdpctx.c
new file mode 100644
index 0000000..52b1c0f
--- /dev/null
+++ b/src/sgsn/pdpctx.c
@@ -0,0 +1,160 @@
+/* PDP context functionality */
+
+/* (C) 2009 by Harald Welte <lafo...@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/stats.h>
+
+#include <osmocom/sgsn/pdpctx.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/gtp_ggsn.h>
+#include <osmocom/sgsn/gprs_llc_xid.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/gtp.h>
+
+LLIST_HEAD(sgsn_pdp_ctxts);
+
+static const struct rate_ctr_desc pdpctx_ctr_description[] = {
+       { "udata:packets:in",   "User Data  Messages ( In)" },
+       { "udata:packets:out",  "User Data  Messages (Out)" },
+       { "udata:bytes:in",     "User Data  Bytes    ( In)" },
+       { "udata:bytes:out",    "User Data  Bytes    (Out)" },
+};
+
+static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
+       .group_name_prefix = "sgsn:pdpctx",
+       .group_description = "SGSN PDP Context Statistics",
+       .num_ctr = ARRAY_SIZE(pdpctx_ctr_description),
+       .ctr_desc = pdpctx_ctr_description,
+       .class_id = OSMO_STATS_CLASS_SUBSCRIBER,
+};
+
+/* you don't want to use this directly, call sgsn_create_pdp_ctx() */
+struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
+                                       struct sgsn_ggsn_ctx *ggsn,
+                                       uint8_t nsapi)
+{
+       struct sgsn_pdp_ctx *pdp;
+
+       pdp = sgsn_pdp_ctx_by_nsapi(mm, nsapi);
+       if (pdp)
+               return NULL;
+
+       pdp = talloc_zero(tall_sgsn_ctx, struct sgsn_pdp_ctx);
+       if (!pdp)
+               return NULL;
+
+       pdp->mm = mm;
+       pdp->ggsn = ggsn;
+       pdp->nsapi = nsapi;
+       pdp->ctrg = rate_ctr_group_alloc(pdp, &pdpctx_ctrg_desc, nsapi);
+       if (!pdp->ctrg) {
+               LOGPDPCTXP(LOGL_ERROR, pdp, "Error allocation counter group\n");
+               talloc_free(pdp);
+               return NULL;
+       }
+       llist_add(&pdp->list, &mm->pdp_list);
+       sgsn_ggsn_ctx_add_pdp(pdp->ggsn, pdp);
+       llist_add(&pdp->g_list, &sgsn_pdp_ctxts);
+
+       return pdp;
+}
+
+/*
+ * This function will not trigger any GSM DEACT PDP ACK messages, so you
+ * probably want to call sgsn_delete_pdp_ctx() instead if the connection
+ * isn't detached already.
+ */
+void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
+{
+       struct sgsn_signal_data sig_data;
+
+       OSMO_ASSERT(pdp->mm != NULL);
+
+       /* There might still be pending callbacks in libgtp. So the parts of
+        * this object relevant to GTP need to remain intact in this case. */
+
+       LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n");
+
+       if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
+               /* Force the deactivation of the SNDCP layer */
+               if (pdp->mm->gb.llme)
+                       
sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
+       }
+
+       memset(&sig_data, 0, sizeof(sig_data));
+       sig_data.pdp = pdp;
+       osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data);
+
+       /* Detach from MM context */
+       pdp_ctx_detach_mm_ctx(pdp);
+       if (pdp->ggsn)
+               sgsn_delete_pdp_ctx(pdp);
+}
+
+/*
+ * Don't call this function directly unless you know what you are doing.
+ * In normal conditions use sgsn_delete_pdp_ctx and in unspecified or
+ * implementation dependent abnormal ones sgsn_pdp_ctx_terminate.
+ */
+void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
+{
+       struct sgsn_signal_data sig_data;
+
+       memset(&sig_data, 0, sizeof(sig_data));
+       sig_data.pdp = pdp;
+       osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_FREE, &sig_data);
+
+       if (osmo_timer_pending(&pdp->timer)) {
+               LOGPDPCTXP(LOGL_ERROR, pdp, "Freeing PDP ctx with timer %u 
pending\n", pdp->T);
+               osmo_timer_del(&pdp->timer);
+       }
+
+       rate_ctr_group_free(pdp->ctrg);
+       if (pdp->mm)
+               llist_del(&pdp->list);
+       if (pdp->ggsn)
+               sgsn_ggsn_ctx_remove_pdp(pdp->ggsn, pdp);
+       llist_del(&pdp->g_list);
+
+       /* _if_ we still have a library handle, at least set it to NULL
+        * to avoid any dereferences of the now-deleted PDP context from
+        * sgsn_libgtp:cb_data_ind() */
+       if (pdp->lib) {
+               struct pdp_t *lib = pdp->lib;
+               LOGPDPCTXP(LOGL_NOTICE, pdp, "freeing PDP context that still "
+                    "has a libgtp handle attached to it, this shouldn't "
+                    "happen!\n");
+               osmo_generate_backtrace();
+               lib->priv = NULL;
+       }
+
+       talloc_free(pdp);
+}
diff --git a/src/sgsn/sgsn_cdr.c b/src/sgsn/sgsn_cdr.c
index c22a6ac..db32644 100644
--- a/src/sgsn/sgsn_cdr.c
+++ b/src/sgsn/sgsn_cdr.c
@@ -28,6 +28,7 @@

 #include <osmocom/sgsn/vty.h>
 #include <osmocom/sgsn/gtp_ggsn.h>
+#include <osmocom/sgsn/pdpctx.h>

 #include <gtp.h>
 #include <pdp.h>
diff --git a/src/sgsn/sgsn_ctrl.c b/src/sgsn/sgsn_ctrl.c
index 278857f..8961f37 100644
--- a/src/sgsn/sgsn_ctrl.c
+++ b/src/sgsn/sgsn_ctrl.c
@@ -22,6 +22,7 @@
 #include <osmocom/ctrl/control_if.h>
 #include <osmocom/ctrl/control_cmd.h>
 #include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/pdpctx.h>
 #include <osmocom/sgsn/sgsn.h>
 #include <osmocom/sgsn/debug.h>

diff --git a/src/sgsn/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c
index dc3f916..19a0f56 100644
--- a/src/sgsn/sgsn_libgtp.c
+++ b/src/sgsn/sgsn_libgtp.c
@@ -59,6 +59,7 @@
 #include <osmocom/sgsn/gtp_mme.h>
 #include <osmocom/sgsn/sgsn_rim.h>
 #include <osmocom/sgsn/gprs_bssgp.h>
+#include <osmocom/sgsn/pdpctx.h>

 #include <gtp.h>
 #include <pdp.h>
diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c
index 2313a9a..8e94041 100644
--- a/src/sgsn/sgsn_vty.c
+++ b/src/sgsn/sgsn_vty.c
@@ -42,6 +42,7 @@
 #include <osmocom/sgsn/gtp_ggsn.h>
 #include <osmocom/sgsn/gtp_mme.h>
 #include <osmocom/sgsn/vty.h>
+#include <osmocom/sgsn/pdpctx.h>
 #include <osmocom/gsupclient/gsup_client.h>

 #include <osmocom/vty/tdef_vty.h>
diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am
index 853d8f1..8df1395 100644
--- a/tests/sgsn/Makefile.am
+++ b/tests/sgsn/Makefile.am
@@ -60,6 +60,7 @@
        $(top_builddir)/src/sgsn/gprs_sgsn.o \
        $(top_builddir)/src/sgsn/gtp_ggsn.o \
        $(top_builddir)/src/sgsn/gtp_mme.o \
+       $(top_builddir)/src/sgsn/pdpctx.o \
        $(top_builddir)/src/sgsn/sgsn_cdr.o \
        $(top_builddir)/src/sgsn/sgsn_ctrl.o \
        $(top_builddir)/src/sgsn/sgsn_vty.o \

--
To view, visit https://gerrit.osmocom.org/c/osmo-sgsn/+/30891
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-Change-Id: Iad4da06efee7d8514ff48423bdaebc0f26413cc1
Gerrit-Change-Number: 30891
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillm...@sysmocom.de>
Gerrit-Reviewer: dexter <pma...@sysmocom.de>
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: pespin <pes...@sysmocom.de>
Gerrit-CC: lynxis lazus <lyn...@fe80.eu>
Gerrit-MessageType: merged

Reply via email to