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; ...@@ -86,50 +86,6 @@ extern itti_mw* itti_inst;
extern smf::smf_app* smf_app_inst; extern smf::smf_app* smf_app_inst;
extern smf::smf_config smf_cfg; 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 { void smf_pdu_session::get_pdu_session_id(uint32_t& psi) const {
psi = pdu_session_id; psi = pdu_session_id;
......
...@@ -133,6 +133,85 @@ bool edge::serves_network( ...@@ -133,6 +133,85 @@ bool edge::serves_network(
return serves_network(dnn, snssai, set, s); 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 pfcp_association::iface_type_from_string(const std::string& input) {
iface_type type_tmp; iface_type type_tmp;
...@@ -238,7 +317,7 @@ bool pfcp_association::find_n3_edge(std::vector<edge>& edges) { ...@@ -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 pfcp_association::find_n6_edge(std::vector<edge>& edges) {
bool success = find_interface_edge(iface_type::N6, edges); bool success = find_interface_edge(iface_type::N6, edges);
if (success) { if (success) {
for (auto e : edges) { for (auto& e : edges) {
e.uplink = true; e.uplink = true;
} }
} }
...@@ -1018,47 +1097,22 @@ void upf_graph::dfs_next_upf( ...@@ -1018,47 +1097,22 @@ void upf_graph::dfs_next_upf(
// copy QOS Flow for the whole graph // copy QOS Flow for the whole graph
// TODO currently only one flow is supported // TODO currently only one flow is supported
if (edge_it->qos_flows.empty()) { 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 // set the correct edges to return
if (edge_it->association) { if (edge_it->uplink) {
// 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); info_ul.push_back(*edge_it);
} else if (edge_it->type == N9) {
info_dl.push_back(*edge_it);
}
} else { } 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_upf_asynch = upf;
current_edges_dl_asynch = info_dl; current_edges_dl_asynch = info_dl;
current_edges_ul_asynch = info_ul; current_edges_ul_asynch = info_ul;
} }
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -1069,31 +1123,6 @@ void upf_graph::dfs_current_upf( ...@@ -1069,31 +1123,6 @@ void upf_graph::dfs_current_upf(
upf = current_upf_asynch; upf = current_upf_asynch;
info_dl = current_edges_dl_asynch; info_dl = current_edges_dl_asynch;
info_ul = current_edges_ul_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( ...@@ -1116,7 +1145,6 @@ void upf_graph::start_asynch_dfs_procedure(
for (auto& edge : it.second) { for (auto& edge : it.second) {
if ((uplink && edge.type == iface_type::N6) || if ((uplink && edge.type == iface_type::N6) ||
(!uplink && edge.type == iface_type::N3)) { (!uplink && edge.type == iface_type::N3)) {
edge.qos_flows.emplace_back(qos_flow_asynch);
stack_asynch.push(it.first); stack_asynch.push(it.first);
break; break;
} }
...@@ -1140,8 +1168,7 @@ edge upf_graph::get_access_edge() const { ...@@ -1140,8 +1168,7 @@ edge upf_graph::get_access_edge() const {
} }
void upf_graph::update_edge_info( void upf_graph::update_edge_info(
const std::shared_ptr<pfcp_association>& upf, const std::shared_ptr<pfcp_association>& upf, const edge& info) {
const std::string& nw_instance, const edge& info) {
std::unique_lock graph_lock(graph_mutex); std::unique_lock graph_lock(graph_mutex);
auto it = adjacency_list.find(upf); auto it = adjacency_list.find(upf);
if (it == adjacency_list.end()) { if (it == adjacency_list.end()) {
...@@ -1150,7 +1177,7 @@ void upf_graph::update_edge_info( ...@@ -1150,7 +1177,7 @@ void upf_graph::update_edge_info(
} }
for (auto& edge_it : it->second) { for (auto& edge_it : it->second) {
if (edge_it.nw_instance == nw_instance) { if (edge_it == info) {
edge_it = info; edge_it = info;
break; break;
} }
......
...@@ -251,6 +251,7 @@ class smf_qos_flow { ...@@ -251,6 +251,7 @@ class smf_qos_flow {
pfcp::fteid_t dl_fteid; // fteid of AN 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_ul; // Packet Detection Rule ID, UL
pfcp::pdr_id_t pdr_id_dl; // Packet Detection Rule ID, DL 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; 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_ul; // FAR ID, UL
std::pair<bool, pfcp::far_id_t> far_id_dl; // FAR ID, DL std::pair<bool, pfcp::far_id_t> far_id_dl; // FAR ID, DL
...@@ -272,7 +273,7 @@ struct edge { ...@@ -272,7 +273,7 @@ struct edge {
std::string nw_instance; std::string nw_instance;
iface_type type; iface_type type;
bool uplink = false; bool uplink = false;
std::vector<smf_qos_flow> qos_flows; std::vector<std::shared_ptr<smf_qos_flow>> qos_flows;
bool n4_sent = false; bool n4_sent = false;
std::shared_ptr<pfcp_association> association; std::shared_ptr<pfcp_association> association;
// we use parts of the upf_interface here // we use parts of the upf_interface here
...@@ -293,6 +294,12 @@ struct edge { ...@@ -293,6 +294,12 @@ struct edge {
const std::unordered_set<std::string>& dnais, const std::unordered_set<std::string>& dnais,
std::string& found_dnai) const; 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 { bool operator==(const edge& other) const {
return nw_instance == other.nw_instance && type == other.type && return nw_instance == other.nw_instance && type == other.type &&
uplink == other.uplink && association == other.association; uplink == other.uplink && association == other.association;
...@@ -539,12 +546,10 @@ class upf_graph { ...@@ -539,12 +546,10 @@ class upf_graph {
/** /**
* Update edge information in the graph * Update edge information in the graph
* @param upf UPF for which edge info should be updated * @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 * @param info info to update
*/ */
void update_edge_info( void update_edge_info(
const std::shared_ptr<pfcp_association>& upf, const std::shared_ptr<pfcp_association>& upf, const edge& info);
const std::string& nw_instance, const edge& info);
/** /**
* @brief: Debug-prints the current graph * @brief: Debug-prints the current graph
......
This diff is collapsed.
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "msg_pfcp.hpp" #include "msg_pfcp.hpp"
#include "smf_msg.hpp" #include "smf_msg.hpp"
#include "uint_generator.hpp" #include "uint_generator.hpp"
#include "smf_pfcp_association.hpp"
namespace smf { namespace smf {
...@@ -76,6 +77,33 @@ class smf_procedure { ...@@ -76,6 +77,33 @@ class smf_procedure {
class smf_qos_flow; class smf_qos_flow;
class smf_pdu_session; 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 { class n4_session_restore_procedure : public smf_procedure {
public: public:
...@@ -94,12 +122,11 @@ class n4_session_restore_procedure : public smf_procedure { ...@@ -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: public:
explicit session_create_sm_context_procedure( explicit session_create_sm_context_procedure(
std::shared_ptr<smf_pdu_session>& ps) std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(), : smf_session_procedure(ps),
sps(ps),
n4_triggered(), n4_triggered(),
n11_triggered_pending(), n11_triggered_pending(),
n11_trigger() {} n11_trigger() {}
...@@ -124,22 +151,20 @@ class session_create_sm_context_procedure : public smf_procedure { ...@@ -124,22 +151,20 @@ class session_create_sm_context_procedure : public smf_procedure {
*/ */
void handle_itti_msg( void handle_itti_msg(
itti_n4_session_establishment_response& resp, 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<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_request> n11_trigger;
std::shared_ptr<itti_n11_create_sm_context_response> n11_triggered_pending; 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: public:
explicit session_update_sm_context_procedure( explicit session_update_sm_context_procedure(
std::shared_ptr<smf_pdu_session>& ps) std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(), : smf_session_procedure(ps),
sps(ps),
n4_triggered(), n4_triggered(),
n11_triggered_pending(), n11_triggered_pending(),
n11_trigger(), n11_trigger(),
...@@ -165,10 +190,9 @@ class session_update_sm_context_procedure : public smf_procedure { ...@@ -165,10 +190,9 @@ class session_update_sm_context_procedure : public smf_procedure {
*/ */
void handle_itti_msg( void handle_itti_msg(
itti_n4_session_modification_response& resp, 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<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_request> n11_trigger;
std::shared_ptr<itti_n11_update_sm_context_response> n11_triggered_pending; 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 { ...@@ -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: public:
explicit session_release_sm_context_procedure( explicit session_release_sm_context_procedure(
std::shared_ptr<smf_pdu_session>& ps) std::shared_ptr<smf_pdu_session>& ps)
: smf_procedure(), : smf_session_procedure(ps),
sps(ps),
n4_triggered(), n4_triggered(),
n11_triggered_pending(), n11_triggered_pending(),
n11_trigger() {} n11_trigger() {}
...@@ -206,10 +229,9 @@ class session_release_sm_context_procedure : public smf_procedure { ...@@ -206,10 +229,9 @@ class session_release_sm_context_procedure : public smf_procedure {
*/ */
void handle_itti_msg( void handle_itti_msg(
itti_n4_session_deletion_response& resp, 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<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_request> n11_trigger;
std::shared_ptr<itti_n11_release_sm_context_response> n11_triggered_pending; 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