2020-12-11 19:03:20 +00:00
|
|
|
/*
|
2024-02-17 19:40:08 +00:00
|
|
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
2020-12-11 19:03:20 +00:00
|
|
|
*
|
|
|
|
* This file is part of Open5GS.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sbi-path.h"
|
|
|
|
#include "pfcp-path.h"
|
|
|
|
#include "nas-path.h"
|
2021-11-14 12:07:56 +00:00
|
|
|
#include "binding.h"
|
2020-12-11 19:03:20 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
#include "npcf-handler.h"
|
2020-12-11 19:03:20 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
static void update_authorized_pcc_rule_and_qos(
|
|
|
|
smf_sess_t *sess, OpenAPI_sm_policy_decision_t *SmPolicyDecision)
|
|
|
|
{
|
2021-01-01 02:07:08 +00:00
|
|
|
OpenAPI_lnode_t *node = NULL, *node2 = NULL;
|
|
|
|
|
2020-12-11 19:03:20 +00:00
|
|
|
ogs_assert(sess);
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_assert(SmPolicyDecision);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TS29.512
|
|
|
|
* 4.2.6 Provisioning and Enforcement of Policy Decisions
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* If no other rules are defined for specific data types
|
|
|
|
* within the SmPolicyDecision data structure, the encoding of changes
|
|
|
|
* of the policies decisions in the SmPolicyDecision data structure
|
|
|
|
* shall follow the following principles:
|
|
|
|
*
|
|
|
|
* 1) To modify an attribute with a value of type map
|
|
|
|
* (e.g. the "sessRules" attribute, the "pccRules" attribute,
|
|
|
|
* the "qosDecs" attribute, the "traffContDecs" attribute,
|
|
|
|
* the "umDecs" attribute, and the "conds" attribute) the attribute
|
|
|
|
* shall be provided with a value containing a map with entries
|
|
|
|
* according to the following principles:
|
|
|
|
*
|
|
|
|
* - A new entry shall be added by supplying a new identifier
|
|
|
|
* (e.g. rule / decision identifier) as key and the corresponding
|
|
|
|
* structured data type instance (e.g. PCC rule) with complete contents
|
|
|
|
* as value as an entry within the map.
|
|
|
|
* - An existing entry shall be modified by supplying the existing
|
|
|
|
* identifier as key and the corresponding structured data type instance
|
|
|
|
* with the same existing identifier (e.g. set the "qosId"
|
|
|
|
* to the same existing QoS data decision identifier),
|
|
|
|
* which shall describe the modifications following bullets 1 to 6,
|
|
|
|
* as value as an entry within the map.
|
|
|
|
* - An existing entry shall be deleted by supplying the existing
|
|
|
|
* identifier as key and "NULL" as value as an entry within the map.
|
|
|
|
* - For an unmodified entry, no entry needs to be provided within the map.
|
|
|
|
*
|
|
|
|
* 2) To modify an attribute with a structured data type instance as value,
|
|
|
|
* the attribute shall be provided with a value containing a structured data
|
|
|
|
* type instance with entries according to bullets 1 to 6.
|
|
|
|
*
|
|
|
|
* 3) To modify an attribute with another type than map or structured data
|
|
|
|
* type as value, the attribute shall be provided with a complete
|
|
|
|
* representation of its value that shall replace the previous value.
|
|
|
|
*
|
|
|
|
* 4) To create an attribute of any type, the attribute shall be provided
|
|
|
|
* with a complete representation of its value.
|
|
|
|
*
|
|
|
|
* 5) To delete an attribute of any type, the attribute shall be provided
|
|
|
|
* with NULL as value.
|
|
|
|
* NOTE 1: Attributes that are allowed to be deleted need to be marked as
|
|
|
|
* "nullable" within the OpenAPI file in Annex A.
|
|
|
|
*
|
|
|
|
* 6) Attributes that are not added, modified, or deleted do not need to be
|
|
|
|
* provided.
|
|
|
|
* NOTE 2: In related data structures no attrib
|
|
|
|
*/
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
if (SmPolicyDecision->pcc_rules) {
|
|
|
|
OpenAPI_map_t *PccRuleMap = NULL;
|
|
|
|
OpenAPI_pcc_rule_t *PccRule = NULL;
|
|
|
|
OpenAPI_flow_information_t *FlowInformation = NULL;
|
|
|
|
OpenAPI_qos_data_t *QosData = NULL;
|
|
|
|
char *QosId = NULL;
|
2021-11-14 12:07:56 +00:00
|
|
|
int i;
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
for (i = 0; i < sess->policy.num_of_pcc_rule; i++)
|
|
|
|
OGS_PCC_RULE_FREE(&sess->policy.pcc_rule[i]);
|
|
|
|
sess->policy.num_of_pcc_rule = 0;
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
OpenAPI_list_for_each(SmPolicyDecision->pcc_rules, node) {
|
|
|
|
ogs_pcc_rule_t *pcc_rule =
|
|
|
|
&sess->policy.pcc_rule[sess->policy.num_of_pcc_rule];
|
2021-01-01 02:07:08 +00:00
|
|
|
ogs_assert(pcc_rule);
|
|
|
|
|
|
|
|
PccRuleMap = node->data;
|
|
|
|
if (!PccRuleMap) {
|
|
|
|
ogs_error("No PccRuleMap");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (!PccRuleMap->key) {
|
|
|
|
ogs_error("No PccRule->id");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
PccRule = PccRuleMap->value;
|
|
|
|
if (!PccRule) {
|
2021-11-14 12:07:56 +00:00
|
|
|
pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE;
|
|
|
|
pcc_rule->id = ogs_strdup(PccRuleMap->key);
|
|
|
|
ogs_assert(pcc_rule->id);
|
|
|
|
|
|
|
|
sess->policy.num_of_pcc_rule++;
|
2021-01-01 02:07:08 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!PccRule->ref_qos_data) {
|
|
|
|
ogs_error("No RefQosData");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!PccRule->ref_qos_data->first) {
|
|
|
|
ogs_error("No RefQosData->first");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
QosId = PccRule->ref_qos_data->first->data;
|
|
|
|
if (!QosId) {
|
|
|
|
ogs_error("no QosId");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SmPolicyDecision->qos_decs) {
|
|
|
|
OpenAPI_map_t *QosDecisionMap = NULL;
|
|
|
|
OpenAPI_qos_data_t *QosDataIter = NULL;
|
|
|
|
|
|
|
|
OpenAPI_list_for_each(SmPolicyDecision->qos_decs, node2) {
|
|
|
|
QosDecisionMap = node2->data;
|
|
|
|
if (!QosDecisionMap) {
|
|
|
|
ogs_error("No QosDecisionMap");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
QosDataIter = QosDecisionMap->value;
|
|
|
|
if (!QosDataIter) {
|
|
|
|
ogs_error("No QosData");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!QosDataIter->qos_id) {
|
|
|
|
ogs_error("No QosId");
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(QosId, QosDataIter->qos_id) == 0) {
|
|
|
|
QosData = QosDataIter;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!QosData) {
|
|
|
|
ogs_error("no qosData");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
|
|
|
|
pcc_rule->id = ogs_strdup(PccRule->pcc_rule_id);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(pcc_rule->id);
|
2021-01-01 02:07:08 +00:00
|
|
|
pcc_rule->precedence = PccRule->precedence;
|
|
|
|
|
|
|
|
if (PccRule->flow_infos) {
|
|
|
|
ogs_assert(pcc_rule->num_of_flow == 0);
|
|
|
|
OpenAPI_list_for_each(PccRule->flow_infos, node2) {
|
|
|
|
ogs_flow_t *flow = &pcc_rule->flow[pcc_rule->num_of_flow];
|
|
|
|
|
|
|
|
ogs_assert(flow);
|
|
|
|
|
|
|
|
FlowInformation = node2->data;
|
|
|
|
if (!FlowInformation) {
|
|
|
|
ogs_error("No FlowInformation");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FlowInformation->flow_direction ==
|
|
|
|
OpenAPI_flow_direction_UPLINK)
|
|
|
|
flow->direction = OGS_FLOW_UPLINK_ONLY;
|
|
|
|
else if (FlowInformation->flow_direction ==
|
|
|
|
OpenAPI_flow_direction_DOWNLINK)
|
|
|
|
flow->direction = OGS_FLOW_DOWNLINK_ONLY;
|
2024-02-17 19:40:08 +00:00
|
|
|
else if (FlowInformation->flow_direction ==
|
|
|
|
OpenAPI_flow_direction_BIDIRECTIONAL)
|
|
|
|
flow->direction = OGS_FLOW_BIDIRECTIONAL;
|
2021-01-01 02:07:08 +00:00
|
|
|
else {
|
2024-02-17 19:40:08 +00:00
|
|
|
ogs_error("Unsupported direction [%d]",
|
2021-01-01 02:07:08 +00:00
|
|
|
FlowInformation->flow_direction);
|
2024-02-17 19:40:08 +00:00
|
|
|
continue;
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
flow->description =
|
|
|
|
ogs_strdup(FlowInformation->flow_description);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(flow->description);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
pcc_rule->num_of_flow++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-08 12:25:09 +00:00
|
|
|
pcc_rule->qos.index = QosData->_5qi;
|
2021-01-01 02:07:08 +00:00
|
|
|
pcc_rule->qos.arp.priority_level = QosData->priority_level;
|
|
|
|
|
|
|
|
if (QosData->arp) {
|
|
|
|
pcc_rule->qos.arp.priority_level = QosData->arp->priority_level;
|
|
|
|
if (QosData->arp->preempt_cap ==
|
|
|
|
OpenAPI_preemption_capability_NOT_PREEMPT)
|
|
|
|
pcc_rule->qos.arp.pre_emption_capability =
|
2021-03-08 12:25:09 +00:00
|
|
|
OGS_5GC_PRE_EMPTION_DISABLED;
|
2021-01-01 02:07:08 +00:00
|
|
|
else if (QosData->arp->preempt_cap ==
|
|
|
|
OpenAPI_preemption_capability_MAY_PREEMPT)
|
|
|
|
pcc_rule->qos.arp.pre_emption_capability =
|
2021-03-08 12:25:09 +00:00
|
|
|
OGS_5GC_PRE_EMPTION_ENABLED;
|
|
|
|
ogs_assert(pcc_rule->qos.arp.pre_emption_capability);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
if (QosData->arp->preempt_vuln ==
|
|
|
|
OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE)
|
|
|
|
pcc_rule->qos.arp.pre_emption_vulnerability =
|
2021-03-08 12:25:09 +00:00
|
|
|
OGS_5GC_PRE_EMPTION_DISABLED;
|
2021-01-01 02:07:08 +00:00
|
|
|
else if (QosData->arp->preempt_vuln ==
|
|
|
|
OpenAPI_preemption_vulnerability_PREEMPTABLE)
|
|
|
|
pcc_rule->qos.arp.pre_emption_vulnerability =
|
2021-03-08 12:25:09 +00:00
|
|
|
OGS_5GC_PRE_EMPTION_ENABLED;
|
|
|
|
ogs_assert(pcc_rule->qos.arp.pre_emption_vulnerability);
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (QosData->maxbr_ul)
|
|
|
|
pcc_rule->qos.mbr.uplink =
|
|
|
|
ogs_sbi_bitrate_from_string(QosData->maxbr_ul);
|
|
|
|
if (QosData->maxbr_dl)
|
|
|
|
pcc_rule->qos.mbr.downlink =
|
|
|
|
ogs_sbi_bitrate_from_string(QosData->maxbr_dl);
|
|
|
|
|
|
|
|
if (QosData->gbr_ul)
|
|
|
|
pcc_rule->qos.gbr.uplink =
|
|
|
|
ogs_sbi_bitrate_from_string(QosData->gbr_ul);
|
|
|
|
if (QosData->gbr_dl)
|
|
|
|
pcc_rule->qos.gbr.downlink =
|
|
|
|
ogs_sbi_bitrate_from_string(QosData->gbr_dl);
|
|
|
|
|
|
|
|
if (pcc_rule->qos.mbr.downlink || pcc_rule->qos.mbr.uplink ||
|
|
|
|
pcc_rule->qos.gbr.downlink || pcc_rule->qos.gbr.uplink) {
|
|
|
|
if (pcc_rule->qos.mbr.downlink == 0)
|
|
|
|
pcc_rule->qos.mbr.downlink = MAX_BIT_RATE;
|
|
|
|
if (pcc_rule->qos.mbr.uplink == 0)
|
|
|
|
pcc_rule->qos.mbr.uplink = MAX_BIT_RATE;
|
|
|
|
if (pcc_rule->qos.gbr.downlink == 0)
|
|
|
|
pcc_rule->qos.gbr.downlink = MAX_BIT_RATE;
|
|
|
|
if (pcc_rule->qos.gbr.uplink == 0)
|
|
|
|
pcc_rule->qos.gbr.uplink = MAX_BIT_RATE;
|
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
sess->policy.num_of_pcc_rule++;
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-14 12:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool smf_npcf_smpolicycontrol_handle_create(
|
2023-07-10 07:29:17 +00:00
|
|
|
smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg)
|
2021-11-14 12:07:56 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
char buf1[OGS_ADDRSTRLEN];
|
|
|
|
char buf2[OGS_ADDRSTRLEN];
|
|
|
|
|
|
|
|
smf_ue_t *smf_ue = NULL;
|
|
|
|
smf_bearer_t *qos_flow = NULL;
|
|
|
|
ogs_pfcp_pdr_t *dl_pdr = NULL;
|
|
|
|
ogs_pfcp_pdr_t *ul_pdr = NULL;
|
|
|
|
ogs_pfcp_pdr_t *cp2up_pdr = NULL;
|
|
|
|
ogs_pfcp_pdr_t *up2cp_pdr = NULL;
|
|
|
|
ogs_pfcp_far_t *up2cp_far = NULL;
|
|
|
|
ogs_pfcp_qer_t *qer = NULL;
|
|
|
|
|
|
|
|
OpenAPI_sm_policy_decision_t *SmPolicyDecision = NULL;
|
|
|
|
OpenAPI_lnode_t *node = NULL;
|
|
|
|
|
|
|
|
#define MAX_TRIGGER_ID 128
|
|
|
|
bool trigger_results[MAX_TRIGGER_ID];
|
|
|
|
|
|
|
|
ogs_sbi_message_t message;
|
|
|
|
ogs_sbi_header_t header;
|
|
|
|
|
2024-04-18 12:13:45 +00:00
|
|
|
bool rc;
|
|
|
|
ogs_sbi_client_t *client = NULL;
|
|
|
|
OpenAPI_uri_scheme_e scheme = OpenAPI_uri_scheme_NULL;
|
|
|
|
char *fqdn = NULL;
|
|
|
|
uint16_t fqdn_port = 0;
|
|
|
|
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
smf_ue = sess->smf_ue;
|
|
|
|
ogs_assert(smf_ue);
|
|
|
|
|
|
|
|
ogs_assert(recvmsg);
|
|
|
|
|
|
|
|
if (!recvmsg->http.location) {
|
2023-07-10 07:29:17 +00:00
|
|
|
ogs_error("[%s:%d] No http.location", smf_ue->supi, sess->psi);
|
|
|
|
return false;
|
2021-11-14 12:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SmPolicyDecision = recvmsg->SmPolicyDecision;
|
|
|
|
if (!SmPolicyDecision) {
|
2023-07-10 07:29:17 +00:00
|
|
|
ogs_error("[%s:%d] No SmPolicyDecision", smf_ue->supi, sess->psi);
|
|
|
|
return false;
|
2021-11-14 12:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memset(&header, 0, sizeof(header));
|
|
|
|
header.uri = recvmsg->http.location;
|
|
|
|
|
|
|
|
rv = ogs_sbi_parse_header(&message, &header);
|
|
|
|
if (rv != OGS_OK) {
|
2023-07-10 07:29:17 +00:00
|
|
|
ogs_error("[%s:%d] Cannot parse http.location [%s]",
|
2021-11-14 12:07:56 +00:00
|
|
|
smf_ue->supi, sess->psi, recvmsg->http.location);
|
2023-07-10 07:29:17 +00:00
|
|
|
return false;
|
2021-11-14 12:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!message.h.resource.component[1]) {
|
2023-07-10 07:29:17 +00:00
|
|
|
ogs_error("[%s:%d] No Assocication ID [%s]",
|
2021-11-14 12:07:56 +00:00
|
|
|
smf_ue->supi, sess->psi, recvmsg->http.location);
|
|
|
|
|
|
|
|
ogs_sbi_header_free(&header);
|
2023-07-10 07:29:17 +00:00
|
|
|
return false;
|
2021-11-14 12:07:56 +00:00
|
|
|
}
|
|
|
|
|
2024-04-18 12:13:45 +00:00
|
|
|
rc = ogs_sbi_getaddr_from_uri(
|
|
|
|
&scheme, &fqdn, &fqdn_port, &addr, &addr6, header.uri);
|
|
|
|
if (rc == false || scheme == OpenAPI_uri_scheme_NULL) {
|
|
|
|
ogs_error("[%s:%d] Invalid URI [%s]",
|
|
|
|
smf_ue->supi, sess->psi, header.uri);
|
|
|
|
ogs_sbi_header_free(&header);
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
client = ogs_sbi_client_find(scheme, fqdn, fqdn_port, addr, addr6);
|
|
|
|
if (!client) {
|
|
|
|
ogs_debug("[%s:%d] ogs_sbi_client_add()", smf_ue->supi, sess->psi);
|
|
|
|
client = ogs_sbi_client_add(scheme, fqdn, fqdn_port, addr, addr6);
|
|
|
|
if (!client) {
|
|
|
|
ogs_error("[%s:%d] ogs_sbi_client_add() failed",
|
|
|
|
smf_ue->supi, sess->psi);
|
|
|
|
|
|
|
|
ogs_sbi_header_free(&header);
|
|
|
|
ogs_free(fqdn);
|
|
|
|
ogs_freeaddrinfo(addr);
|
|
|
|
ogs_freeaddrinfo(addr6);
|
|
|
|
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OGS_SBI_SETUP_CLIENT(&sess->policy_association, client);
|
|
|
|
|
|
|
|
ogs_free(fqdn);
|
|
|
|
ogs_freeaddrinfo(addr);
|
|
|
|
ogs_freeaddrinfo(addr6);
|
|
|
|
|
|
|
|
PCF_SM_POLICY_STORE(sess, header.uri, message.h.resource.component[1]);
|
2021-11-14 12:07:56 +00:00
|
|
|
|
|
|
|
ogs_sbi_header_free(&header);
|
|
|
|
|
|
|
|
/* SBI Features */
|
|
|
|
if (SmPolicyDecision->supp_feat) {
|
2022-08-26 15:12:22 +00:00
|
|
|
uint64_t supported_features =
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_uint64_from_string(SmPolicyDecision->supp_feat);
|
|
|
|
sess->smpolicycontrol_features &= supported_features;
|
|
|
|
} else {
|
|
|
|
sess->smpolicycontrol_features = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
* Handle Policy Control Request Triggers
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
/* Get policy control request triggers */
|
|
|
|
memset(&trigger_results, 0, sizeof(trigger_results));
|
|
|
|
OpenAPI_list_for_each(SmPolicyDecision->policy_ctrl_req_triggers, node) {
|
|
|
|
if (node->data) {
|
|
|
|
OpenAPI_policy_control_request_trigger_e trigger_id =
|
|
|
|
(intptr_t)node->data;
|
|
|
|
|
|
|
|
ogs_assert(trigger_id < MAX_TRIGGER_ID);
|
|
|
|
trigger_results[trigger_id] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update authorized session-AMBR */
|
|
|
|
if (SmPolicyDecision->sess_rules) {
|
|
|
|
OpenAPI_map_t *SessRuleMap = NULL;
|
|
|
|
OpenAPI_session_rule_t *SessionRule = NULL;
|
|
|
|
|
|
|
|
OpenAPI_ambr_t *AuthSessAmbr = NULL;
|
|
|
|
OpenAPI_authorized_default_qos_t *AuthDefQos = NULL;
|
|
|
|
|
|
|
|
OpenAPI_list_for_each(SmPolicyDecision->sess_rules, node) {
|
|
|
|
SessRuleMap = node->data;
|
|
|
|
if (!SessRuleMap) {
|
|
|
|
ogs_error("No SessRuleMap");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
SessionRule = SessRuleMap->value;
|
|
|
|
if (!SessionRule) {
|
|
|
|
ogs_error("No SessionRule");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AuthSessAmbr = SessionRule->auth_sess_ambr;
|
|
|
|
if (AuthSessAmbr && trigger_results[
|
|
|
|
OpenAPI_policy_control_request_trigger_SE_AMBR_CH] == true) {
|
|
|
|
if (AuthSessAmbr->uplink)
|
|
|
|
sess->session.ambr.uplink =
|
|
|
|
ogs_sbi_bitrate_from_string(AuthSessAmbr->uplink);
|
|
|
|
if (AuthSessAmbr->downlink)
|
|
|
|
sess->session.ambr.downlink =
|
|
|
|
ogs_sbi_bitrate_from_string(AuthSessAmbr->downlink);
|
|
|
|
}
|
|
|
|
|
|
|
|
AuthDefQos = SessionRule->auth_def_qos;
|
|
|
|
if (AuthDefQos && trigger_results[
|
|
|
|
OpenAPI_policy_control_request_trigger_DEF_QOS_CH] == true) {
|
|
|
|
sess->session.qos.index = AuthDefQos->_5qi;
|
|
|
|
sess->session.qos.arp.priority_level =
|
|
|
|
AuthDefQos->priority_level;
|
|
|
|
if (AuthDefQos->arp) {
|
|
|
|
sess->session.qos.arp.priority_level =
|
|
|
|
AuthDefQos->arp->priority_level;
|
|
|
|
if (AuthDefQos->arp->preempt_cap ==
|
|
|
|
OpenAPI_preemption_capability_NOT_PREEMPT)
|
|
|
|
sess->session.qos.arp.pre_emption_capability =
|
|
|
|
OGS_5GC_PRE_EMPTION_DISABLED;
|
|
|
|
else if (AuthDefQos->arp->preempt_cap ==
|
|
|
|
OpenAPI_preemption_capability_MAY_PREEMPT)
|
|
|
|
sess->session.qos.arp.pre_emption_capability =
|
|
|
|
OGS_5GC_PRE_EMPTION_ENABLED;
|
|
|
|
ogs_assert(sess->session.qos.arp.pre_emption_capability);
|
|
|
|
|
|
|
|
if (AuthDefQos->arp->preempt_vuln ==
|
|
|
|
OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE)
|
|
|
|
sess->session.qos.arp.pre_emption_vulnerability =
|
|
|
|
OGS_5GC_PRE_EMPTION_DISABLED;
|
|
|
|
else if (AuthDefQos->arp->preempt_vuln ==
|
|
|
|
OpenAPI_preemption_vulnerability_PREEMPTABLE)
|
|
|
|
sess->session.qos.arp.pre_emption_vulnerability =
|
|
|
|
OGS_5GC_PRE_EMPTION_ENABLED;
|
|
|
|
ogs_assert(sess->session.qos.arp.pre_emption_vulnerability);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update authorized PCC rule & QoS */
|
|
|
|
update_authorized_pcc_rule_and_qos(sess, SmPolicyDecision);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2020-12-11 19:03:20 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* Send PFCP Session Establiashment Request to the UPF
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
/* Select UPF based on UE Location Information */
|
|
|
|
smf_sess_select_upf(sess);
|
|
|
|
|
|
|
|
/* Check if selected UPF is associated with SMF */
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) {
|
2023-07-10 07:29:17 +00:00
|
|
|
ogs_error("[%s:%d] No associated UPF", smf_ue->supi, sess->psi);
|
|
|
|
return false;
|
2020-12-11 19:03:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove all previous QoS flow */
|
|
|
|
smf_bearer_remove_all(sess);
|
|
|
|
|
|
|
|
/* Setup Default QoS flow */
|
|
|
|
qos_flow = smf_qos_flow_add(sess);
|
|
|
|
ogs_assert(qos_flow);
|
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
/* Setup CP/UP Data Forwarding PDR/FAR */
|
|
|
|
smf_sess_create_cp_up_data_forwarding(sess);
|
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
/* Copy Session QoS information to Default QoS Flow */
|
2021-03-08 12:25:09 +00:00
|
|
|
memcpy(&qos_flow->qos, &sess->session.qos, sizeof(ogs_qos_t));
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2020-12-11 19:03:20 +00:00
|
|
|
/* Setup QER */
|
|
|
|
qer = qos_flow->qer;
|
|
|
|
ogs_assert(qer);
|
2021-03-08 12:25:09 +00:00
|
|
|
qer->mbr.uplink = sess->session.ambr.uplink;
|
|
|
|
qer->mbr.downlink = sess->session.ambr.downlink;
|
2020-12-11 19:03:20 +00:00
|
|
|
|
|
|
|
/* Setup PDR */
|
|
|
|
dl_pdr = qos_flow->dl_pdr;
|
|
|
|
ogs_assert(dl_pdr);
|
|
|
|
ul_pdr = qos_flow->ul_pdr;
|
|
|
|
ogs_assert(ul_pdr);
|
2021-03-15 01:01:55 +00:00
|
|
|
cp2up_pdr = sess->cp2up_pdr;
|
|
|
|
ogs_assert(cp2up_pdr);
|
|
|
|
up2cp_pdr = sess->up2cp_pdr;
|
|
|
|
ogs_assert(up2cp_pdr);
|
|
|
|
|
|
|
|
/* Setup FAR */
|
|
|
|
up2cp_far = sess->up2cp_far;
|
|
|
|
ogs_assert(up2cp_far);
|
2020-12-11 19:03:20 +00:00
|
|
|
|
2022-07-04 08:37:00 +00:00
|
|
|
/* Set UE IP Address to the Default DL PDR */
|
2022-07-01 17:14:58 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_paa_to_ue_ip_addr(&sess->session.paa,
|
2022-07-04 08:37:00 +00:00
|
|
|
&dl_pdr->ue_ip_addr, &dl_pdr->ue_ip_addr_len));
|
|
|
|
dl_pdr->ue_ip_addr.sd = OGS_PFCP_UE_IP_DST;
|
2022-07-01 17:14:58 +00:00
|
|
|
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_paa_to_ue_ip_addr(&sess->session.paa,
|
2022-07-04 08:37:00 +00:00
|
|
|
&ul_pdr->ue_ip_addr, &ul_pdr->ue_ip_addr_len));
|
2020-12-11 19:03:20 +00:00
|
|
|
|
2023-01-18 11:33:50 +00:00
|
|
|
if (sess->session.ipv4_framed_routes &&
|
|
|
|
sess->pfcp_node->up_function_features.frrt) {
|
|
|
|
int i = 0;
|
2023-01-25 10:12:20 +00:00
|
|
|
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
|
|
|
const char *route = sess->session.ipv4_framed_routes[i];
|
|
|
|
if (!route) break;
|
2023-06-02 12:40:53 +00:00
|
|
|
|
2023-01-18 11:33:50 +00:00
|
|
|
if (!dl_pdr->ipv4_framed_routes) {
|
|
|
|
dl_pdr->ipv4_framed_routes =
|
|
|
|
ogs_calloc(OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI,
|
|
|
|
sizeof(dl_pdr->ipv4_framed_routes[0]));
|
|
|
|
ogs_assert(dl_pdr->ipv4_framed_routes);
|
|
|
|
}
|
2023-01-25 10:12:20 +00:00
|
|
|
dl_pdr->ipv4_framed_routes[i] = ogs_strdup(route);
|
2023-06-02 12:40:53 +00:00
|
|
|
|
|
|
|
if (!ul_pdr->ipv4_framed_routes) {
|
|
|
|
ul_pdr->ipv4_framed_routes =
|
|
|
|
ogs_calloc(OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI,
|
|
|
|
sizeof(ul_pdr->ipv4_framed_routes[0]));
|
|
|
|
ogs_assert(ul_pdr->ipv4_framed_routes);
|
|
|
|
}
|
|
|
|
ul_pdr->ipv4_framed_routes[i] = ogs_strdup(route);
|
2023-01-18 11:33:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sess->session.ipv6_framed_routes &&
|
|
|
|
sess->pfcp_node->up_function_features.frrt) {
|
|
|
|
int i = 0;
|
2023-01-25 10:12:20 +00:00
|
|
|
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
|
|
|
const char *route = sess->session.ipv6_framed_routes[i];
|
|
|
|
if (!route) break;
|
2023-06-02 12:40:53 +00:00
|
|
|
|
2023-01-18 11:33:50 +00:00
|
|
|
if (!dl_pdr->ipv6_framed_routes) {
|
|
|
|
dl_pdr->ipv6_framed_routes =
|
2023-01-25 10:12:20 +00:00
|
|
|
ogs_calloc(OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI,
|
|
|
|
sizeof(dl_pdr->ipv6_framed_routes[0]));
|
2023-01-18 11:33:50 +00:00
|
|
|
ogs_assert(dl_pdr->ipv6_framed_routes);
|
|
|
|
}
|
2023-01-25 10:12:20 +00:00
|
|
|
dl_pdr->ipv6_framed_routes[i] = ogs_strdup(route);
|
2023-06-02 12:40:53 +00:00
|
|
|
|
|
|
|
if (!ul_pdr->ipv6_framed_routes) {
|
|
|
|
ul_pdr->ipv6_framed_routes =
|
|
|
|
ogs_calloc(OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI,
|
|
|
|
sizeof(ul_pdr->ipv6_framed_routes[0]));
|
|
|
|
ogs_assert(ul_pdr->ipv6_framed_routes);
|
|
|
|
}
|
|
|
|
ul_pdr->ipv6_framed_routes[i] = ogs_strdup(route);
|
2023-01-18 11:33:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-23 03:17:01 +00:00
|
|
|
ogs_info("UE SUPI[%s] DNN[%s] IPv4[%s] IPv6[%s]",
|
2022-09-02 14:38:39 +00:00
|
|
|
smf_ue->supi, sess->session.name,
|
2020-12-11 19:03:20 +00:00
|
|
|
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
|
|
|
|
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
|
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
/* Set UE-to-CP Flow-Description and Outer-Header-Creation */
|
2024-02-17 19:40:08 +00:00
|
|
|
up2cp_pdr->flow[up2cp_pdr->num_of_flow].fd = 1;
|
|
|
|
up2cp_pdr->flow[up2cp_pdr->num_of_flow].description =
|
2021-03-15 01:01:55 +00:00
|
|
|
(char *)"permit out 58 from ff02::2/128 to assigned";
|
2024-02-17 19:40:08 +00:00
|
|
|
up2cp_pdr->num_of_flow++;
|
|
|
|
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_ip_to_outer_header_creation(
|
2021-03-15 01:01:55 +00:00
|
|
|
&ogs_gtp_self()->gtpu_ip,
|
|
|
|
&up2cp_far->outer_header_creation,
|
2021-06-06 13:35:46 +00:00
|
|
|
&up2cp_far->outer_header_creation_len));
|
2021-03-15 01:01:55 +00:00
|
|
|
up2cp_far->outer_header_creation.teid = sess->index;
|
|
|
|
|
2020-12-11 19:03:20 +00:00
|
|
|
/* Set UPF-N3 TEID & ADDR to the Default UL PDR */
|
2021-01-01 02:07:08 +00:00
|
|
|
ogs_assert(sess->pfcp_node);
|
2020-12-11 19:03:20 +00:00
|
|
|
if (sess->pfcp_node->up_function_features.ftup) {
|
2022-06-24 06:16:54 +00:00
|
|
|
|
|
|
|
/* TS 129 244 V16.5.0 8.2.3
|
|
|
|
*
|
|
|
|
* At least one of the V4 and V6 flags shall be set to "1",
|
|
|
|
* and both may be set to "1" for both scenarios:
|
|
|
|
*
|
|
|
|
* - when the CP function is providing F-TEID, i.e.
|
|
|
|
* both IPv4 address field and IPv6 address field may be present;
|
|
|
|
* or
|
|
|
|
* - when the UP function is requested to allocate the F-TEID,
|
|
|
|
* i.e. when CHOOSE bit is set to "1",
|
|
|
|
* and the IPv4 address and IPv6 address fields are not present.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ul_pdr->f_teid.ipv4 = 1;
|
|
|
|
ul_pdr->f_teid.ipv6 = 1;
|
2020-12-11 19:03:20 +00:00
|
|
|
ul_pdr->f_teid.ch = 1;
|
2021-01-01 02:07:08 +00:00
|
|
|
ul_pdr->f_teid.chid = 1;
|
|
|
|
ul_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID;
|
|
|
|
ul_pdr->f_teid_len = 2;
|
2021-03-15 01:01:55 +00:00
|
|
|
|
2022-06-24 06:16:54 +00:00
|
|
|
cp2up_pdr->f_teid.ipv4 = 1;
|
|
|
|
cp2up_pdr->f_teid.ipv6 = 1;
|
2021-03-15 01:01:55 +00:00
|
|
|
cp2up_pdr->f_teid.ch = 1;
|
|
|
|
cp2up_pdr->f_teid_len = 1;
|
|
|
|
|
2022-06-24 06:16:54 +00:00
|
|
|
up2cp_pdr->f_teid.ipv4 = 1;
|
|
|
|
up2cp_pdr->f_teid.ipv6 = 1;
|
2021-03-15 01:01:55 +00:00
|
|
|
up2cp_pdr->f_teid.ch = 1;
|
|
|
|
up2cp_pdr->f_teid.chid = 1;
|
|
|
|
up2cp_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID;
|
|
|
|
up2cp_pdr->f_teid_len = 2;
|
2020-12-11 19:03:20 +00:00
|
|
|
} else {
|
2021-05-30 11:35:30 +00:00
|
|
|
ogs_gtpu_resource_t *resource = NULL;
|
2021-03-15 01:01:55 +00:00
|
|
|
resource = ogs_pfcp_find_gtpu_resource(
|
2020-12-11 19:03:20 +00:00
|
|
|
&sess->pfcp_node->gtpu_resource_list,
|
[GTP-U] Fixed ogs_pfcp_find_gtpu_resource()(#2923)
As mentioned in the sgwu.yaml configuration file, it is possible to configure multiple addresses with different source_interface values for the gtpu interface.
Following the this section, I defined two addresses, one with source_interface set to 0 and another with source_interface set to 1. My expectation was to see different addresses for the two PDRs in the Session Establishment Response message during session establishment. However, both addresses were the same, and it was the address I had set for source_interface = 0.
When I looked into the code, I found the reason for the issue. In the lib/pfcp/context.c file, on line 1185, the function that determines the address is called as follows:
...
} else {
ogs_gtpu_resource_t *resource = NULL;
resource = ogs_pfcp_find_gtpu_resource(
&ogs_gtp_self()->gtpu_resource_list,
pdr->dnn, OGS_PFCP_INTERFACE_ACCESS);
if (resource) {
...
In the last parameter of this function, a constant value, OGS_PFCP_INTERFACE_ACCESS, is used. This causes every PDR with any source_interface to be considered as "access," and the value 0 is used for its interface.
I replaced the value with pdr->src_if, and the bug was resolved.
2024-01-30 13:37:48 +00:00
|
|
|
sess->session.name, ul_pdr->src_if);
|
2020-12-11 19:03:20 +00:00
|
|
|
if (resource) {
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
2020-12-11 19:03:20 +00:00
|
|
|
&sess->upf_n3_addr, &sess->upf_n3_addr6);
|
|
|
|
if (resource->info.teidri)
|
|
|
|
sess->upf_n3_teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
2023-04-09 01:34:19 +00:00
|
|
|
ul_pdr->teid, resource->info.teidri,
|
2020-12-11 19:03:20 +00:00
|
|
|
resource->info.teid_range);
|
|
|
|
else
|
2023-04-09 01:34:19 +00:00
|
|
|
sess->upf_n3_teid = ul_pdr->teid;
|
2020-12-11 19:03:20 +00:00
|
|
|
} else {
|
|
|
|
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_copyaddrinfo(
|
|
|
|
&sess->upf_n3_addr, &sess->pfcp_node->addr));
|
2020-12-11 19:03:20 +00:00
|
|
|
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_copyaddrinfo(
|
|
|
|
&sess->upf_n3_addr6, &sess->pfcp_node->addr));
|
2020-12-11 19:03:20 +00:00
|
|
|
else
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
|
2023-04-09 01:34:19 +00:00
|
|
|
sess->upf_n3_teid = ul_pdr->teid;
|
2020-12-11 19:03:20 +00:00
|
|
|
}
|
|
|
|
|
2021-05-30 11:35:30 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_sockaddr_to_f_teid(
|
|
|
|
sess->upf_n3_addr, sess->upf_n3_addr6,
|
|
|
|
&ul_pdr->f_teid, &ul_pdr->f_teid_len));
|
2020-12-11 19:03:20 +00:00
|
|
|
ul_pdr->f_teid.teid = sess->upf_n3_teid;
|
2021-03-15 01:01:55 +00:00
|
|
|
|
2021-05-30 11:35:30 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_sockaddr_to_f_teid(
|
2022-04-16 05:08:56 +00:00
|
|
|
sess->upf_n3_addr, sess->upf_n3_addr6,
|
2021-05-30 11:35:30 +00:00
|
|
|
&cp2up_pdr->f_teid, &cp2up_pdr->f_teid_len));
|
2023-04-09 01:34:19 +00:00
|
|
|
cp2up_pdr->f_teid.teid = cp2up_pdr->teid;
|
2021-03-15 01:01:55 +00:00
|
|
|
|
2021-05-30 11:35:30 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_sockaddr_to_f_teid(
|
|
|
|
sess->upf_n3_addr, sess->upf_n3_addr6,
|
|
|
|
&up2cp_pdr->f_teid, &up2cp_pdr->f_teid_len));
|
2021-03-15 01:01:55 +00:00
|
|
|
up2cp_pdr->f_teid.teid = sess->upf_n3_teid;
|
2020-12-11 19:03:20 +00:00
|
|
|
}
|
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
dl_pdr->precedence = OGS_PFCP_DEFAULT_PDR_PRECEDENCE;
|
|
|
|
ul_pdr->precedence = OGS_PFCP_DEFAULT_PDR_PRECEDENCE;
|
|
|
|
|
|
|
|
cp2up_pdr->precedence = OGS_PFCP_CP2UP_PDR_PRECEDENCE;
|
|
|
|
up2cp_pdr->precedence = OGS_PFCP_UP2CP_PDR_PRECEDENCE;
|
2020-12-11 19:03:20 +00:00
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
2023-04-15 09:54:03 +00:00
|
|
|
smf_5gc_pfcp_send_session_establishment_request(sess, 0));
|
2020-12-11 19:03:20 +00:00
|
|
|
|
|
|
|
return true;
|
2021-05-29 06:56:12 +00:00
|
|
|
}
|
2021-11-14 12:07:56 +00:00
|
|
|
|
|
|
|
bool smf_npcf_smpolicycontrol_handle_update_notify(
|
|
|
|
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
|
|
|
{
|
|
|
|
char *strerror = NULL;
|
|
|
|
smf_ue_t *smf_ue = NULL;
|
|
|
|
|
|
|
|
OpenAPI_sm_policy_notification_t *SmPolicyNotification = NULL;
|
|
|
|
OpenAPI_sm_policy_decision_t *SmPolicyDecision = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(stream);
|
|
|
|
smf_ue = sess->smf_ue;
|
|
|
|
ogs_assert(smf_ue);
|
|
|
|
|
|
|
|
ogs_assert(recvmsg);
|
|
|
|
|
|
|
|
SmPolicyNotification = recvmsg->SmPolicyNotification;
|
|
|
|
if (!SmPolicyNotification) {
|
|
|
|
strerror = ogs_msprintf("[%s:%d] No SmPolicyNotification",
|
|
|
|
smf_ue->supi, sess->psi);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
SmPolicyDecision = SmPolicyNotification->sm_policy_decision;
|
|
|
|
if (!SmPolicyDecision) {
|
|
|
|
strerror = ogs_msprintf("[%s:%d] No SmPolicyDecision",
|
|
|
|
smf_ue->supi, sess->psi);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update authorized PCC rule & QoS */
|
|
|
|
update_authorized_pcc_rule_and_qos(sess, SmPolicyDecision);
|
|
|
|
|
|
|
|
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
|
|
|
|
|
|
|
|
smf_qos_flow_binding(sess);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
ogs_assert(strerror);
|
|
|
|
|
|
|
|
ogs_error("%s", strerror);
|
|
|
|
ogs_assert(true ==
|
|
|
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
2024-04-04 14:29:20 +00:00
|
|
|
recvmsg, strerror, NULL, NULL));
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_free(strerror);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool smf_npcf_smpolicycontrol_handle_terminate_notify(
|
|
|
|
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
|
|
|
{
|
|
|
|
smf_ue_t *smf_ue = NULL;
|
|
|
|
smf_npcf_smpolicycontrol_param_t param;
|
2023-01-31 10:38:17 +00:00
|
|
|
int r;
|
2021-11-14 12:07:56 +00:00
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(stream);
|
|
|
|
smf_ue = sess->smf_ue;
|
|
|
|
ogs_assert(smf_ue);
|
|
|
|
|
|
|
|
ogs_assert(recvmsg);
|
|
|
|
|
|
|
|
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
|
|
|
|
|
2024-04-18 12:13:45 +00:00
|
|
|
if (PCF_SM_POLICY_ASSOCIATED(sess)) {
|
2023-08-10 13:14:48 +00:00
|
|
|
memset(¶m, 0, sizeof(param));
|
|
|
|
r = smf_sbi_discover_and_send(
|
|
|
|
OGS_SBI_SERVICE_TYPE_NPCF_SMPOLICYCONTROL, NULL,
|
|
|
|
smf_npcf_smpolicycontrol_build_delete,
|
|
|
|
sess, NULL, OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED, ¶m);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
|
|
|
} else {
|
|
|
|
ogs_error("[%s:%d] No PolicyAssociationId. Forcibly remove SESSION",
|
|
|
|
smf_ue->supi, sess->psi);
|
|
|
|
SMF_SESS_CLEAR(sess);
|
|
|
|
}
|
2021-11-14 12:07:56 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|