Skip to content

Commit

Permalink
[SMF] Gy: Check Multiple-Services-Credit-Control Result-Code in CCA-I
Browse files Browse the repository at this point in the history
This is the continuation of commit
12158ee, 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.
  • Loading branch information
pespin committed Apr 4, 2024
1 parent eb2b19b commit ff4e977
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 9 deletions.
15 changes: 12 additions & 3 deletions src/smf/gsm-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -422,8 +423,16 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
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);
Expand Down
27 changes: 22 additions & 5 deletions src/smf/gy-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/smf/gy-handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ff4e977

Please sign in to comment.