diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-01-05 17:20:37 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-01-05 17:23:43 +0100 |
commit | e659f75cf18705a72335fbe0cf9d041491601ba9 (patch) | |
tree | b190e552c7c0dd4d51b0fcccc55e6d58b61c2d1c | |
parent | 67e71eac1c087f7b0655058af21b2037c8fcd11c (diff) |
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: Idf60519b8e475b94d38bbb69e737132a5afaefab
-rw-r--r-- | include/osmocom/sgsn/gprs_sgsn.h | 4 | ||||
-rw-r--r-- | include/osmocom/sgsn/sgsn.h | 5 | ||||
-rw-r--r-- | src/sgsn/gprs_sgsn.c | 61 | ||||
-rw-r--r-- | src/sgsn/sgsn_cdr.c | 8 | ||||
-rw-r--r-- | src/sgsn/sgsn_main.c | 27 | ||||
-rw-r--r-- | src/sgsn/sgsn_vty.c | 8 | ||||
-rw-r--r-- | tests/sgsn/Makefile.am | 4 | ||||
-rw-r--r-- | tests/sgsn/sgsn_test.c | 29 |
8 files changed, 83 insertions, 63 deletions
diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h index 8b9a00e16..4f8bc3d13 100644 --- a/include/osmocom/sgsn/gprs_sgsn.h +++ b/include/osmocom/sgsn/gprs_sgsn.h @@ -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 */ diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h index f08037a2e..d558d8781 100644 --- a/include/osmocom/sgsn/sgsn.h +++ b/include/osmocom/sgsn/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); /* diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c index 572e90bb5..5afddb4d5 100644 --- a/src/sgsn/gprs_sgsn.c +++ b/src/sgsn/gprs_sgsn.c @@ -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; } diff --git a/src/sgsn/sgsn_cdr.c b/src/sgsn/sgsn_cdr.c index 24d75241e..ac0a6fde9 100644 --- a/src/sgsn/sgsn_cdr.c +++ b/src/sgsn/sgsn_cdr.c @@ -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); +} diff --git a/src/sgsn/sgsn_main.c b/src/sgsn/sgsn_main.c index 3ad0881a4..72533489f 100644 --- a/src/sgsn/sgsn_main.c +++ b/src/sgsn/sgsn_main.c @@ -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); } diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c index 18951f8e2..4affa9f20 100644 --- a/src/sgsn/sgsn_vty.c +++ b/src/sgsn/sgsn_vty.c @@ -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); diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am index e6cb71b10..8deec2462 100644 --- a/tests/sgsn/Makefile.am +++ b/tests/sgsn/Makefile.am @@ -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) \ diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c index 18d3c1984..7d3bde576 100644 --- a/tests/sgsn/sgsn_test.c +++ b/tests/sgsn/sgsn_test.c @@ -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; } |