[SMF] Gy: Check Multiple-Services-Credit-Control Result-Code in CCA-I

This is the continuation of commit
12158eebb8, which only checked the code in
CCA[Update], but not in CCA[Initial].

The handling in CCA[Initial] is a bit more complex since depending on
the outcome, we may end up with a Result-Code != SUCCESS in MSCC but the
session may still be created at the OCS because the message Result-Code
= SUCCESS. In that scenario, we want to abort setting up the PDN session
but we still need to make sure we terminate the Gy session that was just
created.
This commit is contained in:
Pau Espin 2024-04-04 17:38:26 +02:00 committed by Sukchan Lee
parent eb2b19b39c
commit 990bfe96a8
3 changed files with 36 additions and 9 deletions

View File

@ -337,6 +337,7 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
ogs_diam_gy_message_t *gy_message = NULL;
ogs_diam_gx_message_t *gx_message = NULL;
uint32_t diam_err;
bool need_gy_terminate = false;
ogs_assert(s);
ogs_assert(e);
@ -392,7 +393,7 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
case OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_assert(e->gtp_xact);
diam_err = smf_gy_handle_cca_initial_request(sess,
gy_message, e->gtp_xact);
gy_message, e->gtp_xact, &need_gy_terminate);
sess->sm_data.gy_ccr_init_in_flight = false;
sess->sm_data.gy_cca_init_err = diam_err;
goto test_can_proceed;
@ -422,8 +423,16 @@ test_can_proceed:
smf_epc_pfcp_send_session_establishment_request(
sess, e->gtp_xact, 0));
} else {
/* FIXME: tear down Gx/Gy session
* if its sm_data.*init_err == ER_DIAMETER_SUCCESS */
/* Tear down Gx/Gy session if its sm_data.*init_err == ER_DIAMETER_SUCCESS */
if (sess->sm_data.gx_cca_init_err == ER_DIAMETER_SUCCESS) {
sess->sm_data.gx_ccr_term_in_flight = true;
smf_gx_send_ccr(sess, e->gtp_xact, OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST);
}
if (smf_use_gy_iface() == 1 &&
(sess->sm_data.gy_cca_init_err == ER_DIAMETER_SUCCESS || need_gy_terminate)) {
sess->sm_data.gy_ccr_term_in_flight = true;
smf_gy_send_ccr(sess, e->gtp_xact, OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST);
}
uint8_t gtp_cause = gtp_cause_from_diameter(
e->gtp_xact->gtp_version, diam_err, NULL);
send_gtp_create_err_msg(sess, e->gtp_xact, gtp_cause);

View File

@ -113,24 +113,41 @@ static void urr_update_time(smf_sess_t *sess, ogs_pfcp_urr_t *urr, ogs_diam_gy_m
}
}
/* Returns ER_DIAMETER_SUCCESS on success, Diameter error code on failue. */
/* Returns ER_DIAMETER_SUCCESS on success, Diameter error code on failue.
* Upon failure, CCR-Terminate is needed based on "need_termination" value (this
* may happen eg. if messaged RC is successful but MSCC RC is rejected). */
uint32_t smf_gy_handle_cca_initial_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_gtp_xact_t *gtp_xact)
ogs_gtp_xact_t *gtp_xact,
bool *need_termination)
{
smf_bearer_t *bearer;
ogs_assert(sess);
ogs_assert(gy_message);
ogs_assert(gtp_xact);
ogs_assert(need_termination);
ogs_debug("[Gy CCA Initial]");
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (gy_message->result_code != ER_DIAMETER_SUCCESS)
*need_termination = false;
if (gy_message->result_code != ER_DIAMETER_SUCCESS) {
ogs_warn("Gy CCA Initial Diameter failure: res=%u",
gy_message->result_code);
return gy_message->err ? *gy_message->err :
ER_DIAMETER_AUTHENTICATION_REJECTED;
}
if (gy_message->cca.result_code != ER_DIAMETER_SUCCESS) {
ogs_warn("Gy CCA Initial Diameter Multiple-Services-Credit-Control Result-Code=%u",
gy_message->cca.result_code);
/* Message RC was successful but MSCC was rejected. The session needs to
* be tear down through CCR-T: */
*need_termination = true;
return gy_message->cca.err ? *gy_message->cca.err :
ER_DIAMETER_AUTHENTICATION_REJECTED;
}
bearer = smf_default_bearer_in_sess(sess);
ogs_assert(bearer);
@ -173,8 +190,8 @@ uint32_t smf_gy_handle_cca_update_request(
sess->sgw_s5c_teid, sess->smf_n4_teid);
if (gy_message->result_code != ER_DIAMETER_SUCCESS) {
ogs_warn("Gy CCA Update Diameter failure: res=%u err=%u",
gy_message->result_code, *gy_message->err);
ogs_warn("Gy CCA Update Diameter failure: Result-Code=%u",
gy_message->result_code);
return gy_message->err ? *gy_message->err :
ER_DIAMETER_AUTHENTICATION_REJECTED;
}

View File

@ -29,7 +29,8 @@ extern "C" {
uint32_t smf_gy_handle_cca_initial_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_gtp_xact_t *gtp_xact);
ogs_gtp_xact_t *gtp_xact,
bool *need_termination);
uint32_t smf_gy_handle_cca_update_request(
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
ogs_pfcp_xact_t *pfcp_xact);