Commit df59e39c authored by kharade's avatar kharade

Handle create pdr for DL in session establishment

Signed-off-by: default avatarkharade <rohan.kharade@openairinterface.org>
parent 5c7fbfd7
......@@ -125,6 +125,10 @@ SMF =
HTTP_VERSION = {{ env["HTTP_VERSION"] if "HTTP_VERSION" in env.keys() else '1' }};
# Set yes if UE USAGE REPORTING is to be done at UPF
ENABLE_USAGE_REPORTING = "{{ env["ENABLE_USAGE_REPORTING"] if "ENABLE_USAGE_REPORTING" in env.keys() else 'no' }}"
# Set yes if Downlink PDR is to be included in PFCP session establishment message
ENABLE_DL_PDR_IN_PFCP_SESS_ESTAB = "{{ env["ENABLE_DL_PDR_IN_PFCP_SESS_ESTAB"] if "ENABLE_DL_PDR_IN_PFCP_SESS_ESTAB" in env.keys() else 'no' }}"
# Set N3_LOCAL_IPV4_ADDRESS for SD-Fabric UPF
N3_LOCAL_IPV4_ADDRESS = "{{ env["N3_LOCAL_IPV4_ADDRESS"] if "N3_LOCAL_IPV4_ADDRESS" in env.keys() else '0.0.0.0' }}";
}
AMF :
......
......@@ -9373,6 +9373,11 @@ class pfcp_update_pdr_ie : public pfcp_grouped_ie {
std::shared_ptr<pfcp_pdi_ie> sie(new pfcp_pdi_ie(b.pdi.second));
add_ie(sie);
}
if (b.precedence.first) {
std::shared_ptr<pfcp_precedence_ie> sie(
new pfcp_precedence_ie(b.precedence.second));
add_ie(sie);
}
}
//--------
pfcp_update_pdr_ie() : pfcp_grouped_ie(PFCP_IE_UPDATE_PDR) {}
......
......@@ -573,6 +573,17 @@ int smf_config::load(const string& config_file) {
} else {
enable_ur = false;
}
support_features.lookupValue(
SMF_CONFIG_STRING_SUPPORT_FEATURES_enable_dl_pdr_in_pfcp_sess_estab,
opt);
if (boost::iequals(opt, "yes")) {
enable_dl_pdr_in_pfcp_sess_estab = true;
} else {
enable_dl_pdr_in_pfcp_sess_estab = false;
}
support_features.lookupValue(
SMF_CONFIG_STRING_N3_LOCAL_IPV4_ADDRESS, local_n3_addr);
} catch (const SettingNotFoundException& nfex) {
Logger::smf_app().error(
......@@ -1068,6 +1079,11 @@ void smf_config::display() {
Logger::smf_app().info(
" Use FQDN ...........................: %s",
use_fqdn_dns ? "Yes" : "No");
Logger::smf_app().info(
" ENABLE DL PDR IN PFCP SESSION ESTAB.: %s",
enable_dl_pdr_in_pfcp_sess_estab ? "Yes" : "No");
Logger::smf_app().info(
" UPF N3 LOCAL ADDRESS ...............: %s", local_n3_addr.c_str());
Logger::smf_app().info("- DNN configurations:");
......
......@@ -160,6 +160,9 @@
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_SBI_HTTP_VERSION "HTTP_VERSION"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_ENABLE_USAGE_REPORTING \
"ENABLE_USAGE_REPORTING"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_enable_dl_pdr_in_pfcp_sess_estab \
"ENABLE_DL_PDR_IN_PFCP_SESS_ESTAB"
#define SMF_CONFIG_STRING_N3_LOCAL_IPV4_ADDRESS "N3_LOCAL_IPV4_ADDRESS"
#define SMF_MAX_ALLOCATED_PDN_ADDRESSES 1024
......@@ -245,6 +248,8 @@ class smf_config {
bool use_fqdn_dns;
unsigned int http_version;
bool enable_ur;
bool enable_dl_pdr_in_pfcp_sess_estab;
std::string local_n3_addr;
std::vector<pfcp::node_id_t> upfs;
......@@ -332,12 +337,14 @@ class smf_config {
sbi_api_version = "v1";
http_version = 1;
use_local_subscription_info = false;
use_local_pcc_rules = false;
register_nrf = false;
discover_upf = false;
discover_pcf = false;
use_fqdn_dns = false;
use_local_subscription_info = false;
use_local_pcc_rules = false;
register_nrf = false;
discover_upf = false;
discover_pcf = false;
use_fqdn_dns = false;
enable_ur = false;
enable_dl_pdr_in_pfcp_sess_estab = false;
};
~smf_config();
void lock() { m_rw_lock.lock(); };
......
......@@ -316,6 +316,11 @@ void smf_pdu_session::set_seid(const uint64_t& s) {
seid = s;
}
//------------------------------------------------------------------------------
void smf_pdu_session::generate_teid(pfcp::fteid_t& local_fteid) {
local_fteid.teid = teid_generator.get_uid();
}
//------------------------------------------------------------------------------
// TODO check if urr_id should be unique in the UPF or in the context of a pdn
// connection
......
......@@ -286,6 +286,12 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
*/
void set_seid(const uint64_t& seid);
/*
* Generate a value for TEID
* @return uint32_t
*/
void generate_teid(pfcp::fteid_t& local_fteid);
/*
* Generate a PDR ID
* @param [pfcp::pdr_id_t &]: pdr_id: PDR ID generated
......@@ -539,6 +545,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
util::uint_generator<uint32_t> far_id_generator;
util::uint_generator<uint32_t> urr_id_generator;
util::uint_generator<uint32_t> teid_generator;
// Shared lock
mutable std::shared_mutex m_pdu_session_mutex;
......
......@@ -45,6 +45,7 @@
#include "smf_pfcp_association.hpp"
#include "ProblemDetails.h"
#include "3gpp_24.501.h"
#include "common_defs.h"
using namespace pfcp;
using namespace smf;
......@@ -78,10 +79,22 @@ pfcp::ue_ip_address_t smf_session_procedure::pfcp_ue_ip_address(
//------------------------------------------------------------------------------
pfcp::fteid_t smf_session_procedure::pfcp_prepare_fteid(
const pfcp::fteid_t& fteid) {
pfcp::fteid_t& fteid, const bool& ftup_supported) {
pfcp::fteid_t local_fteid;
if (fteid.is_zero()) {
if (!ftup_supported) {
Logger::smf_app().info(
"Generating N3-UL TEID since current UPF does not support TEID "
"Creation");
local_fteid.ch = 0;
local_fteid.v4 = 1;
local_fteid.chid = 0;
local_fteid.ipv4_address = conv::fromString(smf_cfg.local_n3_addr);
sps->generate_teid(local_fteid);
fteid = local_fteid;
Logger::smf_app().info(
" UL F-TEID 0x%" PRIx32 " allocated for N3 IPv4 Addr : %s",
local_fteid.teid, conv::toString(local_fteid.ipv4_address).c_str());
} else if (fteid.is_zero()) {
local_fteid.ch = 1;
local_fteid.v4 = 1;
local_fteid.chid = 1;
......@@ -213,9 +226,31 @@ void smf_session_procedure::synch_ul_dl_edges(
}
}
//------------------------------------------------------------------------------
pfcp::create_far smf_session_procedure::pfcp_create_far_dl(
edge& edge, const pfcp::qfi_t& qfi) {
pfcp::create_far create_far = {};
pfcp::apply_action_t apply_action = {};
apply_action.drop = 1; // forward the packets
auto flow = edge.get_qos_flow(qfi);
if (!flow) {
Logger::smf_app().error("Could not find QOS flow for this QFI.");
return create_far;
}
sps->generate_far_id((flow->far_id_dl.second));
flow->far_id_dl.first = true;
create_far.set(flow->far_id_dl.second);
create_far.set(apply_action);
return create_far;
}
//------------------------------------------------------------------------------
pfcp::create_pdr smf_session_procedure::pfcp_create_pdr(
edge& edge, const qfi_t& qfi) {
edge& edge, const qfi_t& qfi, pfcp::up_function_features_s up_features) {
// When we have a PDR and edge is uplink we know we are in a downlink
// procedure, e.g. PDR from N6 to N3 -> N6 is uplink edge, so downlink
// procedure
......@@ -279,10 +314,10 @@ pfcp::create_pdr smf_session_procedure::pfcp_create_pdr(
if (edge.type != iface_type::N6) {
// in UPLINK always choose ID
if (edge.uplink) {
local_fteid = pfcp_prepare_fteid(flow->dl_fteid);
local_fteid = pfcp_prepare_fteid(flow->dl_fteid, up_features.ftup);
local_fteid.chid = 0;
} else {
local_fteid = pfcp_prepare_fteid(flow->ul_fteid);
local_fteid = pfcp_prepare_fteid(flow->ul_fteid, up_features.ftup);
}
pdi.set(local_fteid);
}
......@@ -335,7 +370,52 @@ pfcp::create_pdr smf_session_procedure::pfcp_create_pdr(
return create_pdr;
}
//------------------------------------------------------------------------------
pfcp::create_pdr smf_session_procedure::pfcp_create_pdr_dl(
edge& edge, const qfi_t& qfi) {
//-------------------
// IE create_pdr (section 5.8.2.11.3@TS 23.501)
//-------------------
pfcp::create_pdr create_pdr = {};
pfcp::precedence_t precedence = {};
pfcp::pdi pdi = {}; // packet detection information
pfcp::outer_header_removal_t outer_header_removal = {};
// pdi IEs
pfcp::source_interface_t source_interface = {};
pfcp::sdf_filter_t sdf_filter = {};
pfcp::application_id_t application_id = {};
pfcp::_3gpp_interface_type_t source_interface_type = {};
// pfcp::pdr_id_t pdr_id;
pfcp::far_id_t far_id;
auto flow = edge.get_qos_flow(qfi);
if (!flow) {
Logger::smf_app().error("Could not find QOS flow for this QFI.");
return create_pdr;
}
far_id = flow->far_id_dl.second;
sps->generate_pdr_id(flow->pdr_id_dl);
source_interface.interface_value = pfcp::INTERFACE_VALUE_CORE;
pdi.set(source_interface);
pfcp::ue_ip_address_t ue_ip_addr = pfcp_ue_ip_address(edge);
ue_ip_addr.sd = 1;
pdi.set(ue_ip_addr);
source_interface_type.interface_type_value = pfcp::_3GPP_INTERFACE_TYPE_N3;
pdi.set(source_interface_type);
precedence.precedence = 0;
create_pdr.set(flow->pdr_id_dl);
create_pdr.set(precedence);
create_pdr.set(pdi);
create_pdr.set(far_id);
return create_pdr;
}
//------------------------------------------------------------------------------
pfcp::create_urr smf_session_procedure::pfcp_create_urr(
edge& edge, const qfi_t& qfi) {
......@@ -529,14 +609,27 @@ session_create_sm_context_procedure::send_n4_session_establishment_request() {
//-------------------
// IE CREATE_PDR
//-------------------
pfcp::create_pdr create_pdr = pfcp_create_pdr(dl_edge, current_flow.qfi);
pfcp::create_pdr create_pdr = pfcp_create_pdr(
dl_edge, current_flow.qfi, current_upf->function_features.second);
synch_ul_dl_edges(dl_edges, ul_edges, current_flow.qfi);
//-------------------
// ADD IEs to message
//-------------------
n4_triggered->pfcp_ies.set(create_pdr);
n4_triggered->pfcp_ies.set(create_far);
if (smf_cfg.enable_dl_pdr_in_pfcp_sess_estab) {
pfcp::create_far create_far_dl =
pfcp_create_far_dl(dl_edge, current_flow.qfi);
pfcp::create_pdr create_pdr_dl =
pfcp_create_pdr_dl(dl_edge, current_flow.qfi);
n4_triggered->pfcp_ies.set(create_pdr_dl);
n4_triggered->pfcp_ies.set(create_far_dl);
}
// Handle PDR and FAR for downlink if thid feature is enabled
if (smf_cfg.enable_dl_pdr_in_pfcp_sess_estab) {
Logger::smf_app().info("Adding DL PDR and FAR start");
}
}
// TODO: verify whether N4 SessionID should be included in PDR and FAR
......@@ -687,6 +780,18 @@ smf_procedure_code session_create_sm_context_procedure::handle_itti_msg(
}
std::shared_ptr<smf_qos_flow> default_qos_flow = {};
if (smf_cfg.enable_dl_pdr_in_pfcp_sess_estab &&
resp.pfcp_ies.created_pdrs.empty()) {
pfcp::pdr_id_t pdr_id_tmp;
// we use qos flow for 1st PDR for the moment
// TODO: remove this hardcoding of qos flow
pdr_id_tmp.rule_id = 1;
auto flow = dl_edges[0].get_qos_flow(pdr_id_tmp);
if (flow) {
default_qos_flow = flow;
}
}
for (const auto& it : resp.pfcp_ies.created_pdrs) {
pfcp::pdr_id_t pdr_id = {};
pfcp::far_id_t far_id = {};
......@@ -702,7 +807,8 @@ smf_procedure_code session_create_sm_context_procedure::handle_itti_msg(
default_qos_flow = flow;
}
} else {
// This may happen in UL CL, when we have 2 PDR IDs but only one DL edge
// This may happen in UL CL, when we have 2 PDR IDs but only one DL
// edge
Logger::smf_app().debug(
"Could not get QoS Flow for created_pdr %d", pdr_id.rule_id);
}
......@@ -827,7 +933,8 @@ session_update_sm_context_procedure::send_n4_session_modification_request() {
ul_flow->far_id_dl = create_far.far_id;
pfcp::create_pdr create_pdr = pfcp_create_pdr(ul_edge, current_flow.qfi);
pfcp::create_pdr create_pdr = pfcp_create_pdr(
ul_edge, current_flow.qfi, current_upf->function_features.second);
// Add IEs to message
n4_triggered->pfcp_ies.set(create_far);
......@@ -1047,7 +1154,8 @@ smf_procedure_code session_update_sm_context_procedure::run(
//-------------------
// for each UL edge we need a PDR
for (auto& ul_edge : ul_edges) {
pfcp::create_pdr create_pdr = pfcp_create_pdr(ul_edge, flow->qfi);
pfcp::create_pdr create_pdr = pfcp_create_pdr(
ul_edge, flow->qfi, current_upf->function_features.second);
n4_triggered->pfcp_ies.set(create_pdr);
synch_ul_dl_edges(dl_edges, ul_edges, flow->qfi);
}
......@@ -1089,9 +1197,9 @@ smf_procedure_code session_update_sm_context_procedure::run(
if (sps->ipv4) {
ue_ip_address.v4 = 1;
// Bit 3 – S/D: TS 29.244 R16, 8.2.62 In the PDI IE, if this bit is
// set to "0", this indicates a Source IP address; if this bit is
// set to "1", this indicates a Destination IP address.
// Bit 3 – S/D: TS 29.244 R16, 8.2.62 In the PDI IE, if this bit
// is set to "0", this indicates a Source IP address; if this bit
// is set to "1", this indicates a Destination IP address.
ue_ip_address.sd = 1;
ue_ip_address.ipv4_address.s_addr = sps->ipv4_address.s_addr;
}
......@@ -1191,11 +1299,11 @@ smf_procedure_code session_update_sm_context_procedure::handle_itti_msg(
if (cause.cause_value != CAUSE_VALUE_REQUEST_ACCEPTED) {
// TODO: Nsmf_PDUSession_SMContextStatusNotify
/* If the PDU Session establishment is not successful, the SMF informs the
AMF by invoking Nsmf_PDUSession_SMContextStatusNotify (Release). The SMF
also releases any N4 session(s) created, any PDU Session address if
allocated (e.g. IP address) and releases the association with PCF, if any.
see step 18, section 4.3.2.2.1@3GPP TS 23.502)
/* If the PDU Session establishment is not successful, the SMF informs
the AMF by invoking Nsmf_PDUSession_SMContextStatusNotify (Release). The
SMF also releases any N4 session(s) created, any PDU Session address if
allocated (e.g. IP address) and releases the association with PCF, if
any. see step 18, section 4.3.2.2.1@3GPP TS 23.502)
*/
// TODO: should we return here with smf_procedure_code::ERROR;
} else {
......@@ -1203,7 +1311,8 @@ smf_procedure_code session_update_sm_context_procedure::handle_itti_msg(
static_cast<uint8_t>(cause_value_5gsm_e::CAUSE_255_REQUEST_ACCEPTED));
}
// list of accepted QFI(s) and AN Tunnel Info corresponding to the PDU Session
// list of accepted QFI(s) and AN Tunnel Info corresponding to the PDU
// Session
std::vector<pfcp::qfi_t> list_of_qfis_to_be_modified = {};
n11_trigger->req.get_qfis(list_of_qfis_to_be_modified);
......@@ -1214,7 +1323,8 @@ smf_procedure_code session_update_sm_context_procedure::handle_itti_msg(
if (get_current_upf(dl_edges, ul_edges, current_upf) ==
smf_procedure_code::ERROR) {
Logger::smf_app().error("SMF DL procedure: Could not get current UPF");
// TODO is this enough as an error message? We have cause 31 but not values
// TODO is this enough as an error message? We have cause 31 but not
// values
return smf_procedure_code::ERROR;
}
......@@ -1468,7 +1578,8 @@ smf_procedure_code session_release_sm_context_procedure::handle_itti_msg(
itti_n4_session_deletion_response& resp,
std::shared_ptr<smf::smf_context> sc) {
Logger::smf_app().info(
"Handle itti_n4_session_deletion_response (Release SM Context Request): "
"Handle itti_n4_session_deletion_response (Release SM Context "
"Request): "
"pdu-session-id %d",
n11_trigger.get()->req.get_pdu_session_id());
......@@ -1481,8 +1592,8 @@ smf_procedure_code session_release_sm_context_procedure::handle_itti_msg(
bool continue_n4 = false;
if (get_next_upf(dl_edges, ul_edges, current_upf) ==
smf_procedure_code::CONTINUE) {
// If we have to continue, we ignore the PFCP error code, because we should
// at least remove other UPF sessions
// If we have to continue, we ignore the PFCP error code, because we
// should at least remove other UPF sessions
return send_n4_session_deletion_request();
continue_n4 = false;
}
......@@ -1505,7 +1616,7 @@ smf_procedure_code session_release_sm_context_procedure::handle_itti_msg(
Subscription data changes notification with the UDM by means of the
Nudm_SDM_Unsubscribe service operation. The SMF invokes the
Nudm_UECM_Deregistration service operation so that the UDM removes the
association it had stored between the SMF identity and the associated DNN and
PDU Session Id
association it had stored between the SMF identity and the associated DNN
and PDU Session Id
*/
}
......@@ -94,17 +94,24 @@ class smf_session_procedure : public smf_procedure {
pfcp::create_far pfcp_create_far(edge& edge, const pfcp::qfi_t& qfi);
pfcp::create_pdr pfcp_create_pdr(edge& edge, const pfcp::qfi_t& qfi);
pfcp::create_pdr pfcp_create_pdr(
edge& edge, const pfcp::qfi_t& qfi,
pfcp::up_function_features_s up_features);
pfcp::create_urr pfcp_create_urr(edge& edge, const pfcp::qfi_t& qfi);
pfcp::create_pdr pfcp_create_pdr_dl(edge& edge, const pfcp::qfi_t& qfi);
pfcp::create_far pfcp_create_far_dl(edge& edge, const pfcp::qfi_t& qfi);
// TODO eventuell if used more than once
private:
// pfcp::destination_interface_value_e get_interface_value(const edge& edge);
pfcp::ue_ip_address_t pfcp_ue_ip_address(const edge& edge);
static pfcp::fteid_t pfcp_prepare_fteid(const pfcp::fteid_t& fteid);
pfcp::fteid_t pfcp_prepare_fteid(
pfcp::fteid_t& fteid, const bool& ftup_supported);
protected:
void synch_ul_dl_edges(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment