[SMF] Update QoS Rule Handling (#3513)

1. Set packet filter identifier values to 0 when the UE requests to:
  - Create new QoS rule
  - Modify existing QoS rule and replace all packet filters
  - Modify existing QoS rule and add packet filters - As specified in TS24.501, section 9.11.4.13, Table 9.11.4.13.1.

2. Revise QoS rule modification logic:
  - Instead of replacing packet filters based on their identifiers (EPC approach), update the implementation to delete all existing packet filters within the QoS rule and add new ones.
  - This ensures that when modifying an existing QoS rule to replace all packet filters, the packet filters are correctly reset and updated per 5G Core requirements.
This commit is contained in:
Sukchan Lee 2024-10-17 15:52:35 +09:00
parent 5dc3905c39
commit a50c313b81
5 changed files with 15 additions and 78 deletions

View file

@ -1020,7 +1020,7 @@ typedef struct ogs_nas_qos_rule_s {
#define OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE 1
#define OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE 2
#define OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS 3
#define OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS 4
#define OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS 4
#define OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS 5
#define OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS 6
ED3(uint8_t code:3;,

View file

@ -251,87 +251,21 @@ int gsm_handle_pdu_session_modification_request(
pfcp_flags |= OGS_PFCP_MODIFY_REMOVE;
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 &&
j < OGS_MAX_NUM_OF_FLOW_IN_NAS; j++) {
pf = smf_pf_find_by_identifier(
qos_flow, qos_rule[i].pf[j].identifier);
if (pf) {
ogs_assert(
reconfigure_packet_filter(pf, &qos_rule[i], i) > 0);
/*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK/BI-DIRECTIONAL>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
*
* <UPLINK>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
ogs_ipfw_rule_swap(&pf->ipfw_rule);
if (pf->flow_description)
ogs_free(pf->flow_description);
/*
* Issue #338
*
* <DOWNLINK/BI-DIRECTIONAL>
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
* -->
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
*
* <UPLINK>
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
*/
if (pf->direction == OGS_FLOW_UPLINK_ONLY) {
ogs_ipfw_rule_t tmp;
ogs_ipfw_copy_and_swap(&tmp, &pf->ipfw_rule);
pf->flow_description =
ogs_ipfw_encode_flow_description(&tmp);
ogs_assert(pf->flow_description);
} else {
pf->flow_description =
ogs_ipfw_encode_flow_description(
&pf->ipfw_rule);
ogs_assert(pf->flow_description);
}
pfcp_flags |= OGS_PFCP_MODIFY_TFT_REPLACE;
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);
}
}
} else if (qos_rule[i].code ==
OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE ||
qos_rule[i].code ==
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS) {
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS ||
qos_rule[i].code ==
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS) {
if (qos_rule[i].code == OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE)
if (qos_rule[i].code == OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE ||
qos_rule[i].code == OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS)
smf_pf_remove_all(qos_flow);
for (j = 0; j < qos_rule[i].num_of_packet_filter &&
j < OGS_MAX_NUM_OF_FLOW_IN_NAS; j++) {
pf = smf_pf_find_by_identifier(
qos_flow, qos_rule[i].pf[j].identifier);
if (!pf)
pf = smf_pf_add(qos_flow);
pf = smf_pf_add(qos_flow);
ogs_assert(pf);
ogs_assert(
@ -389,6 +323,9 @@ int gsm_handle_pdu_session_modification_request(
} else if (qos_rule[i].code ==
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS) {
pfcp_flags |= OGS_PFCP_MODIFY_TFT_ADD;
} else if (qos_rule[i].code ==
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS) {
pfcp_flags |= OGS_PFCP_MODIFY_TFT_REPLACE;
} else
ogs_assert_if_reached();

View file

@ -602,7 +602,7 @@ void smf_5gc_n4_handle_session_modification_response(
} else if (flags & OGS_PFCP_MODIFY_TFT_ADD) {
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS;
} else if (flags & OGS_PFCP_MODIFY_TFT_REPLACE) {
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS;
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS;
} else if (flags & OGS_PFCP_MODIFY_TFT_DELETE) {
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS;
}

View file

@ -159,7 +159,7 @@ ogs_pkbuf_t *testgsm_build_pdu_session_modification_request(
qos_rule[0].num_of_packet_filter = 1;
qos_rule[0].pf[0].direction = OGS_NAS_QOS_DIRECTION_UPLINK;
qos_rule[0].pf[0].identifier = 5;
qos_rule[0].pf[0].identifier = 0;
qos_rule[0].pf[0].content.length = 18;
qos_rule[0].pf[0].content.num_of_component = 1;
@ -175,12 +175,12 @@ ogs_pkbuf_t *testgsm_build_pdu_session_modification_request(
qos_rule[0].pf[0].content.component[0].ipv6.prefixlen = 120;
} else if (qos_rule_code ==
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS) {
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS) {
qos_rule[0].DQR_bit = 0;
qos_rule[0].num_of_packet_filter = 1;
qos_rule[0].pf[0].direction = OGS_NAS_QOS_DIRECTION_DOWNLINK;
qos_rule[0].pf[0].identifier = 1;
qos_rule[0].pf[0].identifier = 0;
qos_rule[0].pf[0].content.length = 9;
qos_rule[0].pf[0].content.num_of_component = 1;

View file

@ -498,7 +498,7 @@ static void test1_func(abts_case *tc, void *data)
gsmbuf = testgsm_build_pdu_session_modification_request(
qos_flow,
0,
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS,
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_ALL_PACKET_FILTERS,
0);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,