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 @@
#include <pfcp_session.hpp>
#include <unordered_map>
#include "itti_msg_n4.hpp"
class BPFMap;
class ForwardingActionRules;
class PacketDetectionRules;
......@@ -35,9 +37,11 @@ class SessionBpf;
* maps. It communicate with BPF maps in order to update its PDRs and FARs. This
* class does not validate the input.
*/
class SessionManager {
public:
// Set of PDRs.
using pdrs_t = std::vector<std::shared_ptr<PacketDetectionRules>>;
/*****************************************************************************************************************/
......@@ -78,7 +82,11 @@ class SessionManager {
* @param pSession The PFCP session which contains the context that will be
* 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 {
*
* @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(
......@@ -130,15 +155,6 @@ class SessionManager {
uint32_t seid,
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(
const std::shared_ptr<pfcp::pfcp_pdr>& first,
......
......@@ -27,6 +27,8 @@ include_directories(${SRC_TOP_DIR}/oai_upf)
include_directories(${SRC_TOP_DIR}/pfcp)
include_directories(${SRC_TOP_DIR}/upf_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}/udp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
......
......@@ -49,8 +49,6 @@
#include <stdexcept>
#include <net/ethernet.h>
#include <SessionManager.h>
static std::shared_ptr<SessionManager> spSessionManager;
using namespace pfcp;
......@@ -620,6 +618,41 @@ bool pfcp_switch::create_packet_in_access(
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(
std::shared_ptr<itti_n4_session_establishment_request> sreq,
......@@ -690,13 +723,11 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
}
if (upf_cfg.enable_bpf_datapath) {
std::shared_ptr<pfcp::pfcp_session> pSession =
std::make_shared<pfcp::pfcp_session>(*session);
spSessionManager =
UserPlaneComponent::getInstance().getSessionManager();
spSessionManager->sessions.push_back(pSession);
// bool isModification = false;
spSessionManager->createBPFSession(pSession);
Logger::pfcp_switch().info(
"Establishing datapath: create PDRs + create FARs");
start_datapath(
req, NULL, NULL, session, spSessionManager,
&SessionManager::createBPFSession);
}
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
......@@ -766,6 +797,7 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
}
}
}
//------------------------------------------------------------------------------
void pfcp_switch::handle_pfcp_session_modification_request(
std::shared_ptr<itti_n4_session_modification_request> sreq,
......@@ -792,7 +824,15 @@ void pfcp_switch::handle_pfcp_session_modification_request(
resp->seid = session->cp_fseid.seid;
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;
if (not session->remove(pdr, cause, offending_ie.offending_ie)) {
if (cause.cause_value ==
CAUSE_VALUE_RULE_CREATION_MODIFICATION_FAILURE) {
......@@ -805,7 +845,15 @@ void pfcp_switch::handle_pfcp_session_modification_request(
}
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
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;
if (not session->remove(far, cause, offending_ie.offending_ie)) {
if (cause.cause_value ==
CAUSE_VALUE_RULE_CREATION_MODIFICATION_FAILURE) {
......@@ -820,6 +868,12 @@ void pfcp_switch::handle_pfcp_session_modification_request(
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
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;
if (not session->create(cr_far, cause, offending_ie.offending_ie)) {
break;
......@@ -865,17 +919,23 @@ void pfcp_switch::handle_pfcp_session_modification_request(
}
if (upf_cfg.enable_bpf_datapath) {
std::shared_ptr<pfcp::pfcp_session> pSession =
std::make_shared<pfcp::pfcp_session>(*session);
spSessionManager =
UserPlaneComponent::getInstance().getSessionManager();
spSessionManager->sessions.push_back(pSession);
spSessionManager->updateBPFSession(pSession);
Logger::pfcp_switch().info(
"Modifying datapath: create PDRs + create FARs");
start_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
}
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
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;
uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED;
if (not session->update(pdr, cause_value)) {
......@@ -886,6 +946,13 @@ void pfcp_switch::handle_pfcp_session_modification_request(
}
}
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;
uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED;
if (not session->update(far, cause_value)) {
......@@ -955,27 +1022,17 @@ void pfcp_switch::handle_pfcp_session_deletion_request(
if (not get_pfcp_session_by_up_seid(req->seid, s)) {
cause.cause_value = CAUSE_VALUE_SESSION_CONTEXT_NOT_FOUND;
} else {
resp->seid = s->cp_fseid.seid;
if (upf_cfg.enable_bpf_datapath) {
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);
pfcp::pfcp_session* session = s.get();
resp->seid = s->cp_fseid.seid;
// Check if pSession was found before erasing it
if (it != sessions.end()) {
sessions.erase(it); // Erase the element from the vector
spSessionManager->removeBPFSession(pSession->get_up_seid());
} else {
// Element not found, handle the case as needed
Logger::upf_app().warn("Session %d does not exist", resp->seid);
}
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info(
"Deleting datapath: delete PDRs + delete FARs");
start_datapath(
NULL, NULL, req, session, spSessionManager,
&SessionManager::removeBPFSession);
}
remove_pfcp_session(s);
}
pfcp_associations::get_instance().notify_del_session(fseid);
......
......@@ -46,6 +46,9 @@
#include <thread>
#include <vector>
#include <SessionManager.h>
#include <variant>
namespace oai {
namespace upf {
namespace app {
......@@ -176,6 +179,21 @@ class pfcp_switch {
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);
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(
std::shared_ptr<itti_n4_session_establishment_request> sreq,
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