From 05190c36bb73896d72258f1a196ea31ae3a4493a Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 5 Jan 2023 20:13:13 +0100 Subject: [PATCH] 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 --- include/osmocom/sgsn/Makefile.am | 1 + include/osmocom/sgsn/gprs_sgsn.h | 75 +-------------- include/osmocom/sgsn/pdpctx.h | 96 +++++++++++++++++++ src/sgsn/Makefile.am | 1 + src/sgsn/gprs_gmm.c | 1 + src/sgsn/gprs_mm_state_iu_fsm.c | 1 + src/sgsn/gprs_ranap.c | 1 + src/sgsn/gprs_sgsn.c | 120 +---------------------- src/sgsn/gprs_sm.c | 1 + src/sgsn/gtp_ggsn.c | 1 + src/sgsn/pdpctx.c | 160 +++++++++++++++++++++++++++++++ src/sgsn/sgsn_cdr.c | 1 + src/sgsn/sgsn_ctrl.c | 1 + src/sgsn/sgsn_libgtp.c | 1 + src/sgsn/sgsn_vty.c | 1 + tests/sgsn/Makefile.am | 1 + 16 files changed, 270 insertions(+), 193 deletions(-) create mode 100644 include/osmocom/sgsn/pdpctx.h create mode 100644 src/sgsn/pdpctx.c diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am index 4d43c6dde..a3bc21830 100644 --- a/include/osmocom/sgsn/Makefile.am +++ b/include/osmocom/sgsn/Makefile.am @@ -26,6 +26,7 @@ noinst_HEADERS = \ 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 8aaabfd9b..3fdf45d58 100644 --- a/include/osmocom/sgsn/gprs_sgsn.h +++ b/include/osmocom/sgsn/gprs_sgsn.h @@ -23,6 +23,7 @@ struct gprs_llc_lle; struct ctrl_handle; struct gprs_subscr; struct sgsn_ggsn_ctx; +struct sgsn_pdp_ctx; enum gsm48_gsm_cause; @@ -40,13 +41,6 @@ enum gprs_mm_ctr { 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 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, 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_nsapi(const struct sgsn_mm_ctx *mm, 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 000000000..1e982af74 --- /dev/null +++ b/include/osmocom/sgsn/pdpctx.h @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +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 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 #include #include +#include #include 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 #include #include +#include #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 #include #include +#include /* 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 #include #include +#include #include @@ -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 #include #include +#include /* 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 #include #include +#include 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 + * + * 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 . + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 #include +#include #include #include 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 #include #include +#include #include #include 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 #include #include +#include #include #include 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 #include #include +#include #include #include diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am index 853d8f1b9..8df1395ce 100644 --- a/tests/sgsn/Makefile.am +++ b/tests/sgsn/Makefile.am @@ -60,6 +60,7 @@ sgsn_test_LDADD = \ $(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 \