Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
pespin committed Dec 20, 2023
1 parent f490265 commit ee83d5c
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 36 deletions.
38 changes: 34 additions & 4 deletions src/mme/mme-context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -3297,19 +3305,32 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
}
mme_ue->t_implicit_detach.pkbuf = NULL;

mme_ue->gn.t_gn_holding = ogs_timer_add(
ogs_app()->timer_mgr, mme_timer_gn_holding_timer_expire, mme_ue);
if (! mme_ue->gn.t_gn_holding) {
ogs_error("ogs_timer_add() failed");
ogs_pool_free(&mme_ue_pool, mme_ue);
return NULL;
}

mme_ebi_pool_init(mme_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.
Expand Down Expand Up @@ -3353,6 +3374,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);
Expand Down Expand Up @@ -3391,6 +3414,7 @@ void mme_ue_remove(mme_ue_t *mme_ue)
ogs_timer_delete(mme_ue->t3470.timer);
ogs_timer_delete(mme_ue->t_mobile_reachable.timer);
ogs_timer_delete(mme_ue->t_implicit_detach.timer);
ogs_timer_delete(mme_ue->gn.t_gn_holding);

enb_ue_unlink(mme_ue);

Expand All @@ -3400,6 +3424,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",
Expand Down Expand Up @@ -3473,11 +3498,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;
Expand Down
8 changes: 7 additions & 1 deletion src/mme/mme-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -422,9 +423,13 @@ struct mme_ue_s {

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 */
uint32_t sgsn_gn_teid;
ogs_ip_t sgsn_gn_ip;
ogs_ip_t sgsn_gn_ip_alt;
/* Unnamed timer in 3GPP TS 23.401 D.3.5 step 2), see also 3GPP TS 23.060 6.9.1.2.2 */
ogs_timer_t *t_gn_holding;
} gn;

struct {
Expand Down Expand Up @@ -948,7 +953,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);
Expand Down
2 changes: 2 additions & 0 deletions src/mme/mme-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ const char *mme_event_get_name(mme_event_t *e)

case MME_EVENT_GN_MESSAGE:
return "MME_EVENT_GN_MESSAGE";
case MME_EVENT_GN_TIMER:
return "MME_EVENT_GN_TIMER";
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/mme/mme-event.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef enum {
MME_EVENT_SGSAP_LO_CONNREFUSED,

MME_EVENT_GN_MESSAGE,
MME_EVENT_GN_TIMER,

MAX_NUM_OF_MME_EVENT,

Expand Down
26 changes: 14 additions & 12 deletions src/mme/mme-gn-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,23 @@ static int sess_fill_pdp_context_decoded(mme_sess_t *sess, ogs_gtp1_pdp_context_
.vaa = OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_YES,
.asi = OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_NO,
.order = OGS_GTP1_PDPCTX_REORDERING_REQUIRED_NO,
/* 3GPP TS 23.401 Annex D3.5.5 2b.:
* "The GTP equence numbers received from the old 3G-SGSN are only relevant if
* delivery order is required for the PDP context (QoS profile)."
* NOTE 4: "The GTP and PDCP sequence numbers are not relevant" */
.snd = 0,
.snu = 0,
.send_npdu_nr = 0,
.receive_npdu_nr = 0,
.ul_teic = sess->pgw_s5c_teid,
.pdp_type_org = OGS_PDP_EUA_ORG_IETF,
.pdp_type_num = {sess->session->session_type, },
.pdp_address = {sess->session->ue_ip, },
.ggsn_address_c = sess->pgw_s5c_ip,
.trans_id = sess->pti,
};

pdpctx_dec->ggsn_address_c = sess->pgw_s5c_ip;
pdpctx_dec->pdp_type_org = OGS_PDP_EUA_ORG_IETF;
pdpctx_dec->pdp_type_num[0] = sess->session->session_type;
pdpctx_dec->pdp_address[0] = sess->session->ue_ip;
ogs_cpystrn(pdpctx_dec->apn, sess->session->name, sizeof(pdpctx_dec->apn));
pdpctx_dec->trans_id = sess->pti;

ogs_list_for_each(&sess->bearer_list, bearer) {
pdpctx_dec->nsapi = bearer->ebi;
Expand All @@ -158,14 +166,9 @@ static int sess_fill_pdp_context_decoded(mme_sess_t *sess, ogs_gtp1_pdp_context_
//FIXME: sort out where to get each one:
memcpy(&pdpctx_dec->qos_req, &pdpctx_dec->qos_sub, sizeof(pdpctx_dec->qos_sub));
memcpy(&pdpctx_dec->qos_neg, &pdpctx_dec->qos_sub, sizeof(pdpctx_dec->qos_sub));
pdpctx_dec->snd = 0; /* FIXME. */
pdpctx_dec->snu = 0; /* FIXME. */
pdpctx_dec->send_npdu_nr = 0; /* FIXME. */
pdpctx_dec->receive_npdu_nr = 0; /* FIXME. */
pdpctx_dec->ul_teid = bearer->pgw_s5u_teid;
pdpctx_dec->pdp_ctx_id = 0; /* FIXME. */
pdpctx_dec->ggsn_address_u = bearer->pgw_s5u_ip;
/* TODO: session->qos and bearer->qos to fill something in pdpctx_dec. */

/* FIXME: only 1 PDP Context supported in the message so far. */
break;
Expand Down Expand Up @@ -211,9 +214,8 @@ ogs_pkbuf_t *mme_gn_build_sgsn_context_response(

ogs_assert(mme_ue);

/* FIXME: Reuse S11 TEID as local Gn interface for now */
rsp->tunnel_endpoint_identifier_control_plane.presence = 1;
rsp->tunnel_endpoint_identifier_control_plane.u32 = mme_ue->mme_s11_teid;
rsp->tunnel_endpoint_identifier_control_plane.u32 = mme_ue->gn.mme_gn_teid;

ogs_list_for_each(&mme_ue->sess_list, sess) {
if (!MME_HAVE_SGW_S1U_PATH(sess))
Expand Down
42 changes: 38 additions & 4 deletions src/mme/mme-gn-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,49 @@ void mme_gn_handle_sgsn_context_request(
ogs_assert(rv == OGS_OK);
}

mme_gtp1_send_sgsn_context_response(mme_ue, OGS_GTP1_CAUSE_REQUEST_ACCEPTED, xact);
/* 3GPP TS 23.401 Annex D.3.5 "Routing Area Update":
* Step 2. "If the old P-TMSI Signature was valid or if the new SGSN indicates that it has authenticated the MS,
* the old SGSN starts a timer."
*/
ogs_timer_start(mme_ue->gn.t_gn_holding, mme_timer_cfg(MME_TIMER_GN_HOLDING)->duration);

mme_gtp1_send_sgsn_context_response(mme_ue, OGS_GTP1_CAUSE_REQUEST_ACCEPTED, xact);
}

/* TS 29.060 7.5.5 SGSN Context Acknowledge */
void mme_gn_handle_sgsn_context_acknowledge(
ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_acknowledge_t *req)
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp1_sgsn_context_acknowledge_t *req)
{
/* FIXME: find out what to do here, 3GPP TS 23.401 D.3.5
* Probably release the Session on the SGW (without releasing in the PGW) */
int rv;

/* 3GPP TS 23.060 6.9.1.2.2 Step 4), 3GPP TS 23.401 D.3.5 Step 4)
* The new SGSN sends an SGSN Context Acknowledge message to the old SGSN. The old MME (which is the old
* SGSN from the new SGSN's point of view) marks in its context that the information in the GWs and the HSS are
* invalid. This triggers the GWs, and the HSS to be updated if the UE initiates a Tracking Area Update procedure
* back to the old MME before completing the ongoing Routing Area Update procedure. If the security functions do
* not authenticate the MS correctly, then the routing area update shall be rejected, and the new SGSN shall send a
* reject indication to the old SGSN. The old MME shall continue as if the SGSN Context Request was never
* received.
* "NOTE 6: The new SGSN's operation is unmodified compared to pre-Rel-8. The old MME/S-GW (old SGSN from
* the new SGSN's point of view) does not forward any data towards the new SGSN." "*/

if (req->cause.u8 != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) {
ogs_timer_stop(mme_ue->gn.t_gn_holding);
return;
}

/* 3GPP TS 23.060 6.9.1.2.2 Step 13)
* "If the old MME has an S1-MME association for the UE, the source MME sends a S1-U Release Command to the
* source eNodeB when receiving the SGSN Context Acknowledge message from the new SGSN. The RRC
* connection is released by the source eNodeB. The source eNodeB confirms the release of the RRC connection
* and of the S1-U connection by sending a S1-U Release Complete message to the source MME."
*/
if (mme_ue->enb_ue) {
rv = s1ap_send_ue_context_release_command(mme_ue->enb_ue,
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
ogs_expect(rv == OGS_OK);
}
}

/* TS 29.060 7.5.14.1 */
Expand Down
4 changes: 2 additions & 2 deletions src/mme/mme-gn-handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void mme_gn_handle_sgsn_context_request(
ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req);

void mme_gn_handle_sgsn_context_acknowledge(
ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_acknowledge_t *req);
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp1_sgsn_context_acknowledge_t *req);

void mme_gn_handle_ran_information_relay(
ogs_gtp_xact_t *xact, ogs_gtp1_ran_information_relay_t *req);
Expand All @@ -45,4 +45,4 @@ void mme_gn_handle_ran_information_relay(
}
#endif

#endif /* MME_S11_HANDLER_H */
#endif /* MME_GN_HANDLER_H */
16 changes: 8 additions & 8 deletions src/mme/mme-gtp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -775,7 +775,7 @@ int mme_gtp1_send_sgsn_context_response(
return OGS_ERROR;
}
/* FIXME: Reuse S11 TEID as local Gn interface for now */
xact->local_teid = mme_ue ? mme_ue->mme_s11_teid : 0;
xact->local_teid = mme_ue ? mme_ue->gn.mme_gn_teid : 0;

rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
if (rv != OGS_OK) {
Expand Down
13 changes: 11 additions & 2 deletions src/mme/mme-s6a-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
static uint8_t emm_cause_from_diameter(
const uint32_t *dia_err, const uint32_t *dia_exp_err);

static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue,
static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue,
ogs_slice_data_t *slice_data);

uint8_t mme_s6a_handle_aia(
Expand Down Expand Up @@ -281,6 +281,15 @@ void mme_s6a_handle_clr(mme_ue_t *mme_ue, ogs_diam_s6a_message_t *s6a_message)
case OGS_DIAM_S6A_CT_MME_UPDATE_PROCEDURE:
mme_ue->detach_type = MME_DETACH_TYPE_HSS_IMPLICIT;

/* 3GPP TS 23.401 D.3.5.5 8), 3GPP TS 23.060 6.9.1.2.2 8):
* "When the timer described in step 2 is running, the MM and PDP/EPS
* Bearer Contexts and any affected S-GW resources are removed when the
* timer expires and the SGSN received a Cancel Location".
*/
if (mme_ue->gn.t_gn_holding->running) {
break;
}

/*
* There is no need to send NAS or S1AP message to the UE.
* So, we don't have to check whether UE is IDLE or not.
Expand All @@ -299,7 +308,7 @@ void mme_s6a_handle_clr(mme_ue_t *mme_ue, ogs_diam_s6a_message_t *s6a_message)
}
}

static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue,
static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue,
ogs_slice_data_t *slice_data)
{
int i;
Expand Down
Loading

0 comments on commit ee83d5c

Please sign in to comment.