[MME] re-factor to check a piggybacked ESM (#1431)

This commit is contained in:
Sukchan Lee 2022-03-16 20:48:48 +09:00
parent a6ec206998
commit bf77318602
16 changed files with 60 additions and 61 deletions

View File

@ -110,6 +110,8 @@ typedef struct ogs_gtp_xact_s {
#define OGS_GTP_DELETE_INDIRECT_HANDOVER_COMPLETE 1
#define OGS_GTP_DELETE_INDIRECT_HANDOVER_CANCEL 2
int delete_indirect_action;
bool esm_piggybacked;
} ogs_gtp_xact_t;
int ogs_gtp_xact_init(void);

View File

@ -25,7 +25,7 @@
#define OGS_LOG_DOMAIN __esm_log_domain
ogs_pkbuf_t *esm_build_pdn_connectivity_reject(
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause)
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause, bool esm_piggybacked)
{
mme_ue_t *mme_ue = NULL;
ogs_nas_eps_message_t message;
@ -41,7 +41,9 @@ ogs_pkbuf_t *esm_build_pdn_connectivity_reject(
mme_ue->imsi_bcd, sess->pti, esm_cause);
memset(&message, 0, sizeof(message));
if (!SESSION_CONTEXT_IN_ATTACH(sess)) {
if (esm_piggybacked == true) {
/* Nothing */
} else {
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
@ -53,7 +55,7 @@ ogs_pkbuf_t *esm_build_pdn_connectivity_reject(
pdn_connectivity_reject->esm_cause = esm_cause;
if (SESSION_CONTEXT_IN_ATTACH(sess))
if (esm_piggybacked == true)
return ogs_nas_eps_plain_encode(&message);
else
return nas_eps_security_encode(mme_ue, &message);
@ -88,7 +90,7 @@ ogs_pkbuf_t *esm_build_information_request(mme_bearer_t *bearer)
}
ogs_pkbuf_t *esm_build_activate_default_bearer_context_request(
mme_sess_t *sess)
mme_sess_t *sess, bool esm_piggybacked)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_activate_default_eps_bearer_context_request_t
@ -129,7 +131,9 @@ ogs_pkbuf_t *esm_build_activate_default_bearer_context_request(
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
memset(&message, 0, sizeof(message));
if (!SESSION_CONTEXT_IN_ATTACH(sess)) {
if (esm_piggybacked == true) {
/* Nothing */
} else {
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
@ -241,7 +245,7 @@ ogs_pkbuf_t *esm_build_activate_default_bearer_context_request(
}
}
if (SESSION_CONTEXT_IN_ATTACH(sess))
if (esm_piggybacked == true)
return ogs_nas_eps_plain_encode(&message);
else
return nas_eps_security_encode(mme_ue, &message);

View File

@ -27,12 +27,12 @@ extern "C" {
#endif
ogs_pkbuf_t *esm_build_pdn_connectivity_reject(
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause);
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause, bool esm_piggybacked);
ogs_pkbuf_t *esm_build_information_request(mme_bearer_t *bearer);
ogs_pkbuf_t *esm_build_activate_default_bearer_context_request(
mme_sess_t *sess);
mme_sess_t *sess, bool esm_piggybacked);
ogs_pkbuf_t *esm_build_activate_dedicated_bearer_context_request(
mme_bearer_t *bearer);
mme_bearer_t *bearer);
ogs_pkbuf_t *esm_build_modify_bearer_context_request(
mme_bearer_t *bearer, int qos_presence, int tft_presence);
ogs_pkbuf_t *esm_build_deactivate_bearer_context_request(

View File

@ -29,7 +29,7 @@
#define OGS_LOG_DOMAIN __esm_log_domain
int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
ogs_nas_eps_pdn_connectivity_request_t *req)
ogs_nas_eps_pdn_connectivity_request_t *req, bool esm_piggybacked)
{
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess = NULL;
@ -67,7 +67,7 @@ int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
/* Invalid APN */
ogs_assert(OGS_OK ==
nas_eps_send_pdn_connectivity_reject(
sess, ESM_CAUSE_MISSING_OR_UNKNOWN_APN));
sess, ESM_CAUSE_MISSING_OR_UNKNOWN_APN, esm_piggybacked));
ogs_warn("Invalid APN[%s]", req->access_point_name.apn);
return OGS_ERROR;
}
@ -82,7 +82,7 @@ int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
sess->request_type.type, sess->session->session_type);
ogs_assert(OGS_OK ==
nas_eps_send_pdn_connectivity_reject(
sess, ESM_CAUSE_UNKNOWN_PDN_TYPE));
sess, ESM_CAUSE_UNKNOWN_PDN_TYPE, esm_piggybacked));
return OGS_ERROR;
}
} else {
@ -134,12 +134,12 @@ int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
}
ogs_assert(OGS_OK ==
mme_gtp_send_create_session_request(sess));
mme_gtp_send_create_session_request(sess, esm_piggybacked));
} else {
ogs_error("No APN");
ogs_assert(OGS_OK ==
nas_eps_send_pdn_connectivity_reject(
sess, ESM_CAUSE_MISSING_OR_UNKNOWN_APN));
sess, ESM_CAUSE_MISSING_OR_UNKNOWN_APN, esm_piggybacked));
return OGS_ERROR;
}
@ -185,7 +185,7 @@ int esm_handle_information_response(mme_sess_t *sess,
sess->request_type.type, sess->session->session_type);
ogs_assert(OGS_OK ==
nas_eps_send_pdn_connectivity_reject(
sess, ESM_CAUSE_UNKNOWN_PDN_TYPE));
sess, ESM_CAUSE_UNKNOWN_PDN_TYPE, true));
return OGS_ERROR;
}
} else {
@ -207,7 +207,7 @@ int esm_handle_information_response(mme_sess_t *sess,
}
} else {
ogs_assert(OGS_OK ==
mme_gtp_send_create_session_request(sess));
mme_gtp_send_create_session_request(sess, true));
}
} else {
if (rsp->access_point_name.length)
@ -217,7 +217,7 @@ int esm_handle_information_response(mme_sess_t *sess,
ogs_assert(OGS_OK ==
nas_eps_send_pdn_connectivity_reject(
sess, ESM_CAUSE_MISSING_OR_UNKNOWN_APN));
sess, ESM_CAUSE_MISSING_OR_UNKNOWN_APN, true));
return OGS_ERROR;
}

View File

@ -27,7 +27,8 @@ extern "C" {
#endif
int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
ogs_nas_eps_pdn_connectivity_request_t *pdn_connectivity_request);
ogs_nas_eps_pdn_connectivity_request_t *pdn_connectivity_request,
bool esm_piggybacked);
int esm_handle_information_response(mme_sess_t *sess,
ogs_nas_eps_esm_information_response_t *bearer_information_response);
int esm_handle_bearer_resource_allocation_request(

View File

@ -106,7 +106,8 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
rv = esm_handle_pdn_connectivity_request(
bearer, &message->esm.pdn_connectivity_request);
bearer, &message->esm.pdn_connectivity_request,
e->esm_piggybacked);
if (rv != OGS_OK) {
OGS_FSM_TRAN(s, esm_state_exception);
break;
@ -228,7 +229,8 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(OGS_OK ==
nas_eps_send_pdn_connectivity_reject(sess,
ESM_CAUSE_ESM_INFORMATION_NOT_RECEIVED));
ESM_CAUSE_ESM_INFORMATION_NOT_RECEIVED,
e->esm_piggybacked));
} else {
rv = nas_eps_send_esm_information_request(bearer);
if (rv == OGS_OK) {
@ -286,7 +288,8 @@ void esm_state_active(ogs_fsm_t *s, mme_event_t *e)
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
rv = esm_handle_pdn_connectivity_request(
bearer, &message->esm.pdn_connectivity_request);
bearer, &message->esm.pdn_connectivity_request,
e->esm_piggybacked);
if (rv != OGS_OK) {
OGS_FSM_TRAN(s, esm_state_exception);
break;
@ -393,7 +396,8 @@ void esm_state_pdn_will_disconnect(ogs_fsm_t *s, mme_event_t *e)
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
rv = esm_handle_pdn_connectivity_request(
bearer, &message->esm.pdn_connectivity_request);
bearer, &message->esm.pdn_connectivity_request,
e->esm_piggybacked);
if (rv != OGS_OK) {
OGS_FSM_TRAN(s, esm_state_exception);
break;

View File

@ -2756,23 +2756,6 @@ mme_sess_t *mme_sess_next(mme_sess_t *sess)
return ogs_list_next(sess);
}
bool mme_ue_in_attach(mme_ue_t *mme_ue)
{
ogs_assert(mme_ue);
return (ogs_list_count(&mme_ue->sess_list) <= 1);
}
bool mme_sess_in_attach(mme_sess_t *sess)
{
mme_ue_t *mme_ue = NULL;
ogs_assert(sess);
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
return mme_ue_in_attach(mme_ue);
}
unsigned int mme_sess_count(mme_ue_t *mme_ue)
{
unsigned int count = 0;

View File

@ -790,11 +790,6 @@ mme_sess_t *mme_sess_first(mme_ue_t *mme_ue);
mme_sess_t *mme_sess_next(mme_sess_t *sess);
unsigned int mme_sess_count(mme_ue_t *mme_ue);
#define UE_CONTEXT_IN_ATTACH(__mME) mme_ue_in_attach(__mME)
#define SESSION_CONTEXT_IN_ATTACH(__sESS) mme_sess_in_attach(__sESS)
bool mme_ue_in_attach(mme_ue_t *mme_ue);
bool mme_sess_in_attach(mme_sess_t *sess);
mme_bearer_t *mme_bearer_add(mme_sess_t *sess);
void mme_bearer_remove(mme_bearer_t *bearer);
void mme_bearer_remove_all(mme_sess_t *sess);

View File

@ -83,6 +83,7 @@ typedef struct mme_event_s {
ogs_gtp_node_t *gnode;
uint8_t nas_type;
bool esm_piggybacked;
ogs_nas_eps_message_t *nas_message;
ogs_diam_s6a_message_t *s6a_message;

View File

@ -199,7 +199,7 @@ void mme_gtp_close(void)
ogs_socknode_remove_all(&ogs_gtp_self()->gtpc_list6);
}
int mme_gtp_send_create_session_request(mme_sess_t *sess)
int mme_gtp_send_create_session_request(mme_sess_t *sess, bool esm_piggybacked)
{
int rv;
ogs_gtp_header_t h;
@ -219,6 +219,7 @@ int mme_gtp_send_create_session_request(mme_sess_t *sess)
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, sess);
ogs_expect_or_return_val(xact, OGS_ERROR);
xact->esm_piggybacked = esm_piggybacked;
rv = ogs_gtp_xact_commit(xact);
ogs_expect(rv == OGS_OK);

View File

@ -29,7 +29,7 @@ extern "C" {
int mme_gtp_open(void);
void mme_gtp_close(void);
int mme_gtp_send_create_session_request(mme_sess_t *sess);
int mme_gtp_send_create_session_request(mme_sess_t *sess, bool esm_piggybacked);
int mme_gtp_send_modify_bearer_request(mme_bearer_t *bearer, int uli_presence);
int mme_gtp_send_delete_session_request(mme_sess_t *sess, int action);
void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action);
@ -57,4 +57,4 @@ int mme_gtp_send_bearer_resource_command(
}
#endif
#endif /* MME_S11_PATH_H */
#endif /* MME_S11_PATH_H */

View File

@ -92,8 +92,10 @@ void mme_s11_handle_create_session_response(
ogs_gtp_bearer_qos_t bearer_qos;
ogs_gtp_ambr_t *ambr = NULL;
uint16_t decoded = 0;
bool esm_piggybacked = false;
ogs_assert(xact);
esm_piggybacked = xact->esm_piggybacked;
ogs_assert(rsp);
ogs_debug("Create Session Response");
@ -180,7 +182,7 @@ void mme_s11_handle_create_session_response(
cause_value !=
OGS_GTP_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
if (mme_ue_from_teid && mme_ue) {
if (UE_CONTEXT_IN_ATTACH(mme_ue)) {
if (esm_piggybacked == true) {
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
ogs_assert(OGS_OK ==
nas_eps_send_attach_reject(mme_ue,
@ -245,7 +247,7 @@ void mme_s11_handle_create_session_response(
rv = ogs_gtp_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip);
ogs_assert(rv == OGS_OK);
if (SESSION_CONTEXT_IN_ATTACH(sess)) {
if (esm_piggybacked == true) {
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
mme_ue->csmap = csmap;

View File

@ -56,7 +56,7 @@ int nas_eps_send_emm_to_esm(mme_ue_t *mme_ue,
ogs_pkbuf_put_data(esmbuf,
esm_message_container->buffer, esm_message_container->length);
rv = s1ap_send_to_esm(mme_ue, esmbuf, 0);
rv = s1ap_send_to_esm(mme_ue, esmbuf, 0, true);
ogs_expect(rv == OGS_OK);
return rv;
@ -105,7 +105,7 @@ int nas_eps_send_attach_accept(mme_ue_t *mme_ue)
ogs_debug("[%s] Attach accept", mme_ue->imsi_bcd);
esmbuf = esm_build_activate_default_bearer_context_request(sess);
esmbuf = esm_build_activate_default_bearer_context_request(sess, true);
ogs_expect_or_return_val(esmbuf, OGS_ERROR);
emmbuf = emm_build_attach_accept(mme_ue, esmbuf);
@ -140,7 +140,7 @@ int nas_eps_send_attach_reject(mme_ue_t *mme_ue,
sess = mme_sess_first(mme_ue);
if (sess) {
esmbuf = esm_build_pdn_connectivity_reject(sess, esm_cause);
esmbuf = esm_build_pdn_connectivity_reject(sess, esm_cause, true);
ogs_expect_or_return_val(esmbuf, OGS_ERROR);
}
@ -285,7 +285,7 @@ int nas_eps_send_detach_accept(mme_ue_t *mme_ue)
}
int nas_eps_send_pdn_connectivity_reject(
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause)
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause, bool esm_piggybacked)
{
int rv;
mme_ue_t *mme_ue;
@ -295,14 +295,14 @@ int nas_eps_send_pdn_connectivity_reject(
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
if (SESSION_CONTEXT_IN_ATTACH(sess)) {
if (esm_piggybacked == true) {
/* During the UE-attach process, we'll send Attach-Reject
* with pyggybacking PDN-connectivity-Reject */
rv = nas_eps_send_attach_reject(mme_ue,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, esm_cause);
ogs_expect(rv == OGS_OK);
} else {
esmbuf = esm_build_pdn_connectivity_reject(sess, esm_cause);
esmbuf = esm_build_pdn_connectivity_reject(sess, esm_cause, false);
ogs_expect_or_return_val(esmbuf, OGS_ERROR);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, esmbuf);
@ -355,7 +355,7 @@ int nas_eps_send_activate_default_bearer_context_request(mme_bearer_t *bearer)
mme_ue = bearer->mme_ue;
ogs_assert(mme_ue);
esmbuf = esm_build_activate_default_bearer_context_request(sess);
esmbuf = esm_build_activate_default_bearer_context_request(sess, false);
ogs_expect_or_return_val(esmbuf, OGS_ERROR);
s1apbuf = s1ap_build_e_rab_setup_request(bearer, esmbuf);

View File

@ -46,7 +46,7 @@ int nas_eps_send_security_mode_command(mme_ue_t *mme_ue);
int nas_eps_send_detach_accept(mme_ue_t *mme_ue);
int nas_eps_send_pdn_connectivity_reject(
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause);
mme_sess_t *sess, ogs_nas_esm_cause_t esm_cause, bool esm_piggybacked);
int nas_eps_send_esm_information_request(mme_bearer_t *bearer);
int nas_eps_send_activate_default_bearer_context_request(mme_bearer_t *bearer);
int nas_eps_send_activate_dedicated_bearer_context_request(
@ -75,4 +75,4 @@ int nas_eps_send_downlink_nas_transport(
}
#endif
#endif /* NAS_EPS_PATH_H */
#endif /* NAS_EPS_PATH_H */

View File

@ -115,7 +115,9 @@ int s1ap_delayed_send_to_enb_ue(
}
}
int s1ap_send_to_esm(mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf, uint8_t nas_type)
int s1ap_send_to_esm(
mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf,
uint8_t nas_type, bool esm_piggybacked)
{
int rv;
mme_event_t *e = NULL;
@ -128,6 +130,7 @@ int s1ap_send_to_esm(mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf, uint8_t nas_type)
e->mme_ue = mme_ue;
e->pkbuf = esmbuf;
e->nas_type = nas_type;
e->esm_piggybacked = esm_piggybacked;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
@ -231,7 +234,8 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
ogs_pkbuf_free(nasbuf);
return OGS_ERROR;
}
return s1ap_send_to_esm(mme_ue, nasbuf, security_header_type.type);
return s1ap_send_to_esm(
mme_ue, nasbuf, security_header_type.type, false);
} else {
ogs_error("Unknown/Unimplemented NAS Protocol discriminator 0x%02x",
h->protocol_discriminator);

View File

@ -44,7 +44,9 @@ int s1ap_delayed_send_to_enb_ue(enb_ue_t *enb_ue,
ogs_pkbuf_t *pkbuf, ogs_time_t duration);
int s1ap_send_to_nas(enb_ue_t *enb_ue,
S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu);
int s1ap_send_to_esm(mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf, uint8_t nas_type);
int s1ap_send_to_esm(
mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf,
uint8_t nas_type, bool esm_piggybacked);
int s1ap_send_s1_setup_response(mme_enb_t *enb);
int s1ap_send_s1_setup_failure(