From ed0c1f4efb893f71360d40d931da50aadb76ce1e Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Sun, 7 Jul 2024 19:44:08 +0200 Subject: [PATCH] [SMF]: Issue PFCP session modification request if there are additional flows in RAR --- src/smf/binding.c | 102 +++++++++++++++++++++++++++---------------- src/smf/binding.h | 1 + src/smf/n4-handler.c | 4 ++ 3 files changed, 69 insertions(+), 38 deletions(-) diff --git a/src/smf/binding.c b/src/smf/binding.c index 4024dc310e..3617e8973c 100644 --- a/src/smf/binding.c +++ b/src/smf/binding.c @@ -127,9 +127,6 @@ void smf_bearer_binding(smf_sess_t *sess) ogs_assert(sess); for (i = 0; i < sess->policy.num_of_pcc_rule; i++) { - ogs_gtp_xact_t *xact = NULL; - ogs_gtp2_header_t h; - ogs_pkbuf_t *pkbuf = NULL; smf_bearer_t *bearer = NULL; ogs_pcc_rule_t *pcc_rule = &sess->policy.pcc_rule[i]; @@ -359,45 +356,21 @@ void smf_bearer_binding(smf_sess_t *sess) OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); } else { - ogs_gtp2_tft_t tft; + uint64_t pfcp_flags = OGS_PFCP_MODIFY_NETWORK_REQUESTED; - memset(&tft, 0, sizeof tft); if (ogs_list_count(&bearer->pf_to_add_list) > 0) { - encode_traffic_flow_template( - &tft, bearer, - OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT); + pfcp_flags |= OGS_PFCP_MODIFY_EPC_TFT_UPDATE; + smf_bearer_tft_update(bearer); } - - memset(&h, 0, sizeof(ogs_gtp2_header_t)); - h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE; - h.teid = sess->sgw_s5c_teid; - - pkbuf = smf_s5c_build_update_bearer_request( - h.type, bearer, - OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, - (ogs_list_count(&bearer->pf_to_add_list) > 0) ? - &tft : NULL, qos_presence); - if (!pkbuf) { - ogs_error("smf_s5c_build_update_bearer_request() failed"); - return; - } - - xact = ogs_gtp_xact_local_create( - sess->gnode, &h, pkbuf, gtp_bearer_timeout, - OGS_UINT_TO_POINTER(bearer->id)); - if (!xact) { - ogs_error("ogs_gtp_xact_local_create() failed"); - return; + if (qos_presence == true) { + pfcp_flags |= OGS_PFCP_MODIFY_EPC_QOS_UPDATE; + smf_bearer_qos_update(bearer); } - xact->local_teid = sess->smf_n4_teid; - - if (ogs_list_count(&bearer->pf_to_add_list) > 0) - xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE; - if (qos_presence == true) - xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE; - - rv = ogs_gtp_xact_commit(xact); - ogs_expect(rv == OGS_OK); + ogs_assert(OGS_OK == + smf_epc_pfcp_send_one_bearer_modification_request( + bearer, OGS_INVALID_POOL_ID, pfcp_flags, + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, + OGS_GTP2_CAUSE_UNDEFINED_VALUE)); } } else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) { @@ -474,6 +447,59 @@ int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer) return rv; } +int smf_gtp2_send_update_bearer_request(smf_bearer_t *bearer) +{ + int rv; + + smf_sess_t *sess = NULL; + ogs_gtp_xact_t *xact = NULL; + + ogs_gtp2_header_t h; + ogs_pkbuf_t *pkbuf = NULL; + ogs_gtp2_tft_t tft; + + ogs_assert(bearer); + sess = smf_sess_find_by_id(bearer->sess_id); + ogs_assert(sess); + + memset(&h, 0, sizeof(ogs_gtp2_header_t)); + h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE; + h.teid = sess->sgw_s5c_teid; + + memset(&tft, 0, sizeof tft); + if (ogs_list_count(&bearer->pf_to_add_list) > 0) { + encode_traffic_flow_template(&tft, bearer, + OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT); + } + + pkbuf = smf_s5c_build_update_bearer_request( + h.type, bearer, + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, + (ogs_list_count(&bearer->pf_to_add_list) > 0) ? + &tft : NULL, true); + if (!pkbuf) { + ogs_error("smf_s5c_build_update_bearer_request() failed"); + return OGS_ERROR; + } + + xact = ogs_gtp_xact_local_create( + sess->gnode, &h, pkbuf, gtp_bearer_timeout, + OGS_UINT_TO_POINTER(bearer->id)); + if (!xact) { + ogs_error("ogs_gtp_xact_local_create() failed"); + return OGS_ERROR; + } + xact->local_teid = sess->smf_n4_teid; + xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE; + if (ogs_list_count(&bearer->pf_to_add_list) > 0) + xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE; + + rv = ogs_gtp_xact_commit(xact); + ogs_expect(rv == OGS_OK); + + return rv; +} + void smf_qos_flow_binding(smf_sess_t *sess) { int rv; diff --git a/src/smf/binding.h b/src/smf/binding.h index 511028e3b3..b8b3774cd8 100644 --- a/src/smf/binding.h +++ b/src/smf/binding.h @@ -28,6 +28,7 @@ extern "C" { void smf_bearer_binding(smf_sess_t *sess); int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer); +int smf_gtp2_send_update_bearer_request(smf_bearer_t *bearer); void smf_qos_flow_binding(smf_sess_t *sess); diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 48d560880b..2f5fcb419d 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -950,6 +950,10 @@ void smf_epc_n4_handle_session_modification_response( } else if (flags & OGS_PFCP_MODIFY_CREATE) { ogs_assert(bearer); ogs_assert(OGS_OK == smf_gtp2_send_create_bearer_request(bearer)); + + } else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) { + ogs_assert(bearer); + ogs_assert(OGS_OK == smf_gtp2_send_update_bearer_request(bearer)); } else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) { /*