[SMF] Optimiza Session Modification Message

For video in VoNR, multiple QosFlow is required in one session.

In the past, since only one Session Modification Message was supported,
QoS-Flow was put into several Session Messages one by one and processed.

Now that multiple QoS-Flows can be supported,
it is optimized to process one session modification message.
main
Sukchan Lee 9 months ago
parent a7e2a071e0
commit e0a487f479
  1. 2
      docker/docker-compose.yml
  2. 12
      src/sgwc/sxa-handler.c
  3. 75
      src/smf/binding.c
  4. 2
      src/smf/gn-handler.c
  5. 185
      src/smf/gsm-build.c
  6. 4
      src/smf/gsm-build.h
  7. 54
      src/smf/gsm-handler.c
  8. 2
      src/smf/gy-handler.c
  9. 82
      src/smf/n4-handler.c
  10. 133
      src/smf/ngap-build.c
  11. 9
      src/smf/ngap-build.h
  12. 45
      src/smf/ngap-handler.c
  13. 6
      src/smf/nsmf-handler.c
  14. 130
      src/smf/pfcp-path.c
  15. 16
      src/smf/pfcp-path.h
  16. 57
      src/smf/s5c-handler.c
  17. 5
      tests/common/context.h
  18. 55
      tests/common/ngap-build.c
  19. 2
      tests/common/ngap-build.h
  20. 44
      tests/vonr/video-test.c

@ -67,7 +67,7 @@ services:
volumes:
- home:/home/${USER}
- ${HOME}:/mnt
- /tmp/.X11-unix:/tmp/.X11-unix
# - /tmp/.X11-unix:/tmp/.X11-unix
# - /etc/localtime:/etc/localtime:ro
# - /usr/share/zoneinfo/Europe/Helsinki:/etc/localtime:ro
hostname: open5gs-dev

@ -448,8 +448,6 @@ void sgwc_sxa_handle_session_modification_response(
ogs_gtp2_cause_t cause;
OGS_LIST(pdr_to_create_list);
ogs_debug("Session Modification Response");
ogs_assert(pfcp_xact);
@ -507,6 +505,8 @@ void sgwc_sxa_handle_session_modification_response(
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_far_t *far = NULL;
OGS_LIST(pdr_to_create_list);
ogs_assert(sess);
ogs_list_copy(&pdr_to_create_list, &pfcp_xact->pdr_to_create_list);
@ -938,9 +938,14 @@ void sgwc_sxa_handle_session_modification_response(
}
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
OGS_LIST(bearer_to_modify_list);
s11_xact = pfcp_xact->assoc_xact;
ogs_assert(s11_xact);
ogs_list_copy(&bearer_to_modify_list,
&pfcp_xact->bearer_to_modify_list);
ogs_pfcp_xact_commit(pfcp_xact);
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
@ -968,7 +973,8 @@ void sgwc_sxa_handle_session_modification_response(
/* Send Data Plane(UL) : SGW-S1U */
i = 0;
ogs_list_for_each(&sess->bearer_list, bearer) {
ogs_list_for_each_entry(
&bearer_to_modify_list, bearer, to_modify_node) {
ogs_assert(i < OGS_BEARER_PER_UE);
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);

@ -24,7 +24,7 @@
#include "ipfw/ipfw2.h"
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
static void gtp_bearer_timeout(ogs_gtp_xact_t *xact, void *data)
{
smf_bearer_t *bearer = data;
smf_sess_t *sess = NULL;
@ -234,12 +234,12 @@ void smf_bearer_binding(smf_sess_t *sess)
}
}
/*
* We only use the method of adding a flow to an existing tft.
*
* EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT
* 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS
*/
/*
* We only use the method of adding a flow to an existing tft.
*
* EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT
* 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS
*/
ogs_list_init(&bearer->pf_to_add_list);
for (j = 0; j < pcc_rule->num_of_flow; j++) {
@ -351,7 +351,7 @@ void smf_bearer_binding(smf_sess_t *sess)
ogs_expect_or_return(pkbuf);
xact = ogs_gtp_xact_local_create(
sess->gnode, &h, pkbuf, bearer_timeout, bearer);
sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer);
ogs_expect_or_return(xact);
if (ogs_list_count(&bearer->pf_to_add_list) > 0)
@ -413,13 +413,14 @@ int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer)
h.teid = sess->sgw_s5c_teid;
memset(&tft, 0, sizeof tft);
encode_traffic_flow_template(&tft, bearer, OGS_GTP2_TFT_CODE_CREATE_NEW_TFT);
encode_traffic_flow_template(
&tft, bearer, OGS_GTP2_TFT_CODE_CREATE_NEW_TFT);
pkbuf = smf_s5c_build_create_bearer_request(h.type, bearer, &tft);
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
xact = ogs_gtp_xact_local_create(
sess->gnode, &h, pkbuf, bearer_timeout, bearer);
sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer);
ogs_expect_or_return_val(xact, OGS_ERROR);
rv = ogs_gtp_xact_commit(xact);
@ -433,8 +434,14 @@ void smf_qos_flow_binding(smf_sess_t *sess)
int rv;
int i, j;
uint64_t pfcp_flags, check;
ogs_assert(sess);
pfcp_flags = OGS_PFCP_MODIFY_NETWORK_REQUESTED;
ogs_list_init(&sess->qos_flow_to_modify_list);
for (i = 0; i < sess->policy.num_of_pcc_rule; i++) {
smf_bearer_t *qos_flow = NULL;
ogs_pcc_rule_t *pcc_rule = &sess->policy.pcc_rule[i];
@ -521,12 +528,12 @@ void smf_qos_flow_binding(smf_sess_t *sess)
}
}
/*
* We only use the method of adding a flow to an existing tft.
*
* EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT
* 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS
*/
/*
* We only use the method of adding a flow to an existing tft.
*
* EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT
* 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS
*/
ogs_list_init(&qos_flow->pf_to_add_list);
for (j = 0; j < pcc_rule->num_of_flow; j++) {
@ -609,15 +616,11 @@ void smf_qos_flow_binding(smf_sess_t *sess)
smf_bearer_tft_update(qos_flow);
smf_bearer_qos_update(qos_flow);
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_qos_flow_modification_request(
qos_flow, NULL,
OGS_PFCP_MODIFY_NETWORK_REQUESTED|
OGS_PFCP_MODIFY_CREATE));
pfcp_flags |= OGS_PFCP_MODIFY_CREATE;
ogs_list_add(&sess->qos_flow_to_modify_list,
&qos_flow->to_modify_node);
} else {
uint64_t pfcp_flags = 0;
pfcp_flags |= OGS_PFCP_MODIFY_NETWORK_REQUESTED;
if (ogs_list_count(&qos_flow->pf_to_add_list) > 0) {
@ -629,9 +632,8 @@ void smf_qos_flow_binding(smf_sess_t *sess)
smf_bearer_qos_update(qos_flow);
}
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_qos_flow_modification_request(
qos_flow, NULL, pfcp_flags));
ogs_list_add(&sess->qos_flow_to_modify_list,
&qos_flow->to_modify_node);
}
} else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) {
qos_flow = smf_qos_flow_find_by_pcc_rule_id(sess, pcc_rule->id);
@ -643,14 +645,27 @@ void smf_qos_flow_binding(smf_sess_t *sess)
continue;
}
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_qos_flow_modification_request(
qos_flow, NULL,
OGS_PFCP_MODIFY_NETWORK_REQUESTED|OGS_PFCP_MODIFY_REMOVE));
pfcp_flags |= OGS_PFCP_MODIFY_REMOVE;
ogs_list_add(&sess->qos_flow_to_modify_list,
&qos_flow->to_modify_node);
} else {
ogs_error("Invalid Type[%d]", pcc_rule->type);
ogs_assert_if_reached();
}
}
check = pfcp_flags & (OGS_PFCP_MODIFY_CREATE|OGS_PFCP_MODIFY_REMOVE);
if (check != 0 &&
check != OGS_PFCP_MODIFY_CREATE && check != OGS_PFCP_MODIFY_REMOVE) {
ogs_fatal("Invalid flags[%ld]", pfcp_flags);
ogs_assert_if_reached();
}
if (ogs_list_count(&sess->qos_flow_to_modify_list)) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
sess, NULL, pfcp_flags, 0));
}
}

@ -418,7 +418,7 @@ void smf_gn_handle_update_pdp_context_request(
}
}
rv = smf_epc_pfcp_send_session_modification_request(sess, xact, NULL,
rv = smf_epc_pfcp_send_pdr_modification_request(sess, xact, NULL,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);

@ -291,14 +291,14 @@ static void encode_qos_rule_packet_filter(
}
}
ogs_pkbuf_t *gsm_build_qos_flow_modification_command(
smf_bearer_t *qos_flow, uint8_t pti,
ogs_pkbuf_t *gsm_build_pdu_session_modification_command(
smf_sess_t *sess, uint8_t pti,
uint8_t qos_rule_code, uint8_t qos_flow_description_code)
{
ogs_pkbuf_t *pkbuf = NULL;
smf_sess_t *sess = NULL;
smf_bearer_t *qos_flow = NULL;
ogs_pfcp_pdr_t *dl_pdr = NULL;
int num_of_param, rv;
int num_of_param, rv, i;
ogs_nas_5gs_message_t message;
ogs_nas_5gs_pdu_session_modification_command_t
@ -319,11 +319,7 @@ ogs_pkbuf_t *gsm_build_qos_flow_modification_command(
&pdu_session_modification_command->authorized_qos_flow_descriptions;
ogs_assert(authorized_qos_flow_descriptions);
ogs_assert(qos_flow);
sess = qos_flow->sess;
ogs_assert(sess);
dl_pdr = qos_flow->dl_pdr;
ogs_assert(dl_pdr);
memset(&message, 0, sizeof(message));
message.gsm.h.extended_protocol_discriminator =
@ -334,26 +330,39 @@ ogs_pkbuf_t *gsm_build_qos_flow_modification_command(
/* QoS rule */
if (qos_rule_code) {
i = 0;
memset(qos_rule, 0, sizeof(qos_rule));
qos_rule[0].identifier = qos_flow->qfi; /* Use QFI in Open5GS */
qos_rule[0].code = qos_rule_code;
if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE &&
qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS)
encode_qos_rule_packet_filter(&qos_rule[0], qos_flow);
if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE &&
qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS &&
qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) {
ogs_assert(dl_pdr->precedence > 0 && dl_pdr->precedence < 255);
/* Use PCC Rule Precedence */
qos_rule[0].precedence = dl_pdr->precedence;
qos_rule[0].flow.segregation = 0;
qos_rule[0].flow.identifier = qos_flow->qfi;
ogs_list_for_each_entry(
&sess->qos_flow_to_modify_list, qos_flow, to_modify_node) {
ogs_assert(i < OGS_MAX_NUM_OF_BEARER);
dl_pdr = qos_flow->dl_pdr;
ogs_assert(dl_pdr);
qos_rule[i].identifier = qos_flow->qfi; /* Use QFI in Open5GS */
qos_rule[i].code = qos_rule_code;
if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE &&
qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS)
encode_qos_rule_packet_filter(&qos_rule[i], qos_flow);
if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE &&
qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS &&
qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) {
ogs_assert(dl_pdr->precedence > 0 && dl_pdr->precedence < 255);
/* Use PCC Rule Precedence */
qos_rule[i].precedence = dl_pdr->precedence;
qos_rule[i].flow.segregation = 0;
qos_rule[i].flow.identifier = qos_flow->qfi;
}
i++;
}
rv = ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, 1);
rv = ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, i);
ogs_expect_or_return_val(rv == OGS_OK, NULL);
ogs_expect_or_return_val(authorized_qos_rules->length, NULL);
@ -363,69 +372,81 @@ ogs_pkbuf_t *gsm_build_qos_flow_modification_command(
/* QoS flow descriptions */
if (qos_flow_description_code) {
i = 0;
memset(&qos_flow_description, 0, sizeof(qos_flow_description));
qos_flow_description[0].identifier = qos_flow->qfi;
qos_flow_description[0].code = qos_flow_description_code;
num_of_param = 0;
if (qos_flow_description_code != OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION) {
qos_flow_description[0].E_bit = 1;
qos_flow_description[0].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI;
qos_flow_description[0].param[num_of_param].len =
sizeof(qos_flow_description[0].param[num_of_param].qos_index);
qos_flow_description[0].param[num_of_param].qos_index =
qos_flow->qos.index;
num_of_param++;
if (qos_flow->qos.gbr.uplink) {
qos_flow_description[0].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK;
qos_flow_description[0].param[num_of_param].len =
sizeof(qos_flow_description[0].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[0].param[num_of_param].br,
qos_flow->qos.gbr.uplink);
num_of_param++;
}
if (qos_flow->qos.gbr.downlink) {
qos_flow_description[0].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK;
qos_flow_description[0].param[num_of_param].len =
sizeof(qos_flow_description[0].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[0].param[num_of_param].br,
qos_flow->qos.gbr.downlink);
num_of_param++;
}
if (qos_flow->qos.mbr.uplink) {
qos_flow_description[0].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK;
qos_flow_description[0].param[num_of_param].len =
sizeof(qos_flow_description[0].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[0].param[num_of_param].br,
qos_flow->qos.mbr.uplink);
num_of_param++;
}
if (qos_flow->qos.mbr.downlink) {
qos_flow_description[0].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK;
qos_flow_description[0].param[num_of_param].len =
sizeof(qos_flow_description[0].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[0].param[num_of_param].br,
qos_flow->qos.mbr.downlink);
ogs_list_for_each_entry(
&sess->qos_flow_to_modify_list, qos_flow, to_modify_node) {
ogs_assert(i < OGS_MAX_NUM_OF_BEARER);
qos_flow_description[i].identifier = qos_flow->qfi;
qos_flow_description[i].code = qos_flow_description_code;
num_of_param = 0;
if (qos_flow_description_code !=
OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION) {
qos_flow_description[i].E_bit = 1;
qos_flow_description[i].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI;
qos_flow_description[i].param[num_of_param].len =
sizeof(qos_flow_description[i].param[num_of_param].
qos_index);
qos_flow_description[i].param[num_of_param].qos_index =
qos_flow->qos.index;
num_of_param++;
if (qos_flow->qos.gbr.uplink) {
qos_flow_description[i].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK;
qos_flow_description[i].param[num_of_param].len =
sizeof(qos_flow_description[i].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[i].param[num_of_param].br,
qos_flow->qos.gbr.uplink);
num_of_param++;
}
if (qos_flow->qos.gbr.downlink) {
qos_flow_description[i].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK;
qos_flow_description[i].param[num_of_param].len =
sizeof(qos_flow_description[i].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[i].param[num_of_param].br,
qos_flow->qos.gbr.downlink);
num_of_param++;
}
if (qos_flow->qos.mbr.uplink) {
qos_flow_description[i].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK;
qos_flow_description[i].param[num_of_param].len =
sizeof(qos_flow_description[i].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[i].param[num_of_param].br,
qos_flow->qos.mbr.uplink);
num_of_param++;
}
if (qos_flow->qos.mbr.downlink) {
qos_flow_description[i].param[num_of_param].identifier =
OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK;
qos_flow_description[i].param[num_of_param].len =
sizeof(qos_flow_description[i].param[num_of_param].br);
ogs_nas_bitrate_from_uint64(
&qos_flow_description[i].param[num_of_param].br,
qos_flow->qos.mbr.downlink);
num_of_param++;
}
}
}
qos_flow_description[0].num_of_parameter = num_of_param;
qos_flow_description[i].num_of_parameter = num_of_param;
i++;
}
rv = ogs_nas_build_qos_flow_descriptions(
authorized_qos_flow_descriptions, qos_flow_description, 1);
authorized_qos_flow_descriptions, qos_flow_description, i);
ogs_expect_or_return_val(rv == OGS_OK, NULL);
ogs_expect_or_return_val(
authorized_qos_flow_descriptions->length, NULL);

@ -30,8 +30,8 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess);
ogs_pkbuf_t *gsm_build_pdu_session_establishment_reject(
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause);
ogs_pkbuf_t *gsm_build_qos_flow_modification_command(
smf_bearer_t *qos_flow, uint8_t pti,
ogs_pkbuf_t *gsm_build_pdu_session_modification_command(
smf_sess_t *sess, uint8_t pti,
uint8_t qos_rule_code, uint8_t qos_flow_description_code);
ogs_pkbuf_t *gsm_build_pdu_session_modification_reject(
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause);

@ -195,7 +195,7 @@ int gsm_handle_pdu_session_modification_request(
int i, j;
uint64_t pfcp_flags = 0;
ogs_list_t update_list, delete_list;
smf_bearer_t *qos_flow = NULL;
smf_pf_t *pf = NULL;
@ -217,8 +217,7 @@ int gsm_handle_pdu_session_modification_request(
ogs_assert(stream);
ogs_assert(pdu_session_modification_request);
ogs_list_init(&update_list);
ogs_list_init(&delete_list);
ogs_list_init(&sess->qos_flow_to_modify_list);
if (pdu_session_modification_request->presencemask &
OGS_NAS_5GS_PDU_SESSION_MODIFICATION_REQUEST_5GSM_CAUSE_PRESENT) {
@ -246,7 +245,8 @@ int gsm_handle_pdu_session_modification_request(
smf_pf_remove_all(qos_flow);
pfcp_flags |= OGS_PFCP_MODIFY_REMOVE;
qos_flow_find_or_add(&delete_list, qos_flow, to_delete_node);
qos_flow_find_or_add(&sess->qos_flow_to_modify_list,
qos_flow, to_modify_node);
} else if (qos_rule[i].code ==
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS) {
for (j = 0; j < qos_rule[i].num_of_packet_filter &&
@ -306,8 +306,8 @@ int gsm_handle_pdu_session_modification_request(
}
pfcp_flags |= OGS_PFCP_MODIFY_TFT_REPLACE;
qos_flow_find_or_add(
&update_list, qos_flow, to_modify_node);
qos_flow_find_or_add(&sess->qos_flow_to_modify_list,
qos_flow, to_modify_node);
ogs_list_add(
&qos_flow->pf_to_add_list, &pf->to_add_node);
@ -388,8 +388,8 @@ int gsm_handle_pdu_session_modification_request(
} else
ogs_assert_if_reached();
qos_flow_find_or_add(
&update_list, qos_flow, to_modify_node);
qos_flow_find_or_add(&sess->qos_flow_to_modify_list,
qos_flow, to_modify_node);
ogs_list_add(
&qos_flow->pf_to_add_list, &pf->to_add_node);
@ -413,12 +413,12 @@ int gsm_handle_pdu_session_modification_request(
if (ogs_list_count(&qos_flow->pf_list)) {
pfcp_flags |= OGS_PFCP_MODIFY_TFT_DELETE;
qos_flow_find_or_add(
&update_list, qos_flow, to_modify_node);
qos_flow_find_or_add(&sess->qos_flow_to_modify_list,
qos_flow, to_modify_node);
} else {
pfcp_flags |= OGS_PFCP_MODIFY_REMOVE;
qos_flow_find_or_add(
&delete_list, qos_flow, to_delete_node);
qos_flow_find_or_add(&sess->qos_flow_to_modify_list,
qos_flow, to_modify_node);
}
}
}
@ -469,14 +469,15 @@ int gsm_handle_pdu_session_modification_request(
}
pfcp_flags |= OGS_PFCP_MODIFY_QOS_MODIFY;
qos_flow_find_or_add(&update_list, qos_flow, to_modify_node);
qos_flow_find_or_add(&sess->qos_flow_to_modify_list,
qos_flow, to_modify_node);
}
}
if ((ogs_list_count(&update_list) + ogs_list_count(&delete_list)) != 1) {
if (ogs_list_count(&sess->qos_flow_to_modify_list) != 1) {
strerror = ogs_msprintf("[%s:%d] Invalid modification request "
"[update:%d,delete:%d]", smf_ue->supi, sess->psi,
ogs_list_count(&update_list), ogs_list_count(&delete_list));
"[modify:%d]", smf_ue->supi, sess->psi,
ogs_list_count(&sess->qos_flow_to_modify_list));
ogs_assert(strerror);
ogs_error("%s", strerror);
@ -492,20 +493,19 @@ int gsm_handle_pdu_session_modification_request(
return OGS_ERROR;
}
ogs_assert(qos_flow);
if (pfcp_flags & OGS_PFCP_MODIFY_REMOVE) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_qos_flow_modification_request(
qos_flow, stream,
OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags));
ogs_assert((pfcp_flags &
(OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD|
OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE|
OGS_PFCP_MODIFY_QOS_MODIFY)) == 0);
} else if (pfcp_flags &
(OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD|
OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE|
OGS_PFCP_MODIFY_QOS_MODIFY)) {
ogs_assert((pfcp_flags & OGS_PFCP_MODIFY_REMOVE) == 0);
if (pfcp_flags &
(OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD|
OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE))
@ -514,13 +514,15 @@ int gsm_handle_pdu_session_modification_request(
if (pfcp_flags & OGS_PFCP_MODIFY_QOS_MODIFY)
smf_bearer_qos_update(qos_flow);
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_qos_flow_modification_request(
qos_flow, stream, OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags));
} else {
ogs_fatal("Unknown PFCP-Flags : [0x%llx]", (long long)pfcp_flags);
ogs_assert_if_reached();
}
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
sess, stream,
OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags, 0));
return OGS_OK;
}

@ -174,7 +174,7 @@ void smf_gy_handle_cca_update_request(
/* Send PFCP Session Modification Request if we need to update the params. */
if (modify_flags) {
modify_flags |= OGS_PFCP_MODIFY_URR|OGS_PFCP_MODIFY_UL_ONLY;
rv = smf_epc_pfcp_send_session_modification_request(
rv = smf_epc_pfcp_send_pdr_modification_request(
sess, pfcp_xact, NULL, modify_flags,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);

@ -265,7 +265,7 @@ void smf_5gc_n4_handle_session_modification_response(
stream = xact->assoc_stream;
if (flags & OGS_PFCP_MODIFY_SESSION) {
/* If smf_5gc_pfcp_send_session_modification_request() is called */
/* If smf_5gc_pfcp_send_pdr_modification_request() is called */
} else {
/* If smf_5gc_pfcp_send_qos_flow_modification_request() is called */
@ -390,7 +390,7 @@ void smf_5gc_n4_handle_session_modification_response(
if (smf_sess_have_indirect_data_forwarding(sess) == true) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE,
ogs_app()->time.handover.duration));
@ -444,7 +444,7 @@ void smf_5gc_n4_handle_session_modification_response(
smf_sess_create_indirect_data_forwarding(sess);
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE,
0));
@ -454,47 +454,57 @@ void smf_5gc_n4_handle_session_modification_response(
}
} else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) {
smf_n1_n2_message_transfer_param_t param;
smf_bearer_t *next = NULL;
ogs_assert(qos_flow);
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow,
param.n1smbuf = gsm_build_pdu_session_modification_command(
sess,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE,
OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION);
ogs_assert(param.n1smbuf);
param.n2smbuf =
ngap_build_qos_flow_resource_release_request_transfer(
qos_flow,
ngap_build_pdu_session_resource_release_request_transfer(
sess,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
smf_bearer_remove(qos_flow);
ogs_list_for_each_entry_safe(&sess->qos_flow_to_modify_list,
next, qos_flow, to_modify_node)
smf_bearer_remove(qos_flow);
} else if (flags & OGS_PFCP_MODIFY_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
smf_bearer_t *next = NULL;
ogs_assert(stream);
ogs_assert(qos_flow);
n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow, sess->pti,
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
n1smbuf = gsm_build_pdu_session_modification_command(
sess, sess->pti,
OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE,
OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_qos_flow_resource_release_request_transfer(
qos_flow,
n2smbuf = ngap_build_pdu_session_resource_release_request_transfer(
sess,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_MOD_REQ, n2smbuf);
smf_sbi_send_sm_context_updated_data_n1_n2_message(
sess, stream, n1smbuf,
OpenAPI_n2_sm_info_type_PDU_RES_MOD_REQ, n2smbuf);
ogs_list_for_each_entry_safe(&sess->qos_flow_to_modify_list,
next, qos_flow, to_modify_node)
smf_bearer_remove(qos_flow);
smf_bearer_remove(qos_flow);
} else {
ogs_fatal("Unknown flags [0x%llx]", (long long)flags);
ogs_assert_if_reached();
@ -511,22 +521,23 @@ void smf_5gc_n4_handle_session_modification_response(
} else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) {
smf_n1_n2_message_transfer_param_t param;
ogs_assert(qos_flow);
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow,
param.n1smbuf = gsm_build_pdu_session_modification_command(
sess,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE,
OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION);
ogs_assert(param.n1smbuf);
param.n2smbuf =
ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow, true);
ngap_build_pdu_session_resource_modify_request_transfer(
sess, true);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
ogs_fatal("Unknown flags [0x%llx]", (long long)flags);
ogs_assert_if_reached();
@ -559,35 +570,36 @@ void smf_5gc_n4_handle_session_modification_response(
}
if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) {
ogs_assert(qos_flow);
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow,
param.n1smbuf = gsm_build_pdu_session_modification_command(
sess,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
qos_rule_code, qos_flow_description_code);
ogs_assert(param.n1smbuf);
param.n2smbuf =
ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow,
(flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false);
ngap_build_pdu_session_resource_modify_request_transfer(
sess,
(flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else if (flags & OGS_PFCP_MODIFY_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
ogs_assert(stream);
ogs_assert(qos_flow);
n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow, sess->pti,
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
n1smbuf = gsm_build_pdu_session_modification_command(
sess, sess->pti,
qos_rule_code, qos_flow_description_code);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow,
n2smbuf = ngap_build_pdu_session_resource_modify_request_transfer(
sess,
(flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false);
ogs_assert(n2smbuf);
@ -794,7 +806,7 @@ void smf_epc_n4_handle_session_modification_response(
ogs_debug("Session Modification Response [epc]");
if (flags & OGS_PFCP_MODIFY_SESSION) {
/* If smf_epc_pfcp_send_session_modification_request() is called */
/* If smf_epc_pfcp_send_pdr_modification_request() is called */
} else {
/* If smf_epc_pfcp_send_bearer_modification_request() is called */
bearer = xact->data;
@ -1207,7 +1219,7 @@ void smf_n4_handle_session_report_request(
if (error_indication_session) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
error_indication_session, NULL,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE|
OGS_PFCP_MODIFY_ERROR_INDICATION,

@ -199,8 +199,8 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, &message);
}
ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer(
smf_bearer_t *qos_flow, bool qos_presence)
ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request_transfer(
smf_sess_t *sess, bool qos_presence)
{
NGAP_PDUSessionResourceModifyRequestTransfer_t message;
@ -215,7 +215,9 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer(
NGAP_AllocationAndRetentionPriority_t *allocationAndRetentionPriority;
NGAP_GBR_QosInformation_t *gBR_QosInformation;
ogs_assert(qos_flow);
smf_bearer_t *qos_flow = NULL;
ogs_assert(sess);
ogs_debug("PDUSessionResourceModifyRequestTransfer");
memset(&message, 0, sizeof(NGAP_PDUSessionResourceModifyRequestTransfer_t));
@ -229,66 +231,70 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer(
QosFlowAddOrModifyRequestList = &ie->value.choice.QosFlowAddOrModifyRequestList;
QosFlowAddOrModifyRequestItem =
CALLOC(1, sizeof(*QosFlowAddOrModifyRequestItem));
ASN_SEQUENCE_ADD(&QosFlowAddOrModifyRequestList->list, QosFlowAddOrModifyRequestItem);
ogs_list_for_each_entry(
&sess->qos_flow_to_modify_list, qos_flow, to_modify_node) {
qosFlowIdentifier = &QosFlowAddOrModifyRequestItem->qosFlowIdentifier;
QosFlowAddOrModifyRequestItem =
CALLOC(1, sizeof(*QosFlowAddOrModifyRequestItem));
ASN_SEQUENCE_ADD(&QosFlowAddOrModifyRequestList->list, QosFlowAddOrModifyRequestItem);
QosFlowAddOrModifyRequestItem->qosFlowLevelQosParameters =
qosFlowLevelQosParameters =
CALLOC(1, sizeof(*qosFlowLevelQosParameters));
qosFlowIdentifier = &QosFlowAddOrModifyRequestItem->qosFlowIdentifier;
allocationAndRetentionPriority =
&qosFlowLevelQosParameters->allocationAndRetentionPriority;
qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics;
QosFlowAddOrModifyRequestItem->qosFlowLevelQosParameters =
qosFlowLevelQosParameters =
CALLOC(1, sizeof(*qosFlowLevelQosParameters));
qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI;
qosCharacteristics->choice.nonDynamic5QI =
nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor));
allocationAndRetentionPriority =
&qosFlowLevelQosParameters->allocationAndRetentionPriority;
qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics;
qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI;
qosCharacteristics->choice.nonDynamic5QI =
nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor));
*qosFlowIdentifier = qos_flow->qfi;
nonDynamic5QI->fiveQI = qos_flow->qos.index;
*qosFlowIdentifier = qos_flow->qfi;
nonDynamic5QI->fiveQI = qos_flow->qos.index;
allocationAndRetentionPriority->priorityLevelARP =
qos_flow->qos.arp.priority_level;
if (qos_flow->qos.arp.pre_emption_capability ==
OGS_5GC_PRE_EMPTION_ENABLED)
allocationAndRetentionPriority->pre_emptionCapability =
NGAP_Pre_emptionCapability_may_trigger_pre_emption;
if (qos_flow->qos.arp.pre_emption_vulnerability ==
OGS_5GC_PRE_EMPTION_ENABLED)
allocationAndRetentionPriority->pre_emptionVulnerability =
NGAP_Pre_emptionVulnerability_pre_emptable;
if (qos_presence == true &&
(qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink ||
qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink)) {
ogs_assert(qos_flow->qos.mbr.downlink);
ogs_assert(qos_flow->qos.mbr.uplink);
ogs_assert(qos_flow->qos.gbr.downlink);
ogs_assert(qos_flow->qos.gbr.uplink);
qosFlowLevelQosParameters->gBR_QosInformation =
gBR_QosInformation = CALLOC(1, sizeof(*gBR_QosInformation));
asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateDL,
qos_flow->qos.mbr.downlink);
asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateUL,
qos_flow->qos.mbr.uplink);
asn_uint642INTEGER(&gBR_QosInformation->
guaranteedFlowBitRateDL, qos_flow->qos.gbr.downlink);
asn_uint642INTEGER(&gBR_QosInformation->
guaranteedFlowBitRateUL, qos_flow->qos.gbr.uplink);
allocationAndRetentionPriority->priorityLevelARP =
qos_flow->qos.arp.priority_level;
if (qos_flow->qos.arp.pre_emption_capability ==
OGS_5GC_PRE_EMPTION_ENABLED)
allocationAndRetentionPriority->pre_emptionCapability =
NGAP_Pre_emptionCapability_may_trigger_pre_emption;
if (qos_flow->qos.arp.pre_emption_vulnerability ==
OGS_5GC_PRE_EMPTION_ENABLED)
allocationAndRetentionPriority->pre_emptionVulnerability =
NGAP_Pre_emptionVulnerability_pre_emptable;
if (qos_presence == true &&
(qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink ||
qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink)) {
ogs_assert(qos_flow->qos.mbr.downlink);
ogs_assert(qos_flow->qos.mbr.uplink);
ogs_assert(qos_flow->qos.gbr.downlink);
ogs_assert(qos_flow->qos.gbr.uplink);
qosFlowLevelQosParameters->gBR_QosInformation =
gBR_QosInformation = CALLOC(1, sizeof(*gBR_QosInformation));
asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateDL,
qos_flow->qos.mbr.downlink);
asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateUL,
qos_flow->qos.mbr.uplink);
asn_uint642INTEGER(&gBR_QosInformation->
guaranteedFlowBitRateDL, qos_flow->qos.gbr.downlink);
asn_uint642INTEGER(&gBR_QosInformation->
guaranteedFlowBitRateUL, qos_flow->qos.gbr.uplink);
}
}
return ogs_asn_encode(
&asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, &message);
}
ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer(
smf_bearer_t *qos_flow, NGAP_Cause_PR group, long cause)
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_request_transfer(
smf_sess_t *sess, NGAP_Cause_PR group, long cause)
{
NGAP_PDUSessionResourceModifyRequestTransfer_t message;
@ -299,7 +305,9 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer(
NGAP_QosFlowIdentifier_t *qosFlowIdentifier = NULL;
NGAP_Cause_t *Cause = NULL;
ogs_assert(qos_flow);
smf_bearer_t *qos_flow = NULL;
ogs_assert(sess);
ogs_debug("PDUSessionResourceModifyRequestTransfer");
memset(&message, 0, sizeof(NGAP_PDUSessionResourceModifyRequestTransfer_t));
@ -313,16 +321,21 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer(
QosFlowListWithCause = &ie->value.choice.QosFlowListWithCause;
QosFlowWithCauseItem = CALLOC(1, sizeof(*QosFlowWithCauseItem));
ASN_SEQUENCE_ADD(&QosFlowListWithCause->list, QosFlowWithCauseItem);
ogs_list_for_each_entry(
&sess->qos_flow_to_modify_list, qos_flow, to_modify_node) {
qosFlowIdentifier = &QosFlowWithCauseItem->qosFlowIdentifier;
QosFlowWithCauseItem = CALLOC(1, sizeof(*QosFlowWithCauseItem));
ASN_SEQUENCE_ADD(&QosFlowListWithCause->list, QosFlowWithCauseItem);
*qosFlowIdentifier = qos_flow->qfi;
qosFlowIdentifier = &QosFlowWithCauseItem->qosFlowIdentifier;
Cause = &QosFlowWithCauseItem->cause;
Cause->present = group;
Cause->choice.radioNetwork = cause;
*qosFlowIdentifier = qos_flow->qfi;
Cause = &QosFlowWithCauseItem->cause;
Cause->present = group;
Cause->choice.radioNetwork = cause;
}
return ogs_asn_encode(
&asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, &message);

@ -29,11 +29,10 @@ extern "C" {
ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
smf_sess_t *sess);
ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer(
smf_bearer_t *qos_flow, bool qos_presence);
ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer(
smf_bearer_t *qos_flow, NGAP_Cause_PR group, long cause);
ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request_transfer(
smf_sess_t *sess, bool qos_presence);
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_request_transfer(
smf_sess_t *sess, NGAP_Cause_PR group, long cause);
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
smf_sess_t *sess, int state, NGAP_Cause_PR group, long cause);

@ -147,7 +147,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
if (far_update) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE,
0));
} else {
@ -247,7 +247,7 @@ int ngap_handle_pdu_session_resource_setup_unsuccessful_transfer(
*/
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, 0));
@ -304,6 +304,8 @@ int ngap_handle_pdu_session_resource_modify_response_transfer(
goto cleanup;
}
ogs_list_init(&sess->qos_flow_to_modify_list);
if (qosFlowAddOrModifyResponseList) {
for (i = 0; i < qosFlowAddOrModifyResponseList->list.count; i++) {
NGAP_QosFlowAddOrModifyResponseItem_t
@ -315,11 +317,26 @@ int ngap_handle_pdu_session_resource_modify_response_transfer(
if (qosFlowAddOrModifyResponseItem) {
qos_flow = smf_qos_flow_find_by_qfi(sess,
qosFlowAddOrModifyResponseItem->qosFlowIdentifier);
if (qos_flow) {
dl_far = qos_flow->dl_far;
ogs_assert(dl_far);
dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
ogs_assert(OGS_OK ==
ogs_pfcp_ip_to_outer_header_creation(
&sess->gnb_n3_ip,
&dl_far->outer_header_creation,
&dl_far->outer_header_creation_len));
dl_far->outer_header_creation.teid = sess->gnb_n3_teid;
ogs_list_add(&sess->qos_flow_to_modify_list,
&qos_flow->to_modify_node);
}
}
}
}
if (!qos_flow) {
if (ogs_list_count(&sess->qos_flow_to_modify_list) == 0) {
ogs_error("[%s:%d] No QoS flow", smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
@ -327,20 +344,10 @@ int ngap_handle_pdu_session_resource_modify_response_transfer(
goto cleanup;
}
dl_far = qos_flow->dl_far;
ogs_assert(dl_far);
dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
ogs_assert(OGS_OK ==
ogs_pfcp_ip_to_outer_header_creation(
&sess->gnb_n3_ip,
&dl_far->outer_header_creation,
&dl_far->outer_header_creation_len));
dl_far->outer_header_creation.teid = sess->gnb_n3_teid;
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_qos_flow_modification_request(
qos_flow, stream, OGS_PFCP_MODIFY_ACTIVATE));
smf_5gc_pfcp_send_session_modification_request(
sess, stream,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, 0));
rv = OGS_OK;
@ -467,7 +474,7 @@ int ngap_handle_path_switch_request_transfer(
if (far_update) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE|
OGS_PFCP_MODIFY_XN_HANDOVER|OGS_PFCP_MODIFY_END_MARKER,
@ -676,7 +683,7 @@ int ngap_handle_handover_request_ack(
ogs_error("It will be automatically removed");
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|
/*
@ -698,7 +705,7 @@ int ngap_handle_handover_request_ack(
smf_sess_create_indirect_data_forwarding(sess);
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE,
0));

@ -370,7 +370,7 @@ bool smf_nsmf_handle_update_sm_context(
sess, stream, OpenAPI_up_cnx_state_DEACTIVATED);
} else {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, 0));
}
@ -506,7 +506,7 @@ bool smf_nsmf_handle_update_sm_context(
if (far_update) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE|
OGS_PFCP_MODIFY_N2_HANDOVER|OGS_PFCP_MODIFY_END_MARKER,
@ -539,7 +539,7 @@ bool smf_nsmf_handle_update_sm_context(
if (smf_sess_have_indirect_data_forwarding(sess) == true) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
smf_5gc_pfcp_send_pdr_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE|
OGS_PFCP_MODIFY_HANDOVER_CANCEL,

@ -19,7 +19,6 @@
#include "sbi-path.h"
#include "pfcp-path.h"
#include "n4-build.h"
static void pfcp_node_fsm_init(ogs_pfcp_node_t *node, bool try_to_assoicate)
{
@ -215,45 +214,6 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
}
}
static void qos_flow_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
{
smf_ue_t *smf_ue = NULL;
smf_sess_t *sess = NULL;
smf_bearer_t *qos_flow = NULL;
ogs_sbi_stream_t *stream = NULL;
uint8_t type;
char *strerror = NULL;
ogs_assert(xact);
ogs_assert(data);
qos_flow = data;
ogs_assert(qos_flow);
sess = qos_flow->sess;
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
type = xact->seq[0].type;
switch (type) {
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
strerror = ogs_msprintf("[%s:%d] No PFCP session modification response",
smf_ue->supi, sess->psi);
ogs_assert(strerror);
ogs_error("%s", strerror);
if (stream)
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT,
strerror, NULL, NULL, NULL);
ogs_free(strerror);
break;
default:
ogs_error("Not implemented [type:%d]", type);
break;
}
}
static void sess_epc_timeout(ogs_pfcp_xact_t *xact, void *data)
{
uint8_t type;
@ -367,11 +327,8 @@ int smf_5gc_pfcp_send_session_modification_request(
{
int rv;
ogs_pfcp_xact_t *xact = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_assert(sess);
if ((flags & OGS_PFCP_MODIFY_ERROR_INDICATION) == 0)
ogs_assert(stream);
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess);
ogs_expect_or_return_val(xact, OGS_ERROR);
@ -379,40 +336,37 @@ int smf_5gc_pfcp_send_session_modification_request(
xact->assoc_stream = stream;
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
ogs_list_init(&sess->pdr_to_modify_list);
ogs_list_for_each(&sess->pfcp.pdr_list, pdr)
ogs_list_add(&sess->pdr_to_modify_list, &pdr->to_modify_node);
rv = smf_pfcp_send_modify_list(
sess, smf_n4_build_pdr_to_modify_list, xact, duration);
sess, smf_n4_build_qos_flow_to_modify_list, xact, duration);
ogs_expect(rv == OGS_OK);
return rv;
}
int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
ogs_sbi_stream_t *stream, uint64_t flags)
int smf_5gc_pfcp_send_pdr_modification_request(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
uint64_t flags, ogs_time_t duration)
{
int rv;
ogs_pfcp_xact_t *xact = NULL;
smf_sess_t *sess = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_assert(qos_flow);
sess = qos_flow->sess;
ogs_assert(sess);
if ((flags & OGS_PFCP_MODIFY_ERROR_INDICATION) == 0