Commit 062d0390 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge branch 'fix-pdu-session-modification' into 'develop'

fix: fix pdu session modification crashing UPF

See merge request oai/cn5g/oai-cn5g-upf!26
parents 90a95369 4b0e1059
This diff is collapsed.
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <pfcp_session.hpp> #include <pfcp_session.hpp>
#include <unordered_map> #include <unordered_map>
#include "itti_msg_n4.hpp"
class BPFMap; class BPFMap;
class ForwardingActionRules; class ForwardingActionRules;
class PacketDetectionRules; class PacketDetectionRules;
...@@ -35,9 +37,11 @@ class SessionBpf; ...@@ -35,9 +37,11 @@ class SessionBpf;
* maps. It communicate with BPF maps in order to update its PDRs and FARs. This * maps. It communicate with BPF maps in order to update its PDRs and FARs. This
* class does not validate the input. * class does not validate the input.
*/ */
class SessionManager { class SessionManager {
public: public:
// Set of PDRs. // Set of PDRs.
using pdrs_t = std::vector<std::shared_ptr<PacketDetectionRules>>; using pdrs_t = std::vector<std::shared_ptr<PacketDetectionRules>>;
/*****************************************************************************************************************/ /*****************************************************************************************************************/
...@@ -78,7 +82,11 @@ class SessionManager { ...@@ -78,7 +82,11 @@ class SessionManager {
* @param pSession The PFCP session which contains the context that will be * @param pSession The PFCP session which contains the context that will be
* deployed. * deployed.
*/ */
void createBPFSession(std::shared_ptr<pfcp::pfcp_session> pSession); void createBPFSession(
std::shared_ptr<pfcp::pfcp_session> pSession,
itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req);
/*****************************************************************************************************************/ /*****************************************************************************************************************/
/** /**
...@@ -86,7 +94,24 @@ class SessionManager { ...@@ -86,7 +94,24 @@ class SessionManager {
* *
* @param pSession The session object to be updated. * @param pSession The session object to be updated.
*/ */
void updateBPFSession(std::shared_ptr<pfcp::pfcp_session> pSession); void updateBPFSession(
std::shared_ptr<pfcp::pfcp_session> pSession,
itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req);
/*****************************************************************************************************************/
/**
* @brief Remove BPF pipeline.
*
* @param seid The PFCP session which contains the context that will be
* removed.
*/
void removeBPFSession(
std::shared_ptr<pfcp::pfcp_session> pSession,
itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req);
/*****************************************************************************************************************/ /*****************************************************************************************************************/
void createBPFSessionUL( void createBPFSessionUL(
...@@ -130,15 +155,6 @@ class SessionManager { ...@@ -130,15 +155,6 @@ class SessionManager {
uint32_t seid, uint32_t seid,
const std::vector<std::shared_ptr<pfcp::pfcp_session>>& sessions); const std::vector<std::shared_ptr<pfcp::pfcp_session>>& sessions);
/*****************************************************************************************************************/
/**
* @brief Remove BPF pipeline.
*
* @param seid The PFCP session which contains the context that will be
* removed.
*/
void removeBPFSession(uint64_t seid);
/*****************************************************************************************************************/ /*****************************************************************************************************************/
static bool comparePDR( static bool comparePDR(
const std::shared_ptr<pfcp::pfcp_pdr>& first, const std::shared_ptr<pfcp::pfcp_pdr>& first,
......
...@@ -27,6 +27,8 @@ include_directories(${SRC_TOP_DIR}/oai_upf) ...@@ -27,6 +27,8 @@ include_directories(${SRC_TOP_DIR}/oai_upf)
include_directories(${SRC_TOP_DIR}/pfcp) include_directories(${SRC_TOP_DIR}/pfcp)
include_directories(${SRC_TOP_DIR}/upf_app) include_directories(${SRC_TOP_DIR}/upf_app)
include_directories(${SRC_TOP_DIR}/upf_app/app) include_directories(${SRC_TOP_DIR}/upf_app/app)
include_directories(${SRC_TOP_DIR}/upf_app/bpf)
include_directories(${SRC_TOP_DIR}/upf_app/include)
include_directories(${SRC_TOP_DIR}/upf_app/simpleswitch) include_directories(${SRC_TOP_DIR}/upf_app/simpleswitch)
include_directories(${SRC_TOP_DIR}/udp) include_directories(${SRC_TOP_DIR}/udp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger) include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
......
...@@ -49,8 +49,6 @@ ...@@ -49,8 +49,6 @@
#include <stdexcept> #include <stdexcept>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <SessionManager.h>
static std::shared_ptr<SessionManager> spSessionManager; static std::shared_ptr<SessionManager> spSessionManager;
using namespace pfcp; using namespace pfcp;
...@@ -620,6 +618,41 @@ bool pfcp_switch::create_packet_in_access( ...@@ -620,6 +618,41 @@ bool pfcp_switch::create_packet_in_access(
return true; return true;
} }
//------------------------------------------------------------------------------
void pfcp_switch::start_datapath(
itti_n4_session_establishment_request* establishment_request,
itti_n4_session_modification_request* modification_request,
itti_n4_session_deletion_request* deletion_request, pfcp::pfcp_session* s,
std::shared_ptr<SessionManager> obj,
void (SessionManager::*crud_func)(
std::shared_ptr<pfcp::pfcp_session>,
itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req)) {
std::shared_ptr<pfcp::pfcp_session> pSession =
std::make_shared<pfcp::pfcp_session>(*s);
obj = UserPlaneComponent::getInstance().getSessionManager();
itti_n4_session_establishment_request* est_req = establishment_request;
itti_n4_session_modification_request* mod_req = modification_request;
itti_n4_session_deletion_request* del_req = deletion_request;
if (!del_req) {
obj->sessions.push_back(pSession);
(obj.get()->*crud_func)(pSession, est_req, mod_req, del_req);
} else {
auto& sessions = spSessionManager->sessions;
auto it = std::find(sessions.begin(), sessions.end(), pSession);
if (it != sessions.end()) {
sessions.erase(it); // Erase the element from the vector
(obj.get()->*crud_func)(pSession, est_req, mod_req, del_req);
} else {
Logger::upf_app().warn("Session does not exist");
}
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void pfcp_switch::handle_pfcp_session_establishment_request( void pfcp_switch::handle_pfcp_session_establishment_request(
std::shared_ptr<itti_n4_session_establishment_request> sreq, std::shared_ptr<itti_n4_session_establishment_request> sreq,
...@@ -690,13 +723,11 @@ void pfcp_switch::handle_pfcp_session_establishment_request( ...@@ -690,13 +723,11 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
} }
if (upf_cfg.enable_bpf_datapath) { if (upf_cfg.enable_bpf_datapath) {
std::shared_ptr<pfcp::pfcp_session> pSession = Logger::pfcp_switch().info(
std::make_shared<pfcp::pfcp_session>(*session); "Establishing datapath: create PDRs + create FARs");
spSessionManager = start_datapath(
UserPlaneComponent::getInstance().getSessionManager(); req, NULL, NULL, session, spSessionManager,
spSessionManager->sessions.push_back(pSession); &SessionManager::createBPFSession);
// bool isModification = false;
spSessionManager->createBPFSession(pSession);
} }
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) { if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
...@@ -766,6 +797,7 @@ void pfcp_switch::handle_pfcp_session_establishment_request( ...@@ -766,6 +797,7 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
} }
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void pfcp_switch::handle_pfcp_session_modification_request( void pfcp_switch::handle_pfcp_session_modification_request(
std::shared_ptr<itti_n4_session_modification_request> sreq, std::shared_ptr<itti_n4_session_modification_request> sreq,
...@@ -792,7 +824,15 @@ void pfcp_switch::handle_pfcp_session_modification_request( ...@@ -792,7 +824,15 @@ void pfcp_switch::handle_pfcp_session_modification_request(
resp->seid = session->cp_fseid.seid; resp->seid = session->cp_fseid.seid;
for (auto it : req->pfcp_ies.remove_pdrs) { for (auto it : req->pfcp_ies.remove_pdrs) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: remove PDRs");
start_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
remove_pdr& pdr = it; remove_pdr& pdr = it;
if (not session->remove(pdr, cause, offending_ie.offending_ie)) { if (not session->remove(pdr, cause, offending_ie.offending_ie)) {
if (cause.cause_value == if (cause.cause_value ==
CAUSE_VALUE_RULE_CREATION_MODIFICATION_FAILURE) { CAUSE_VALUE_RULE_CREATION_MODIFICATION_FAILURE) {
...@@ -805,7 +845,15 @@ void pfcp_switch::handle_pfcp_session_modification_request( ...@@ -805,7 +845,15 @@ void pfcp_switch::handle_pfcp_session_modification_request(
} }
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) { if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
for (auto it : req->pfcp_ies.remove_fars) { for (auto it : req->pfcp_ies.remove_fars) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: remove FARs");
start_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
remove_far& far = it; remove_far& far = it;
if (not session->remove(far, cause, offending_ie.offending_ie)) { if (not session->remove(far, cause, offending_ie.offending_ie)) {
if (cause.cause_value == if (cause.cause_value ==
CAUSE_VALUE_RULE_CREATION_MODIFICATION_FAILURE) { CAUSE_VALUE_RULE_CREATION_MODIFICATION_FAILURE) {
...@@ -820,6 +868,12 @@ void pfcp_switch::handle_pfcp_session_modification_request( ...@@ -820,6 +868,12 @@ void pfcp_switch::handle_pfcp_session_modification_request(
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) { if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
for (auto it : req->pfcp_ies.create_fars) { for (auto it : req->pfcp_ies.create_fars) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: create FARs");
start_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
create_far& cr_far = it; create_far& cr_far = it;
if (not session->create(cr_far, cause, offending_ie.offending_ie)) { if (not session->create(cr_far, cause, offending_ie.offending_ie)) {
break; break;
...@@ -865,17 +919,23 @@ void pfcp_switch::handle_pfcp_session_modification_request( ...@@ -865,17 +919,23 @@ void pfcp_switch::handle_pfcp_session_modification_request(
} }
if (upf_cfg.enable_bpf_datapath) { if (upf_cfg.enable_bpf_datapath) {
std::shared_ptr<pfcp::pfcp_session> pSession = Logger::pfcp_switch().info(
std::make_shared<pfcp::pfcp_session>(*session); "Modifying datapath: create PDRs + create FARs");
spSessionManager = start_datapath(
UserPlaneComponent::getInstance().getSessionManager(); NULL, req, NULL, session, spSessionManager,
spSessionManager->sessions.push_back(pSession); &SessionManager::updateBPFSession);
spSessionManager->updateBPFSession(pSession);
} }
} }
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) { if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
for (auto it : req->pfcp_ies.update_pdrs) { for (auto it : req->pfcp_ies.update_pdrs) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: update PDRs");
start_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
update_pdr& pdr = it; update_pdr& pdr = it;
uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED; uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED;
if (not session->update(pdr, cause_value)) { if (not session->update(pdr, cause_value)) {
...@@ -886,6 +946,13 @@ void pfcp_switch::handle_pfcp_session_modification_request( ...@@ -886,6 +946,13 @@ void pfcp_switch::handle_pfcp_session_modification_request(
} }
} }
for (auto it : req->pfcp_ies.update_fars) { for (auto it : req->pfcp_ies.update_fars) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: update FARs");
start_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
update_far& far = it; update_far& far = it;
uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED; uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED;
if (not session->update(far, cause_value)) { if (not session->update(far, cause_value)) {
...@@ -955,27 +1022,17 @@ void pfcp_switch::handle_pfcp_session_deletion_request( ...@@ -955,27 +1022,17 @@ void pfcp_switch::handle_pfcp_session_deletion_request(
if (not get_pfcp_session_by_up_seid(req->seid, s)) { if (not get_pfcp_session_by_up_seid(req->seid, s)) {
cause.cause_value = CAUSE_VALUE_SESSION_CONTEXT_NOT_FOUND; cause.cause_value = CAUSE_VALUE_SESSION_CONTEXT_NOT_FOUND;
} else { } else {
resp->seid = s->cp_fseid.seid; pfcp::pfcp_session* session = s.get();
if (upf_cfg.enable_bpf_datapath) { resp->seid = s->cp_fseid.seid;
std::shared_ptr<pfcp::pfcp_session> pSession =
std::make_shared<pfcp::pfcp_session>(*s);
spSessionManager = UserPlaneComponent::getInstance().getSessionManager();
// spSessionManager->sessions.push_back(pSession);
auto& sessions = spSessionManager->sessions;
// Find the iterator pointing to pSession in the vector
auto it = std::find(sessions.begin(), sessions.end(), pSession);
// Check if pSession was found before erasing it if (upf_cfg.enable_bpf_datapath) {
if (it != sessions.end()) { Logger::pfcp_switch().info(
sessions.erase(it); // Erase the element from the vector "Deleting datapath: delete PDRs + delete FARs");
spSessionManager->removeBPFSession(pSession->get_up_seid()); start_datapath(
} else { NULL, NULL, req, session, spSessionManager,
// Element not found, handle the case as needed &SessionManager::removeBPFSession);
Logger::upf_app().warn("Session %d does not exist", resp->seid);
}
} }
remove_pfcp_session(s); remove_pfcp_session(s);
} }
pfcp_associations::get_instance().notify_del_session(fseid); pfcp_associations::get_instance().notify_del_session(fseid);
......
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <SessionManager.h>
#include <variant>
namespace oai { namespace oai {
namespace upf { namespace upf {
namespace app { namespace app {
...@@ -176,6 +179,21 @@ class pfcp_switch { ...@@ -176,6 +179,21 @@ class pfcp_switch {
bool no_internal_loop(struct iphdr* const iph, const std::size_t num_bytes); bool no_internal_loop(struct iphdr* const iph, const std::size_t num_bytes);
void send_to_core(char* const ip_packet, const ssize_t len); void send_to_core(char* const ip_packet, const ssize_t len);
using itti_n4_session_request = std::variant<
itti_n4_session_establishment_request*,
itti_n4_session_modification_request*, itti_n4_session_deletion_request*>;
void start_datapath(
itti_n4_session_establishment_request* establishment_req,
itti_n4_session_modification_request* modification_request,
itti_n4_session_deletion_request* deletion_req, pfcp::pfcp_session* s,
std::shared_ptr<SessionManager> obj,
void (SessionManager::*crud_func)(
std::shared_ptr<pfcp::pfcp_session>,
itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req));
void handle_pfcp_session_establishment_request( void handle_pfcp_session_establishment_request(
std::shared_ptr<itti_n4_session_establishment_request> sreq, std::shared_ptr<itti_n4_session_establishment_request> sreq,
itti_n4_session_establishment_response*); itti_n4_session_establishment_response*);
......
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