diff --git a/lib/core/ogs-core.c b/lib/core/ogs-core.c index 3341df616..4b76be5d5 100644 --- a/lib/core/ogs-core.c +++ b/lib/core/ogs-core.c @@ -38,9 +38,9 @@ static ogs_core_context_t self = { void ogs_core_initialize(void) { + ogs_mem_init(); ogs_log_init(); ogs_pkbuf_init(); - ogs_mem_init(); ogs_socket_init(); ogs_tlv_init(); @@ -56,9 +56,9 @@ void ogs_core_terminate(void) { ogs_tlv_final(); ogs_socket_final(); - ogs_mem_final(); ogs_pkbuf_final(); ogs_log_final(); + ogs_mem_final(); } ogs_core_context_t *ogs_core(void) diff --git a/lib/core/ogs-memory.h b/lib/core/ogs-memory.h index 0dc909d0b..1570b3bf7 100644 --- a/lib/core/ogs-memory.h +++ b/lib/core/ogs-memory.h @@ -58,7 +58,7 @@ void *ogs_realloc_debug( void *ptr, size_t size, const char *file_line); int ogs_free_debug(void *ptr); -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 /***************************************** * Memory Pool - Use talloc library diff --git a/lib/core/ogs-pkbuf.c b/lib/core/ogs-pkbuf.c index 562088f1f..6d3cbe76a 100644 --- a/lib/core/ogs-pkbuf.c +++ b/lib/core/ogs-pkbuf.c @@ -99,6 +99,7 @@ void ogs_pkbuf_init(void) { #if OGS_USE_TALLOC == 0 ogs_pool_init(&pkbuf_pool, ogs_core()->pkbuf.pool); + #endif } @@ -219,7 +220,7 @@ void ogs_pkbuf_pool_destroy(ogs_pkbuf_pool_t *pool) ogs_pkbuf_t *ogs_pkbuf_alloc_debug( ogs_pkbuf_pool_t *pool, unsigned int size, const char *file_line) { -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 ogs_pkbuf_t *pkbuf = NULL; pkbuf = ogs_talloc_zero_size(pool, sizeof(*pkbuf) + size, file_line); @@ -287,7 +288,7 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug( void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf) { -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 ogs_talloc_free(pkbuf, OGS_FILE_LINE); #else ogs_pkbuf_pool_t *pool = NULL; @@ -315,7 +316,7 @@ void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf) ogs_pkbuf_t *ogs_pkbuf_copy_debug(ogs_pkbuf_t *pkbuf, const char *file_line) { -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 ogs_pkbuf_t *newbuf; #else ogs_pkbuf_pool_t *pool = NULL; @@ -331,7 +332,7 @@ ogs_pkbuf_t *ogs_pkbuf_copy_debug(ogs_pkbuf_t *pkbuf, const char *file_line) return NULL; } -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 newbuf = ogs_pkbuf_alloc_debug(NULL, size, file_line); if (!newbuf) { ogs_error("ogs_pkbuf_alloc() failed [size=%d]", size); diff --git a/lib/core/ogs-pkbuf.h b/lib/core/ogs-pkbuf.h index ba81c2622..5dc065557 100644 --- a/lib/core/ogs-pkbuf.h +++ b/lib/core/ogs-pkbuf.h @@ -35,7 +35,7 @@ typedef struct ogs_cluster_s { unsigned int reference_count; } ogs_cluster_t; -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 typedef void ogs_pkbuf_pool_t; #else typedef struct ogs_pkbuf_pool_s ogs_pkbuf_pool_t; diff --git a/lib/core/ogs-pool.h b/lib/core/ogs-pool.h index 94ded03a8..e5f3c8c4f 100644 --- a/lib/core/ogs-pool.h +++ b/lib/core/ogs-pool.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -28,7 +28,15 @@ extern "C" { #endif -typedef unsigned int ogs_index_t; +#if OGS_USE_TALLOC == 1 +#define ogs_pool_create ogs_malloc +#define ogs_pool_destroy ogs_free +#else +#define ogs_pool_create malloc +#define ogs_pool_destroy free +#endif + +typedef uint32_t ogs_pool_id_t; #define OGS_POOL(pool, type) \ struct { \ @@ -41,11 +49,11 @@ typedef unsigned int ogs_index_t; #define ogs_pool_init(pool, _size) do { \ int i; \ (pool)->name = #pool; \ - (pool)->free = malloc(sizeof(*(pool)->free) * _size); \ + (pool)->free = ogs_pool_create(sizeof(*(pool)->free) * _size); \ ogs_assert((pool)->free); \ - (pool)->array = malloc(sizeof(*(pool)->array) * _size); \ + (pool)->array = ogs_pool_create(sizeof(*(pool)->array) * _size); \ ogs_assert((pool)->array); \ - (pool)->index = malloc(sizeof(*(pool)->index) * _size); \ + (pool)->index = ogs_pool_create(sizeof(*(pool)->index) * _size); \ ogs_assert((pool)->index); \ (pool)->size = (pool)->avail = _size; \ (pool)->head = (pool)->tail = 0; \ @@ -59,9 +67,9 @@ typedef unsigned int ogs_index_t; if (((pool)->size != (pool)->avail)) \ ogs_error("%d in '%s[%d]' were not released.", \ (pool)->size - (pool)->avail, (pool)->name, (pool)->size); \ - free((pool)->free); \ - free((pool)->array); \ - free((pool)->index); \ + ogs_pool_destroy((pool)->free); \ + ogs_pool_destroy((pool)->array); \ + ogs_pool_destroy((pool)->index); \ } while (0) #define ogs_pool_index(pool, node) (((node) - (pool)->array)+1) @@ -93,30 +101,23 @@ typedef unsigned int ogs_index_t; #define ogs_pool_size(pool) ((pool)->size) #define ogs_pool_avail(pool) ((pool)->avail) -#define ogs_index_init(pool, _size) do { \ +#define ogs_pool_sequence_id_generate(pool) do { \ int i; \ - (pool)->name = #pool; \ - (pool)->free = ogs_malloc(sizeof(*(pool)->free) * _size); \ - ogs_assert((pool)->free); \ - (pool)->array = ogs_malloc(sizeof(*(pool)->array) * _size); \ - ogs_assert((pool)->array); \ - (pool)->index = ogs_malloc(sizeof(*(pool)->index) * _size); \ - ogs_assert((pool)->index); \ - (pool)->size = (pool)->avail = _size; \ - (pool)->head = (pool)->tail = 0; \ - for (i = 0; i < _size; i++) { \ - (pool)->free[i] = &((pool)->array[i]); \ - (pool)->index[i] = NULL; \ - } \ + for (i = 0; i < (pool)->size; i++) \ + (pool)->array[i] = i+1; \ } while (0) -#define ogs_index_final(pool) do { \ - if (((pool)->size != (pool)->avail)) \ - ogs_error("%d in '%s[%d]' were not released.", \ - (pool)->size - (pool)->avail, (pool)->name, (pool)->size); \ - ogs_free((pool)->free); \ - ogs_free((pool)->array); \ - ogs_free((pool)->index); \ +#define ogs_pool_random_id_generate(pool) do { \ + int i, j; \ + ogs_pool_id_t temp; \ + for (i = 0; i < (pool)->size; i++) \ + (pool)->array[i] = i+1; \ + for (i = (pool)->size - 1; i > 0; i--) { \ + j = ogs_random32() % (i + 1); \ + temp = (pool)->array[i]; \ + (pool)->array[i] = (pool)->array[j]; \ + (pool)->array[j] = temp; \ + } \ } while (0) #ifdef __cplusplus diff --git a/lib/core/ogs-strings.h b/lib/core/ogs-strings.h index 21eecf455..aa2207bdf 100644 --- a/lib/core/ogs-strings.h +++ b/lib/core/ogs-strings.h @@ -110,7 +110,7 @@ char *ogs_mstrcatf_debug( char *source, const char *file_line, const char *message, ...) OGS_GNUC_PRINTF(3, 4); -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 /***************************************** * Memory Pool - Use talloc library diff --git a/lib/gtp/xact.h b/lib/gtp/xact.h index 216cb04f1..5bb25242b 100644 --- a/lib/gtp/xact.h +++ b/lib/gtp/xact.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2019 by Sukchan Lee * Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH + * Copyright (C) 2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -57,7 +58,7 @@ extern "C" { */ typedef struct ogs_gtp_xact_s { ogs_lnode_t node; /**< A node of list */ - ogs_index_t index; + ogs_pool_id_t index; uint8_t gtp_version; /**< 1 or 2 */ diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index a76560307..51b0aaa20 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -28,6 +28,7 @@ static OGS_POOL(ogs_pfcp_node_pool, ogs_pfcp_node_t); static OGS_POOL(ogs_pfcp_sess_pool, ogs_pfcp_sess_t); static OGS_POOL(ogs_pfcp_pdr_pool, ogs_pfcp_pdr_t); +static OGS_POOL(ogs_pfcp_pdr_teid_pool, ogs_pool_id_t); static OGS_POOL(ogs_pfcp_far_pool, ogs_pfcp_far_t); static OGS_POOL(ogs_pfcp_urr_pool, ogs_pfcp_urr_t); static OGS_POOL(ogs_pfcp_qer_pool, ogs_pfcp_qer_t); @@ -54,6 +55,9 @@ void ogs_pfcp_context_init(void) ogs_pool_init(&ogs_pfcp_pdr_pool, ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR); + ogs_pool_init(&ogs_pfcp_pdr_teid_pool, + ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR); + ogs_pool_random_id_generate(&ogs_pfcp_pdr_teid_pool); ogs_pool_init(&ogs_pfcp_far_pool, ogs_app()->pool.sess * OGS_MAX_NUM_OF_FAR); ogs_pool_init(&ogs_pfcp_urr_pool, @@ -100,6 +104,7 @@ void ogs_pfcp_context_final(void) ogs_pool_final(&ogs_pfcp_sess_pool); ogs_pool_final(&ogs_pfcp_pdr_pool); + ogs_pool_final(&ogs_pfcp_pdr_teid_pool); ogs_pool_final(&ogs_pfcp_far_pool); ogs_pool_final(&ogs_pfcp_urr_pool); ogs_pool_final(&ogs_pfcp_qer_pool); @@ -894,6 +899,16 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_add(ogs_pfcp_sess_t *sess) } memset(pdr, 0, sizeof *pdr); + pdr->obj.type = OGS_PFCP_OBJ_PDR_TYPE; + pdr->src_if = OGS_PFCP_INTERFACE_UNKNOWN; + + /* Set TEID */ + ogs_pool_alloc(&ogs_pfcp_pdr_teid_pool, &pdr->teid_node); + ogs_assert(pdr->teid_node); + + pdr->teid = *(pdr->teid_node); + + /* Set PDR-ID */ ogs_pool_alloc(&sess->pdr_id_pool, &pdr->id_node); if (pdr->id_node == NULL) { ogs_error("pdr_id_pool() failed"); @@ -901,17 +916,9 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_add(ogs_pfcp_sess_t *sess) return NULL; } - pdr->obj.type = OGS_PFCP_OBJ_PDR_TYPE; - - pdr->index = ogs_pool_index(&ogs_pfcp_pdr_pool, pdr); - ogs_assert(pdr->index > 0 && - pdr->index <= ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR); - pdr->id = *(pdr->id_node); ogs_assert(pdr->id > 0 && pdr->id <= OGS_MAX_NUM_OF_PDR); - pdr->src_if = OGS_PFCP_INTERFACE_UNKNOWN; - pdr->sess = sess; ogs_list_add(&sess->pdr_list, pdr); @@ -1107,6 +1114,7 @@ void ogs_pfcp_pdr_remove(ogs_pfcp_pdr_t *pdr) ogs_free(pdr->ipv6_framed_routes); } + ogs_pool_free(&ogs_pfcp_pdr_teid_pool, pdr->teid_node); ogs_pool_free(&ogs_pfcp_pdr_pool, pdr); } @@ -1929,41 +1937,29 @@ ogs_pfcp_subnet_t *ogs_pfcp_find_subnet_by_dnn(int family, const char *dnn) void ogs_pfcp_pool_init(ogs_pfcp_sess_t *sess) { - int i; - ogs_assert(sess); sess->obj.type = OGS_PFCP_OBJ_SESS_TYPE; - ogs_index_init(&sess->pdr_id_pool, OGS_MAX_NUM_OF_PDR); - ogs_index_init(&sess->far_id_pool, OGS_MAX_NUM_OF_FAR); - ogs_index_init(&sess->urr_id_pool, OGS_MAX_NUM_OF_URR); - ogs_index_init(&sess->qer_id_pool, OGS_MAX_NUM_OF_QER); - ogs_index_init(&sess->bar_id_pool, OGS_MAX_NUM_OF_BAR); + ogs_pool_init(&sess->pdr_id_pool, OGS_MAX_NUM_OF_PDR); + ogs_pool_init(&sess->far_id_pool, OGS_MAX_NUM_OF_FAR); + ogs_pool_init(&sess->urr_id_pool, OGS_MAX_NUM_OF_URR); + ogs_pool_init(&sess->qer_id_pool, OGS_MAX_NUM_OF_QER); + ogs_pool_init(&sess->bar_id_pool, OGS_MAX_NUM_OF_BAR); - for (i = 1; i <= OGS_MAX_NUM_OF_PDR; i++) { - sess->pdr_id_pool.array[i-1] = i; - } - for (i = 1; i <= OGS_MAX_NUM_OF_FAR; i++) { - sess->far_id_pool.array[i-1] = i; - } - for (i = 1; i <= OGS_MAX_NUM_OF_URR; i++) { - sess->urr_id_pool.array[i-1] = i; - } - for (i = 1; i <= OGS_MAX_NUM_OF_QER; i++) { - sess->qer_id_pool.array[i-1] = i; - } - for (i = 1; i <= OGS_MAX_NUM_OF_BAR; i++) { - sess->bar_id_pool.array[i-1] = i; - } + ogs_pool_sequence_id_generate(&sess->pdr_id_pool); + ogs_pool_sequence_id_generate(&sess->far_id_pool); + ogs_pool_sequence_id_generate(&sess->urr_id_pool); + ogs_pool_sequence_id_generate(&sess->qer_id_pool); + ogs_pool_sequence_id_generate(&sess->bar_id_pool); } void ogs_pfcp_pool_final(ogs_pfcp_sess_t *sess) { ogs_assert(sess); - ogs_index_final(&sess->pdr_id_pool); - ogs_index_final(&sess->far_id_pool); - ogs_index_final(&sess->urr_id_pool); - ogs_index_final(&sess->qer_id_pool); - ogs_index_final(&sess->bar_id_pool); + ogs_pool_final(&sess->pdr_id_pool); + ogs_pool_final(&sess->far_id_pool); + ogs_pool_final(&sess->urr_id_pool); + ogs_pool_final(&sess->qer_id_pool); + ogs_pool_final(&sess->bar_id_pool); } diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index a14f0e3c4..ad317336b 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -137,7 +137,9 @@ typedef struct ogs_pfcp_bar_s ogs_pfcp_bar_t; typedef struct ogs_pfcp_pdr_s { ogs_pfcp_object_t obj; - uint32_t index; + + ogs_pool_id_t *teid_node; /* A node of TEID */ + ogs_pool_id_t teid; ogs_lnode_t to_create_node; ogs_lnode_t to_modify_node; diff --git a/lib/pfcp/xact.h b/lib/pfcp/xact.h index bc6a85803..aa0f2bfd2 100644 --- a/lib/pfcp/xact.h +++ b/lib/pfcp/xact.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -35,7 +35,7 @@ typedef struct ogs_pfcp_xact_s { ogs_lnode_t lnode; /**< A node of list */ ogs_lnode_t tmpnode; /**< A node of temp-list */ - ogs_index_t index; + ogs_pool_id_t index; #define OGS_PFCP_LOCAL_ORIGINATOR 0 #define OGS_PFCP_REMOTE_ORIGINATOR 1 diff --git a/src/amf/context.c b/src/amf/context.c index ad5260a85..e13600083 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -29,6 +29,8 @@ static OGS_POOL(amf_ue_pool, amf_ue_t); static OGS_POOL(ran_ue_pool, ran_ue_t); static OGS_POOL(amf_sess_pool, amf_sess_t); +static OGS_POOL(m_tmsi_pool, amf_m_tmsi_t); + static int context_initialized = 0; static int num_of_ran_ue = 0; @@ -60,7 +62,8 @@ void amf_context_init(void) ogs_pool_init(&amf_ue_pool, ogs_app()->max.ue); ogs_pool_init(&ran_ue_pool, ogs_app()->max.ue); ogs_pool_init(&amf_sess_pool, ogs_app()->pool.sess); - ogs_pool_init(&self.m_tmsi, ogs_app()->max.ue*2); + ogs_pool_init(&m_tmsi_pool, ogs_app()->max.ue*2); + ogs_pool_random_id_generate(&m_tmsi_pool); ogs_list_init(&self.gnb_list); ogs_list_init(&self.amf_ue_list); @@ -98,7 +101,7 @@ void amf_context_final(void) ogs_assert(self.supi_hash); ogs_hash_destroy(self.supi_hash); - ogs_pool_final(&self.m_tmsi); + ogs_pool_final(&m_tmsi_pool); ogs_pool_final(&amf_sess_pool); ogs_pool_final(&amf_ue_pool); ogs_pool_final(&ran_ue_pool); @@ -1697,11 +1700,6 @@ amf_ue_t *amf_ue_find_by_guti(ogs_nas_5gs_guti_t *guti) self.guti_ue_hash, guti, sizeof(ogs_nas_5gs_guti_t)); } -amf_ue_t *amf_ue_find_by_teid(uint32_t teid) -{ - return ogs_pool_find(&amf_ue_pool, teid); -} - amf_ue_t *amf_ue_find_by_suci(char *suci) { ogs_assert(suci); @@ -2368,6 +2366,7 @@ ogs_s_nssai_t *amf_find_s_nssai( return NULL; } +#if 0 /* DEPRECATED */ int amf_m_tmsi_pool_generate(void) { int j; @@ -2378,7 +2377,7 @@ int amf_m_tmsi_pool_generate(void) amf_m_tmsi_t *m_tmsi = NULL; int conflict = 0; - m_tmsi = &self.m_tmsi.array[index]; + m_tmsi = &m_tmsi_pool.array[index]; ogs_assert(m_tmsi); *m_tmsi = ogs_random32(); @@ -2387,10 +2386,10 @@ int amf_m_tmsi_pool_generate(void) *m_tmsi &= 0xff00ffff; for (j = 0; j < index; j++) { - if (*m_tmsi == self.m_tmsi.array[j]) { + if (*m_tmsi == m_tmsi_pool.array[j]) { conflict = 1; ogs_trace("[M-TMSI CONFLICT] %d:0x%x == %d:0x%x", - index, *m_tmsi, j, self.m_tmsi.array[j]); + index, *m_tmsi, j, m_tmsi_pool.array[j]); break; } } @@ -2400,26 +2399,48 @@ int amf_m_tmsi_pool_generate(void) index++; } - self.m_tmsi.size = index; + m_tmsi_pool.size = index; ogs_trace("M-TMSI Pool generate...done"); return OGS_OK; } +#endif amf_m_tmsi_t *amf_m_tmsi_alloc(void) { amf_m_tmsi_t *m_tmsi = NULL; - ogs_pool_alloc(&self.m_tmsi, &m_tmsi); + ogs_pool_alloc(&m_tmsi_pool, &m_tmsi); ogs_assert(m_tmsi); + /* TS23.003 + * 2.8.2.1.2 Mapping in the UE + * + * E-UTRAN maps as follows: + * - 6 bits of the E-UTRAN starting at bit 29 and down to bit 24 + * are mapped into bit 29 and down to bit 24 of the GERAN/UTRAN ; + * - 16 bits of the E-UTRAN starting at bit 15 and down to bit 0 + * are mapped into bit 15 and down to bit 0 of the GERAN/UTRAN ; + * - and the remaining 8 bits of the E-UTRAN are + * mapped into the 8 Most Significant Bits of the field. + * + * The UE shall fill the remaining 2 octets of the + * according to clauses 9.1.1, 9.4.1, 10.2.1, or 10.5.1 + * of 3GPP TS.33.401 [89] , as appropriate, for RAU/Attach procedures + */ + + ogs_assert(*m_tmsi <= 0x003fffff); + + *m_tmsi = ((*m_tmsi & 0xffff) | ((*m_tmsi & 0x003f0000) << 8)); + *m_tmsi |= 0xc0000000; + return m_tmsi; } int amf_m_tmsi_free(amf_m_tmsi_t *m_tmsi) { ogs_assert(m_tmsi); - ogs_pool_free(&self.m_tmsi, m_tmsi); + ogs_pool_free(&m_tmsi_pool, m_tmsi); return OGS_OK; } diff --git a/src/amf/context.h b/src/amf/context.h index e95db3d4d..1479f00d2 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -111,8 +111,6 @@ typedef struct amf_context_s { ogs_hash_t *suci_hash; /* hash table (SUCI) */ ogs_hash_t *supi_hash; /* hash table (SUPI) */ - OGS_POOL(m_tmsi, amf_m_tmsi_t); /* M-TMSI Pool */ - uint16_t ngap_port; /* Default NGAP Port */ ogs_list_t ngap_list; /* AMF NGAP IPv4 Server List */ @@ -697,7 +695,6 @@ void amf_ue_fsm_init(amf_ue_t *amf_ue); void amf_ue_fsm_fini(amf_ue_t *amf_ue); amf_ue_t *amf_ue_find_by_guti(ogs_nas_5gs_guti_t *nas_guti); -amf_ue_t *amf_ue_find_by_teid(uint32_t teid); amf_ue_t *amf_ue_find_by_suci(char *suci); amf_ue_t *amf_ue_find_by_supi(char *supi); @@ -823,7 +820,6 @@ int amf_find_served_tai(ogs_5gs_tai_t *nr_tai); ogs_s_nssai_t *amf_find_s_nssai( ogs_plmn_id_t *served_plmn_id, ogs_s_nssai_t *s_nssai); -int amf_m_tmsi_pool_generate(void); amf_m_tmsi_t *amf_m_tmsi_alloc(void); int amf_m_tmsi_free(amf_m_tmsi_t *tmsi); diff --git a/src/amf/init.c b/src/amf/init.c index 18b3dbda3..9c485d646 100644 --- a/src/amf/init.c +++ b/src/amf/init.c @@ -46,9 +46,6 @@ int amf_initialize(void) rv = amf_context_nf_info(); if (rv != OGS_OK) return rv; - rv = amf_m_tmsi_pool_generate(); - if (rv != OGS_OK) return rv; - rv = ogs_log_config_domain( ogs_app()->logger.domain, ogs_app()->logger.level); if (rv != OGS_OK) return rv; diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 61eca1073..8013aab10 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -44,11 +44,14 @@ static OGS_POOL(mme_csmap_pool, mme_csmap_t); static OGS_POOL(mme_enb_pool, mme_enb_t); static OGS_POOL(mme_ue_pool, mme_ue_t); +static OGS_POOL(mme_s11_teid_pool, ogs_pool_id_t); static OGS_POOL(enb_ue_pool, enb_ue_t); static OGS_POOL(sgw_ue_pool, sgw_ue_t); static OGS_POOL(mme_sess_pool, mme_sess_t); static OGS_POOL(mme_bearer_pool, mme_bearer_t); +static OGS_POOL(m_tmsi_pool, mme_m_tmsi_t); + static int context_initialized = 0; static int num_of_enb_ue = 0; @@ -100,11 +103,15 @@ void mme_context_init(void) ogs_pool_init(&mme_enb_pool, ogs_app()->max.peer*2); ogs_pool_init(&mme_ue_pool, ogs_app()->max.ue); + ogs_pool_init(&mme_s11_teid_pool, ogs_app()->max.ue); + ogs_pool_random_id_generate(&mme_s11_teid_pool); + ogs_pool_init(&enb_ue_pool, ogs_app()->max.ue); ogs_pool_init(&sgw_ue_pool, ogs_app()->max.ue); ogs_pool_init(&mme_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&mme_bearer_pool, ogs_app()->pool.bearer); - ogs_pool_init(&self.m_tmsi, ogs_app()->max.ue*2); + ogs_pool_init(&m_tmsi_pool, ogs_app()->max.ue*2); + ogs_pool_random_id_generate(&m_tmsi_pool); self.enb_addr_hash = ogs_hash_make(); ogs_assert(self.enb_addr_hash); @@ -114,6 +121,8 @@ void mme_context_init(void) ogs_assert(self.imsi_ue_hash); self.guti_ue_hash = ogs_hash_make(); ogs_assert(self.guti_ue_hash); + self.mme_s11_teid_hash = ogs_hash_make(); + ogs_assert(self.mme_s11_teid_hash); ogs_list_init(&self.mme_ue_list); @@ -141,11 +150,14 @@ void mme_context_final(void) ogs_hash_destroy(self.imsi_ue_hash); ogs_assert(self.guti_ue_hash); ogs_hash_destroy(self.guti_ue_hash); + ogs_assert(self.mme_s11_teid_hash); + ogs_hash_destroy(self.mme_s11_teid_hash); - ogs_pool_final(&self.m_tmsi); + ogs_pool_final(&m_tmsi_pool); ogs_pool_final(&mme_bearer_pool); ogs_pool_final(&mme_sess_pool); ogs_pool_final(&mme_ue_pool); + ogs_pool_final(&mme_s11_teid_pool); ogs_pool_final(&enb_ue_pool); ogs_pool_final(&sgw_ue_pool); @@ -2327,11 +2339,6 @@ void sgw_ue_switch_to_sgw(sgw_ue_t *sgw_ue, mme_sgw_t *new_sgw) sgw_ue->sgw = new_sgw; } -sgw_ue_t *sgw_ue_find(uint32_t index) -{ - return ogs_pool_find(&sgw_ue_pool, index); -} - sgw_ue_t *sgw_ue_cycle(sgw_ue_t *sgw_ue) { return ogs_pool_cycle(&sgw_ue_pool, sgw_ue); @@ -2564,9 +2571,14 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue) ogs_list_init(&mme_ue->sess_list); - mme_ue->mme_s11_teid = ogs_pool_index(&mme_ue_pool, mme_ue); - ogs_assert(mme_ue->mme_s11_teid > 0 && - mme_ue->mme_s11_teid <= ogs_app()->max.ue); + /* Set MME-S11_TEID */ + ogs_pool_alloc(&mme_s11_teid_pool, &mme_ue->mme_s11_teid_node); + ogs_assert(mme_ue->mme_s11_teid_node); + + mme_ue->mme_s11_teid = *(mme_ue->mme_s11_teid_node); + + ogs_hash_set(self.mme_s11_teid_hash, + &mme_ue->mme_s11_teid, sizeof(mme_ue->mme_s11_teid), mme_ue); /* * When used for the first time, if last node is set, @@ -2609,6 +2621,9 @@ void mme_ue_remove(mme_ue_t *mme_ue) mme_ue_fsm_fini(mme_ue); + ogs_hash_set(self.mme_s11_teid_hash, + &mme_ue->mme_s11_teid, sizeof(mme_ue->mme_s11_teid), NULL); + ogs_assert(mme_ue->sgw_ue); sgw_ue_remove(mme_ue->sgw_ue); @@ -2654,6 +2669,7 @@ void mme_ue_remove(mme_ue_t *mme_ue) mme_ebi_pool_final(mme_ue); + ogs_pool_free(&mme_s11_teid_pool, mme_ue->mme_s11_teid_node); ogs_pool_free(&mme_ue_pool, mme_ue); ogs_info("[Removed] Number of MME-UEs is now %d", @@ -2729,7 +2745,7 @@ mme_ue_t *mme_ue_find_by_guti(ogs_nas_eps_guti_t *guti) mme_ue_t *mme_ue_find_by_teid(uint32_t teid) { - return ogs_pool_find(&mme_ue_pool, teid); + return ogs_hash_get(self.mme_s11_teid_hash, &teid, sizeof(teid)); } mme_ue_t *mme_ue_find_by_message(ogs_nas_eps_message_t *message) @@ -3743,6 +3759,7 @@ int mme_find_served_tai(ogs_eps_tai_t *tai) return -1; } +#if 0 /* DEPRECATED */ int mme_m_tmsi_pool_generate(void) { int j; @@ -3753,7 +3770,7 @@ int mme_m_tmsi_pool_generate(void) mme_m_tmsi_t *m_tmsi = NULL; int conflict = 0; - m_tmsi = &self.m_tmsi.array[index]; + m_tmsi = &m_tmsi_pool.array[index]; ogs_assert(m_tmsi); *m_tmsi = ogs_random32(); @@ -3762,10 +3779,10 @@ int mme_m_tmsi_pool_generate(void) *m_tmsi &= 0xff00ffff; for (j = 0; j < index; j++) { - if (*m_tmsi == self.m_tmsi.array[j]) { + if (*m_tmsi == m_tmsi_pool.array[j]) { conflict = 1; ogs_trace("[M-TMSI CONFLICT] %d:0x%x == %d:0x%x", - index, *m_tmsi, j, self.m_tmsi.array[j]); + index, *m_tmsi, j, m_tmsi_pool.array[j]); break; } } @@ -3775,26 +3792,48 @@ int mme_m_tmsi_pool_generate(void) index++; } - self.m_tmsi.size = index; + m_tmsi_pool.size = index; ogs_trace("M-TMSI Pool generate...done"); return OGS_OK; } +#endif mme_m_tmsi_t *mme_m_tmsi_alloc(void) { mme_m_tmsi_t *m_tmsi = NULL; - ogs_pool_alloc(&self.m_tmsi, &m_tmsi); + ogs_pool_alloc(&m_tmsi_pool, &m_tmsi); ogs_assert(m_tmsi); + /* TS23.003 + * 2.8.2.1.2 Mapping in the UE + * + * E-UTRAN maps as follows: + * - 6 bits of the E-UTRAN starting at bit 29 and down to bit 24 + * are mapped into bit 29 and down to bit 24 of the GERAN/UTRAN ; + * - 16 bits of the E-UTRAN starting at bit 15 and down to bit 0 + * are mapped into bit 15 and down to bit 0 of the GERAN/UTRAN ; + * - and the remaining 8 bits of the E-UTRAN are + * mapped into the 8 Most Significant Bits of the field. + * + * The UE shall fill the remaining 2 octets of the + * according to clauses 9.1.1, 9.4.1, 10.2.1, or 10.5.1 + * of 3GPP TS.33.401 [89] , as appropriate, for RAU/Attach procedures + */ + + ogs_assert(*m_tmsi <= 0x003fffff); + + *m_tmsi = ((*m_tmsi & 0xffff) | ((*m_tmsi & 0x003f0000) << 8)); + *m_tmsi |= 0xc0000000; + return m_tmsi; } int mme_m_tmsi_free(mme_m_tmsi_t *m_tmsi) { ogs_assert(m_tmsi); - ogs_pool_free(&self.m_tmsi, m_tmsi); + ogs_pool_free(&m_tmsi_pool, m_tmsi); return OGS_OK; } @@ -3805,7 +3844,7 @@ void mme_ebi_pool_init(mme_ue_t *mme_ue) ogs_assert(mme_ue); - ogs_index_init(&mme_ue->ebi_pool, MAX_EPS_BEARER_ID-MIN_EPS_BEARER_ID+1); + ogs_pool_init(&mme_ue->ebi_pool, MAX_EPS_BEARER_ID-MIN_EPS_BEARER_ID+1); for (i = MIN_EPS_BEARER_ID, index = 0; i <= MAX_EPS_BEARER_ID; i++, index++) { @@ -3817,17 +3856,17 @@ void mme_ebi_pool_final(mme_ue_t *mme_ue) { ogs_assert(mme_ue); - ogs_index_final(&mme_ue->ebi_pool); + ogs_pool_final(&mme_ue->ebi_pool); } void mme_ebi_pool_clear(mme_ue_t *mme_ue) { ogs_assert(mme_ue); - ogs_free(mme_ue->ebi_pool.free); - ogs_free(mme_ue->ebi_pool.array); - ogs_free(mme_ue->ebi_pool.index); + /* Suppress log message (mme_ue->ebi_pool.avail != mme_ue->ebi_pool.size) */ + mme_ue->ebi_pool.avail = mme_ue->ebi_pool.size; + mme_ebi_pool_final(mme_ue); mme_ebi_pool_init(mme_ue); } diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index 9c705939f..6e44c0ba9 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -145,15 +145,14 @@ typedef struct mme_context_s { /* Generator for unique identification */ uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */ - /* M-TMSI Pool */ - OGS_POOL(m_tmsi, mme_m_tmsi_t); - ogs_list_t mme_ue_list; - ogs_hash_t *enb_addr_hash; /* hash table for ENB Address */ - ogs_hash_t *enb_id_hash; /* hash table for ENB-ID */ - ogs_hash_t *imsi_ue_hash; /* hash table (IMSI : MME_UE) */ - ogs_hash_t *guti_ue_hash; /* hash table (GUTI : MME_UE) */ + ogs_hash_t *enb_addr_hash; /* hash table for ENB Address */ + ogs_hash_t *enb_id_hash; /* hash table for ENB-ID */ + ogs_hash_t *imsi_ue_hash; /* hash table (IMSI : MME_UE) */ + ogs_hash_t *guti_ue_hash; /* hash table (GUTI : MME_UE) */ + + ogs_hash_t *mme_s11_teid_hash; /* hash table (MME-S11-TEID : MME_UE) */ struct { struct { @@ -286,7 +285,6 @@ struct enb_ue_s { struct sgw_ue_s { ogs_lnode_t lnode; - uint32_t index; sgw_ue_t *source_ue; sgw_ue_t *target_ue; @@ -371,7 +369,8 @@ struct mme_ue_s { ogs_nas_eps_guti_t guti; } current, next; - uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */ + ogs_pool_id_t *mme_s11_teid_node; /* A node of MME-S11-TEID */ + uint32_t mme_s11_teid; /* MME-S11-TEID is derived from NODE */ uint16_t vlr_ostream_id; /* SCTP output stream id for VLR */ @@ -685,7 +684,6 @@ typedef struct mme_bearer_s { ogs_lnode_t lnode; ogs_lnode_t to_modify_node; - uint32_t index; ogs_fsm_t sm; /* State Machine */ uint8_t *ebi_node; /* Pool-Node for EPS Bearer ID */ @@ -794,7 +792,6 @@ enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue); sgw_ue_t *sgw_ue_add(mme_sgw_t *sgw); void sgw_ue_remove(sgw_ue_t *sgw_ue); void sgw_ue_switch_to_sgw(sgw_ue_t *sgw_ue, mme_sgw_t *new_sgw); -sgw_ue_t *sgw_ue_find(uint32_t index); sgw_ue_t *sgw_ue_cycle(sgw_ue_t *sgw_ue); typedef enum { @@ -923,7 +920,6 @@ ogs_session_t *mme_default_session(mme_ue_t *mme_ue); int mme_find_served_tai(ogs_eps_tai_t *tai); -int mme_m_tmsi_pool_generate(void); mme_m_tmsi_t *mme_m_tmsi_alloc(void); int mme_m_tmsi_free(mme_m_tmsi_t *tmsi); diff --git a/src/mme/mme-init.c b/src/mme/mme-init.c index 72adbf9cf..3c2571a28 100644 --- a/src/mme/mme-init.c +++ b/src/mme/mme-init.c @@ -61,9 +61,6 @@ int mme_initialize(void) ogs_app()->logger.domain, ogs_app()->logger.level); if (rv != OGS_OK) return rv; - rv = mme_m_tmsi_pool_generate(); - if (rv != OGS_OK) return rv; - ogs_metrics_context_open(ogs_metrics_self()); rv = mme_fd_init(); diff --git a/src/sgwc/context.c b/src/sgwc/context.c index 079a6a0ab..95e77a8b9 100644 --- a/src/sgwc/context.c +++ b/src/sgwc/context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -25,11 +25,15 @@ static sgwc_context_t self; int __sgwc_log_domain; -static OGS_POOL(sgwc_ue_pool, sgwc_ue_t); -static OGS_POOL(sgwc_sess_pool, sgwc_sess_t); static OGS_POOL(sgwc_bearer_pool, sgwc_bearer_t); static OGS_POOL(sgwc_tunnel_pool, sgwc_tunnel_t); +static OGS_POOL(sgwc_ue_pool, sgwc_ue_t); +static OGS_POOL(sgwc_s11_teid_pool, ogs_pool_id_t); + +static OGS_POOL(sgwc_sess_pool, sgwc_sess_t); +static OGS_POOL(sgwc_sxa_seid_pool, ogs_pool_id_t); + static int context_initialized = 0; static int num_of_sgwc_sess = 0; @@ -45,13 +49,23 @@ void sgwc_context_init(void) ogs_log_install_domain(&__sgwc_log_domain, "sgwc", ogs_core()->log.level); - ogs_pool_init(&sgwc_ue_pool, ogs_app()->max.ue); - ogs_pool_init(&sgwc_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&sgwc_bearer_pool, ogs_app()->pool.bearer); ogs_pool_init(&sgwc_tunnel_pool, ogs_app()->pool.tunnel); + ogs_pool_init(&sgwc_ue_pool, ogs_app()->max.ue); + ogs_pool_init(&sgwc_s11_teid_pool, ogs_app()->max.ue); + ogs_pool_random_id_generate(&sgwc_s11_teid_pool); + + ogs_pool_init(&sgwc_sess_pool, ogs_app()->pool.sess); + ogs_pool_init(&sgwc_sxa_seid_pool, ogs_app()->pool.sess); + ogs_pool_random_id_generate(&sgwc_sxa_seid_pool); + self.imsi_ue_hash = ogs_hash_make(); ogs_assert(self.imsi_ue_hash); + self.sgw_s11_teid_hash = ogs_hash_make(); + ogs_assert(self.sgw_s11_teid_hash); + self.sgwc_sxa_seid_hash = ogs_hash_make(); + ogs_assert(self.sgwc_sxa_seid_hash); ogs_list_init(&self.sgw_ue_list); @@ -66,11 +80,19 @@ void sgwc_context_final(void) ogs_assert(self.imsi_ue_hash); ogs_hash_destroy(self.imsi_ue_hash); + ogs_assert(self.sgw_s11_teid_hash); + ogs_hash_destroy(self.sgw_s11_teid_hash); + ogs_assert(self.sgwc_sxa_seid_hash); + ogs_hash_destroy(self.sgwc_sxa_seid_hash); ogs_pool_final(&sgwc_tunnel_pool); ogs_pool_final(&sgwc_bearer_pool); - ogs_pool_final(&sgwc_sess_pool); + ogs_pool_final(&sgwc_ue_pool); + ogs_pool_final(&sgwc_s11_teid_pool); + + ogs_pool_final(&sgwc_sess_pool); + ogs_pool_final(&sgwc_sxa_seid_pool); ogs_gtp_node_remove_all(&self.mme_s11_list); ogs_gtp_node_remove_all(&self.pgw_s5c_list); @@ -192,9 +214,14 @@ sgwc_ue_t *sgwc_ue_add(uint8_t *imsi, int imsi_len) ogs_assert(sgwc_ue); memset(sgwc_ue, 0, sizeof *sgwc_ue); - sgwc_ue->sgw_s11_teid = ogs_pool_index(&sgwc_ue_pool, sgwc_ue); - ogs_assert(sgwc_ue->sgw_s11_teid > 0 && - sgwc_ue->sgw_s11_teid <= ogs_app()->max.ue); + /* Set SGW-S11-TEID */ + ogs_pool_alloc(&sgwc_s11_teid_pool, &sgwc_ue->sgw_s11_teid_node); + ogs_assert(sgwc_ue->sgw_s11_teid_node); + + sgwc_ue->sgw_s11_teid = *(sgwc_ue->sgw_s11_teid_node); + + ogs_hash_set(self.sgw_s11_teid_hash, + &sgwc_ue->sgw_s11_teid, sizeof(sgwc_ue->sgw_s11_teid), sgwc_ue); /* Set IMSI */ sgwc_ue->imsi_len = imsi_len; @@ -219,10 +246,13 @@ int sgwc_ue_remove(sgwc_ue_t *sgwc_ue) ogs_list_remove(&self.sgw_ue_list, sgwc_ue); + ogs_hash_set(self.sgw_s11_teid_hash, + &sgwc_ue->sgw_s11_teid, sizeof(sgwc_ue->sgw_s11_teid), NULL); ogs_hash_set(self.imsi_ue_hash, sgwc_ue->imsi, sgwc_ue->imsi_len, NULL); sgwc_sess_remove_all(sgwc_ue); + ogs_pool_free(&sgwc_s11_teid_pool, sgwc_ue->sgw_s11_teid_node); ogs_pool_free(&sgwc_ue_pool, sgwc_ue); ogs_info("[Removed] Number of SGWC-UEs is now %d", @@ -255,12 +285,12 @@ sgwc_ue_t *sgwc_ue_find_by_imsi(uint8_t *imsi, int imsi_len) { ogs_assert(imsi && imsi_len); - return (sgwc_ue_t *)ogs_hash_get(self.imsi_ue_hash, imsi, imsi_len); + return ogs_hash_get(self.imsi_ue_hash, imsi, imsi_len); } sgwc_ue_t *sgwc_ue_find_by_teid(uint32_t teid) { - return ogs_pool_find(&sgwc_ue_pool, teid); + return ogs_hash_get(self.sgw_s11_teid_hash, &teid, sizeof(teid)); } sgwc_sess_t *sgwc_sess_add(sgwc_ue_t *sgwc_ue, char *apn) @@ -279,12 +309,15 @@ sgwc_sess_t *sgwc_sess_add(sgwc_ue_t *sgwc_ue, char *apn) ogs_pfcp_pool_init(&sess->pfcp); - sess->index = ogs_pool_index(&sgwc_sess_pool, sess); - ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); - /* Set TEID & SEID */ - sess->sgw_s5c_teid = sess->index; - sess->sgwc_sxa_seid = sess->index; + ogs_pool_alloc(&sgwc_sxa_seid_pool, &sess->sgwc_sxa_seid_node); + ogs_assert(sess->sgwc_sxa_seid_node); + + sess->sgw_s5c_teid = *(sess->sgwc_sxa_seid_node); + sess->sgwc_sxa_seid = *(sess->sgwc_sxa_seid_node); + + ogs_hash_set(self.sgwc_sxa_seid_hash, + &sess->sgwc_sxa_seid, sizeof(sess->sgwc_sxa_seid), sess); /* Create BAR in PFCP Session */ ogs_pfcp_bar_new(&sess->pfcp); @@ -400,6 +433,9 @@ int sgwc_sess_remove(sgwc_sess_t *sess) ogs_list_remove(&sgwc_ue->sess_list, sess); + ogs_hash_set(self.sgwc_sxa_seid_hash, &sess->sgwc_sxa_seid, + sizeof(sess->sgwc_sxa_seid), NULL); + sgwc_bearer_remove_all(sess); ogs_assert(sess->pfcp.bar); @@ -410,6 +446,7 @@ int sgwc_sess_remove(sgwc_sess_t *sess) ogs_assert(sess->session.name); ogs_free(sess->session.name); + ogs_pool_free(&sgwc_sxa_seid_pool, sess->sgwc_sxa_seid_node); ogs_pool_free(&sgwc_sess_pool, sess); stats_remove_sgwc_session(); @@ -426,19 +463,14 @@ void sgwc_sess_remove_all(sgwc_ue_t *sgwc_ue) sgwc_sess_remove(sess); } -sgwc_sess_t *sgwc_sess_find(uint32_t index) -{ - return ogs_pool_find(&sgwc_sess_pool, index); -} - sgwc_sess_t* sgwc_sess_find_by_teid(uint32_t teid) { - return ogs_pool_find(&sgwc_sess_pool, teid); + return sgwc_sess_find_by_seid(teid); } sgwc_sess_t *sgwc_sess_find_by_seid(uint64_t seid) { - return sgwc_sess_find(seid); + return ogs_hash_get(self.sgwc_sxa_seid_hash, &seid, sizeof(seid)); } sgwc_sess_t* sgwc_sess_find_by_apn(sgwc_ue_t *sgwc_ue, char *apn) @@ -697,8 +729,6 @@ sgwc_tunnel_t *sgwc_tunnel_add( memset(tunnel, 0, sizeof *tunnel); tunnel->interface_type = interface_type; - tunnel->index = ogs_pool_index(&sgwc_tunnel_pool, tunnel); - ogs_assert(tunnel->index > 0 && tunnel->index <= ogs_app()->pool.tunnel); pdr = ogs_pfcp_pdr_add(&sess->pfcp); ogs_assert(pdr); @@ -753,10 +783,10 @@ sgwc_tunnel_t *sgwc_tunnel_add( &tunnel->local_addr, &tunnel->local_addr6); if (resource->info.teidri) tunnel->local_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - pdr->index, resource->info.teidri, + pdr->teid, resource->info.teidri, resource->info.teid_range); else - tunnel->local_teid = pdr->index; + tunnel->local_teid = pdr->teid; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -769,7 +799,7 @@ sgwc_tunnel_t *sgwc_tunnel_add( else ogs_assert_if_reached(); - tunnel->local_teid = pdr->index; + tunnel->local_teid = pdr->teid; } ogs_assert(OGS_OK == diff --git a/src/sgwc/context.h b/src/sgwc/context.h index efa3a6461..59eecea9b 100644 --- a/src/sgwc/context.h +++ b/src/sgwc/context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -39,18 +39,21 @@ extern int __sgwc_log_domain; typedef struct sgwc_tunnel_s sgwc_tunnel_t; typedef struct sgwc_context_s { - ogs_list_t mme_s11_list; /* MME GTPC Node List */ - ogs_list_t pgw_s5c_list; /* PGW GTPC Node List */ + ogs_list_t mme_s11_list; /* MME GTPC Node List */ + ogs_list_t pgw_s5c_list; /* PGW GTPC Node List */ - ogs_hash_t *imsi_ue_hash; /* hash table (IMSI : SGW_UE) */ + ogs_hash_t *imsi_ue_hash; /* hash table (IMSI : SGW_UE) */ + ogs_hash_t *sgw_s11_teid_hash; /* hash table (SGW-S11-TEID : SGW_UE) */ + ogs_hash_t *sgwc_sxa_seid_hash; /* hash table (SGWC-SXA-SEID : Session) */ - ogs_list_t sgw_ue_list; /* SGW_UE List */ + ogs_list_t sgw_ue_list; /* SGW_UE List */ } sgwc_context_t; typedef struct sgwc_ue_s { ogs_lnode_t lnode; + ogs_pool_id_t *sgw_s11_teid_node; /* A node of SGW-S11-TEID */ - uint32_t sgw_s11_teid; /* SGW-S11-TEID is derived from INDEX */ + uint32_t sgw_s11_teid; /* SGW-S11-TEID is derived from NODE */ uint32_t mme_s11_teid; /* MME-S11-TEID is received from MME */ /* UE identity */ @@ -70,15 +73,15 @@ typedef struct sgwc_ue_s { #define SGWC_SESS(pfcp_sess) ogs_container_of(pfcp_sess, sgwc_sess_t, pfcp) typedef struct sgwc_sess_s { - ogs_lnode_t lnode; /* A node of list_t */ - uint32_t index; /**< An index of this node */ + ogs_lnode_t lnode; /* A node of list_t */ + ogs_pool_id_t *sgwc_sxa_seid_node; /* A node of SGWC-SXA-SEID */ ogs_pfcp_sess_t pfcp; /* PFCP session context */ - uint32_t sgw_s5c_teid; /* SGW-S5C-TEID is derived from INDEX */ + uint32_t sgw_s5c_teid; /* SGW-S5C-TEID is derived from NODE */ uint32_t pgw_s5c_teid; /* PGW-S5C-TEID is received from PGW */ - uint64_t sgwc_sxa_seid; /* SGW-C SEID is dervied from INDEX */ + uint64_t sgwc_sxa_seid; /* SGW-C SEID is dervied from NODE */ uint64_t sgwu_sxa_seid; /* SGW-U SEID is received from Peer */ /* APN Configuration */ @@ -106,7 +109,6 @@ typedef struct sgwc_bearer_s { typedef struct sgwc_tunnel_s { ogs_lnode_t lnode; - uint32_t index; /**< An index of this node */ uint8_t interface_type; @@ -147,7 +149,6 @@ void sgwc_sess_select_sgwu(sgwc_sess_t *sess); int sgwc_sess_remove(sgwc_sess_t *sess); void sgwc_sess_remove_all(sgwc_ue_t *sgwc_ue); -sgwc_sess_t *sgwc_sess_find(uint32_t index); sgwc_sess_t *sgwc_sess_find_by_teid(uint32_t teid); sgwc_sess_t *sgwc_sess_find_by_seid(uint64_t seid); diff --git a/src/sgwu/context.c b/src/sgwu/context.c index 2f1fd4a60..27a5dbdb8 100644 --- a/src/sgwu/context.c +++ b/src/sgwu/context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -24,6 +24,7 @@ static sgwu_context_t self; int __sgwu_log_domain; static OGS_POOL(sgwu_sess_pool, sgwu_sess_t); +static OGS_POOL(sgwu_sxa_seid_pool, ogs_pool_id_t); static int context_initialized = 0; @@ -43,11 +44,15 @@ void sgwu_context_init(void) ogs_list_init(&self.sess_list); ogs_pool_init(&sgwu_sess_pool, ogs_app()->pool.sess); + ogs_pool_init(&sgwu_sxa_seid_pool, ogs_app()->pool.sess); + ogs_pool_random_id_generate(&sgwu_sxa_seid_pool); - self.seid_hash = ogs_hash_make(); - ogs_assert(self.seid_hash); - self.f_seid_hash = ogs_hash_make(); - ogs_assert(self.f_seid_hash); + self.sgwu_sxa_seid_hash = ogs_hash_make(); + ogs_assert(self.sgwu_sxa_seid_hash); + self.sgwc_sxa_seid_hash = ogs_hash_make(); + ogs_assert(self.sgwc_sxa_seid_hash); + self.sgwc_sxa_f_seid_hash = ogs_hash_make(); + ogs_assert(self.sgwc_sxa_f_seid_hash); context_initialized = 1; } @@ -58,12 +63,15 @@ void sgwu_context_final(void) sgwu_sess_remove_all(); - ogs_assert(self.seid_hash); - ogs_hash_destroy(self.seid_hash); - ogs_assert(self.f_seid_hash); - ogs_hash_destroy(self.f_seid_hash); + ogs_assert(self.sgwu_sxa_seid_hash); + ogs_hash_destroy(self.sgwu_sxa_seid_hash); + ogs_assert(self.sgwc_sxa_seid_hash); + ogs_hash_destroy(self.sgwc_sxa_seid_hash); + ogs_assert(self.sgwc_sxa_f_seid_hash); + ogs_hash_destroy(self.sgwc_sxa_f_seid_hash); ogs_pool_final(&sgwu_sess_pool); + ogs_pool_final(&sgwu_sxa_seid_pool); context_initialized = 0; } @@ -137,10 +145,14 @@ sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *cp_f_seid) ogs_pfcp_pool_init(&sess->pfcp); - sess->index = ogs_pool_index(&sgwu_sess_pool, sess); - ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); + /* Set SEID */ + ogs_pool_alloc(&sgwu_sxa_seid_pool, &sess->sgwu_sxa_seid_node); + ogs_assert(sess->sgwu_sxa_seid_node); - sess->sgwu_sxa_seid = sess->index; + sess->sgwu_sxa_seid = *(sess->sgwu_sxa_seid_node); + + ogs_hash_set(self.sgwu_sxa_seid_hash, &sess->sgwu_sxa_seid, + sizeof(sess->sgwu_sxa_seid), sess); /* Since F-SEID is composed of ogs_ip_t and uint64-seid, * all these values must be put into the structure-sgwc_sxa_f_eid @@ -149,9 +161,9 @@ sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *cp_f_seid) ogs_assert(OGS_OK == ogs_pfcp_f_seid_to_ip(cp_f_seid, &sess->sgwc_sxa_f_seid.ip)); - ogs_hash_set(self.f_seid_hash, &sess->sgwc_sxa_f_seid, + ogs_hash_set(self.sgwc_sxa_f_seid_hash, &sess->sgwc_sxa_f_seid, sizeof(sess->sgwc_sxa_f_seid), sess); - ogs_hash_set(self.seid_hash, &sess->sgwc_sxa_f_seid.seid, + ogs_hash_set(self.sgwc_sxa_seid_hash, &sess->sgwc_sxa_f_seid.seid, sizeof(sess->sgwc_sxa_f_seid.seid), sess); ogs_info("UE F-SEID[UP:0x%lx CP:0x%lx]", @@ -172,13 +184,17 @@ int sgwu_sess_remove(sgwu_sess_t *sess) ogs_list_remove(&self.sess_list, sess); ogs_pfcp_sess_clear(&sess->pfcp); - ogs_hash_set(self.seid_hash, &sess->sgwc_sxa_f_seid.seid, + ogs_hash_set(self.sgwu_sxa_seid_hash, &sess->sgwu_sxa_seid, + sizeof(sess->sgwu_sxa_seid), NULL); + + ogs_hash_set(self.sgwc_sxa_seid_hash, &sess->sgwc_sxa_f_seid.seid, sizeof(sess->sgwc_sxa_f_seid.seid), NULL); - ogs_hash_set(self.f_seid_hash, &sess->sgwc_sxa_f_seid, + ogs_hash_set(self.sgwc_sxa_f_seid_hash, &sess->sgwc_sxa_f_seid, sizeof(sess->sgwc_sxa_f_seid), NULL); ogs_pfcp_pool_final(&sess->pfcp); + ogs_pool_free(&sgwu_sxa_seid_pool, sess->sgwu_sxa_seid_node); ogs_pool_free(&sgwu_sess_pool, sess); ogs_info("[Removed] Number of SGWU-sessions is now %d", @@ -196,14 +212,9 @@ void sgwu_sess_remove_all(void) } } -sgwu_sess_t *sgwu_sess_find(uint32_t index) -{ - return ogs_pool_find(&sgwu_sess_pool, index); -} - sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_seid(uint64_t seid) { - return (sgwu_sess_t *)ogs_hash_get(self.seid_hash, &seid, sizeof(seid)); + return ogs_hash_get(self.sgwc_sxa_seid_hash, &seid, sizeof(seid)); } sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_f_seid(ogs_pfcp_f_seid_t *f_seid) @@ -217,12 +228,12 @@ sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_f_seid(ogs_pfcp_f_seid_t *f_seid) ogs_assert(OGS_OK == ogs_pfcp_f_seid_to_ip(f_seid, &key.ip)); key.seid = f_seid->seid; - return (sgwu_sess_t *)ogs_hash_get(self.f_seid_hash, &key, sizeof(key)); + return ogs_hash_get(self.sgwc_sxa_f_seid_hash, &key, sizeof(key)); } sgwu_sess_t *sgwu_sess_find_by_sgwu_sxa_seid(uint64_t seid) { - return sgwu_sess_find(seid); + return ogs_hash_get(self.sgwu_sxa_seid_hash, &seid, sizeof(seid)); } sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message) diff --git a/src/sgwu/context.h b/src/sgwu/context.h index 723adc71b..81928498b 100644 --- a/src/sgwu/context.h +++ b/src/sgwu/context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -37,16 +37,17 @@ extern int __sgwu_log_domain; #define OGS_LOG_DOMAIN __sgwu_log_domain typedef struct sgwu_context_s { - ogs_hash_t *seid_hash; /* hash table (SEID) */ - ogs_hash_t *f_seid_hash; /* hash table (F-SEID) */ + ogs_hash_t *sgwu_sxa_seid_hash; /* hash table (SGWU-SXA-SEID) */ + ogs_hash_t *sgwc_sxa_seid_hash; /* hash table (SGWC-SXA-SEID) */ + ogs_hash_t *sgwc_sxa_f_seid_hash; /* hash table (SGWC-SXA-F-SEID) */ - ogs_list_t sess_list; + ogs_list_t sess_list; } sgwu_context_t; #define SGWU_SESS(pfcp_sess) ogs_container_of(pfcp_sess, sgwu_sess_t, pfcp) typedef struct sgwu_sess_s { ogs_lnode_t lnode; - uint32_t index; /**< An index of this node */ + ogs_pool_id_t *sgwu_sxa_seid_node; /* A node of SGWU-SXA-SEID */ ogs_pfcp_sess_t pfcp; @@ -70,7 +71,6 @@ sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message); sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *f_seid); int sgwu_sess_remove(sgwu_sess_t *sess); void sgwu_sess_remove_all(void); -sgwu_sess_t *sgwu_sess_find(uint32_t index); sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_seid(uint64_t seid); sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_f_seid(ogs_pfcp_f_seid_t *f_seid); sgwu_sess_t *sgwu_sess_find_by_sgwu_sxa_seid(uint64_t seid); diff --git a/src/sgwu/gtp-path.c b/src/sgwu/gtp-path.c index 91484bef9..91c5a6f5b 100644 --- a/src/sgwu/gtp-path.c +++ b/src/sgwu/gtp-path.c @@ -266,7 +266,7 @@ int sgwu_gtp_init(void) config.cluster_2048_pool = ogs_app()->pool.packet; -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 /* allocate a talloc pool for GTP to ensure it doesn't have to go back * to the libc malloc all the time */ packet_pool = talloc_pool(__ogs_talloc_core, 1000*1024); diff --git a/src/sgwu/sxa-handler.c b/src/sgwu/sxa-handler.c index b000626d6..b4d7f795f 100644 --- a/src/sgwu/sxa-handler.c +++ b/src/sgwu/sxa-handler.c @@ -128,10 +128,10 @@ void sgwu_sxa_handle_session_establishment_request( &resource->info, &pdr->f_teid, &pdr->f_teid_len)); if (resource->info.teidri) pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - pdr->index, resource->info.teidri, + pdr->teid, resource->info.teidri, resource->info.teid_range); else - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } else { ogs_assert( (ogs_gtp_self()->gtpu_addr && pdr->f_teid.ipv4) || @@ -143,7 +143,7 @@ void sgwu_sxa_handle_session_establishment_request( pdr->f_teid.ipv6 ? ogs_gtp_self()->gtpu_addr6 : NULL, &pdr->f_teid, &pdr->f_teid_len)); - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } } } @@ -343,10 +343,10 @@ void sgwu_sxa_handle_session_modification_request( &resource->info, &pdr->f_teid, &pdr->f_teid_len)); if (resource->info.teidri) pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - pdr->index, resource->info.teidri, + pdr->teid, resource->info.teidri, resource->info.teid_range); else - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } else { ogs_assert( (ogs_gtp_self()->gtpu_addr && pdr->f_teid.ipv4) || @@ -358,7 +358,7 @@ void sgwu_sxa_handle_session_modification_request( pdr->f_teid.ipv6 ? ogs_gtp_self()->gtpu_addr6 : NULL, &pdr->f_teid, &pdr->f_teid_len)); - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } } } diff --git a/src/smf/binding.c b/src/smf/binding.c index 7a27fb52d..bd254b903 100644 --- a/src/smf/binding.c +++ b/src/smf/binding.c @@ -197,10 +197,10 @@ void smf_bearer_binding(smf_sess_t *sess) &bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6); if (resource->info.teidri) bearer->pgw_s5u_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - ul_pdr->index, resource->info.teidri, + ul_pdr->teid, resource->info.teidri, resource->info.teid_range); else - bearer->pgw_s5u_teid = ul_pdr->index; + bearer->pgw_s5u_teid = ul_pdr->teid; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -214,7 +214,7 @@ void smf_bearer_binding(smf_sess_t *sess) else ogs_assert_if_reached(); - bearer->pgw_s5u_teid = ul_pdr->index; + bearer->pgw_s5u_teid = ul_pdr->teid; } ogs_assert(OGS_OK == diff --git a/src/smf/context.c b/src/smf/context.c index f4a9b6a75..eb5cf4fde 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -29,11 +29,12 @@ int __gsm_log_domain; static OGS_POOL(smf_gtp_node_pool, smf_gtp_node_t); static OGS_POOL(smf_ue_pool, smf_ue_t); -static OGS_POOL(smf_sess_pool, smf_sess_t); static OGS_POOL(smf_bearer_pool, smf_bearer_t); - static OGS_POOL(smf_pf_pool, smf_pf_t); +static OGS_POOL(smf_sess_pool, smf_sess_t); +static OGS_POOL(smf_n4_seid_pool, ogs_pool_id_t); + static int context_initialized = 0; static int num_of_smf_sess = 0; @@ -82,16 +83,20 @@ void smf_context_init(void) ogs_pool_init(&smf_gtp_node_pool, ogs_app()->pool.nf); ogs_pool_init(&smf_ue_pool, ogs_app()->max.ue); - ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer); - ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * OGS_MAX_NUM_OF_FLOW_IN_BEARER); + ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess); + ogs_pool_init(&smf_n4_seid_pool, ogs_app()->pool.sess); + ogs_pool_random_id_generate(&smf_n4_seid_pool); + self.supi_hash = ogs_hash_make(); ogs_assert(self.supi_hash); self.imsi_hash = ogs_hash_make(); ogs_assert(self.imsi_hash); + self.smf_n4_seid_hash = ogs_hash_make(); + ogs_assert(self.smf_n4_seid_hash); self.ipv4_hash = ogs_hash_make(); ogs_assert(self.ipv4_hash); self.ipv6_hash = ogs_hash_make(); @@ -99,7 +104,6 @@ void smf_context_init(void) self.n1n2message_hash = ogs_hash_make(); ogs_assert(self.n1n2message_hash); - context_initialized = 1; } @@ -114,6 +118,8 @@ void smf_context_final(void) ogs_hash_destroy(self.supi_hash); ogs_assert(self.imsi_hash); ogs_hash_destroy(self.imsi_hash); + ogs_assert(self.smf_n4_seid_hash); + ogs_hash_destroy(self.smf_n4_seid_hash); ogs_assert(self.ipv4_hash); ogs_hash_destroy(self.ipv4_hash); ogs_assert(self.ipv6_hash); @@ -123,10 +129,11 @@ void smf_context_final(void) ogs_pool_final(&smf_ue_pool); ogs_pool_final(&smf_bearer_pool); - ogs_pool_final(&smf_sess_pool); - ogs_pool_final(&smf_pf_pool); + ogs_pool_final(&smf_sess_pool); + ogs_pool_final(&smf_n4_seid_pool); + ogs_list_for_each_entry_safe(&self.sgw_s5c_list, next_gnode, gnode, node) { smf_gtp_node_t *smf_gnode = gnode->data_ptr; ogs_assert(smf_gnode); @@ -1198,8 +1205,14 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type) ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); /* Set TEID & SEID */ - sess->smf_n4_teid = sess->index; - sess->smf_n4_seid = sess->index; + ogs_pool_alloc(&smf_n4_seid_pool, &sess->smf_n4_seid_node); + ogs_assert(sess->smf_n4_seid_node); + + sess->smf_n4_teid = *(sess->smf_n4_seid_node); + sess->smf_n4_seid = *(sess->smf_n4_seid_node); + + ogs_hash_set(self.smf_n4_seid_hash, &sess->smf_n4_seid, + sizeof(sess->smf_n4_seid), sess); /* Set Charging ID */ sess->charging.id = sess->index; @@ -1403,9 +1416,18 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi) sess->index = ogs_pool_index(&smf_sess_pool, sess); ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); + /* Set TEID & SEID */ + ogs_pool_alloc(&smf_n4_seid_pool, &sess->smf_n4_seid_node); + ogs_assert(sess->smf_n4_seid_node); + + sess->smf_n4_teid = *(sess->smf_n4_seid_node); + sess->smf_n4_seid = *(sess->smf_n4_seid_node); + + ogs_hash_set(self.smf_n4_seid_hash, &sess->smf_n4_seid, + sizeof(sess->smf_n4_seid), sess); + /* Set SmContextRef in 5GC */ - sess->sm_context_ref = ogs_msprintf("%d", - (int)ogs_pool_index(&smf_sess_pool, sess)); + sess->sm_context_ref = ogs_msprintf("%d", sess->index); ogs_assert(sess->sm_context_ref); /* Create BAR in PFCP Session */ @@ -1420,10 +1442,6 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi) sess->mapped_hplmn.sst = 0; sess->mapped_hplmn.sd.v = OGS_S_NSSAI_NO_SD_VALUE; - /* Set TEID & SEID */ - sess->smf_n4_teid = sess->index; - sess->smf_n4_seid = sess->index; - /* Set Charging Id */ sess->charging.id = sess->index; @@ -1722,6 +1740,9 @@ void smf_sess_remove(smf_sess_t *sess) OGS_PCC_RULE_FREE(&sess->policy.pcc_rule[i]); sess->policy.num_of_pcc_rule = 0; + ogs_hash_set(self.smf_n4_seid_hash, &sess->smf_n4_seid, + sizeof(sess->smf_n4_seid), NULL); + if (sess->ipv4) { ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, NULL); ogs_pfcp_ue_ip_free(sess->ipv4); @@ -1809,6 +1830,8 @@ void smf_sess_remove(smf_sess_t *sess) break; } stats_remove_smf_session(sess); + + ogs_pool_free(&smf_n4_seid_pool, sess->smf_n4_seid_node); ogs_pool_free(&smf_sess_pool, sess); } @@ -1822,19 +1845,14 @@ void smf_sess_remove_all(smf_ue_t *smf_ue) smf_sess_remove(sess); } -smf_sess_t *smf_sess_find(uint32_t index) -{ - return ogs_pool_find(&smf_sess_pool, index); -} - smf_sess_t *smf_sess_find_by_teid(uint32_t teid) { - return smf_sess_find(teid); + return smf_sess_find_by_seid(teid); } smf_sess_t *smf_sess_find_by_seid(uint64_t seid) { - return smf_sess_find(seid); + return ogs_hash_get(self.smf_n4_seid_hash, &seid, sizeof(seid)); } smf_sess_t *smf_sess_find_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type) @@ -1868,6 +1886,11 @@ smf_sess_t *smf_sess_find_by_psi(smf_ue_t *smf_ue, uint8_t psi) return NULL; } +smf_sess_t *smf_sess_find(uint32_t index) +{ + return ogs_pool_find(&smf_sess_pool, index); +} + smf_sess_t *smf_sess_find_by_charging_id(uint32_t charging_id) { ogs_assert(charging_id); @@ -1939,10 +1962,6 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess) smf_pf_identifier_pool_init(qos_flow); - qos_flow->index = ogs_pool_index(&smf_bearer_pool, qos_flow); - ogs_assert(qos_flow->index > 0 && qos_flow->index <= - ogs_app()->pool.bearer); - ogs_list_init(&qos_flow->pf_list); /* PDR */ @@ -2139,10 +2158,10 @@ void smf_sess_create_indirect_data_forwarding(smf_sess_t *sess) &sess->handover.upf_dl_addr, &sess->handover.upf_dl_addr6); if (resource->info.teidri) sess->handover.upf_dl_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - pdr->index, resource->info.teidri, + pdr->teid, resource->info.teidri, resource->info.teid_range); else - sess->handover.upf_dl_teid = pdr->index; + sess->handover.upf_dl_teid = pdr->teid; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == ogs_copyaddrinfo( @@ -2153,7 +2172,7 @@ void smf_sess_create_indirect_data_forwarding(smf_sess_t *sess) else ogs_assert_if_reached(); - sess->handover.upf_dl_teid = pdr->index; + sess->handover.upf_dl_teid = pdr->teid; } ogs_assert(OGS_OK == @@ -2370,10 +2389,6 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess) smf_pf_identifier_pool_init(bearer); - bearer->index = ogs_pool_index(&smf_bearer_pool, bearer); - ogs_assert(bearer->index > 0 && bearer->index <= - ogs_app()->pool.bearer); - ogs_list_init(&bearer->pf_list); /* PDR */ @@ -3033,64 +3048,48 @@ int smf_pco_build(uint8_t *pco_buf, uint8_t *buffer, int length) void smf_qfi_pool_init(smf_sess_t *sess) { - int i; - ogs_assert(sess); - ogs_index_init(&sess->qfi_pool, OGS_MAX_QOS_FLOW_ID); - - for (i = 1; i <= OGS_MAX_QOS_FLOW_ID; i++) { - sess->qfi_pool.array[i-1] = i; - } + ogs_pool_init(&sess->qfi_pool, OGS_MAX_QOS_FLOW_ID); + ogs_pool_sequence_id_generate(&sess->qfi_pool); } void smf_qfi_pool_final(smf_sess_t *sess) { ogs_assert(sess); - ogs_index_final(&sess->qfi_pool); + ogs_pool_final(&sess->qfi_pool); } void smf_pf_identifier_pool_init(smf_bearer_t *bearer) { - int i; - ogs_assert(bearer); - ogs_index_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_FLOW_IN_BEARER); - - for (i = 1; i <= OGS_MAX_NUM_OF_FLOW_IN_BEARER; i++) { - bearer->pf_identifier_pool.array[i-1] = i; - } + ogs_pool_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_FLOW_IN_BEARER); + ogs_pool_sequence_id_generate(&bearer->pf_identifier_pool); } void smf_pf_identifier_pool_final(smf_bearer_t *bearer) { ogs_assert(bearer); - ogs_index_final(&bearer->pf_identifier_pool); + ogs_pool_final(&bearer->pf_identifier_pool); } void smf_pf_precedence_pool_init(smf_sess_t *sess) { - int i; - ogs_assert(sess); - ogs_index_init(&sess->pf_precedence_pool, + ogs_pool_init(&sess->pf_precedence_pool, OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW_IN_BEARER); - - for (i = 1; i <= - OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW_IN_BEARER; i++) { - sess->pf_precedence_pool.array[i-1] = i; - } + ogs_pool_sequence_id_generate(&sess->pf_precedence_pool); } void smf_pf_precedence_pool_final(smf_sess_t *sess) { ogs_assert(sess); - ogs_index_final(&sess->pf_precedence_pool); + ogs_pool_final(&sess->pf_precedence_pool); } static void stats_add_smf_session(void) diff --git a/src/smf/context.h b/src/smf/context.h index 9fbd98b8e..fc20ade17 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -88,6 +88,7 @@ typedef struct smf_context_s { ogs_hash_t *imsi_hash; /* hash table (IMSI) */ ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */ ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */ + ogs_hash_t *smf_n4_seid_hash; /* hash table (SMF-N4-SEID) */ ogs_hash_t *n1n2message_hash; /* hash table (N1N2Message Location) */ uint16_t mtu; /* MTU to advertise in PCO */ @@ -173,8 +174,6 @@ typedef struct smf_bearer_s { ogs_lnode_t to_modify_node; ogs_lnode_t to_delete_node; - uint32_t index; - ogs_pfcp_pdr_t *dl_pdr; ogs_pfcp_pdr_t *ul_pdr; ogs_pfcp_far_t *dl_far; @@ -215,7 +214,10 @@ typedef struct smf_bearer_s { #define SMF_SESS(pfcp_sess) ogs_container_of(pfcp_sess, smf_sess_t, pfcp) typedef struct smf_sess_s { ogs_sbi_object_t sbi; - uint32_t index; /**< An index of this node */ + + uint32_t index; /* An index of this node */ + ogs_pool_id_t *smf_n4_seid_node; /* A node of SMF-N4-SEID */ + ogs_fsm_t sm; /* A state machine */ struct { bool gx_ccr_init_in_flight; /* Waiting for Gx CCA */ @@ -236,12 +238,12 @@ typedef struct smf_sess_s { uint64_t smpolicycontrol_features; /* SBI features */ - uint32_t smf_n4_teid; /* SMF-N4-TEID is derived from INDEX */ + uint32_t smf_n4_teid; /* SMF-N4-TEID is derived from NODE */ uint32_t sgw_s5c_teid; /* SGW-S5C-TEID is received from SGW */ ogs_ip_t sgw_s5c_ip; /* SGW-S5C IPv4/IPv6 */ - uint64_t smf_n4_seid; /* SMF SEID is dervied from INDEX */ + uint64_t smf_n4_seid; /* SMF SEID is dervied from NODE */ uint64_t upf_n4_seid; /* UPF SEID is received from Peer */ uint32_t upf_n3_teid; /* UPF-N3 TEID */ diff --git a/src/smf/fd-path.c b/src/smf/fd-path.c index 885776f3e..17acea9bc 100644 --- a/src/smf/fd-path.c +++ b/src/smf/fd-path.c @@ -62,6 +62,7 @@ void smf_fd_final(void) } smf_gx_final(); + smf_gy_final(); smf_s6b_final(); ogs_diam_final(); diff --git a/src/smf/gx-handler.c b/src/smf/gx-handler.c index a3e4a4fce..3b4177bd2 100644 --- a/src/smf/gx-handler.c +++ b/src/smf/gx-handler.c @@ -202,10 +202,10 @@ uint32_t smf_gx_handle_cca_initial_request( &bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6); if (resource->info.teidri) bearer->pgw_s5u_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - ul_pdr->index, resource->info.teidri, + ul_pdr->teid, resource->info.teidri, resource->info.teid_range); else - bearer->pgw_s5u_teid = ul_pdr->index; + bearer->pgw_s5u_teid = ul_pdr->teid; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -218,7 +218,7 @@ uint32_t smf_gx_handle_cca_initial_request( else ogs_assert_if_reached(); - bearer->pgw_s5u_teid = ul_pdr->index; + bearer->pgw_s5u_teid = ul_pdr->teid; } ogs_assert(OGS_OK == @@ -231,7 +231,7 @@ uint32_t smf_gx_handle_cca_initial_request( ogs_pfcp_sockaddr_to_f_teid( bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6, &cp2up_pdr->f_teid, &cp2up_pdr->f_teid_len)); - cp2up_pdr->f_teid.teid = cp2up_pdr->index; + cp2up_pdr->f_teid.teid = cp2up_pdr->teid; ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( diff --git a/src/smf/npcf-handler.c b/src/smf/npcf-handler.c index c035346dd..e902ada25 100644 --- a/src/smf/npcf-handler.c +++ b/src/smf/npcf-handler.c @@ -585,10 +585,10 @@ bool smf_npcf_smpolicycontrol_handle_create( &sess->upf_n3_addr, &sess->upf_n3_addr6); if (resource->info.teidri) sess->upf_n3_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - ul_pdr->index, resource->info.teidri, + ul_pdr->teid, resource->info.teidri, resource->info.teid_range); else - sess->upf_n3_teid = ul_pdr->index; + sess->upf_n3_teid = ul_pdr->teid; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -601,7 +601,7 @@ bool smf_npcf_smpolicycontrol_handle_create( else ogs_assert_if_reached(); - sess->upf_n3_teid = ul_pdr->index; + sess->upf_n3_teid = ul_pdr->teid; } ogs_assert(OGS_OK == @@ -614,7 +614,7 @@ bool smf_npcf_smpolicycontrol_handle_create( ogs_pfcp_sockaddr_to_f_teid( sess->upf_n3_addr, sess->upf_n3_addr6, &cp2up_pdr->f_teid, &cp2up_pdr->f_teid_len)); - cp2up_pdr->f_teid.teid = cp2up_pdr->index; + cp2up_pdr->f_teid.teid = cp2up_pdr->teid; ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( diff --git a/src/upf/context.c b/src/upf/context.c index f0caba97e..c6a664073 100644 --- a/src/upf/context.c +++ b/src/upf/context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -25,6 +25,7 @@ static upf_context_t self; int __upf_log_domain; static OGS_POOL(upf_sess_pool, upf_sess_t); +static OGS_POOL(upf_n4_seid_pool, ogs_pool_id_t); static int context_initialized = 0; @@ -49,11 +50,15 @@ void upf_context_init(void) ogs_list_init(&self.sess_list); ogs_pool_init(&upf_sess_pool, ogs_app()->pool.sess); + ogs_pool_init(&upf_n4_seid_pool, ogs_app()->pool.sess); + ogs_pool_random_id_generate(&upf_n4_seid_pool); - self.seid_hash = ogs_hash_make(); - ogs_assert(self.seid_hash); - self.f_seid_hash = ogs_hash_make(); - ogs_assert(self.f_seid_hash); + self.upf_n4_seid_hash = ogs_hash_make(); + ogs_assert(self.upf_n4_seid_hash); + self.smf_n4_seid_hash = ogs_hash_make(); + ogs_assert(self.smf_n4_seid_hash); + self.smf_n4_f_seid_hash = ogs_hash_make(); + ogs_assert(self.smf_n4_f_seid_hash); self.ipv4_hash = ogs_hash_make(); ogs_assert(self.ipv4_hash); self.ipv6_hash = ogs_hash_make(); @@ -77,10 +82,12 @@ void upf_context_final(void) upf_sess_remove_all(); - ogs_assert(self.seid_hash); - ogs_hash_destroy(self.seid_hash); - ogs_assert(self.f_seid_hash); - ogs_hash_destroy(self.f_seid_hash); + ogs_assert(self.upf_n4_seid_hash); + ogs_hash_destroy(self.upf_n4_seid_hash); + ogs_assert(self.smf_n4_seid_hash); + ogs_hash_destroy(self.smf_n4_seid_hash); + ogs_assert(self.smf_n4_f_seid_hash); + ogs_hash_destroy(self.smf_n4_f_seid_hash); ogs_assert(self.ipv4_hash); ogs_hash_destroy(self.ipv4_hash); ogs_assert(self.ipv6_hash); @@ -90,6 +97,7 @@ void upf_context_final(void) free_upf_route_trie_node(self.ipv6_framed_routes); ogs_pool_final(&upf_sess_pool); + ogs_pool_final(&upf_n4_seid_pool); context_initialized = 0; } @@ -171,10 +179,14 @@ upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid) ogs_pfcp_pool_init(&sess->pfcp); - sess->index = ogs_pool_index(&upf_sess_pool, sess); - ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); + /* Set UPF-N4-SEID */ + ogs_pool_alloc(&upf_n4_seid_pool, &sess->upf_n4_seid_node); + ogs_assert(sess->upf_n4_seid_node); - sess->upf_n4_seid = sess->index; + sess->upf_n4_seid = *(sess->upf_n4_seid_node); + + ogs_hash_set(self.upf_n4_seid_hash, &sess->upf_n4_seid, + sizeof(sess->upf_n4_seid), sess); /* Since F-SEID is composed of ogs_ip_t and uint64-seid, * all these values must be put into the structure-smf_n4_f_seid @@ -183,9 +195,9 @@ upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid) ogs_assert(OGS_OK == ogs_pfcp_f_seid_to_ip(cp_f_seid, &sess->smf_n4_f_seid.ip)); - ogs_hash_set(self.f_seid_hash, &sess->smf_n4_f_seid, + ogs_hash_set(self.smf_n4_f_seid_hash, &sess->smf_n4_f_seid, sizeof(sess->smf_n4_f_seid), sess); - ogs_hash_set(self.seid_hash, &sess->smf_n4_f_seid.seid, + ogs_hash_set(self.smf_n4_seid_hash, &sess->smf_n4_f_seid.seid, sizeof(sess->smf_n4_f_seid.seid), sess); ogs_list_add(&self.sess_list, sess); @@ -206,9 +218,12 @@ int upf_sess_remove(upf_sess_t *sess) ogs_list_remove(&self.sess_list, sess); ogs_pfcp_sess_clear(&sess->pfcp); - ogs_hash_set(self.seid_hash, &sess->smf_n4_f_seid.seid, + ogs_hash_set(self.upf_n4_seid_hash, &sess->upf_n4_seid, + sizeof(sess->upf_n4_seid), NULL); + + ogs_hash_set(self.smf_n4_seid_hash, &sess->smf_n4_f_seid.seid, sizeof(sess->smf_n4_f_seid.seid), NULL); - ogs_hash_set(self.f_seid_hash, &sess->smf_n4_f_seid, + ogs_hash_set(self.smf_n4_f_seid_hash, &sess->smf_n4_f_seid, sizeof(sess->smf_n4_f_seid), NULL); if (sess->ipv4) { @@ -226,7 +241,9 @@ int upf_sess_remove(upf_sess_t *sess) ogs_pfcp_pool_final(&sess->pfcp); + ogs_pool_free(&upf_n4_seid_pool, sess->upf_n4_seid_node); ogs_pool_free(&upf_sess_pool, sess); + upf_metrics_inst_global_dec(UPF_METR_GLOB_GAUGE_UPF_SESSIONNBR); ogs_info("[Removed] Number of UPF-sessions is now %d", @@ -244,14 +261,9 @@ void upf_sess_remove_all(void) } } -upf_sess_t *upf_sess_find(uint32_t index) -{ - return ogs_pool_find(&upf_sess_pool, index); -} - upf_sess_t *upf_sess_find_by_smf_n4_seid(uint64_t seid) { - return (upf_sess_t *)ogs_hash_get(self.seid_hash, &seid, sizeof(seid)); + return ogs_hash_get(self.smf_n4_seid_hash, &seid, sizeof(seid)); } upf_sess_t *upf_sess_find_by_smf_n4_f_seid(ogs_pfcp_f_seid_t *f_seid) @@ -265,12 +277,12 @@ upf_sess_t *upf_sess_find_by_smf_n4_f_seid(ogs_pfcp_f_seid_t *f_seid) ogs_assert(OGS_OK == ogs_pfcp_f_seid_to_ip(f_seid, &key.ip)); key.seid = f_seid->seid; - return (upf_sess_t *)ogs_hash_get(self.f_seid_hash, &key, sizeof(key)); + return ogs_hash_get(self.smf_n4_f_seid_hash, &key, sizeof(key)); } upf_sess_t *upf_sess_find_by_upf_n4_seid(uint64_t seid) { - return upf_sess_find(seid); + return ogs_hash_get(self.upf_n4_seid_hash, &seid, sizeof(seid)); } upf_sess_t *upf_sess_find_by_ipv4(uint32_t addr) diff --git a/src/upf/context.h b/src/upf/context.h index 49747092c..9153ce937 100644 --- a/src/upf/context.h +++ b/src/upf/context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -48,14 +48,18 @@ extern int __upf_log_domain; struct upf_route_trie_node; typedef struct upf_context_s { - ogs_hash_t *seid_hash; /* hash table (SEID) */ - ogs_hash_t *f_seid_hash; /* hash table (F-SEID) */ - ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */ - ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */ - struct upf_route_trie_node *ipv4_framed_routes; /* IPv4 framed routes trie */ - struct upf_route_trie_node *ipv6_framed_routes; /* IPv6 framed routes trie */ + ogs_hash_t *upf_n4_seid_hash; /* hash table (UPF-N4-SEID) */ + ogs_hash_t *smf_n4_seid_hash; /* hash table (SMF-N4-SEID) */ + ogs_hash_t *smf_n4_f_seid_hash; /* hash table (SMF-N4-F-SEID) */ + ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */ + ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */ - ogs_list_t sess_list; + /* IPv4 framed routes trie */ + struct upf_route_trie_node *ipv4_framed_routes; + /* IPv6 framed routes trie */ + struct upf_route_trie_node *ipv6_framed_routes; + + ogs_list_t sess_list; } upf_context_t; /* trie mapping from IP framed routes to session. */ @@ -96,11 +100,11 @@ typedef struct upf_sess_urr_acc_s { #define UPF_SESS(pfcp_sess) ogs_container_of(pfcp_sess, upf_sess_t, pfcp) typedef struct upf_sess_s { ogs_lnode_t lnode; - uint32_t index; /**< An index of this node */ + ogs_pool_id_t *upf_n4_seid_node; /* A node of UPF-N4-SEID */ ogs_pfcp_sess_t pfcp; - uint64_t upf_n4_seid; /* UPF SEID is dervied from INDEX */ + uint64_t upf_n4_seid; /* UPF SEID is dervied from NODE */ struct { uint64_t seid; ogs_ip_t ip; @@ -131,7 +135,6 @@ upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message); upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *f_seid); int upf_sess_remove(upf_sess_t *sess); void upf_sess_remove_all(void); -upf_sess_t *upf_sess_find(uint32_t index); upf_sess_t *upf_sess_find_by_smf_n4_seid(uint64_t seid); upf_sess_t *upf_sess_find_by_smf_n4_f_seid(ogs_pfcp_f_seid_t *f_seid); upf_sess_t *upf_sess_find_by_upf_n4_seid(uint64_t seid); diff --git a/src/upf/gtp-path.c b/src/upf/gtp-path.c index 17fe69cf1..f6bc70ef4 100644 --- a/src/upf/gtp-path.c +++ b/src/upf/gtp-path.c @@ -684,7 +684,7 @@ int upf_gtp_init(void) config.cluster_2048_pool = ogs_app()->pool.packet; -#if OGS_USE_TALLOC +#if OGS_USE_TALLOC == 1 /* allocate a talloc pool for GTP to ensure it doesn't have to go back * to the libc malloc all the time */ packet_pool = talloc_pool(__ogs_talloc_core, 1000*1024); diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c index 6f1f35982..b5cd61f4f 100644 --- a/src/upf/n4-handler.c +++ b/src/upf/n4-handler.c @@ -192,10 +192,10 @@ void upf_n4_handle_session_establishment_request( &resource->info, &pdr->f_teid, &pdr->f_teid_len)); if (resource->info.teidri) pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - pdr->index, resource->info.teidri, + pdr->teid, resource->info.teidri, resource->info.teid_range); else - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } else { ogs_assert( (ogs_gtp_self()->gtpu_addr && pdr->f_teid.ipv4) || @@ -207,7 +207,7 @@ void upf_n4_handle_session_establishment_request( pdr->f_teid.ipv6 ? ogs_gtp_self()->gtpu_addr6 : NULL, &pdr->f_teid, &pdr->f_teid_len)); - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } } } @@ -441,10 +441,10 @@ void upf_n4_handle_session_modification_request( &resource->info, &pdr->f_teid, &pdr->f_teid_len)); if (resource->info.teidri) pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - pdr->index, resource->info.teidri, + pdr->teid, resource->info.teidri, resource->info.teid_range); else - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } else { ogs_assert( (ogs_gtp_self()->gtpu_addr && pdr->f_teid.ipv4) || @@ -456,7 +456,7 @@ void upf_n4_handle_session_modification_request( pdr->f_teid.ipv6 ? ogs_gtp_self()->gtpu_addr6 : NULL, &pdr->f_teid, &pdr->f_teid_len)); - pdr->f_teid.teid = pdr->index; + pdr->f_teid.teid = pdr->teid; } } } diff --git a/tests/core/memory-test.c b/tests/core/memory-test.c index 7d316ac20..6792234ed 100644 --- a/tests/core/memory-test.c +++ b/tests/core/memory-test.c @@ -41,7 +41,7 @@ static void test2_func(abts_case *tc, void *data) static void test3_func(abts_case *tc, void *data) { -#if OGS_USE_TALLOC != 1 +#if OGS_USE_TALLOC == 0 char *ptr = ogs_realloc(0, 10); ABTS_PTR_NOTNULL(tc, ptr); ogs_free(ptr); @@ -54,7 +54,7 @@ static void test3_func(abts_case *tc, void *data) static void test4_func(abts_case *tc, void *data) { -#if OGS_USE_TALLOC != 1 +#if OGS_USE_TALLOC == 0 char *p, *q; p = ogs_malloc(10);