[PFCP/GTP] SEID/TEID Randomness (#1303)

This commit is contained in:
Sukchan Lee 2023-04-09 10:34:19 +09:00
parent ca5e039f46
commit 642d9e2e18
33 changed files with 436 additions and 330 deletions

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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

View File

@ -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

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Copyright (C) 2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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

View File

@ -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 <M-TMSI> maps as follows:
* - 6 bits of the E-UTRAN <M-TMSI> starting at bit 29 and down to bit 24
* are mapped into bit 29 and down to bit 24 of the GERAN/UTRAN <P-TMSI>;
* - 16 bits of the E-UTRAN <M-TMSI> starting at bit 15 and down to bit 0
* are mapped into bit 15 and down to bit 0 of the GERAN/UTRAN <P-TMSI>;
* - and the remaining 8 bits of the E-UTRAN <M-TMSI> are
* mapped into the 8 Most Significant Bits of the <P-TMSI signature> field.
*
* The UE shall fill the remaining 2 octets of the <P-TMSI signature>
* 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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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 <M-TMSI> maps as follows:
* - 6 bits of the E-UTRAN <M-TMSI> starting at bit 29 and down to bit 24
* are mapped into bit 29 and down to bit 24 of the GERAN/UTRAN <P-TMSI>;
* - 16 bits of the E-UTRAN <M-TMSI> starting at bit 15 and down to bit 0
* are mapped into bit 15 and down to bit 0 of the GERAN/UTRAN <P-TMSI>;
* - and the remaining 8 bits of the E-UTRAN <M-TMSI> are
* mapped into the 8 Most Significant Bits of the <P-TMSI signature> field.
*
* The UE shall fill the remaining 2 octets of the <P-TMSI signature>
* 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);
}

View File

@ -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);

View File

@ -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();

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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 ==

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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);

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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 ==

View File

@ -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)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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 */

View File

@ -62,6 +62,7 @@ void smf_fd_final(void)
}
smf_gx_final();
smf_gy_final();
smf_s6b_final();
ogs_diam_final();

View File

@ -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(

View File

@ -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(

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* 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);

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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);