diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-01-05 20:13:13 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-01-11 12:51:34 +0100 |
commit | 05190c36bb73896d72258f1a196ea31ae3a4493a (patch) | |
tree | 43e81491888fc62c1fa1c91be9d00f8c0979363a /src | |
parent | 3d3c8c55f05eee921051b9059408acdad916007e (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.am | 1 | ||||
-rw-r--r-- | src/sgsn/gprs_gmm.c | 1 | ||||
-rw-r--r-- | src/sgsn/gprs_mm_state_iu_fsm.c | 1 | ||||
-rw-r--r-- | src/sgsn/gprs_ranap.c | 1 | ||||
-rw-r--r-- | src/sgsn/gprs_sgsn.c | 120 | ||||
-rw-r--r-- | src/sgsn/gprs_sm.c | 1 | ||||
-rw-r--r-- | src/sgsn/gtp_ggsn.c | 1 | ||||
-rw-r--r-- | src/sgsn/pdpctx.c | 160 | ||||
-rw-r--r-- | src/sgsn/sgsn_cdr.c | 1 | ||||
-rw-r--r-- | src/sgsn/sgsn_ctrl.c | 1 | ||||
-rw-r--r-- | src/sgsn/sgsn_libgtp.c | 1 | ||||
-rw-r--r-- | src/sgsn/sgsn_vty.c | 1 |
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> |