Keep sgsn subsystems under struct sgsn_instance lifecycle
Rework initialization and destruction of several sgsn subsystems to be allocated & released together with the struct sgsn_instance. This makes it easier to destroy and recreate the entire context and allows us to start moving global variables scattered around to be under struct sgsn_instance. Change-Id: Idf60519b8e475b94d38bbb69e737132a5afaefabchanges/80/30880/1
parent
67e71eac1c
commit
e659f75cf1
|
@ -381,8 +381,6 @@ extern struct llist_head sgsn_apn_ctxts;
|
|||
extern struct llist_head sgsn_pdp_ctxts;
|
||||
|
||||
uint32_t sgsn_alloc_ptmsi(void);
|
||||
struct sgsn_instance *sgsn_instance_alloc(void *talloc_ctx);
|
||||
void sgsn_inst_init(struct sgsn_instance *sgsn);
|
||||
|
||||
char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len, bool return_ipv6);
|
||||
|
||||
|
@ -438,6 +436,4 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx,
|
|||
/* Called on subscriber data updates */
|
||||
void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx);
|
||||
|
||||
void sgsn_rate_ctr_init(void);
|
||||
|
||||
#endif /* _GPRS_SGSN_H */
|
||||
|
|
|
@ -152,6 +152,8 @@ struct sgsn_instance {
|
|||
struct rate_ctr_group *rate_ctrs;
|
||||
|
||||
struct llist_head mme_list; /* list of struct sgsn_mme_ctx */
|
||||
|
||||
struct ctrl_handle *ctrlh;
|
||||
};
|
||||
|
||||
extern struct sgsn_instance *sgsn;
|
||||
|
@ -163,6 +165,8 @@ int sgsn_parse_config(const char *config_file);
|
|||
char *sgsn_gtp_ntoa(struct ul16_t *ul);
|
||||
|
||||
/* sgsn.c */
|
||||
struct sgsn_instance *sgsn_instance_alloc(void *talloc_ctx);
|
||||
int sgsn_inst_init(struct sgsn_instance *sgsn);
|
||||
|
||||
/* Main input function for Gb proxy */
|
||||
int sgsn_rcvmsg(struct msgb *msg, struct gprs_ns2_vc *nsvc, uint16_t ns_bvci);
|
||||
|
@ -197,6 +201,7 @@ int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
|
|||
* CDR related functionality
|
||||
*/
|
||||
int sgsn_cdr_init(struct sgsn_instance *sgsn);
|
||||
void sgsn_cdr_release(struct sgsn_instance *sgsn);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/stats.h>
|
||||
#include <osmocom/core/backtrace.h>
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
#include <osmocom/ctrl/ports.h>
|
||||
#include <osmocom/gprs/gprs_ns2.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
|
@ -59,6 +61,7 @@
|
|||
|
||||
extern struct sgsn_instance *sgsn;
|
||||
extern void *tall_sgsn_ctx;
|
||||
extern struct osmo_tdef sgsn_T_defs[];
|
||||
|
||||
LLIST_HEAD(sgsn_mm_ctxts);
|
||||
LLIST_HEAD(sgsn_ggsn_ctxts);
|
||||
|
@ -145,12 +148,6 @@ static const struct rate_ctr_group_desc sgsn_ctrg_desc = {
|
|||
sgsn_ctr_description,
|
||||
};
|
||||
|
||||
void sgsn_rate_ctr_init(void)
|
||||
{
|
||||
sgsn->rate_ctrs = rate_ctr_group_alloc(tall_sgsn_ctx, &sgsn_ctrg_desc, 0);
|
||||
OSMO_ASSERT(sgsn->rate_ctrs);
|
||||
}
|
||||
|
||||
/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
|
||||
{
|
||||
|
@ -893,21 +890,67 @@ static void sgsn_llme_check_cb(void *data_)
|
|||
osmo_timer_schedule(&sgsn->llme_timer, GPRS_LLME_CHECK_TICK, 0);
|
||||
}
|
||||
|
||||
static int sgsn_instance_talloc_destructor(struct sgsn_instance *sgi)
|
||||
{
|
||||
sgsn_cdr_release(sgi);
|
||||
osmo_timer_del(&sgi->llme_timer);
|
||||
rate_ctr_group_free(sgi->rate_ctrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sgsn_instance *sgsn_instance_alloc(void *talloc_ctx)
|
||||
{
|
||||
struct sgsn_instance *inst;
|
||||
inst = talloc_zero(talloc_ctx, struct sgsn_instance);
|
||||
|
||||
talloc_set_destructor(inst, sgsn_instance_talloc_destructor);
|
||||
|
||||
inst->cfg.gtp_statedir = talloc_strdup(inst, "./");
|
||||
inst->cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
|
||||
inst->cfg.require_authentication = true; /* only applies if auth_policy is REMOTE */
|
||||
inst->cfg.gsup_server_port = OSMO_GSUP_PORT;
|
||||
|
||||
inst->cfg.T_defs = sgsn_T_defs;
|
||||
osmo_tdefs_reset(inst->cfg.T_defs);
|
||||
inst->cfg.T_defs_gtp = gtp_T_defs;
|
||||
osmo_tdefs_reset(inst->cfg.T_defs_gtp);
|
||||
|
||||
inst->rate_ctrs = rate_ctr_group_alloc(inst, &sgsn_ctrg_desc, 0);
|
||||
OSMO_ASSERT(inst->rate_ctrs);
|
||||
|
||||
INIT_LLIST_HEAD(&inst->mme_list);
|
||||
|
||||
osmo_timer_setup(&inst->llme_timer, sgsn_llme_check_cb, NULL);
|
||||
osmo_timer_schedule(&inst->llme_timer, GPRS_LLME_CHECK_TICK, 0);
|
||||
/* These are mostly setting up stuff not related to VTY cfg, so they can be set up here: */
|
||||
sgsn_auth_init(inst);
|
||||
sgsn_cdr_init(inst);
|
||||
return inst;
|
||||
}
|
||||
|
||||
void sgsn_inst_init(struct sgsn_instance *sgsn)
|
||||
/* To be called after VTY config parsing: */
|
||||
int sgsn_inst_init(struct sgsn_instance *sgsn)
|
||||
{
|
||||
osmo_timer_setup(&sgsn->llme_timer, sgsn_llme_check_cb, NULL);
|
||||
osmo_timer_schedule(&sgsn->llme_timer, GPRS_LLME_CHECK_TICK, 0);
|
||||
int rc;
|
||||
|
||||
/* start control interface after reading config for
|
||||
* ctrl_vty_get_bind_addr() */
|
||||
sgsn->ctrlh = ctrl_interface_setup(NULL, OSMO_CTRL_PORT_SGSN, NULL);
|
||||
if (!sgsn->ctrlh) {
|
||||
LOGP(DGPRS, LOGL_ERROR, "Failed to create CTRL interface.\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = sgsn_ctrl_cmds_install();
|
||||
if (rc != 0) {
|
||||
LOGP(DGPRS, LOGL_ERROR, "Failed to install CTRL commands.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = gprs_subscr_init(sgsn);
|
||||
if (rc < 0) {
|
||||
LOGP(DGPRS, LOGL_FATAL, "Cannot set up SGSN\n");
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
/* TODO...avoid going through a global */
|
||||
extern struct sgsn_instance *sgsn;
|
||||
extern struct ctrl_handle *g_ctrlh;
|
||||
|
||||
/**
|
||||
* The CDR module will generate an entry like:
|
||||
|
@ -65,7 +64,7 @@ extern struct ctrl_handle *g_ctrlh;
|
|||
|
||||
static void send_cdr_trap(char *value)
|
||||
{
|
||||
if (ctrl_cmd_send_trap(g_ctrlh, "cdr-v1", value) < 0)
|
||||
if (ctrl_cmd_send_trap(sgsn->ctrlh, "cdr-v1", value) < 0)
|
||||
LOGP(DGPRS, LOGL_ERROR, "Failed to create and send TRAP cdr-v1\n");
|
||||
}
|
||||
|
||||
|
@ -300,3 +299,8 @@ int sgsn_cdr_init(struct sgsn_instance *sgsn)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sgsn_cdr_release(struct sgsn_instance *sgsn)
|
||||
{
|
||||
osmo_signal_unregister_handler(SS_SGSN, handle_sgsn_sig, sgsn);
|
||||
}
|
||||
|
|
|
@ -67,9 +67,6 @@
|
|||
#include <osmocom/sgsn/gprs_subscriber.h>
|
||||
#include <osmocom/sgsn/gtp.h>
|
||||
|
||||
#include <osmocom/ctrl/control_if.h>
|
||||
#include <osmocom/ctrl/ports.h>
|
||||
|
||||
#include <gtp.h>
|
||||
#include <osmocom/sgsn/sgsn_rim.h>
|
||||
|
||||
|
@ -85,7 +82,6 @@
|
|||
#include <getopt.h>
|
||||
|
||||
void *tall_sgsn_ctx;
|
||||
struct ctrl_handle *g_ctrlh;
|
||||
|
||||
struct gprs_ns2_inst *sgsn_nsi;
|
||||
static int daemonize = 0;
|
||||
|
@ -418,16 +414,11 @@ int main(int argc, char **argv)
|
|||
bssgp_set_bssgp_callback(sgsn_bssgp_dispatch_ns_unitdata_req_cb, sgsn_nsi);
|
||||
|
||||
gprs_llc_init("/usr/local/lib/osmocom/crypt/");
|
||||
sgsn_rate_ctr_init();
|
||||
sgsn_inst_init(sgsn);
|
||||
|
||||
|
||||
gprs_ns2_vty_init(sgsn_nsi);
|
||||
bssgp_vty_init();
|
||||
gprs_llc_vty_init();
|
||||
gprs_sndcp_vty_init();
|
||||
sgsn_auth_init(sgsn);
|
||||
sgsn_cdr_init(sgsn);
|
||||
|
||||
handle_options(argc, argv);
|
||||
|
||||
|
@ -458,20 +449,6 @@ int main(int argc, char **argv)
|
|||
if (rc < 0)
|
||||
exit(1);
|
||||
|
||||
/* start control interface after reading config for
|
||||
* ctrl_vty_get_bind_addr() */
|
||||
g_ctrlh = ctrl_interface_setup(NULL, OSMO_CTRL_PORT_SGSN, NULL);
|
||||
if (!g_ctrlh) {
|
||||
LOGP(DGPRS, LOGL_ERROR, "Failed to create CTRL interface.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sgsn_ctrl_cmds_install() != 0) {
|
||||
LOGP(DGPRS, LOGL_ERROR, "Failed to install CTRL commands.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
rc = sgsn_gtp_init(sgsn);
|
||||
if (rc) {
|
||||
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on GTP socket\n");
|
||||
|
@ -479,9 +456,9 @@ int main(int argc, char **argv)
|
|||
} else
|
||||
LOGP(DGPRS, LOGL_NOTICE, "libGTP v%s initialized\n", gtp_version());
|
||||
|
||||
rc = gprs_subscr_init(sgsn);
|
||||
rc = sgsn_inst_init(sgsn);
|
||||
if (rc < 0) {
|
||||
LOGP(DGPRS, LOGL_FATAL, "Cannot set up subscriber management\n");
|
||||
LOGP(DGPRS, LOGL_FATAL, "Cannot set up SGSN\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ const struct value_string sgsn_auth_pol_strs[] = {
|
|||
#define NONSPEC_X1001_SECS 5 /* wait for a RANAP Release Complete */
|
||||
|
||||
|
||||
static struct osmo_tdef sgsn_T_defs[] = {
|
||||
struct osmo_tdef sgsn_T_defs[] = {
|
||||
{ .T=3312, .default_val=GSM0408_T3312_SECS, .desc="Periodic RA Update timer (s)" },
|
||||
{ .T=3313, .default_val=GSM0408_T3313_SECS, .desc="Waiting for paging response timer (s)" },
|
||||
{ .T=3314, .default_val=GSM0408_T3314_SECS, .desc="READY timer. Force to STANDBY on expiry timer (s)" },
|
||||
|
@ -1739,12 +1739,6 @@ int sgsn_vty_init(struct sgsn_config *cfg)
|
|||
{
|
||||
g_cfg = cfg;
|
||||
|
||||
g_cfg->T_defs = sgsn_T_defs;
|
||||
osmo_tdefs_reset(g_cfg->T_defs);
|
||||
|
||||
g_cfg->T_defs_gtp = gtp_T_defs;
|
||||
osmo_tdefs_reset(g_cfg->T_defs_gtp);
|
||||
|
||||
install_element_ve(&show_sgsn_cmd);
|
||||
//install_element_ve(&show_mmctx_tlli_cmd);
|
||||
install_element_ve(&show_mmctx_imsi_cmd);
|
||||
|
|
|
@ -7,6 +7,7 @@ AM_CFLAGS = \
|
|||
-Wall \
|
||||
-ggdb3 \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOCTRL_CFLAGS) \
|
||||
$(LIBOSMOABIS_CFLAGS) \
|
||||
$(LIBOSMOGSM_CFLAGS) \
|
||||
$(LIBOSMOGSUPCLIENT_CFLAGS) \
|
||||
|
@ -58,6 +59,8 @@ 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/sgsn_cdr.o \
|
||||
$(top_builddir)/src/sgsn/sgsn_ctrl.o \
|
||||
$(top_builddir)/src/sgsn/sgsn_vty.o \
|
||||
$(top_builddir)/src/sgsn/sgsn_libgtp.o \
|
||||
$(top_builddir)/src/sgsn/sgsn_auth.o \
|
||||
|
@ -77,6 +80,7 @@ sgsn_test_LDADD = \
|
|||
$(top_builddir)/src/gprs/sgsn_ares.o \
|
||||
$(LIBOSMOABIS_LIBS) \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOCTRL_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
$(LIBOSMOGB_LIBS) \
|
||||
$(LIBOSMOGSUPCLIENT_LIBS) \
|
||||
|
|
|
@ -45,15 +45,7 @@
|
|||
#include "gprs_gb_parse.h"
|
||||
|
||||
void *tall_sgsn_ctx;
|
||||
static struct sgsn_instance sgsn_inst = {
|
||||
.config_file = "osmo_sgsn.cfg",
|
||||
.cfg = {
|
||||
.gtp_statedir = "./",
|
||||
.auth_policy = SGSN_AUTH_POLICY_CLOSED,
|
||||
.gea_encryption_mask = 0x1,
|
||||
},
|
||||
};
|
||||
struct sgsn_instance *sgsn = &sgsn_inst;
|
||||
struct sgsn_instance *sgsn;
|
||||
unsigned sgsn_tx_counter = 0;
|
||||
struct msgb *last_msg = NULL;
|
||||
struct gprs_gb_parse_context last_dl_parse_ctx;
|
||||
|
@ -70,6 +62,7 @@ static void reset_last_msg(void)
|
|||
static void cleanup_test(void)
|
||||
{
|
||||
reset_last_msg();
|
||||
TALLOC_FREE(sgsn);
|
||||
}
|
||||
|
||||
static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
|
||||
|
@ -574,6 +567,7 @@ static void test_subscriber_gsup(void)
|
|||
printf("Testing subscriber GSUP handling\n");
|
||||
|
||||
update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
|
||||
/* Check for emptiness */
|
||||
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
|
||||
|
@ -750,6 +744,7 @@ static void test_gmm_detach(void)
|
|||
uint32_t local_tlli;
|
||||
|
||||
printf("Testing GMM detach\n");
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
|
||||
/* DTAP - Detach Request (MO) */
|
||||
/* normal detach, power_off = 0 */
|
||||
|
@ -791,6 +786,7 @@ static void test_gmm_detach_power_off(void)
|
|||
uint32_t local_tlli;
|
||||
|
||||
printf("Testing GMM detach (power off)\n");
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
|
||||
/* DTAP - Detach Request (MO) */
|
||||
/* normal detach, power_off = 1 */
|
||||
|
@ -831,6 +827,7 @@ static void test_gmm_detach_no_mmctx(void)
|
|||
uint32_t local_tlli;
|
||||
|
||||
printf("Testing GMM detach (no MMCTX)\n");
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
|
||||
/* DTAP - Detach Request (MO) */
|
||||
/* normal detach, power_off = 0 */
|
||||
|
@ -1197,6 +1194,7 @@ static void test_gmm_reject(void)
|
|||
};
|
||||
|
||||
printf("Testing GMM reject\n");
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
|
||||
/* reset the PRNG used by sgsn_alloc_ptmsi */
|
||||
srand(1);
|
||||
|
@ -1243,6 +1241,9 @@ static void test_gmm_cancel(void)
|
|||
uint32_t foreign_tlli;
|
||||
uint32_t local_tlli = 0;
|
||||
struct gprs_llc_lle *lle;
|
||||
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
sgsn->cfg.gea_encryption_mask = 0x1;
|
||||
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
|
||||
|
||||
/* DTAP - Attach Request */
|
||||
|
@ -1273,8 +1274,7 @@ static void test_gmm_cancel(void)
|
|||
};
|
||||
|
||||
printf("Testing cancellation\n");
|
||||
|
||||
sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
|
||||
sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
|
||||
|
||||
foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
|
||||
|
||||
|
@ -1456,6 +1456,7 @@ static void test_ggsn_selection(void)
|
|||
printf("Testing GGSN selection\n");
|
||||
|
||||
osmo_gsup_client_send_cb = my_gsup_client_send_dummy;
|
||||
sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
|
||||
|
||||
/* Check for emptiness */
|
||||
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
|
||||
|
@ -1654,11 +1655,7 @@ int main(int argc, char **argv)
|
|||
tall_sgsn_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "sgsn");
|
||||
msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
|
||||
|
||||
sgsn_rate_ctr_init();
|
||||
sgsn_auth_init(sgsn);
|
||||
gprs_subscr_init(sgsn);
|
||||
vty_init(&vty_info);
|
||||
sgsn_vty_init(&sgsn->cfg);
|
||||
|
||||
test_llme();
|
||||
test_subscriber();
|
||||
|
@ -1678,7 +1675,7 @@ int main(int argc, char **argv)
|
|||
|
||||
talloc_report_full(osmo_sgsn_ctx, stderr);
|
||||
OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
|
||||
OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 2);
|
||||
OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue