Commit eb7d7309 authored by Stefan Spettel's avatar Stefan Spettel

refact(smf): Created functions for PFCP IEs based on UPF graph edge infos

Signed-off-by: default avatarStefan Spettel <stefan.spettel@eurecom.fr>
parent a3c6d62b
......@@ -86,50 +86,6 @@ extern itti_mw* itti_inst;
extern smf::smf_app* smf_app_inst;
extern smf::smf_config smf_cfg;
//------------------------------------------------------------------------------
void smf_qos_flow::mark_as_released() {
released = true;
}
//------------------------------------------------------------------------------
std::string smf_qos_flow::toString() const {
std::string s = {};
s.append("QoS Flow:\n");
s.append("\t\tQFI:\t\t")
.append(std::to_string((uint8_t) qfi.qfi))
.append("\n");
s.append("\t\tUL FTEID:\t").append(ul_fteid.toString()).append("\n");
s.append("\t\tDL FTEID:\t").append(dl_fteid.toString()).append("\n");
s.append("\t\tPDR ID UL:\t")
.append(std::to_string(pdr_id_ul.rule_id))
.append("\n");
s.append("\t\tPDR ID DL:\t")
.append(std::to_string(pdr_id_dl.rule_id))
.append("\n");
s.append("\t\tPrecedence:\t")
.append(std::to_string(precedence.precedence))
.append("\n");
if (far_id_ul.first) {
s.append("\t\tFAR ID UL:\t")
.append(std::to_string(far_id_ul.second.far_id))
.append("\n");
}
if (far_id_dl.first) {
s.append("\t\tFAR ID DL:\t")
.append(std::to_string(far_id_dl.second.far_id))
.append("\n");
}
return s;
}
//------------------------------------------------------------------------------
void smf_qos_flow::deallocate_ressources() {
clear();
Logger::smf_app().info(
"Resources associated with this QoS Flow (%d) have been released",
(uint8_t) qfi.qfi);
}
//------------------------------------------------------------------------------
void smf_pdu_session::get_pdu_session_id(uint32_t& psi) const {
psi = pdu_session_id;
......
......@@ -133,6 +133,85 @@ bool edge::serves_network(
return serves_network(dnn, snssai, set, s);
}
std::shared_ptr<smf_qos_flow> edge::get_qos_flow(const pfcp::pdr_id_t& pdr_id) {
// it may happen that 2 qos flows have the same PDR ID e.g. in an
// UL CL scenario, but then they will also have the same FTEID
for (auto& flow_it : qos_flows) {
if (flow_it->pdr_id_ul == pdr_id || flow_it->pdr_id_dl == pdr_id) {
return flow_it;
}
}
return {};
}
std::shared_ptr<smf_qos_flow> edge::get_qos_flow(const pfcp::qfi_t& qfi) {
for (auto& flow_it : qos_flows) {
if (flow_it->qfi == qfi) {
return flow_it;
}
}
return {};
}
std::shared_ptr<smf_qos_flow> edge::get_qos_flow(const pfcp::far_id_t& far_id) {
for (auto& flow_it : qos_flows) {
if (flow_it->far_id_ul.second == far_id ||
flow_it->far_id_dl.second == far_id) {
return flow_it;
}
}
return {};
}
//------------------------------------------------------------------------------
void smf_qos_flow::mark_as_released() {
released = true;
}
//------------------------------------------------------------------------------
std::string smf_qos_flow::toString() const {
std::string s = {};
s.append("QoS Flow:\n");
s.append("\t\tQFI:\t\t")
.append(std::to_string((uint8_t) qfi.qfi))
.append("\n");
s.append("\t\tUL FTEID:\t").append(ul_fteid.toString()).append("\n");
s.append("\t\tDL FTEID:\t").append(dl_fteid.toString()).append("\n");
s.append("\t\tPDR ID UL:\t")
.append(std::to_string(pdr_id_ul.rule_id))
.append("\n");
s.append("\t\tPDR ID DL:\t")
.append(std::to_string(pdr_id_dl.rule_id))
.append("\n");
s.append("\t\tPrecedence:\t")
.append(std::to_string(precedence.precedence))
.append("\n");
if (far_id_ul.first) {
s.append("\t\tFAR ID UL:\t")
.append(std::to_string(far_id_ul.second.far_id))
.append("\n");
}
if (far_id_dl.first) {
s.append("\t\tFAR ID DL:\t")
.append(std::to_string(far_id_dl.second.far_id))
.append("\n");
}
if (urr_id.urr_id != 0) {
s.append("\t\tURR ID:\t")
.append(std::to_string(urr_id.urr_id))
.append("\n");
}
return s;
}
//------------------------------------------------------------------------------
void smf_qos_flow::deallocate_ressources() {
clear();
Logger::smf_app().info(
"Resources associated with this QoS Flow (%d) have been released",
(uint8_t) qfi.qfi);
}
//------------------------------------------------------------------------------
iface_type pfcp_association::iface_type_from_string(const std::string& input) {
iface_type type_tmp;
......@@ -238,7 +317,7 @@ bool pfcp_association::find_n3_edge(std::vector<edge>& edges) {
bool pfcp_association::find_n6_edge(std::vector<edge>& edges) {
bool success = find_interface_edge(iface_type::N6, edges);
if (success) {
for (auto e : edges) {
for (auto& e : edges) {
e.uplink = true;
}
}
......@@ -1018,46 +1097,21 @@ void upf_graph::dfs_next_upf(
// copy QOS Flow for the whole graph
// TODO currently only one flow is supported
if (edge_it->qos_flows.empty()) {
edge_it->qos_flows.emplace_back(qos_flow_asynch);
std::shared_ptr<smf_qos_flow> flow =
std::make_shared<smf_qos_flow>(qos_flow_asynch);
edge_it->qos_flows.emplace_back(flow);
}
// pointer is not null -> N9 interface
if (edge_it->association) {
// we add the TEID here for the edge in the other direction
// direct access is safe as we know the edge exists
auto edge_node = adjacency_list[edge_it->association];
for (auto edge_edge : edge_node) {
if (edge_edge.qos_flows.empty()) {
edge_edge.qos_flows.emplace_back(qos_flow_asynch);
}
if (edge_edge.association &&
edge_edge.association == node_it->first) {
if (edge_edge.type == iface_type::N9 && edge_edge.uplink) {
// downlink direction
edge_it->qos_flows[0].dl_fteid = edge_edge.qos_flows[0].dl_fteid;
} else if (edge_edge.type == iface_type::N9) {
edge_it->qos_flows[0].ul_fteid = edge_edge.qos_flows[0].ul_fteid;
}
}
}
if (edge_it->type == N9 && edge_it->uplink) {
info_ul.push_back(*edge_it);
} else if (edge_it->type == N9) {
info_dl.push_back(*edge_it);
}
// set the correct edges to return
if (edge_it->uplink) {
info_ul.push_back(*edge_it);
} else {
// N3 or N6 interface
if (edge_it->type == iface_type::N6) {
info_ul.push_back(*edge_it);
} else if (edge_it->type == iface_type::N3) {
info_dl.push_back(*edge_it);
}
info_dl.push_back(*edge_it);
}
current_upf_asynch = upf;
current_edges_dl_asynch = info_dl;
current_edges_ul_asynch = info_ul;
}
current_upf_asynch = upf;
current_edges_dl_asynch = info_dl;
current_edges_ul_asynch = info_ul;
}
}
......@@ -1069,31 +1123,6 @@ void upf_graph::dfs_current_upf(
upf = current_upf_asynch;
info_dl = current_edges_dl_asynch;
info_ul = current_edges_ul_asynch;
auto it = adjacency_list.find(upf);
if (it != adjacency_list.end()) {
// update edge info
info_dl.clear();
info_ul.clear();
for (const auto& edge_it : it->second) {
for (const auto& current_edge : current_edges_dl_asynch) {
if (edge_it.nw_instance == current_edge.nw_instance) {
info_dl.push_back(edge_it);
}
}
for (const auto& current_edge : current_edges_ul_asynch) {
if (edge_it.nw_instance == current_edge.nw_instance) {
info_ul.push_back(edge_it);
}
}
}
} else {
Logger::smf_app().error(
"We want to get the current UPF in DFS, but it is not in graph "
"(anymore");
}
}
//------------------------------------------------------------------------------
......@@ -1116,7 +1145,6 @@ void upf_graph::start_asynch_dfs_procedure(
for (auto& edge : it.second) {
if ((uplink && edge.type == iface_type::N6) ||
(!uplink && edge.type == iface_type::N3)) {
edge.qos_flows.emplace_back(qos_flow_asynch);
stack_asynch.push(it.first);
break;
}
......@@ -1140,8 +1168,7 @@ edge upf_graph::get_access_edge() const {
}
void upf_graph::update_edge_info(
const std::shared_ptr<pfcp_association>& upf,
const std::string& nw_instance, const edge& info) {
const std::shared_ptr<pfcp_association>& upf, const edge& info) {
std::unique_lock graph_lock(graph_mutex);
auto it = adjacency_list.find(upf);
if (it == adjacency_list.end()) {
......@@ -1150,7 +1177,7 @@ void upf_graph::update_edge_info(
}
for (auto& edge_it : it->second) {
if (edge_it.nw_instance == nw_instance) {
if (edge_it == info) {
edge_it = info;
break;
}
......
......@@ -251,6 +251,7 @@ class smf_qos_flow {
pfcp::fteid_t dl_fteid; // fteid of AN
pfcp::pdr_id_t pdr_id_ul; // Packet Detection Rule ID, UL
pfcp::pdr_id_t pdr_id_dl; // Packet Detection Rule ID, DL
pfcp::urr_id_t urr_id; // Usage reporting Rule, use same for UL and DL
pfcp::precedence_t precedence;
std::pair<bool, pfcp::far_id_t> far_id_ul; // FAR ID, UL
std::pair<bool, pfcp::far_id_t> far_id_dl; // FAR ID, DL
......@@ -272,7 +273,7 @@ struct edge {
std::string nw_instance;
iface_type type;
bool uplink = false;
std::vector<smf_qos_flow> qos_flows;
std::vector<std::shared_ptr<smf_qos_flow>> qos_flows;
bool n4_sent = false;
std::shared_ptr<pfcp_association> association;
// we use parts of the upf_interface here
......@@ -293,6 +294,12 @@ struct edge {
const std::unordered_set<std::string>& dnais,
std::string& found_dnai) const;
std::shared_ptr<smf_qos_flow> get_qos_flow(const pfcp::pdr_id_t& pdr_id);
std::shared_ptr<smf_qos_flow> get_qos_flow(const pfcp::qfi_t& qfi);
std::shared_ptr<smf_qos_flow> get_qos_flow(const pfcp::far_id_t& far_id);
bool operator==(const edge& other) const {
return nw_instance == other.nw_instance && type == other.type &&
uplink == other.uplink && association == other.association;
......@@ -539,12 +546,10 @@ class upf_graph {
/**
* Update edge information in the graph
* @param upf UPF for which edge info should be updated
* @param nw_instance NW instance of the edge, must be unique for this UPF
* @param info info to update
*/
void update_edge_info(
const std::shared_ptr<pfcp_association>& upf,
const std::string& nw_instance, const edge& info);
const std::shared_ptr<pfcp_association>& upf, const edge& info);
/**
* @brief: Debug-prints the current graph
......
This diff is collapsed.
......@@ -41,6 +41,7 @@
#include "msg_pfcp.hpp"
#include "smf_msg.hpp"
#include "uint_generator.hpp"
#include "smf_pfcp_association.hpp"
namespace smf {
......@@ -76,6 +77,33 @@ class smf_procedure {
class smf_qos_flow;
class smf_pdu_session;
class smf_session_procedure : public smf_procedure {
public:
explicit smf_session_procedure(std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(), sps(ps) {}
std::shared_ptr<smf_pdu_session> sps;
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_urr pfcp_create_urr(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);
protected:
void synch_ul_dl_edges(
const vector<edge>& dl_edges, const vector<edge>& ul_edges,
const pfcp::qfi_t& qfi);
};
//------------------------------------------------------------------------------
class n4_session_restore_procedure : public smf_procedure {
public:
......@@ -94,12 +122,11 @@ class n4_session_restore_procedure : public smf_procedure {
};
//------------------------------------------------------------------------------
class session_create_sm_context_procedure : public smf_procedure {
class session_create_sm_context_procedure : public smf_session_procedure {
public:
explicit session_create_sm_context_procedure(
std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(),
sps(ps),
: smf_session_procedure(ps),
n4_triggered(),
n11_triggered_pending(),
n11_trigger() {}
......@@ -124,22 +151,20 @@ class session_create_sm_context_procedure : public smf_procedure {
*/
void handle_itti_msg(
itti_n4_session_establishment_response& resp,
std::shared_ptr<smf::smf_context> sc);
std::shared_ptr<smf::smf_context> sc) override;
std::shared_ptr<itti_n4_session_establishment_request> n4_triggered;
std::shared_ptr<smf_pdu_session> sps;
std::shared_ptr<itti_n11_create_sm_context_request> n11_trigger;
std::shared_ptr<itti_n11_create_sm_context_response> n11_triggered_pending;
};
//------------------------------------------------------------------------------
class session_update_sm_context_procedure : public smf_procedure {
class session_update_sm_context_procedure : public smf_session_procedure {
public:
explicit session_update_sm_context_procedure(
std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(),
sps(ps),
: smf_session_procedure(ps),
n4_triggered(),
n11_triggered_pending(),
n11_trigger(),
......@@ -165,10 +190,9 @@ class session_update_sm_context_procedure : public smf_procedure {
*/
void handle_itti_msg(
itti_n4_session_modification_response& resp,
std::shared_ptr<smf::smf_context> sc);
std::shared_ptr<smf::smf_context> sc) override;
std::shared_ptr<itti_n4_session_modification_request> n4_triggered;
std::shared_ptr<smf_pdu_session> sps;
std::shared_ptr<itti_n11_update_sm_context_request> n11_trigger;
std::shared_ptr<itti_n11_update_sm_context_response> n11_triggered_pending;
......@@ -176,12 +200,11 @@ class session_update_sm_context_procedure : public smf_procedure {
};
//------------------------------------------------------------------------------
class session_release_sm_context_procedure : public smf_procedure {
class session_release_sm_context_procedure : public smf_session_procedure {
public:
explicit session_release_sm_context_procedure(
std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(),
sps(ps),
: smf_session_procedure(ps),
n4_triggered(),
n11_triggered_pending(),
n11_trigger() {}
......@@ -206,10 +229,9 @@ class session_release_sm_context_procedure : public smf_procedure {
*/
void handle_itti_msg(
itti_n4_session_deletion_response& resp,
std::shared_ptr<smf::smf_context> sc);
std::shared_ptr<smf::smf_context> sc) override;
std::shared_ptr<itti_n4_session_deletion_request> n4_triggered;
std::shared_ptr<smf_pdu_session> sps;
std::shared_ptr<itti_n11_release_sm_context_request> n11_trigger;
std::shared_ptr<itti_n11_release_sm_context_response> n11_triggered_pending;
......
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