2020-04-26 19:36:05 +00:00
|
|
|
/*
|
2024-03-25 23:04:26 +00:00
|
|
|
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
2020-04-26 19:36:05 +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/>.
|
|
|
|
*/
|
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
#include "binding.h"
|
2020-04-26 19:36:05 +00:00
|
|
|
#include "s5c-build.h"
|
2020-10-26 02:43:53 +00:00
|
|
|
#include "pfcp-path.h"
|
2021-06-21 13:36:38 +00:00
|
|
|
#include "gtp-path.h"
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
#include "ipfw/ipfw2.h"
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
static void gtp_bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
2020-04-26 19:36:05 +00:00
|
|
|
{
|
2020-11-07 22:27:12 +00:00
|
|
|
smf_bearer_t *bearer = data;
|
|
|
|
smf_sess_t *sess = NULL;
|
|
|
|
smf_ue_t *smf_ue = NULL;
|
2020-04-26 19:36:05 +00:00
|
|
|
uint8_t type = 0;
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
2020-04-26 19:36:05 +00:00
|
|
|
ogs_assert(sess);
|
2020-11-07 22:27:12 +00:00
|
|
|
smf_ue = sess->smf_ue;
|
|
|
|
ogs_assert(smf_ue);
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
type = xact->seq[0].type;
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
switch (type) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Create Bearer Response", smf_ue->imsi_bcd);
|
2021-01-08 20:09:02 +00:00
|
|
|
if (!smf_bearer_cycle(bearer)) {
|
|
|
|
ogs_warn("[%s] Bearer has already been removed", smf_ue->imsi_bcd);
|
|
|
|
break;
|
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
2022-05-18 01:29:58 +00:00
|
|
|
smf_epc_pfcp_send_one_bearer_modification_request(
|
2021-11-23 05:19:30 +00:00
|
|
|
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
|
|
|
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
|
2020-11-07 22:27:12 +00:00
|
|
|
break;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Update Bearer Response", smf_ue->imsi_bcd);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
|
|
|
|
smf_ue->imsi_bcd, type);
|
|
|
|
break;
|
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
}
|
|
|
|
|
2020-09-21 03:35:10 +00:00
|
|
|
/*
|
|
|
|
* Issue #338
|
|
|
|
*
|
2024-02-17 19:40:08 +00:00
|
|
|
* <DOWNLINK/BI-DIRECTIONAL>
|
2020-09-21 03:35:10 +00:00
|
|
|
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
|
|
|
|
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
|
|
|
|
*
|
|
|
|
* <UPLINK>
|
|
|
|
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
|
|
|
|
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
|
|
|
|
*/
|
2020-04-26 19:36:05 +00:00
|
|
|
static void encode_traffic_flow_template(
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_tft_t *tft, smf_bearer_t *bearer, uint8_t tft_operation_code)
|
2020-04-26 19:36:05 +00:00
|
|
|
{
|
2021-01-01 02:07:08 +00:00
|
|
|
int i;
|
2020-04-26 19:36:05 +00:00
|
|
|
smf_pf_t *pf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(tft);
|
2021-05-28 14:46:48 +00:00
|
|
|
ogs_assert(bearer);
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
memset(tft, 0, sizeof(*tft));
|
2021-05-26 19:29:32 +00:00
|
|
|
tft->code = tft_operation_code;
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
i = 0;
|
2022-04-12 22:07:39 +00:00
|
|
|
if (tft_operation_code != OGS_GTP2_TFT_CODE_DELETE_EXISTING_TFT &&
|
|
|
|
tft_operation_code != OGS_GTP2_TFT_CODE_NO_TFT_OPERATION) {
|
2021-05-28 14:46:48 +00:00
|
|
|
ogs_list_for_each_entry(&bearer->pf_to_add_list, pf, to_add_node) {
|
2021-08-07 05:23:20 +00:00
|
|
|
ogs_assert(i < OGS_MAX_NUM_OF_FLOW_IN_GTP);
|
2021-05-26 19:29:32 +00:00
|
|
|
tft->pf[i].identifier = pf->identifier - 1;
|
|
|
|
|
2021-05-28 14:46:48 +00:00
|
|
|
/* Deletion of packet filters
|
|
|
|
* from existing requires only the identifier */
|
2021-05-26 19:29:32 +00:00
|
|
|
if (tft_operation_code !=
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING) {
|
2021-05-26 19:29:32 +00:00
|
|
|
|
|
|
|
tft->pf[i].direction = pf->direction;
|
|
|
|
tft->pf[i].precedence = pf->precedence - 1;
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2021-05-26 19:29:32 +00:00
|
|
|
ogs_pf_content_from_ipfw_rule(
|
2022-02-25 13:11:51 +00:00
|
|
|
pf->direction, &tft->pf[i].content, &pf->ipfw_rule,
|
2023-11-19 10:34:51 +00:00
|
|
|
ogs_global_conf()->parameter.
|
|
|
|
no_ipv4v6_local_addr_in_packet_filter);
|
2021-05-26 19:29:32 +00:00
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2021-05-26 19:29:32 +00:00
|
|
|
i++;
|
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
}
|
|
|
|
tft->num_of_packet_filter = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
void smf_bearer_binding(smf_sess_t *sess)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
for (i = 0; i < sess->policy.num_of_pcc_rule; i++) {
|
2020-04-26 19:36:05 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2020-04-26 19:36:05 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
smf_bearer_t *bearer = NULL;
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_pcc_rule_t *pcc_rule = &sess->policy.pcc_rule[i];
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
ogs_assert(pcc_rule);
|
|
|
|
if (pcc_rule->name == NULL) {
|
|
|
|
ogs_error("No PCC Rule Name");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pcc_rule->type == OGS_PCC_RULE_TYPE_INSTALL) {
|
2021-11-14 12:07:56 +00:00
|
|
|
bool bearer_created = false;
|
|
|
|
bool qos_presence = false;
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2021-03-29 01:28:08 +00:00
|
|
|
bearer = smf_bearer_find_by_pcc_rule_name(sess, pcc_rule->name);
|
2020-04-26 19:36:05 +00:00
|
|
|
if (!bearer) {
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_pfcp_pdr_t *dl_pdr = NULL, *ul_pdr = NULL;
|
|
|
|
|
2020-04-26 19:36:05 +00:00
|
|
|
if (pcc_rule->num_of_flow == 0) {
|
|
|
|
/* TFT is mandatory in
|
|
|
|
* activate dedicated EPS bearer context request */
|
|
|
|
ogs_error("No flow in PCC Rule");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-11-23 05:19:30 +00:00
|
|
|
if (ogs_list_count(&sess->bearer_list) >=
|
|
|
|
OGS_MAX_NUM_OF_BEARER) {
|
|
|
|
ogs_error("Bearer Overflow[%d]",
|
|
|
|
ogs_list_count(&sess->bearer_list));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-04-26 19:36:05 +00:00
|
|
|
bearer = smf_bearer_add(sess);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
dl_pdr = bearer->dl_pdr;
|
|
|
|
ogs_assert(dl_pdr);
|
|
|
|
ul_pdr = bearer->ul_pdr;
|
|
|
|
ogs_assert(ul_pdr);
|
|
|
|
|
2020-04-26 19:36:05 +00:00
|
|
|
/* Precedence is set to the order in which it was created */
|
2021-03-15 01:01:55 +00:00
|
|
|
dl_pdr->precedence = dl_pdr->id;
|
|
|
|
ul_pdr->precedence = ul_pdr->id;
|
|
|
|
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
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;
|
2021-03-15 01:01:55 +00:00
|
|
|
ul_pdr->f_teid.ch = 1;
|
|
|
|
ul_pdr->f_teid_len = 1;
|
|
|
|
} else {
|
2021-05-30 11:35:30 +00:00
|
|
|
ogs_gtpu_resource_t *resource = NULL;
|
|
|
|
resource = ogs_pfcp_find_gtpu_resource(
|
2021-03-15 01:01:55 +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);
|
2021-03-15 01:01:55 +00:00
|
|
|
if (resource) {
|
|
|
|
ogs_user_plane_ip_resource_info_to_sockaddr(
|
|
|
|
&resource->info,
|
|
|
|
&bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6);
|
|
|
|
if (resource->info.teidri)
|
|
|
|
bearer->pgw_s5u_teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
2023-04-09 01:34:19 +00:00
|
|
|
ul_pdr->teid, resource->info.teidri,
|
2021-03-15 01:01:55 +00:00
|
|
|
resource->info.teid_range);
|
|
|
|
else
|
2023-04-09 01:34:19 +00:00
|
|
|
bearer->pgw_s5u_teid = ul_pdr->teid;
|
2021-03-15 01:01:55 +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(&bearer->pgw_s5u_addr,
|
|
|
|
&sess->pfcp_node->addr));
|
2021-03-15 01:01:55 +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(&bearer->pgw_s5u_addr6,
|
|
|
|
&sess->pfcp_node->addr));
|
2021-03-15 01:01:55 +00:00
|
|
|
else
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
|
2023-04-09 01:34:19 +00:00
|
|
|
bearer->pgw_s5u_teid = ul_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(
|
|
|
|
bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6,
|
|
|
|
&ul_pdr->f_teid, &ul_pdr->f_teid_len));
|
2021-03-15 01:01:55 +00:00
|
|
|
ul_pdr->f_teid.teid = bearer->pgw_s5u_teid;
|
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
bearer->pcc_rule.name = ogs_strdup(pcc_rule->name);
|
|
|
|
ogs_assert(bearer->pcc_rule.name);
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
memcpy(&bearer->qos, &pcc_rule->qos, sizeof(ogs_qos_t));
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
bearer_created = true;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-04-26 19:36:05 +00:00
|
|
|
} else {
|
2021-01-01 02:07:08 +00:00
|
|
|
ogs_assert(strcmp(bearer->pcc_rule.name, pcc_rule->name) == 0);
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
if ((pcc_rule->qos.mbr.downlink &&
|
|
|
|
bearer->qos.mbr.downlink != pcc_rule->qos.mbr.downlink) ||
|
|
|
|
(pcc_rule->qos.mbr.uplink &&
|
|
|
|
bearer->qos.mbr.uplink != pcc_rule->qos.mbr.uplink) ||
|
|
|
|
(pcc_rule->qos.gbr.downlink &&
|
|
|
|
bearer->qos.gbr.downlink != pcc_rule->qos.gbr.downlink) ||
|
|
|
|
(pcc_rule->qos.gbr.uplink &&
|
|
|
|
bearer->qos.gbr.uplink != pcc_rule->qos.gbr.uplink)) {
|
|
|
|
/* Update QoS parameter */
|
|
|
|
memcpy(&bearer->qos, &pcc_rule->qos, sizeof(ogs_qos_t));
|
|
|
|
|
|
|
|
/* Update Bearer Request encodes updated QoS parameter */
|
2021-11-14 12:07:56 +00:00
|
|
|
qos_presence = true;
|
2020-04-26 19:36:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
2021-05-28 14:46:48 +00:00
|
|
|
ogs_list_init(&bearer->pf_to_add_list);
|
|
|
|
|
2020-04-26 19:36:05 +00:00
|
|
|
for (j = 0; j < pcc_rule->num_of_flow; j++) {
|
|
|
|
smf_pf_t *pf = NULL;
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_flow_t *flow = &pcc_rule->flow[j];
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!flow) {
|
|
|
|
ogs_error("No Flow");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!flow->description) {
|
|
|
|
ogs_error("No Flow-Description");
|
|
|
|
return;
|
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
/*
|
|
|
|
* To add a flow to an existing tft.
|
|
|
|
* duplicated flows are not added
|
|
|
|
*/
|
2021-05-28 14:46:48 +00:00
|
|
|
if (smf_pf_find_by_flow(
|
|
|
|
bearer, flow->direction, flow->description) != NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
/*
|
|
|
|
* To add a flow to an existing tft.
|
|
|
|
*
|
|
|
|
* Only new flows are added to the PF list.
|
|
|
|
* Then, in the PF list, there are all flows
|
|
|
|
* from the beginning to the present.
|
|
|
|
*/
|
2021-01-01 02:07:08 +00:00
|
|
|
pf = smf_pf_add(bearer);
|
2021-08-07 05:23:20 +00:00
|
|
|
if (!pf) {
|
|
|
|
ogs_error("Overflow: PacketFilter in Bearer");
|
|
|
|
break;
|
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
pf->direction = flow->direction;
|
2020-08-13 00:31:22 +00:00
|
|
|
pf->flow_description = ogs_strdup(flow->description);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(pf->flow_description);
|
2020-09-21 03:35:10 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
rv = ogs_ipfw_compile_rule(
|
|
|
|
&pf->ipfw_rule, pf->flow_description);
|
2020-09-21 03:35:10 +00:00
|
|
|
/*
|
|
|
|
* Refer to lib/ipfw/ogs-ipfw.h
|
|
|
|
* Issue #338
|
|
|
|
*
|
2024-02-17 19:40:08 +00:00
|
|
|
* <DOWNLINK/BI-DIRECTIONAL>
|
2020-09-21 03:35:10 +00:00
|
|
|
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
|
|
|
|
* -->
|
|
|
|
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
|
|
|
|
*
|
|
|
|
* <UPLINK>
|
|
|
|
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
|
|
|
|
* -->
|
|
|
|
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
|
|
|
|
*/
|
|
|
|
if (flow->direction == OGS_FLOW_UPLINK_ONLY)
|
|
|
|
ogs_ipfw_rule_swap(&pf->ipfw_rule);
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("Invalid Flow-Description[%s]",
|
|
|
|
pf->flow_description);
|
|
|
|
smf_pf_remove(pf);
|
|
|
|
break;
|
|
|
|
}
|
2021-05-26 19:29:32 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
/*
|
|
|
|
* To add a flow to an existing tft.
|
|
|
|
*
|
|
|
|
* 'pf_to_add_list' now has the added flow.
|
|
|
|
*/
|
2021-05-28 14:46:48 +00:00
|
|
|
ogs_list_add(&bearer->pf_to_add_list, &pf->to_add_node);
|
2020-04-26 19:36:05 +00:00
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (bearer_created == false &&
|
|
|
|
qos_presence == false &&
|
|
|
|
ogs_list_count(&bearer->pf_to_add_list) == 0) {
|
2022-01-12 11:06:26 +00:00
|
|
|
ogs_warn("No need to send 'Update Bearer Request'");
|
|
|
|
ogs_warn("bearer_created:%d, qos_presence:%d, rule_count:%d",
|
2021-11-14 12:07:56 +00:00
|
|
|
bearer_created, qos_presence,
|
|
|
|
ogs_list_count(&bearer->pf_to_add_list));
|
|
|
|
continue;
|
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (bearer_created == true) {
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
smf_bearer_tft_update(bearer);
|
|
|
|
smf_bearer_qos_update(bearer);
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
2022-05-18 01:29:58 +00:00
|
|
|
smf_epc_pfcp_send_one_bearer_modification_request(
|
2021-11-23 05:19:30 +00:00
|
|
|
bearer, NULL, OGS_PFCP_MODIFY_CREATE,
|
|
|
|
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
|
2020-10-26 02:43:53 +00:00
|
|
|
} else {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_tft_t tft;
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2020-10-26 02:43:53 +00:00
|
|
|
memset(&tft, 0, sizeof tft);
|
2021-11-14 12:07:56 +00:00
|
|
|
if (ogs_list_count(&bearer->pf_to_add_list) > 0) {
|
2021-05-26 19:29:32 +00:00
|
|
|
encode_traffic_flow_template(
|
2021-05-28 14:46:48 +00:00
|
|
|
&tft, bearer,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT);
|
2021-08-07 05:23:20 +00:00
|
|
|
}
|
2021-05-26 19:29:32 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
2020-04-26 19:36:05 +00:00
|
|
|
h.teid = sess->sgw_s5c_teid;
|
|
|
|
|
|
|
|
pkbuf = smf_s5c_build_update_bearer_request(
|
|
|
|
h.type, bearer,
|
|
|
|
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
2021-11-14 12:07:56 +00:00
|
|
|
(ogs_list_count(&bearer->pf_to_add_list) > 0) ?
|
|
|
|
&tft : NULL, qos_presence);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("smf_s5c_build_update_bearer_request() failed");
|
|
|
|
return;
|
|
|
|
}
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(
|
2022-05-15 14:35:41 +00:00
|
|
|
sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-06-30 01:53:19 +00:00
|
|
|
xact->local_teid = sess->smf_n4_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (ogs_list_count(&bearer->pf_to_add_list) > 0)
|
2020-08-13 00:31:22 +00:00
|
|
|
xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE;
|
2021-11-14 12:07:56 +00:00
|
|
|
if (qos_presence == true)
|
2020-08-13 00:31:22 +00:00
|
|
|
xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE;
|
2020-04-26 19:36:05 +00:00
|
|
|
|
2020-10-26 02:43:53 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-04-26 19:36:05 +00:00
|
|
|
} else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) {
|
2021-01-01 02:07:08 +00:00
|
|
|
bearer = smf_bearer_find_by_pcc_rule_name(sess, pcc_rule->name);
|
2020-04-26 19:36:05 +00:00
|
|
|
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_warn("No need to send 'Delete Bearer Request'");
|
|
|
|
ogs_warn(" - Bearer[Name:%s] has already been removed.",
|
|
|
|
pcc_rule->name);
|
2020-08-29 14:53:02 +00:00
|
|
|
continue;
|
2020-04-26 19:36:05 +00:00
|
|
|
}
|
|
|
|
|
2021-11-23 05:19:30 +00:00
|
|
|
/*
|
|
|
|
* TS23.214
|
|
|
|
* 6.3.1.7 Procedures with modification of bearer
|
|
|
|
* p50
|
|
|
|
* 2. ...
|
|
|
|
* For "PGW/MME initiated bearer deactivation procedure",
|
|
|
|
* PGW-C shall indicate PGW-U to stop counting and stop
|
|
|
|
* forwarding downlink packets for the affected bearer(s).
|
|
|
|
*/
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
2022-05-18 01:29:58 +00:00
|
|
|
smf_epc_pfcp_send_one_bearer_modification_request(
|
2021-11-23 05:19:30 +00:00
|
|
|
bearer, NULL,
|
|
|
|
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
|
|
|
|
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
|
2020-04-26 19:36:05 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("Invalid Type[%d]", pcc_rule->type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer)
|
2020-10-26 02:43:53 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
smf_sess_t *sess = NULL;
|
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2020-10-26 02:43:53 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_tft_t tft;
|
2020-10-26 02:43:53 +00:00
|
|
|
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
h.type = OGS_GTP2_CREATE_BEARER_REQUEST_TYPE;
|
2020-10-26 02:43:53 +00:00
|
|
|
h.teid = sess->sgw_s5c_teid;
|
|
|
|
|
|
|
|
memset(&tft, 0, sizeof tft);
|
2022-05-15 14:35:41 +00:00
|
|
|
encode_traffic_flow_template(
|
|
|
|
&tft, bearer, OGS_GTP2_TFT_CODE_CREATE_NEW_TFT);
|
2020-10-26 02:43:53 +00:00
|
|
|
|
|
|
|
pkbuf = smf_s5c_build_create_bearer_request(h.type, bearer, &tft);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("smf_s5c_build_create_bearer_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(
|
2022-05-15 14:35:41 +00:00
|
|
|
sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2022-06-30 01:53:19 +00:00
|
|
|
xact->local_teid = sess->smf_n4_teid;
|
2020-10-26 02:43:53 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-06-06 13:35:46 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-10-26 02:43:53 +00:00
|
|
|
}
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
void smf_qos_flow_binding(smf_sess_t *sess)
|
2021-01-01 02:07:08 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
int i, j;
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
uint64_t pfcp_flags, check;
|
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
pfcp_flags = OGS_PFCP_MODIFY_NETWORK_REQUESTED;
|
|
|
|
|
|
|
|
ogs_list_init(&sess->qos_flow_to_modify_list);
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
for (i = 0; i < sess->policy.num_of_pcc_rule; i++) {
|
2021-01-01 02:07:08 +00:00
|
|
|
smf_bearer_t *qos_flow = NULL;
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_pcc_rule_t *pcc_rule = &sess->policy.pcc_rule[i];
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
ogs_assert(pcc_rule);
|
|
|
|
if (pcc_rule->id == NULL) {
|
|
|
|
ogs_error("No PCC Rule Id");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pcc_rule->type == OGS_PCC_RULE_TYPE_INSTALL) {
|
2021-11-14 12:07:56 +00:00
|
|
|
smf_pf_t *pf = NULL;
|
2021-01-01 02:07:08 +00:00
|
|
|
ogs_pfcp_pdr_t *dl_pdr = NULL, *ul_pdr = NULL;
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
bool qos_flow_created = false;
|
|
|
|
bool qos_presence = false;
|
|
|
|
|
2021-03-29 01:28:08 +00:00
|
|
|
qos_flow = smf_qos_flow_find_by_pcc_rule_id(sess, pcc_rule->id);
|
2021-01-01 02:07:08 +00:00
|
|
|
if (!qos_flow) {
|
|
|
|
if (pcc_rule->num_of_flow == 0) {
|
|
|
|
/* TFT is mandatory in
|
|
|
|
* activate dedicated EPS bearer context request */
|
|
|
|
ogs_error("No flow in PCC Rule");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-11-23 05:19:30 +00:00
|
|
|
if (ogs_list_count(&sess->bearer_list) >=
|
|
|
|
OGS_MAX_NUM_OF_BEARER) {
|
|
|
|
ogs_error("QosFlow Overflow[%d]",
|
|
|
|
ogs_list_count(&sess->bearer_list));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
qos_flow = smf_qos_flow_add(sess);
|
|
|
|
ogs_assert(qos_flow);
|
|
|
|
|
|
|
|
dl_pdr = qos_flow->dl_pdr;
|
|
|
|
ogs_assert(dl_pdr);
|
|
|
|
ul_pdr = qos_flow->ul_pdr;
|
|
|
|
ogs_assert(ul_pdr);
|
|
|
|
|
|
|
|
/* Precedence is derived from PCC Rule Precedence */
|
|
|
|
dl_pdr->precedence = pcc_rule->precedence;
|
|
|
|
ul_pdr->precedence = pcc_rule->precedence;
|
|
|
|
|
|
|
|
/* Set UPF-N3 TEID & ADDR to the UL PDR */
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
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;
|
2021-01-01 02:07:08 +00:00
|
|
|
ul_pdr->f_teid.ch = 1;
|
|
|
|
ul_pdr->f_teid.chid = 1;
|
|
|
|
ul_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID;
|
|
|
|
ul_pdr->f_teid_len = 2;
|
|
|
|
} else {
|
2021-05-30 11:35:30 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_sockaddr_to_f_teid(
|
2021-01-01 02:07:08 +00:00
|
|
|
sess->upf_n3_addr, sess->upf_n3_addr6,
|
2021-05-30 11:35:30 +00:00
|
|
|
&ul_pdr->f_teid, &ul_pdr->f_teid_len));
|
2021-01-01 02:07:08 +00:00
|
|
|
ul_pdr->f_teid.teid = sess->upf_n3_teid;
|
|
|
|
}
|
|
|
|
|
|
|
|
qos_flow->pcc_rule.id = ogs_strdup(pcc_rule->id);
|
|
|
|
ogs_assert(qos_flow->pcc_rule.id);
|
|
|
|
|
|
|
|
memcpy(&qos_flow->qos, &pcc_rule->qos, sizeof(ogs_qos_t));
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
qos_flow_created = true;
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
ogs_assert(strcmp(qos_flow->pcc_rule.id, pcc_rule->id) == 0);
|
|
|
|
|
|
|
|
if ((pcc_rule->qos.mbr.downlink &&
|
|
|
|
qos_flow->qos.mbr.downlink != pcc_rule->qos.mbr.downlink) ||
|
|
|
|
(pcc_rule->qos.mbr.uplink &&
|
|
|
|
qos_flow->qos.mbr.uplink != pcc_rule->qos.mbr.uplink) ||
|
|
|
|
(pcc_rule->qos.gbr.downlink &&
|
|
|
|
qos_flow->qos.gbr.downlink != pcc_rule->qos.gbr.downlink) ||
|
|
|
|
(pcc_rule->qos.gbr.uplink &&
|
|
|
|
qos_flow->qos.gbr.uplink != pcc_rule->qos.gbr.uplink)) {
|
|
|
|
/* Update QoS parameter */
|
|
|
|
memcpy(&qos_flow->qos, &pcc_rule->qos, sizeof(ogs_qos_t));
|
|
|
|
|
|
|
|
/* Update Bearer Request encodes updated QoS parameter */
|
2021-11-14 12:07:56 +00:00
|
|
|
qos_presence = true;
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
2021-05-28 14:46:48 +00:00
|
|
|
ogs_list_init(&qos_flow->pf_to_add_list);
|
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
for (j = 0; j < pcc_rule->num_of_flow; j++) {
|
|
|
|
ogs_flow_t *flow = &pcc_rule->flow[j];
|
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!flow) {
|
|
|
|
ogs_error("No Flow");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!flow->description) {
|
|
|
|
ogs_error("No Flow-Description");
|
|
|
|
return;
|
|
|
|
}
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
/*
|
|
|
|
* To add a flow to an existing tft.
|
|
|
|
* duplicated flows are not added
|
|
|
|
*/
|
2021-05-28 14:46:48 +00:00
|
|
|
if (smf_pf_find_by_flow(
|
|
|
|
qos_flow, flow->direction, flow->description) != NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
/*
|
|
|
|
* To add a flow to an existing tft.
|
|
|
|
*
|
|
|
|
* Only new flows are added to the PF list.
|
|
|
|
* Then, in the PF list, there are all flows
|
|
|
|
* from the beginning to the present.
|
|
|
|
*/
|
2021-01-01 02:07:08 +00:00
|
|
|
pf = smf_pf_add(qos_flow);
|
2021-11-14 12:07:56 +00:00
|
|
|
if (!pf) {
|
|
|
|
ogs_error("Overflow: PacketFilter in Bearer");
|
|
|
|
break;
|
|
|
|
}
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
pf->direction = flow->direction;
|
|
|
|
pf->flow_description = ogs_strdup(flow->description);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(pf->flow_description);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
rv = ogs_ipfw_compile_rule(
|
|
|
|
&pf->ipfw_rule, pf->flow_description);
|
|
|
|
/*
|
|
|
|
* Refer to lib/ipfw/ogs-ipfw.h
|
|
|
|
* Issue #338
|
|
|
|
*
|
2024-02-17 19:40:08 +00:00
|
|
|
* <DOWNLINK/BI-DIRECTIONAL>
|
2021-01-01 02:07:08 +00:00
|
|
|
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
|
|
|
|
* -->
|
|
|
|
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
|
|
|
|
*
|
|
|
|
* <UPLINK>
|
|
|
|
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
|
|
|
|
* -->
|
|
|
|
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
|
|
|
|
*/
|
|
|
|
if (flow->direction == OGS_FLOW_UPLINK_ONLY)
|
|
|
|
ogs_ipfw_rule_swap(&pf->ipfw_rule);
|
|
|
|
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("Invalid Flow-Description[%s]",
|
|
|
|
pf->flow_description);
|
|
|
|
smf_pf_remove(pf);
|
|
|
|
break;
|
|
|
|
}
|
2021-05-26 19:29:32 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
/*
|
|
|
|
* To add a flow to an existing tft.
|
|
|
|
*
|
|
|
|
* 'pf_to_add_list' now has the added flow.
|
|
|
|
*/
|
2021-05-28 14:46:48 +00:00
|
|
|
ogs_list_add(&qos_flow->pf_to_add_list, &pf->to_add_node);
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (qos_flow_created == false &&
|
|
|
|
qos_presence == false &&
|
|
|
|
ogs_list_count(&qos_flow->pf_to_add_list) == 0) {
|
2022-01-12 11:06:26 +00:00
|
|
|
ogs_warn("No need to send 'Session Modification Request'");
|
|
|
|
ogs_warn("qos_flow_created:%d, qos_presence:%d, rule_count:%d",
|
2021-11-14 12:07:56 +00:00
|
|
|
qos_flow_created, qos_presence,
|
|
|
|
ogs_list_count(&qos_flow->pf_to_add_list));
|
|
|
|
continue;
|
|
|
|
}
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (qos_flow_created == true) {
|
|
|
|
smf_bearer_tft_update(qos_flow);
|
|
|
|
smf_bearer_qos_update(qos_flow);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
pfcp_flags |= OGS_PFCP_MODIFY_CREATE;
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
ogs_list_add(&sess->qos_flow_to_modify_list,
|
|
|
|
&qos_flow->to_modify_node);
|
2021-01-01 02:07:08 +00:00
|
|
|
} else {
|
2021-11-14 12:07:56 +00:00
|
|
|
pfcp_flags |= OGS_PFCP_MODIFY_NETWORK_REQUESTED;
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
if (ogs_list_count(&qos_flow->pf_to_add_list) > 0) {
|
|
|
|
pfcp_flags |= OGS_PFCP_MODIFY_TFT_ADD;
|
|
|
|
smf_bearer_tft_update(qos_flow);
|
|
|
|
}
|
|
|
|
if (qos_presence == true) {
|
|
|
|
pfcp_flags |= OGS_PFCP_MODIFY_QOS_MODIFY;
|
|
|
|
smf_bearer_qos_update(qos_flow);
|
|
|
|
}
|
2021-01-01 02:07:08 +00:00
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
ogs_list_add(&sess->qos_flow_to_modify_list,
|
|
|
|
&qos_flow->to_modify_node);
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|
|
|
|
} else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) {
|
2021-11-14 12:07:56 +00:00
|
|
|
qos_flow = smf_qos_flow_find_by_pcc_rule_id(sess, pcc_rule->id);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
if (!qos_flow) {
|
2021-11-14 12:07:56 +00:00
|
|
|
ogs_warn("No need to send 'Session Modification Request'");
|
|
|
|
ogs_warn(" - QosFlow[Id:%s] has already been removed.",
|
|
|
|
pcc_rule->id);
|
2021-01-01 02:07:08 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
pfcp_flags |= OGS_PFCP_MODIFY_REMOVE;
|
|
|
|
|
|
|
|
ogs_list_add(&sess->qos_flow_to_modify_list,
|
|
|
|
&qos_flow->to_modify_node);
|
2021-01-01 02:07:08 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
ogs_error("Invalid Type[%d]", pcc_rule->type);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
}
|
2022-05-15 14:35:41 +00:00
|
|
|
|
|
|
|
check = pfcp_flags & (OGS_PFCP_MODIFY_CREATE|OGS_PFCP_MODIFY_REMOVE);
|
|
|
|
if (check != 0 &&
|
|
|
|
check != OGS_PFCP_MODIFY_CREATE && check != OGS_PFCP_MODIFY_REMOVE) {
|
2022-05-15 14:40:51 +00:00
|
|
|
ogs_fatal("Invalid flags[%d]", (int)pfcp_flags);
|
2022-05-15 14:35:41 +00:00
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ogs_list_count(&sess->qos_flow_to_modify_list)) {
|
|
|
|
ogs_assert(OGS_OK ==
|
2022-05-18 01:29:58 +00:00
|
|
|
smf_5gc_pfcp_send_qos_flow_list_modification_request(
|
2022-05-15 14:35:41 +00:00
|
|
|
sess, NULL, pfcp_flags, 0));
|
|
|
|
}
|
2021-01-01 02:07:08 +00:00
|
|
|
}
|