open5gs/src/mme/esm_build.c

348 lines
12 KiB
C
Raw Normal View History

2019-06-11 09:28:25 +00:00
#include "nas/nas-message.h"
2017-04-11 03:57:54 +00:00
#include "nas_security.h"
#include "esm_build.h"
2017-11-30 11:13:15 +00:00
#include "mme_sm.h"
2017-04-11 03:57:54 +00:00
2019-04-27 14:54:30 +00:00
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __esm_log_domain
int esm_build_pdn_connectivity_reject(
ogs_pkbuf_t **pkbuf, mme_sess_t *sess, nas_esm_cause_t esm_cause)
2017-08-11 03:05:01 +00:00
{
2017-09-08 09:50:27 +00:00
mme_ue_t *mme_ue = NULL;
2017-08-11 03:05:01 +00:00
nas_message_t message;
nas_pdn_connectivity_reject_t *pdn_connectivity_reject =
&message.esm.pdn_connectivity_reject;
2019-04-27 14:54:30 +00:00
ogs_assert(sess);
2017-09-08 09:50:27 +00:00
mme_ue = sess->mme_ue;
2019-04-27 14:54:30 +00:00
ogs_assert(mme_ue);
2017-09-08 09:50:27 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[ESM] PDN connectivity reject");
ogs_debug(" IMSI[%s] PTI[%d] Cause[%d]",
2018-01-22 14:14:20 +00:00
mme_ue->imsi_bcd, sess->pti, esm_cause);
2017-08-11 03:05:01 +00:00
memset(&message, 0, sizeof(message));
2019-04-27 14:54:30 +00:00
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_registered))
2017-09-08 09:50:27 +00:00
{
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
}
2017-08-11 03:05:01 +00:00
message.esm.h.eps_bearer_identity = 0;
message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM;
2017-09-08 09:50:27 +00:00
message.esm.h.procedure_transaction_identity = sess->pti;
2017-08-11 03:05:01 +00:00
message.esm.h.message_type = NAS_PDN_CONNECTIVITY_REJECT;
pdn_connectivity_reject->esm_cause = esm_cause;
2019-04-27 14:54:30 +00:00
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_registered))
2017-09-08 09:50:27 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_assert(nas_security_encode(pkbuf, mme_ue, &message) == OGS_OK &&
*pkbuf);
2017-09-08 09:50:27 +00:00
}
else
{
2019-04-27 14:54:30 +00:00
ogs_assert(nas_plain_encode(pkbuf, &message) == OGS_OK && *pkbuf);
2017-09-08 09:50:27 +00:00
}
2017-08-11 03:05:01 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-11 03:05:01 +00:00
}
2019-04-27 14:54:30 +00:00
int esm_build_information_request(ogs_pkbuf_t **pkbuf, mme_bearer_t *bearer)
2017-04-11 03:57:54 +00:00
{
nas_message_t message;
mme_ue_t *mme_ue = NULL;
2017-09-07 12:28:12 +00:00
mme_sess_t *sess = NULL;
2017-04-11 03:57:54 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(bearer);
2017-09-07 12:28:12 +00:00
sess = bearer->sess;
2019-04-27 14:54:30 +00:00
ogs_assert(sess);
mme_ue = bearer->mme_ue;
2019-04-27 14:54:30 +00:00
ogs_assert(mme_ue);
2017-04-11 03:57:54 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[ESM] ESM information request");
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
2018-01-22 14:14:20 +00:00
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
2017-04-11 03:57:54 +00:00
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM;
2017-09-07 12:28:12 +00:00
message.esm.h.procedure_transaction_identity = sess->pti;
2017-04-11 03:57:54 +00:00
message.esm.h.message_type = NAS_ESM_INFORMATION_REQUEST;
2019-04-27 14:54:30 +00:00
ogs_assert(nas_security_encode(pkbuf, mme_ue, &message) == OGS_OK &&
*pkbuf);
2017-04-11 03:57:54 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-04-11 03:57:54 +00:00
}
2019-04-27 14:54:30 +00:00
int esm_build_activate_default_bearer_context_request(
ogs_pkbuf_t **pkbuf, mme_sess_t *sess)
2017-04-13 02:08:42 +00:00
{
nas_message_t message;
2017-04-13 03:21:47 +00:00
nas_activate_default_eps_bearer_context_request_t
*activate_default_eps_bearer_context_request =
&message.esm.activate_default_eps_bearer_context_request;
nas_eps_quality_of_service_t *eps_qos =
&activate_default_eps_bearer_context_request->eps_qos;
nas_access_point_name_t *access_point_name =
&activate_default_eps_bearer_context_request->access_point_name;
nas_pdn_address_t *pdn_address =
&activate_default_eps_bearer_context_request->pdn_address;
nas_apn_aggregate_maximum_bit_rate_t *apn_ambr =
&activate_default_eps_bearer_context_request->apn_ambr;
nas_protocol_configuration_options_t *protocol_configuration_options =
&activate_default_eps_bearer_context_request
->protocol_configuration_options;
mme_ue_t *mme_ue = NULL;
mme_bearer_t *bearer = NULL;
2017-04-13 03:21:47 +00:00
pdn_t *pdn = NULL;
2017-04-13 02:08:42 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(sess);
2017-08-11 11:25:52 +00:00
mme_ue = sess->mme_ue;
2019-04-27 14:54:30 +00:00
ogs_assert(mme_ue);
2017-08-11 11:25:52 +00:00
pdn = sess->pdn;
2019-04-27 14:54:30 +00:00
ogs_assert(pdn);
bearer = mme_default_bearer_in_sess(sess);
2019-04-27 14:54:30 +00:00
ogs_assert(bearer);
ogs_assert(mme_bearer_next(bearer) == NULL);
2017-04-13 02:08:42 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[ESM] Activate default bearer context request");
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
2018-01-22 14:14:20 +00:00
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
2017-04-13 02:08:42 +00:00
memset(&message, 0, sizeof(message));
2019-04-27 14:54:30 +00:00
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_registered))
2017-09-06 15:37:16 +00:00
{
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
}
message.esm.h.eps_bearer_identity = bearer->ebi;
2017-04-13 02:08:42 +00:00
message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM;
2017-09-07 12:28:12 +00:00
message.esm.h.procedure_transaction_identity = sess->pti;
2017-04-13 03:21:47 +00:00
message.esm.h.message_type =
NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST;
memcpy(&bearer->qos, &pdn->qos, sizeof(qos_t));
eps_qos_build(eps_qos, bearer->qos.qci,
bearer->qos.mbr.downlink, bearer->qos.mbr.uplink,
bearer->qos.gbr.downlink, bearer->qos.gbr.uplink);
2017-04-13 03:21:47 +00:00
access_point_name->length = strlen(pdn->apn);
2019-04-27 14:54:30 +00:00
ogs_cpystrn(access_point_name->apn, pdn->apn,
ogs_min(access_point_name->length, MAX_APN_LEN) + 1);
ogs_debug(" APN[%s]", pdn->apn);
2017-04-13 03:21:47 +00:00
2017-12-14 12:42:19 +00:00
pdn_address->pdn_type = pdn->paa.pdn_type;
if (pdn_address->pdn_type == GTP_PDN_TYPE_IPV4)
{
pdn_address->addr = pdn->paa.addr;
pdn_address->length = NAS_PDN_ADDRESS_IPV4_LEN;
2019-04-27 14:54:30 +00:00
ogs_debug(" IPv4");
2017-12-14 12:42:19 +00:00
}
else if (pdn_address->pdn_type == GTP_PDN_TYPE_IPV6)
{
memcpy(pdn_address->addr6, pdn->paa.addr6+(IPV6_LEN>>1), IPV6_LEN>>1);
2017-12-14 12:42:19 +00:00
pdn_address->length = NAS_PDN_ADDRESS_IPV6_LEN;
2019-04-27 14:54:30 +00:00
ogs_debug(" IPv6");
2017-12-14 12:42:19 +00:00
}
else if (pdn_address->pdn_type == GTP_PDN_TYPE_IPV4V6)
{
pdn_address->both.addr = pdn->paa.both.addr;
memcpy(pdn_address->both.addr6,
pdn->paa.both.addr6+(IPV6_LEN>>1), IPV6_LEN>>1);
2017-12-14 12:42:19 +00:00
pdn_address->length = NAS_PDN_ADDRESS_IPV4V6_LEN;
2019-04-27 14:54:30 +00:00
ogs_debug(" IPv4v6");
2017-12-14 12:42:19 +00:00
}
else
2019-04-27 14:54:30 +00:00
ogs_assert_if_reached();
2017-04-13 03:21:47 +00:00
if (pdn->ambr.downlink || pdn->ambr.uplink)
2017-08-20 10:04:23 +00:00
{
activate_default_eps_bearer_context_request->presencemask |=
NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_APN_AMBR_PRESENT;
apn_ambr_build(apn_ambr, pdn->ambr.downlink, pdn->ambr.uplink);
2017-08-20 10:04:23 +00:00
}
2017-04-13 03:21:47 +00:00
if (sess->pgw_pco.presence && sess->pgw_pco.len && sess->pgw_pco.data)
2017-04-13 03:21:47 +00:00
{
activate_default_eps_bearer_context_request->presencemask |=
NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
protocol_configuration_options->length = sess->pgw_pco.len;
2017-04-13 03:21:47 +00:00
memcpy(protocol_configuration_options->buffer,
sess->pgw_pco.data, protocol_configuration_options->length);
2017-04-13 03:21:47 +00:00
}
2017-04-13 02:08:42 +00:00
2019-04-27 14:54:30 +00:00
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_registered))
2017-09-06 15:37:16 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_assert(nas_security_encode(pkbuf, mme_ue, &message) == OGS_OK &&
*pkbuf);
2017-09-06 15:37:16 +00:00
}
else
{
2019-04-27 14:54:30 +00:00
ogs_assert(nas_plain_encode(pkbuf, &message) == OGS_OK && *pkbuf);
2017-09-06 15:37:16 +00:00
}
2017-04-13 02:08:42 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-04-13 02:08:42 +00:00
}
2017-09-04 15:04:05 +00:00
2019-04-27 14:54:30 +00:00
int esm_build_activate_dedicated_bearer_context_request(
ogs_pkbuf_t **pkbuf, mme_bearer_t *bearer)
2017-09-04 15:04:05 +00:00
{
mme_ue_t *mme_ue = NULL;
mme_bearer_t *linked_bearer = NULL;
nas_message_t message;
nas_activate_dedicated_eps_bearer_context_request_t
*activate_dedicated_eps_bearer_context_request =
&message.esm.activate_dedicated_eps_bearer_context_request;
nas_linked_eps_bearer_identity_t *linked_ebi =
&activate_dedicated_eps_bearer_context_request->
linked_eps_bearer_identity;
nas_eps_quality_of_service_t *eps_qos =
&activate_dedicated_eps_bearer_context_request->eps_qos;
2017-09-06 06:38:24 +00:00
nas_traffic_flow_template_t *tft =
&activate_dedicated_eps_bearer_context_request->tft;
2017-09-04 15:04:05 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(bearer);
2017-09-04 15:04:05 +00:00
mme_ue = bearer->mme_ue;
2019-04-27 14:54:30 +00:00
ogs_assert(mme_ue);
2017-09-04 15:04:05 +00:00
linked_bearer = mme_linked_bearer(bearer);
2019-04-27 14:54:30 +00:00
ogs_assert(linked_bearer);
2017-09-04 15:04:05 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[ESM] Activate dedicated bearer context request");
ogs_debug(" IMSI[%s] EBI[%d] Linked-EBI[%d]",
2018-01-22 14:14:20 +00:00
mme_ue->imsi_bcd, bearer->ebi, linked_bearer->ebi);
2017-09-04 15:04:05 +00:00
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.esm.h.eps_bearer_identity = bearer->ebi;
message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM;
message.esm.h.procedure_transaction_identity = 0;
message.esm.h.message_type =
NAS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST;
linked_ebi->eps_bearer_identity = linked_bearer->ebi;
eps_qos_build(eps_qos, bearer->qos.qci,
bearer->qos.mbr.downlink, bearer->qos.mbr.uplink,
bearer->qos.gbr.downlink, bearer->qos.gbr.uplink);
tft->length = bearer->tft.len;
2019-04-27 14:54:30 +00:00
ogs_assert(tft->length);
ogs_assert(bearer->tft.data);
memcpy(tft->buffer, bearer->tft.data, tft->length);
2019-04-27 14:54:30 +00:00
ogs_assert(nas_security_encode(pkbuf, mme_ue, &message) == OGS_OK &&
*pkbuf);
2017-09-04 15:04:05 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-09-04 15:04:05 +00:00
}
2017-09-07 14:41:05 +00:00
2019-04-27 14:54:30 +00:00
int esm_build_modify_bearer_context_request(
ogs_pkbuf_t **pkbuf, mme_bearer_t *bearer, int qos_presence, int tft_presence)
{
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess = NULL;
nas_message_t message;
nas_modify_eps_bearer_context_request_t
*modify_eps_bearer_context_request =
&message.esm.modify_eps_bearer_context_request;
nas_eps_quality_of_service_t *new_eps_qos =
&modify_eps_bearer_context_request->new_eps_qos;
nas_traffic_flow_template_t *tft =
&modify_eps_bearer_context_request->tft;
2019-04-27 14:54:30 +00:00
ogs_assert(bearer);
sess = bearer->sess;
2019-04-27 14:54:30 +00:00
ogs_assert(sess);
mme_ue = bearer->mme_ue;
2019-04-27 14:54:30 +00:00
ogs_assert(mme_ue);
2019-04-27 14:54:30 +00:00
ogs_debug("[ESM] Modify bearer context request");
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
2018-01-22 14:14:20 +00:00
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.esm.h.eps_bearer_identity = bearer->ebi;
message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM;
message.esm.h.procedure_transaction_identity = sess->pti;
message.esm.h.message_type = NAS_MODIFY_EPS_BEARER_CONTEXT_REQUEST;
if (qos_presence == 1)
{
modify_eps_bearer_context_request->presencemask |=
NAS_MODIFY_EPS_BEARER_CONTEXT_REQUEST_NEW_EPS_QOS_PRESENT;
eps_qos_build(new_eps_qos, bearer->qos.qci,
bearer->qos.mbr.downlink, bearer->qos.mbr.uplink,
bearer->qos.gbr.downlink, bearer->qos.gbr.uplink);
}
if (tft_presence == 1)
{
modify_eps_bearer_context_request->presencemask |=
NAS_MODIFY_EPS_BEARER_CONTEXT_REQUEST_TFT_PRESENT;
tft->length = bearer->tft.len;
2019-04-27 14:54:30 +00:00
ogs_assert(tft->length);
ogs_assert(bearer->tft.data);
memcpy(tft->buffer, bearer->tft.data, tft->length);
}
2019-04-27 14:54:30 +00:00
ogs_assert(nas_security_encode(pkbuf, mme_ue, &message) == OGS_OK &&
*pkbuf);
2019-04-27 14:54:30 +00:00
return OGS_OK;
}
2019-04-27 14:54:30 +00:00
int esm_build_deactivate_bearer_context_request(
ogs_pkbuf_t **pkbuf, mme_bearer_t *bearer, nas_esm_cause_t esm_cause)
2017-09-07 14:41:05 +00:00
{
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess = NULL;
nas_message_t message;
nas_deactivate_eps_bearer_context_request_t
*deactivate_eps_bearer_context_request =
&message.esm.deactivate_eps_bearer_context_request;
2019-04-27 14:54:30 +00:00
ogs_assert(bearer);
2017-09-07 14:41:05 +00:00
sess = bearer->sess;
2019-04-27 14:54:30 +00:00
ogs_assert(sess);
2017-09-07 14:41:05 +00:00
mme_ue = bearer->mme_ue;
2019-04-27 14:54:30 +00:00
ogs_assert(mme_ue);
2017-09-07 14:41:05 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[ESM] Deactivate bearer context request");
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
2018-01-22 14:14:20 +00:00
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
2019-04-27 14:54:30 +00:00
ogs_debug(" Cause[%d]", esm_cause);
2018-01-22 14:14:20 +00:00
2017-09-07 14:41:05 +00:00
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.esm.h.eps_bearer_identity = bearer->ebi;
message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM;
message.esm.h.procedure_transaction_identity = sess->pti;
message.esm.h.message_type = NAS_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST;
2017-09-07 14:41:05 +00:00
deactivate_eps_bearer_context_request->esm_cause = esm_cause;
2019-04-27 14:54:30 +00:00
ogs_assert(nas_security_encode(pkbuf, mme_ue, &message) == OGS_OK &&
*pkbuf);
2017-09-07 14:41:05 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-09-07 14:41:05 +00:00
}