[MME] Split Gn local TEID generation from S11 TEID generation

This commit is contained in:
Pau Espin 2023-12-20 19:15:47 +01:00 committed by Sukchan Lee
parent 6a9c7f16c1
commit 14932a7254
4 changed files with 50 additions and 14 deletions

View File

@ -47,6 +47,7 @@ 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(mme_gn_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);
@ -110,6 +111,8 @@ void mme_context_init(void)
ogs_pool_init(&mme_ue_pool, ogs_global_conf()->max.ue);
ogs_pool_init(&mme_s11_teid_pool, ogs_global_conf()->max.ue);
ogs_pool_random_id_generate(&mme_s11_teid_pool);
ogs_pool_init(&mme_gn_teid_pool, ogs_global_conf()->max.ue);
ogs_pool_random_id_generate(&mme_gn_teid_pool);
ogs_pool_init(&enb_ue_pool, ogs_global_conf()->max.ue);
ogs_pool_init(&sgw_ue_pool, ogs_global_conf()->max.ue);
@ -128,6 +131,8 @@ void mme_context_init(void)
ogs_assert(self.guti_ue_hash);
self.mme_s11_teid_hash = ogs_hash_make();
ogs_assert(self.mme_s11_teid_hash);
self.mme_gn_teid_hash = ogs_hash_make();
ogs_assert(self.mme_gn_teid_hash);
ogs_list_init(&self.mme_ue_list);
@ -158,12 +163,15 @@ void mme_context_final(void)
ogs_hash_destroy(self.guti_ue_hash);
ogs_assert(self.mme_s11_teid_hash);
ogs_hash_destroy(self.mme_s11_teid_hash);
ogs_assert(self.mme_gn_teid_hash);
ogs_hash_destroy(self.mme_gn_teid_hash);
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(&mme_gn_teid_pool);
ogs_pool_final(&enb_ue_pool);
ogs_pool_final(&sgw_ue_pool);
@ -3301,15 +3309,20 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
ogs_list_init(&mme_ue->sess_list);
/* Set MME-S11_TEID */
/* 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);
/* Set MME-Gn-TEID */
ogs_pool_alloc(&mme_gn_teid_pool, &mme_ue->gn.mme_gn_teid_node);
ogs_assert(mme_ue->gn.mme_gn_teid_node);
mme_ue->gn.mme_gn_teid = *(mme_ue->gn.mme_gn_teid_node);
ogs_hash_set(self.mme_gn_teid_hash,
&mme_ue->gn.mme_gn_teid, sizeof(mme_ue->gn.mme_gn_teid), mme_ue);
/*
* When used for the first time, if last node is set,
* the search is performed from the first SGW in a round-robin manner.
@ -3353,6 +3366,8 @@ void mme_ue_remove(mme_ue_t *mme_ue)
ogs_hash_set(self.mme_s11_teid_hash,
&mme_ue->mme_s11_teid, sizeof(mme_ue->mme_s11_teid), NULL);
ogs_hash_set(self.mme_gn_teid_hash,
&mme_ue->gn.mme_gn_teid, sizeof(mme_ue->gn.mme_gn_teid), NULL);
ogs_assert(mme_ue->sgw_ue);
sgw_ue_remove(mme_ue->sgw_ue);
@ -3400,6 +3415,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_gn_teid_pool, mme_ue->gn.mme_gn_teid_node);
ogs_pool_free(&mme_ue_pool, mme_ue);
ogs_info("[Removed] Number of MME-UEs is now %d",
@ -3473,11 +3489,16 @@ mme_ue_t *mme_ue_find_by_guti(ogs_nas_eps_guti_t *guti)
self.guti_ue_hash, guti, sizeof(ogs_nas_eps_guti_t));
}
mme_ue_t *mme_ue_find_by_teid(uint32_t teid)
mme_ue_t *mme_ue_find_by_s11_local_teid(uint32_t teid)
{
return ogs_hash_get(self.mme_s11_teid_hash, &teid, sizeof(teid));
}
mme_ue_t *mme_ue_find_by_gn_local_teid(uint32_t teid)
{
return ogs_hash_get(self.mme_gn_teid_hash, &teid, sizeof(teid));
}
mme_ue_t *mme_ue_find_by_message(ogs_nas_eps_message_t *message)
{
mme_ue_t *mme_ue = NULL;

View File

@ -192,6 +192,7 @@ typedef struct mme_context_s {
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) */
ogs_hash_t *mme_gn_teid_hash; /* hash table (MME-GN-TEID : MME_UE) */
struct {
struct {
@ -421,6 +422,10 @@ struct mme_ue_s {
char a_msisdn_bcd[OGS_MAX_MSISDN_BCD_LEN+1];
mme_p_tmsi_t p_tmsi;
struct {
ogs_pool_id_t *mme_gn_teid_node; /* A node of MME-Gn-TEID */
uint32_t mme_gn_teid; /* MME-Gn-TEID is derived from NODE */
} gn;
struct {
mme_m_tmsi_t *m_tmsi;
@ -943,7 +948,8 @@ void mme_ue_fsm_fini(mme_ue_t *mme_ue);
mme_ue_t *mme_ue_find_by_imsi(uint8_t *imsi, int imsi_len);
mme_ue_t *mme_ue_find_by_imsi_bcd(char *imsi_bcd);
mme_ue_t *mme_ue_find_by_guti(ogs_nas_eps_guti_t *nas_guti);
mme_ue_t *mme_ue_find_by_teid(uint32_t teid);
mme_ue_t *mme_ue_find_by_s11_local_teid(uint32_t teid);
mme_ue_t *mme_ue_find_by_gn_local_teid(uint32_t teid);
mme_ue_t *mme_ue_find_by_message(ogs_nas_eps_message_t *message);
int mme_ue_set_imsi(mme_ue_t *mme_ue, char *imsi_bcd);

View File

@ -268,7 +268,7 @@ int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action)
return OGS_ERROR;
}
xact->create_action = create_action;
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
@ -307,7 +307,7 @@ int mme_gtp_send_modify_bearer_request(
return OGS_ERROR;
}
xact->modify_action = modify_action;
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
@ -346,7 +346,7 @@ int mme_gtp_send_delete_session_request(
return OGS_ERROR;
}
xact->delete_action = action;
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
@ -537,7 +537,7 @@ int mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action)
return OGS_ERROR;
}
xact->release_action = action;
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
@ -670,7 +670,7 @@ int mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
ogs_error("ogs_gtp_xact_local_create() failed");
return OGS_ERROR;
}
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
@ -709,7 +709,7 @@ int mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
return OGS_ERROR;
}
xact->delete_indirect_action = action;
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
@ -750,7 +750,7 @@ int mme_gtp_send_bearer_resource_command(
return OGS_ERROR;
}
xact->xid |= OGS_GTP_CMD_XACT_ID;
xact->local_teid = mme_ue->mme_s11_teid;
xact->local_teid = mme_ue->gn.mme_gn_teid;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);

View File

@ -528,14 +528,14 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
*/
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
/* Cause is not "Context not found" */
mme_ue = mme_ue_find_by_teid(gtp_message.h.teid);
mme_ue = mme_ue_find_by_s11_local_teid(gtp_message.h.teid);
} else if (xact->local_teid) { /* rx no TEID or TEID=0 */
/* 3GPP TS 29.274 5.5.2: we receive TEID=0 under some
* conditions, such as cause "Session context not found". In those
* cases, we still want to identify the local session which
* originated the message, so try harder by using the TEID we
* locally stored in xact when sending the original request: */
mme_ue = mme_ue_find_by_teid(xact->local_teid);
mme_ue = mme_ue_find_by_s11_local_teid(xact->local_teid);
}
switch (gtp_message.h.type) {
@ -655,6 +655,15 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
break;
}
if (gtp1_message.h.teid != 0) {
/* Cause is not "Context not found" */
mme_ue = mme_ue_find_by_gn_local_teid(gtp1_message.h.teid);
} else if (xact->local_teid) { /* rx no TEID or TEID=0 */
/* Try harder by using the TEID we locally stored in xact when
*sending the original request: */
mme_ue = mme_ue_find_by_gn_local_teid(xact->local_teid);
}
switch (gtp1_message.h.type) {
case OGS_GTP1_ECHO_REQUEST_TYPE:
mme_gn_handle_echo_request(xact, &gtp1_message.echo_request);