aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2023-01-05 20:13:13 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2023-01-11 12:51:34 +0100
commit05190c36bb73896d72258f1a196ea31ae3a4493a (patch)
tree43e81491888fc62c1fa1c91be9d00f8c0979363a /src
parent3d3c8c55f05eee921051b9059408acdad916007e (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/sgsn/Makefile.am1
-rw-r--r--src/sgsn/gprs_gmm.c1
-rw-r--r--src/sgsn/gprs_mm_state_iu_fsm.c1
-rw-r--r--src/sgsn/gprs_ranap.c1
-rw-r--r--src/sgsn/gprs_sgsn.c120
-rw-r--r--src/sgsn/gprs_sm.c1
-rw-r--r--src/sgsn/gtp_ggsn.c1
-rw-r--r--src/sgsn/pdpctx.c160
-rw-r--r--src/sgsn/sgsn_cdr.c1
-rw-r--r--src/sgsn/sgsn_ctrl.c1
-rw-r--r--src/sgsn/sgsn_libgtp.c1
-rw-r--r--src/sgsn/sgsn_vty.c1
12 files changed, 171 insertions, 119 deletions
diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am
index ba752ad95..75f96082b 100644
--- a/src/sgsn/Makefile.am
+++ b/src/sgsn/Makefile.am
@@ -62,6 +62,7 @@ osmo_sgsn_SOURCES = \
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 b12102ed8..2630db975 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 d0e9ffcdc..597507c7d 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 af1a61c02..245de4bdb 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 c911b6a9f..9d2ed7d98 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 @@ static const struct rate_ctr_group_desc mmctx_ctrg_desc = {
.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 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
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 3177a7040..9a66e0a69 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 b43fb25cd..7cc65f884 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 000000000..52b1c0ff0
--- /dev/null
+++ b/src/sgsn/pdpctx.c
@@ -0,0 +1,160 @@
+/* PDP context functionality */
+
+/* (C) 2009 by Harald Welte <laforge@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 c22a6ac81..db326448c 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 278857f64..8961f3725 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 dc3f916ef..19a0f569a 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 2313a9acd..8e94041fc 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>