Commit 3313d4e2 authored by Franck Messaoudi's avatar Franck Messaoudi

Update: update code to manage separately the tc bpf program

parent 694fc287
......@@ -115,9 +115,6 @@ void my_app_signal_handler(int s) {
//------------------------------------------------------------------------------
void setup_bpf() {
// std::shared_ptr<RulesUtilities> mpRulesFactory;
// mpRulesFactory = std::make_shared<RulesUtilitiesImpl>();
std::string sGTPInterface = N3_IF_NAME;
std::string sUDPInterface = N6_IF_NAME;
Logger::upf_app().info("GTP interface: %s", sGTPInterface.c_str());
......@@ -134,6 +131,8 @@ int main(int argc, char** argv) {
return 1;
}
const bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
// Logger
// Config
std::string conf_file_name = Options::getlibconfigConfig();
......@@ -208,7 +207,7 @@ int main(int argc, char** argv) {
fflush(fp);
fclose(fp);
if (upf_cfg.enable_bpf_datapath) {
if (isBpfAccelerationEnabled) {
setup_bpf();
}
// once all udp servers initialized
......
......@@ -144,7 +144,8 @@ void SessionManager::processPDRs(
const bool is_qos_enabled = upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos;
// Helper function to find QER by ID
auto find_qer_by_id = [&](uint64_t qer_id) -> std::shared_ptr<pfcp::pfcp_qer> {
auto find_qer_by_id =
[&](uint64_t qer_id) -> std::shared_ptr<pfcp::pfcp_qer> {
for (auto& qer : pSession_establishment->qers) {
if (qer->qer_id.second.qer_id == qer_id) {
return qer;
......@@ -235,24 +236,24 @@ void SessionManager::prepareEbpfSession(
pfcp::pdi pdi;
pfcp::source_interface_t sourceInterface;
if (!(pdrHighPrecedence->get(pdi) && pdi.get(sourceInterface))){
if (!(pdrHighPrecedence->get(pdi) && pdi.get(sourceInterface))) {
throw std::runtime_error(
"Missing Mandatory IE (PDI or Source Interface) within PDR: " +
std::to_string(pdrHighPrecedence->pdr_id.rule_id));
"Missing Mandatory IE (PDI or Source Interface) within PDR: " +
std::to_string(pdrHighPrecedence->pdr_id.rule_id));
}
logger.debug(
"The PDR %d has the Highest Precedence",
pdrHighPrecedence->pdr_id.rule_id);
"The PDR %d has the Highest Precedence",
pdrHighPrecedence->pdr_id.rule_id);
processPDRDetails(pSession_establishment,pdrHighPrecedence);
}
processPDRDetails(pSession_establishment, pdrHighPrecedence);
}
//---------------------------------------------------------------------------------------------------------------
void SessionManager::processPDRDetails(
std::shared_ptr<pfcp::pfcp_session> pSession,
std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedence) {
auto& logger = Logger::upf_app();
auto& logger = Logger::upf_app();
const bool is_qos_enabled = upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos;
pfcp::pdi pdi;
......@@ -271,38 +272,44 @@ void SessionManager::processPDRDetails(
int interfaceValue = sourceInterface.interface_value;
switch (interfaceValue) {
case INTERFACE_VALUE_CORE:{
case INTERFACE_VALUE_CORE: {
direction = Direction::Uplink;
logger.debug("Create the eBPF Uplink Datapath for Session %lu", pSession->get_up_seid());
logger.debug(
"Create the eBPF Uplink Datapath for Session %lu",
pSession->get_up_seid());
break;
}
case INTERFACE_VALUE_ACCESS:{
case INTERFACE_VALUE_ACCESS: {
direction = Direction::Downlink;
logger.debug("Create the eBPF Downlink Datapath for Session %lu", pSession->get_up_seid());
logger.debug(
"Create the eBPF Downlink Datapath for Session %lu",
pSession->get_up_seid());
break;
}
default:{
default: {
Logger::upf_app().warn("Unknown interface value: %d", interfaceValue);
break;
}
}
// Check for missing FTEID
// Check for missing FTEID
if (!pdi.get(fteid)) {
fteid.teid = -1;
logger.warn(
"FTEID is missing for the current PDR. "
"Note: This IE should not be present if the Traffic Endpoint ID is present. "
"If the CHOOSE (CH) bit is set to 1, the UP function is expected to assign "
"Note: This IE should not be present if the Traffic Endpoint ID is "
"present. "
"If the CHOOSE (CH) bit is set to 1, the UP function is expected to "
"assign "
"a local F-TEID to the PDR.");
if (fteid.ch) {
logger.debug("CHOOSE (CH) bit is set in FTEID.");
logger.debug("CHOOSE (CH) bit is set in FTEID.");
} else {
logger.debug("CHOOSE (CH) bit is not set in FTEID.");
logger.debug("CHOOSE (CH) bit is not set in FTEID.");
}
}
......@@ -312,14 +319,15 @@ void SessionManager::processPDRDetails(
logger.warn(
"UE IP Address is missing for the current PDR. "
"Note: This IE should not be present if the Traffic Endpoint ID is present.");
"Note: This IE should not be present if the Traffic Endpoint ID is "
"present.");
}
// Log PDI extraction details
logger.debug("PDI successfully extracted from PDR ID: %d.", pdr_id);
logger.debug(
"Extracting FAR from the highest precedence PDR ID: %d.", pdr_id);
std::shared_ptr<pfcp::pfcp_far> pFar;
if (!extractFar(pdrHighPrecedence, pSession, pFar)) {
......@@ -334,18 +342,26 @@ void SessionManager::processPDRDetails(
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer;
/*
* TODO: implement the QoS Enforcement on the uplink side
if (is_qos_enabled) {
pQer = (direction == Direction::Uplink) ? pSession->qers_uplink :
pSession->qers_downlink;
SessionProgramManager::getInstance().createPipeline(
std::vector<std::shared_ptr<pfcp::pfcp_qer>>{};
}
SessionProgramManager::getInstance().createPipeline(
pSession->get_up_seid(), fteid.teid, interfaceValue,
ueIpAddress.ipv4_address.s_addr, pFar, pQer, false, 0);
} else{
SessionProgramManager::getInstance().createPipeline(
pSession->get_up_seid(), fteid.teid, interfaceValue,
ueIpAddress.ipv4_address.s_addr, pFar, false, 0);
}
ueIpAddress.ipv4_address.s_addr, pFar, pQer, false, 0);
*/
if (is_qos_enabled) {
pQer = (direction == Direction::Downlink) ?
pSession->qers_downlink :
std::vector<std::shared_ptr<pfcp::pfcp_qer>>{};
}
SessionProgramManager::getInstance().createPipeline(
pSession->get_up_seid(), fteid.teid, interfaceValue,
ueIpAddress.ipv4_address.s_addr, pFar, pQer, false, 0);
}
//---------------------------------------------------------------------------------------------------------------
......
......@@ -196,30 +196,30 @@ void SessionProgramManager::storeSessionMappingMap(
void SessionProgramManager::updateARPTableForN6(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t dnIP, uint32_t upfn6IP) {
try {
std::string remoteDN = "192.168.24.160";
uint32_t remoteN6IPv4 = inet_addr(remoteDN.c_str());
// const char* remoteN6MAC = "0061BB000001";
uint8_t remoteN6MAC[6] = {0x00, 0x61, 0xbb, 0x00, 0x00, 0x01};
Logger::upf_app().warn(
"updateARPTableForN6 is modified with hard values to test with "
"Trex! I dont understand why the execution goes through the "
"exception!"
"Need to check and debug");
struct s_arp_mapping map_table;
memset(&map_table, 0, sizeof(struct s_arp_mapping));
memcpy(map_table.mac_address, remoteN6MAC, 6);
map_table.ipv4_address = remoteN6IPv4;
try {
std::string remoteDN = "192.168.24.160";
uint32_t remoteN6IPv4 = inet_addr(remoteDN.c_str());
// const char* remoteN6MAC = "0061BB000001";
uint8_t remoteN6MAC[6] = {0x00, 0x61, 0xbb, 0x00, 0x00, 0x01};
pPFCP_Session_LookupProgram->getArpTableMap()->update(
upfn6IP, map_table, BPF_ANY);
} catch (const std::exception& ex) {
Logger::upf_app().error(
"Error: The ARP table was not updated for N6 Next HOP");
}
}
Logger::upf_app().warn(
"updateARPTableForN6 is modified with hard values to test with "
"Trex! I dont understand why the execution goes through the "
"exception!"
"Need to check and debug");
struct s_arp_mapping map_table;
memset(&map_table, 0, sizeof(struct s_arp_mapping));
memcpy(map_table.mac_address, remoteN6MAC, 6);
map_table.ipv4_address = remoteN6IPv4;
pPFCP_Session_LookupProgram->getArpTableMap()->update(
upfn6IP, map_table, BPF_ANY);
} catch (const std::exception& ex) {
Logger::upf_app().error(
"Error: The ARP table was not updated for N6 Next HOP");
}
}
/*
void SessionProgramManager::updateARPTableForN6(
......@@ -272,8 +272,7 @@ void SessionProgramManager::updateARPTableForN3(
for (auto it = pfcpPrograms->begin(); it != pfcpPrograms->end(); ++it) {
// Access the members of the 'farprograms' struct
uint64_t savedSeid = it->seid;
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram
=
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram =
it->pPFCP_Session_LookupProgram;
if (savedSeid == seid) {
......@@ -311,7 +310,8 @@ void SessionProgramManager::updateARPTableForN3(
// for (auto it = pfcpPrograms->begin(); it != pfcpPrograms->end(); ++it) {
// // Access the members of the 'farprograms' struct
// uint64_t savedSeid = it->seid;
// std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram =
// std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram
// =
// it->pPFCP_Session_LookupProgram;
// if (savedSeid == seid) {
......@@ -366,15 +366,27 @@ void SessionProgramManager::createPipeline(
uint32_t ueIpAddress, std::shared_ptr<pfcp::pfcp_far> pFar,
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer, bool isModification,
uint32_t teid2) {
uint32_t dnIP = upf_cfg.remote_n6.s_addr;
uint32_t upfn3IP = upf_cfg.n3.addr4.s_addr;
uint32_t upfn6IP = upf_cfg.n6.addr4.s_addr;
uint32_t far_id = pFar->far_id.far_id;
uint32_t dnIP = upf_cfg.remote_n6.s_addr;
uint32_t upfn3IP = upf_cfg.n3.addr4.s_addr;
uint32_t upfn6IP = upf_cfg.n6.addr4.s_addr;
uint32_t far_id = pFar->far_id.far_id;
next_rule_prog_index_key key;
initializeNextRuleProgIndexKey(key, teid1, ueIpAddress, sourceInterface);
bool enforcing_qos = !pQer.empty();
const bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
const bool isQosEnabled = isBpfAccelerationEnabled && upf_cfg.enable_qos;
/*======================================================================================*/
if (isQosEnabled && enforcing_qos) {
Logger::upf_app().debug("Instantiate a new QERProgram ");
std::shared_ptr<QERProgram> pQERProgram = std::make_shared<QERProgram>();
pQERProgram->setup(seid, pQer);
}
/*======================================================================================*/
auto pPFCP_Session_LookupProgram =
UserPlaneComponent::getInstance().getPFCP_Session_LookupProgram();
......@@ -414,12 +426,9 @@ void SessionProgramManager::createPipeline(
void SessionProgramManager::removePipeline(uint64_t seid) {
Logger::upf_app().debug("Remove FARProgram index from UPFProgram map");
auto it = mSessionProgramsMap.find(seid);
if (it == mSessionProgramsMap.end()) {
Logger::upf_app().error(
"Session %d Does Not Exist. It Cannot be Removed", seid);
// throw std::runtime_error("Session does Not Exist. It Cannot be
// Removed");
Logger::upf_app().error("Session with SEID: %lu Does Not Exist", seid);
}
Logger::upf_app().debug(
......
......@@ -14,7 +14,6 @@
class BPFMap;
class OnStateChangeSessionProgramObserver;
class PFCP_Session_LookupProgram;
// class PFCP_Session_PDR_LookupProgram;
class SessionPrograms;
class FARProgram;
......@@ -112,11 +111,6 @@ class SessionProgramManager {
bool isModification = false, uint32_t teid2 = 0);
/*---------------------------------------------------------------------------------------------------------------*/
void createPipeline(
uint64_t seid, uint32_t teid1, uint8_t sourceInterface,
uint32_t ueIpAddress, std::shared_ptr<pfcp::pfcp_far> pFar,
bool isModification = false, uint32_t teid2 = 0);
/*---------------------------------------------------------------------------------------------------------------*/
void initializeNextRuleProgIndexKey(
next_rule_prog_index_key& key, uint32_t teid, uint32_t ueIpAddress,
uint8_t sourceInterface);
......
......@@ -7,8 +7,8 @@
#include <next_prog_rule_key.h>
/**
* @brief This class represents the datapath path. It stores the program related
* to a PFCP session. For each session, there might be a QERProgram. The
* @brief This class represents the Data-Path path. It stores the program
* related to a PFCP session. For each session, there might be a QERProgram. The
* FARProgram is mandatory.
*
*/
......
#include "UserPlaneComponent.h"
#include <SessionManager.h>
//#include <pfcp_session_pdr_lookup_xdp_user.h>
#include <SessionProgramManager.h>
#include <SignalHandler.h>
#include <pfcp_session_lookup_xdp_user.h>
#include "logger.hpp"
#include <helpers/GetNicInformation.hpp>
#include "upf_config.hpp"
using namespace oai::config;
extern upf_config upf_cfg;
//---------------------------------------------------------------------------------------------------------------
UserPlaneComponent::UserPlaneComponent() {
// Set new handlers for libbpf.
......@@ -82,9 +85,12 @@ void UserPlaneComponent::setMembers(
//---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::setup(
const std::string& gtpInterface, const std::string& udpInterface) {
const bool isQosEnabled = upf_cfg.enable_qos;
setMembers(gtpInterface, udpInterface);
SignalHandler::getInstance().enable();
mpPFCP_Session_LookupProgram->setup();
mpPFCP_Session_LookupProgram->setup(isQosEnabled);
// Pass maps to sessionManager.
mpSessionManager = std::make_shared<SessionManager>();
......
......@@ -6,17 +6,18 @@
#include <linux/bpf.h>
#include <linux/if_ether.h>
//#define UDP_CSUM_OFFSET (sizeof(struct ethhdr) + offsetof(struct udphdr, check))
//#define UDP_CSUM_OFFSET (sizeof(struct ethhdr) + offsetof(struct udphdr,
//check))
// static u32 udp_handle(
// struct xdp_md* ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip);
// static u32 udp_handle(
// struct xdp_md* ctx, struct udphdr* udph, u32 dest_ip);
static u32 udp_handle(
struct xdp_md* p_ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip,
u8 dscp);
// static u32 udp_handle(
// struct xdp_md* p_ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip,
// u8 dscp);
static u32 handle_uplink_traffic(struct xdp_md* p_ctx, struct udphdr* udph);
// static u32 handle_uplink_traffic(struct xdp_md* p_ctx, struct udphdr* udph);
#endif // PROTOCOLS_UDP_H
......@@ -37,12 +37,12 @@ struct {
} m_arp_table SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_FAR_PROGRAMS);
__type(key, u32);
__type(value, u32);
} m_enforcing_qos SEC(".maps");
// struct {
// __uint(type, BPF_MAP_TYPE_HASH);
// __uint(max_entries, MAX_FAR_PROGRAMS);
// __type(key, u32);
// __type(value, u32);
// } m_enforcing_qos SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
......
......@@ -57,7 +57,6 @@ struct vlan_hdr {
static u32 upf_n3_ip = 0;
static u32 upf_n6_ip = 0;
static u32 ue_ip = 0;
static u8 next_hop_n3_mac_address[6] = {0};
static u8 next_hop_n6_mac_address[6] = {0};
......@@ -259,69 +258,69 @@ create_outer_header_gtpu_ipv4(struct xdp_md* ctx, pfcp_far_t_* p_far) {
/*---------------------------------------------------------------------------------------------------------------*/
SEC("xdp")
int xdp_handle_uplink(struct xdp_md* ctx) {
bpf_debug("================< PFCP PDR Sesction: Handle Uplink >================");
bpf_debug("================< XDP: Handle Uplink >================");
void* data = (void*) (long) ctx->data;
void* data_end = (void*) (long) ctx->data_end;
struct ethhdr* ethh = (void*) (long) ctx->data;
u16 eth_type = bpf_htons(ethh->h_proto);
u64 offset = sizeof(*ethh);
if ((void*) (ethh + 1) > (void*) (long) ctx->data_end) {
bpf_debug("Invalid Ethernet header");
bpf_debug("Error: Invalid Ethernet header");
return XDP_DROP;
}
u16 eth_type = bpf_htons(ethh->h_proto);
bpf_debug("Debug: eth_type:0x%x", eth_type);
switch (eth_type) {
case ETH_P_IP: {
struct iphdr* iph = (struct iphdr*) ((void*) ethh + offset);
struct iphdr* iph = (struct iphdr*) ((void*) ethh + sizeof(*ethh));
if ((void*) (iph + 1) > data_end) {
bpf_debug("Invalid IPv4 Packet");
bpf_debug("Error: Invalid IPv4 Packet");
return XDP_DROP;
}
struct udphdr* udph = (struct udphdr*) (iph + 1);
if ((void*) (udph + 1) > data_end) {
bpf_debug("Invalid UDP packet");
bpf_debug("Error: Invalid UDP packet");
return XDP_DROP;
}
if (bpf_htons(udph->dest) == GTP_UDP_PORT) {
bpf_debug("This is a GTP traffic");
bpf_debug("Identified GTP Traffic");
struct gtpuhdr* gtpuh = (struct gtpuhdr*) (udph + 1);
// Check if the GTP header extends beyond the data end.
if ((void*) gtpuh + sizeof(*gtpuh) > data_end) {
bpf_debug("Invalid GTPU packet");
bpf_debug("Error: Invalid GTP-U packet");
return XDP_DROP;
}
if (gtpuh->message_type != GTPU_G_PDU) {
bpf_debug(
"Message type 0x%x is not GTPU GPDU(0x%x)\n", gtpuh->message_type,
GTPU_G_PDU);
return XDP_PASS;
}
struct ethhdr* ethh_new = data + GTP_ENCAPSULATED_SIZE;
if ((void*) ethh_new + sizeof(*ethh_new) > data_end) {
bpf_debug("Invalid Ethernet packet");
bpf_debug("Error: Invalid encapsulated Ethernet packet");
return XDP_DROP;
}
struct iphdr* iph_inner = (void*) (ethh_new + 1);
if ((void*) iph_inner + sizeof(*iph_inner) > data_end) {
bpf_debug("Invalid Inner IP packet");
bpf_debug("Error: Invalid Inner IP packet");
return XDP_DROP;
}
u32 src_ip_in = bpf_htonl(iph_inner->saddr);
if (gtpuh->message_type != GTPU_G_PDU) {
bpf_debug(
"Message type 0x%x is not GTPU GPDU(0x%x)\n", gtpuh->message_type,
GTPU_G_PDU);
return XDP_PASS;
}
struct next_rule_prog_index_key map_key = {0};
map_key.teid = gtpuh->teid;
map_key.source_value = INTERFACE_VALUE_ACCESS;
......@@ -332,19 +331,17 @@ int xdp_handle_uplink(struct xdp_md* ctx) {
if (p_far) {
bpf_debug("FAR ID = %d", p_far->far_id.far_id);
u8 dest_interface = p_far->forwarding_parameters.destination_interface
.interface_value;
// u8 dest_interface = p_far->forwarding_parameters.destination_interface.interface_value;
if (!p_far->apply_action.forw) {
bpf_debug("Forward Action Is NOT set");
return XDP_PASS;
}
bpf_debug("GTP Header Removal ...");
bpf_debug("GTP Header Removal in Progress");
__builtin_memcpy(ethh_new, ethh, sizeof(*ethh));
// Retrieve the N6 Interface IP address:
e_reference_point n6_key = N6_INTERFACE;
if (!cached_n6) {
......@@ -378,6 +375,7 @@ int xdp_handle_uplink(struct xdp_md* ctx) {
sizeof(ethh_new->h_dest));
// Adjust head to the right.
if (bpf_xdp_adjust_head(ctx, GTP_ENCAPSULATED_SIZE)) {
bpf_debug("Error: Adjusting packet head failed");
return XDP_DROP;
}
......@@ -385,7 +383,7 @@ int xdp_handle_uplink(struct xdp_md* ctx) {
// ethh_new->h_dest[1], ethh_new->h_dest[2]); bpf_debug(" %x:%x:%x",
// ethh_new->h_dest[3], ethh_new->h_dest[4], ethh_new->h_dest[5]);
bpf_debug("The Packet is redirected for transmission to DN ...");
bpf_debug("Redirecting Packet to DN");
return bpf_redirect_map(&m_redirect_interfaces, UPLINK, 0);
......@@ -396,7 +394,7 @@ int xdp_handle_uplink(struct xdp_md* ctx) {
}
}
default: {
bpf_debug("Cannot parse L2: L3off:%llu proto:0x%x", offset, eth_type);
bpf_debug("Unsupported protocol: 0x%x", eth_type);
return XDP_PASS;
}
}
......@@ -405,32 +403,32 @@ int xdp_handle_uplink(struct xdp_md* ctx) {
/*---------------------------------------------------------------------------------------------------------------*/
SEC("xdp")
int xdp_handle_downlink(struct xdp_md* ctx) {
bpf_debug("================< PFCP PDR Sesction: Handle Downlink >================");
bpf_debug("================< XDP: Handle Downlink >================");
void* data_end = (void*) (long) ctx->data_end;
struct ethhdr* ethh = (void*) (long) ctx->data;
u64 offset = sizeof(*ethh);
if ((void*) (ethh + 1) > (void*) (long) ctx->data_end) {
bpf_debug("Invalid Ethernet header");
bpf_debug("Error: Invalid Ethernet header");
return XDP_DROP;
}
struct iphdr* iph = (struct iphdr*) ((void*) ethh + offset);
struct iphdr* iph = (struct iphdr*) ((void*) ethh + sizeof(*ethh));
if ((void*) (iph + 1) > data_end) {
bpf_debug("Invalid IPv4 Packet");
bpf_debug("Error: Invalid IPv4 Packet");
return XDP_DROP;
}
u32 ip_dest = bpf_htonl(iph->daddr);
struct session_id* session =
bpf_map_lookup_elem(&m_session_mapping, &ip_dest);
// u32* teid_dl = bpf_map_lookup_elem(&m_session_mapping, &ip_dest);
if (session) {
u32 teid_dl = session->teid_dl;
bpf_debug(
"TEID downlink: 0x%x was found for UE IP: 0x%x", teid_dl, ip_dest);
"TEID for downlink: 0x%x, UE IP: 0x%x", teid_dl, ip_dest);
struct next_rule_prog_index_key map_key = {0};
map_key.teid = teid_dl;
map_key.source_value = INTERFACE_VALUE_CORE;
......@@ -446,6 +444,55 @@ int xdp_handle_downlink(struct xdp_md* ctx) {
}
}
bpf_debug("Session not found for Downlink, tail call failed");
return XDP_PASS;
}
/*---------------------------------------------------------------------------------------------------------------*/
SEC("xdp")
int xdp_handle_shaping(struct xdp_md* ctx) {
bpf_debug("================< XDP: Handle Shaping >================");
void* data_end = (void*) (long) ctx->data_end;
struct ethhdr* ethh = (void*) (long) ctx->data;
if ((void*) (ethh + 1) > (void*) (long) ctx->data_end) {
bpf_debug("Error: Invalid Ethernet header");
return XDP_DROP;
}
struct iphdr* iph = (struct iphdr*) ((void*) ethh + sizeof(*ethh));
if ((void*) (iph + 1) > data_end) {
bpf_debug("Error: Invalid IPv4 Packet");
return XDP_DROP;
}
u32 ip_dest = bpf_htonl(iph->daddr);
struct session_id* session =
bpf_map_lookup_elem(&m_session_mapping, &ip_dest);
if (session) {
u32 teid_dl = session->teid_dl;
bpf_debug(
"TEID downlink: 0x%x was found for UE IP: 0x%x", teid_dl, ip_dest);
struct next_rule_prog_index_key map_key = {0};
map_key.teid = teid_dl;
map_key.source_value = INTERFACE_VALUE_CORE;
map_key.ipv4_address = ip_dest;
pfcp_far_t_* p_far = bpf_map_lookup_elem(&m_next_rule_prog_index, &map_key);
if (p_far) {
bpf_debug("FAR ID = %d", p_far->far_id.far_id);
create_outer_header_gtpu_ipv4(ctx, p_far);
bpf_debug("The packet is passed to tc layer");
return XDP_PASS;
}
}
bpf_debug("BPF tail call was not executed!");
return XDP_PASS;
......
......@@ -226,7 +226,7 @@ sdf_filter(struct __sk_buff* skb, struct ethhdr* ethh) {
SEC("tc/egress")
int tc_filter_traffic(struct __sk_buff* skb) {
bpf_debug("==========< QER Rules >==========\n");
bpf_debug("==========< tc/egress: Filter Traffic >==========\n");
// void *data = (void *)(long)skb->data;
// void *data_meta = (void *)(long)skb->data_meta;
......@@ -265,6 +265,7 @@ int tc_filter_traffic(struct __sk_buff* skb) {
SEC("tc/ingress")
int tc_redirect_traffic(struct __sk_buff* skb) {
bpf_debug("==========< tc/ingress: Redirect Traffic >==========\n");
int key = DOWNLINK, *ifindex;
// return bpf_redirect_map(&m_redirect_interfaces, DOWNLINK, 0);
......
......@@ -4,27 +4,37 @@
#include <types.h>
/* Use uint8_t*/
struct s_gate {
uint8_t ul_gate;
uint8_t dl_gate;
};
// /* Use uint8_t*/
// struct s_gate {
// uint8_t ul_gate;
// uint8_t dl_gate;
// };
struct s_mbr {
uint64_t ul_mbr;
uint64_t dl_mbr;
};
// struct s_mbr {
// uint64_t ul_mbr;
// uint64_t dl_mbr;
// };
// struct s_gbr {
// uint64_t ul_gbr;
// uint64_t dl_gbr;
// };
// struct s_fiveQosFlow {
// struct s_gate gate;
// struct s_mbr mbr;
// struct s_gbr gbr;
// uint64_t qfi;
// };
struct s_gbr {
uint64_t ul_gbr;
uint64_t dl_gbr;
};
struct s_fiveQosFlow {
struct s_gate gate;
struct s_mbr mbr;
struct s_gbr gbr;
uint64_t qfi;
uint8_t gate;
uint64_t mbr;
uint64_t gbr;
uint8_t qfi;
};
#endif //__QOS_FLOW_H__
\ No newline at end of file
#ifndef CONFIG_MANAGER_HPP
#define CONFIG_MANAGER_HPP
class ConfigManager {
public:
// Returns the singleton instance
static ConfigManager& getInstance();
// Initializes the configuration
void initialize(bool enableBpfDatapath, bool enableQos);
// Checks if BPF datapath is enabled
bool isBpfDatapathEnabled() const;
// Checks if QoS is enabled
bool isQosEnabled() const;
private:
// Private constructor to prevent instantiation
ConfigManager() = default;
// Deleted copy constructor and assignment operator
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
// Configuration variables
bool enable_bpf_datapath = false;
bool enable_qos = false;
};
#endif // CONFIG_MANAGER_HPP
\ No newline at end of file
......@@ -12,6 +12,14 @@
using namespace oai::config;
extern upf_config upf_cfg;
class XDPSection {
public:
static constexpr const char* Uplink = "xdp_handle_uplink";
static constexpr const char* Downlink = "xdp_handle_downlink";
static constexpr const char* Shaping = "xdp_handle_shaping";
};
/*---------------------------------------------------------------------------------------------------------------*/
int is_little_endian2() {
u32 value = 1;
......@@ -73,7 +81,7 @@ void PFCP_Session_LookupProgram::create_upf_interface_map_entry(
PFCP_Session_LookupProgram::~PFCP_Session_LookupProgram() {}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::setup() {
void PFCP_Session_LookupProgram::setup(bool isQosEnabled) {
spSkeleton = mpLifeCycle->open();
initializeMaps();
mpLifeCycle->load();
......@@ -91,7 +99,7 @@ void PFCP_Session_LookupProgram::setup() {
mpEgressInterfaceMap->update(uplinkId, udpInterfaceIndex, BPF_ANY);
mpEgressInterfaceMap->update(downlinkId, gtpInterfaceIndex, BPF_ANY);
Logger::upf_app().debug("Adding Reference Points to m_upf_interface Map:");
Logger::upf_app().debug("Adding Reference Points to m_upf_interface Map");
create_upf_interface_map_entry(N3_INTERFACE);
create_upf_interface_map_entry(N6_INTERFACE);
create_upf_interface_map_entry(N4_INTERFACE);
......@@ -103,12 +111,21 @@ void PFCP_Session_LookupProgram::setup() {
}
Logger::upf_app().debug(
"Link Non-GTP interface to interface %s", mUDPInterface.c_str());
mpLifeCycle->link("xdp_handle_downlink", mUDPInterface.c_str());
"Link GTP XDP Section to interface %s", mGTPInterface.c_str());
mpLifeCycle->link(XDPSection::Uplink, mGTPInterface.c_str());
Logger::upf_app().debug(
"Link GTP interface to interface %s", mGTPInterface.c_str());
mpLifeCycle->link("xdp_handle_uplink", mGTPInterface.c_str());
"Link Non-GTP XDP Section to interface %s", mUDPInterface.c_str());
if (isQosEnabled) {
Logger::upf_app().debug(
"QoS enforcement is enabled in the configuration. A TC BPF section is "
"created ");
mpLifeCycle->link(XDPSection::Shaping, mUDPInterface.c_str());
} else {
Logger::upf_app().debug(
"QoS enforcement is disabled in the configuration.");
mpLifeCycle->link(XDPSection::Downlink, mUDPInterface.c_str());
}
}
/*---------------------------------------------------------------------------------------------------------------*/
......
......@@ -42,7 +42,7 @@ class PFCP_Session_LookupProgram {
* @brief Setup the BPF program.
*
*/
void setup();
void setup(bool isQosEnabled);
/*---------------------------------------------------------------------------------------------------------------*/
/**
......
......@@ -54,10 +54,6 @@
#endif // MAX_CEIL
#endif // DEFAULT_CEIL
#ifndef DEFAULT_QFI
#define DEFAULT_QFI 5
#endif // DEFAULT_QFI
#ifndef BUILD_DIRECTORY
#define BUILD_DIRECTORY \
"build/upf/build/upf_app/bpf/CMakeFiles/qer_tc.dir/rules/qer"
......@@ -86,16 +82,10 @@ void QERProgram::storeQosFlow(std::shared_ptr<pfcp::pfcp_qer> pQer) {
struct s_fiveQosFlow fiveFlow;
memset(&fiveFlow, 0, sizeof(struct s_fiveQosFlow));
fiveFlow.gate.dl_gate = pQer->gate_status.second.dl_gate;
fiveFlow.gate.ul_gate = pQer->gate_status.second.ul_gate;
fiveFlow.gbr.dl_gbr = pQer->gbr.second.dl_gbr;
fiveFlow.gbr.ul_gbr = pQer->gbr.second.ul_gbr;
fiveFlow.mbr.dl_mbr = pQer->mbr.second.dl_mbr;
fiveFlow.mbr.ul_mbr = pQer->mbr.second.ul_mbr;
fiveFlow.qfi = pQer->qfi.second.qfi;
fiveFlow.gate = pQer->gate_status.second.dl_gate;
fiveFlow.gbr = pQer->gbr.second.dl_gbr;
fiveFlow.mbr = pQer->mbr.second.dl_mbr;
fiveFlow.qfi = pQer->qfi.second.qfi;
qosFlowsQfis.push_back(fiveFlow);
......@@ -117,6 +107,23 @@ bool QERProgram::no_htb_root_qdisc(std::string interface) {
return ret ? false : true;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<pfcp::pfcp_qer>
QERProgram::retrive_default_qer_with_default_qfi(
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer) {
for (const auto& qer : pQer) {
if (!qer->gbr.first && !qer->mbr.first) {
Logger::upf_app().debug(
"Default QoS Flow: (QER ID, QFI): (%d, %d)",
qer->qer_id.second.qer_id, qer->qfi.second.qfi);
return qer;
}
}
// Return nullptr if no such QER is found
return nullptr;
}
/*---------------------------------------------------------------------------------------------------------------*/
void QERProgram::setup(
uint64_t seid, std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer) {
......@@ -125,7 +132,7 @@ void QERProgram::setup(
mpLifeCycle->load();
mpLifeCycle->attach();
struct qer_tc_kernel_c* obj = NULL;
std::shared_ptr<pfcp::pfcp_qer> default_qer = nullptr;
std::string cmd = {};
int rc = 0;
......@@ -133,97 +140,106 @@ void QERProgram::setup(
uint32_t udpInterfaceIndex = if_nametoindex(UDP_INTERFACE.c_str());
uint32_t gtpInterfaceIndex = if_nametoindex(GTP_INTERFACE.c_str());
uint32_t uplinkId = static_cast<uint32_t>(FlowDirection::UPLINK);
uint32_t downlinkId = static_cast<uint32_t>(FlowDirection::DOWNLINK);
mpEgressIfindexMap->update(uplinkId, udpInterfaceIndex, BPF_ANY);
mpEgressIfindexMap->update(downlinkId, gtpInterfaceIndex, BPF_ANY);
if (no_htb_root_qdisc(GTP_INTERFACE)) {
Logger::upf_app().info(
"Creating Root qdisc on interface %s", GTP_INTERFACE.c_str());
cmd = fmt::format(
"tc qdisc add dev {} root handle 1:0 htb default {}", GTP_INTERFACE,
DEFAULT_QFI);
rc = system((const char*) cmd.c_str());
if (udpInterfaceIndex == 0 || gtpInterfaceIndex == 0) {
Logger::upf_app().error("Failed to retrieve interface indices");
throw std::runtime_error("Invalid network interface index");
}
Logger::upf_app().info("Create PDU Session Class 1:%d", seid);
cmd = fmt::format(
"tc class add dev {} parent 1:0 classid 1:{} htb rate {}kbit",
GTP_INTERFACE, seid, MAX_RATE);
rc = system((const char*) cmd.c_str());
Logger::upf_app().debug("QDISC Root DL Rate (GBR) : %dkbps", MAX_RATE);
Logger::upf_app().debug("QDISC Root DL Ceil (MBR) : %dkbps", MAX_CEIL);
uint32_t uplinkId = static_cast<uint32_t>(FlowDirection::UPLINK);
uint32_t downlinkId = static_cast<uint32_t>(FlowDirection::DOWNLINK);
for (const auto& qer : pQer) {
if (qer == nullptr) {
continue;
}
uint8_t qfi = qer->qfi.second.qfi;
uint32_t qer_id = qer->qer_id.second.qer_id;
Logger::upf_app().warn(
"Set dl_rate and dl_ceil to 1kbit, for QER %d, as the minimum required "
"values to \n"
"create a tc class within the Linux kernel. These values are only used "
"if \n"
" dl_rate and dl_ceil are null within the PFCP Establishment request. "
"Of course, the \n "
"class rate and ceil are updated from the PFCP Modification request",
qer_id);
uint64_t dl_rate = 1;
uint64_t dl_ceil = 1;
uint64_t ul_rate = 1;
uint64_t ul_ceil = 1;
uint8_t dl_gate = 0;
uint8_t ul_gate = 0;
mpEgressIfindexMap->update(uplinkId, udpInterfaceIndex, BPF_ANY);
mpEgressIfindexMap->update(downlinkId, gtpInterfaceIndex, BPF_ANY);
if (qfi != DEFAULT_QFI) {
if (qer->gbr.second.dl_gbr != 0) dl_rate = qer->gbr.second.dl_gbr;
if (!pQer.empty()) {
default_qer = retrive_default_qer_with_default_qfi(pQer);
if (qer->gbr.second.ul_gbr != 0) ul_rate = qer->gbr.second.ul_gbr;
if (!default_qer) {
Logger::upf_app().error(
"QER with default QFI not found! select the first element as "
"default");
default_qer = pQer.front();
}
if (qer->mbr.second.dl_mbr != 0) dl_ceil = qer->mbr.second.dl_mbr;
// Configure Root Qdisc if not already present
if (no_htb_root_qdisc(GTP_INTERFACE)) {
Logger::upf_app().info(
"Create Root qdisc on interface %s", GTP_INTERFACE.c_str());
cmd = fmt::format(
"tc qdisc add dev {} root handle 1:0 htb default {}", GTP_INTERFACE,
static_cast<uint8_t>(default_qer->qfi.second.qfi));
// rc = system((const char*) cmd.c_str());
if (system(cmd.c_str()) != 0) {
Logger::upf_app().error("Failed to create root Qdisc");
}
}
if (qer->mbr.second.ul_mbr != 0) ul_ceil = qer->mbr.second.ul_mbr;
// Create PDU Session Class
Logger::upf_app().info("Create PDU Session Class 1:%d", seid);
cmd = fmt::format(
"tc class add dev {} parent 1:0 classid 1:{} htb rate {}kbit",
GTP_INTERFACE, seid, MAX_RATE);
dl_gate = qer->gate_status.second.dl_gate;
ul_gate = qer->gate_status.second.ul_gate;
if (system(cmd.c_str()) != 0) {
Logger::upf_app().error("Failed to create PDU Session class");
}
struct s_fiveQosFlow fiveFlow;
memset(&fiveFlow, 0, sizeof(struct s_fiveQosFlow));
fiveFlow.gate.dl_gate = dl_gate;
fiveFlow.gate.ul_gate = ul_gate;
fiveFlow.gbr.dl_gbr = dl_rate;
fiveFlow.gbr.ul_gbr = ul_rate;
fiveFlow.mbr.dl_mbr = dl_ceil;
fiveFlow.mbr.ul_mbr = ul_ceil;
fiveFlow.qfi = qfi;
getQoSFlowMap()->update(qer_id, fiveFlow, BPF_ANY);
uint16_t minor = (ntohs(seid) * 256) + (qfi * 251 % 256);
cmd = fmt::format(
"tc class add dev {} parent 1:{} classid {}:{} htb rate {}kbit ceil "
"{}kbit",
GTP_INTERFACE, seid, seid, minor, dl_rate, dl_ceil);
rc = system((const char*) cmd.c_str());
Logger::upf_app().debug(" HTB Class ID (QER) ........... %d", qer_id);
Logger::upf_app().debug(" Class QFI: %d", qfi);
Logger::upf_app().debug(" Class DL Rate: %dkbps", dl_rate);
Logger::upf_app().debug(" Class DL Ceil: %dkbps", dl_ceil);
}
Logger::upf_app().debug("QDISC Root DL Rate (GBR) : %dkbps", MAX_RATE);
Logger::upf_app().debug("QDISC Root DL Ceil (MBR) : %dkbps", MAX_CEIL);
// Process each QER
for (const auto& qer : pQer) {
if (qer == default_qer) {
continue;
}
if ((qer->gbr.first) && (qer->mbr.first)) {
uint32_t qer_id = qer->qer_id.second.qer_id;
uint8_t qfi = qer->qfi.second.qfi;
uint64_t dl_rate = qer->gbr.second.dl_gbr ? qer->gbr.second.dl_gbr : 1;
uint64_t dl_ceil = qer->mbr.second.dl_mbr ? qer->mbr.second.dl_mbr : 1;
uint8_t dl_gate = qer->gate_status.second.dl_gate;
Logger::upf_app().warn(
"Setting dl_rate and dl_ceil to minimum values (1 kbit) for QER %d "
"if GBR/MBR are null",
qer_id);
// Update QoS flow map
struct s_fiveQosFlow fiveFlow = {};
fiveFlow.gate = dl_gate;
fiveFlow.gbr = dl_rate;
fiveFlow.mbr = dl_ceil;
getQoSFlowMap()->update(qer_id, fiveFlow, BPF_ANY);
// Add tc class for QER
uint16_t minor = (ntohs(seid) * 256) + (qfi * 251 % 256);
cmd = fmt::format(
"tc class add dev {} parent 1:{} classid {}:{} htb rate {}kbit "
"ceil "
"{}kbit",
GTP_INTERFACE, seid, seid, minor, dl_rate, dl_ceil);
if (system(cmd.c_str()) != 0) {
Logger::upf_app().error("Failed to add tc class for QER {}", qer_id);
}
Logger::upf_app().debug(
" HTB Class ID (QER) ........... %d", qer_id);
Logger::upf_app().debug(" Class QFI: %d", qfi);
Logger::upf_app().debug(" Class DL Rate: %dkbps", dl_rate);
Logger::upf_app().debug(" Class DL Ceil: %dkbps", dl_ceil);
}
}
Logger::upf_app().info("Attach Section tc_filter_traffic to gtp interface");
mpLifeCycle->tcAttachEgress("tc_filter_traffic", GTP_INTERFACE.c_str());
Logger::upf_app().info("Attach Section tc_filter_traffic to gtp interface");
mpLifeCycle->tcAttachEgress("tc_filter_traffic", GTP_INTERFACE.c_str());
Logger::upf_app().info("Attach Sesction tc_redirect to udp interface");
mpLifeCycle->tcAttachIngress("tc_redirect_traffic", UDP_INTERFACE.c_str());
Logger::upf_app().info("Attach Sesction tc_redirect to udp interface");
mpLifeCycle->tcAttachIngress("tc_redirect_traffic", UDP_INTERFACE.c_str());
}
}
// change:
......
......@@ -109,6 +109,10 @@ class QERProgram : public BPFProgram {
// int add_clsact_qdisc(int ifindex, enum bpf_tc_attach_point attach_point);
bool no_htb_root_qdisc(std::string interface);
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<pfcp::pfcp_qer> retrive_default_qer_with_default_qfi(
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer);
/*---------------------------------------------------------------------------------------------------------------*/
private:
/**
......
......@@ -419,6 +419,7 @@ pfcp_switch::pfcp_switch()
ul_n3_teid2pfcp_pdr(PFCP_SWITCH_MAX_PDRS),
up_seid2pfcp_sessions(PFCP_SWITCH_MAX_SESSIONS),
sock_w(0) {
bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
num_threads_ = upf_cfg.n6.thread_rd_sched_params.thread_pool_size;
int num_blocks = num_threads_ * 16;
free_pool_ = new folly::MPMCQueue<iovec_q_item_t*>(num_blocks);
......@@ -440,7 +441,7 @@ pfcp_switch::pfcp_switch()
v->msg.msg_controllen = 0;
free_pool_->blockingWrite(v);
}
if (!upf_cfg.enable_bpf_datapath) {
if (!isBpfAccelerationEnabled) {
// num_threads_ is currently fixed to 1
for (int i = 0; i < num_threads_; i++) {
pwThread_ = std::thread(
......@@ -689,6 +690,9 @@ void pfcp_switch::call_datapath(
void pfcp_switch::handle_pfcp_session_establishment_request(
std::shared_ptr<itti_n4_session_establishment_request> sreq,
itti_n4_session_establishment_response* resp) {
bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
bool isQosEnabled = isBpfAccelerationEnabled && upf_cfg.enable_qos;
itti_n4_session_establishment_request* req = sreq.get();
pfcp::fseid_t fseid = {};
pfcp::cause_t cause = {.cause_value = CAUSE_VALUE_REQUEST_ACCEPTED};
......@@ -737,11 +741,11 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
break;
}
/*======================================================================*/
/*======================================================================*/
/*
* Add create_qers
*/
if (upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos) {
if (isQosEnabled) {
pfcp::qer_id_t qer_id = {};
if (cr_pdr.get(qer_id)) {
pfcp::create_qer cr_qer = {};
......@@ -759,9 +763,9 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
session->create(cr_qer, cause, offending_ie.offending_ie);
}
}
}
/*======================================================================*/
if (not session->create(
cr_pdr, cause, offending_ie.offending_ie, allocated_fteid)) {
session->cleanup();
......@@ -779,7 +783,7 @@ void pfcp_switch::handle_pfcp_session_establishment_request(
}
}
if (upf_cfg.enable_bpf_datapath) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info(
"Establishing datapath: create PDRs + create FARs + create QERs "
"(if any)");
......@@ -860,6 +864,9 @@ 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,
itti_n4_session_modification_response* resp) {
bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
bool isQosEnabled = isBpfAccelerationEnabled && upf_cfg.enable_qos;
itti_n4_session_modification_request* req = sreq.get();
std::shared_ptr<pfcp::pfcp_session> s = {};
......@@ -882,7 +889,7 @@ 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) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info("Modifying datapath: remove PDRs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
......@@ -904,7 +911,7 @@ 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) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info("Modifying datapath: remove FARs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
......@@ -929,15 +936,13 @@ void pfcp_switch::handle_pfcp_session_modification_request(
/*
* Add remove_qers
*/
if (upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos) {
if (isQosEnabled) {
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
for (auto it : req->pfcp_ies.remove_qers) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: remove QERs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
Logger::pfcp_switch().info("Modifying datapath: remove QERs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
remove_qer& qer = it;
......@@ -957,7 +962,7 @@ 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) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info("Modifying datapath: create FARs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
......@@ -1007,7 +1012,7 @@ void pfcp_switch::handle_pfcp_session_modification_request(
resp->pfcp_ies.set(created_pdr);
}
if (upf_cfg.enable_bpf_datapath) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info(
"Modifying datapath: create PDRs + create FARs");
call_datapath(
......@@ -1021,15 +1026,13 @@ void pfcp_switch::handle_pfcp_session_modification_request(
/*
* Add create_qers
*/
if (upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos) {
if (isQosEnabled) {
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
for (auto it : req->pfcp_ies.create_qers) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: create QERs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
Logger::pfcp_switch().info("Modifying datapath: create QERs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
create_qer& cr_qer = it;
if (not session->create(cr_qer, cause, offending_ie.offending_ie)) {
break;
......@@ -1041,7 +1044,7 @@ void pfcp_switch::handle_pfcp_session_modification_request(
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
for (auto it : req->pfcp_ies.update_pdrs) {
if (upf_cfg.enable_bpf_datapath) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info("Modifying datapath: update PDRs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
......@@ -1059,7 +1062,7 @@ void pfcp_switch::handle_pfcp_session_modification_request(
}
for (auto it : req->pfcp_ies.update_fars) {
if (upf_cfg.enable_bpf_datapath) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info("Modifying datapath: update FARs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
......@@ -1082,14 +1085,12 @@ void pfcp_switch::handle_pfcp_session_modification_request(
/*
* Add update_qers
*/
if (upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos) {
if (isQosEnabled) {
for (auto it : req->pfcp_ies.update_qers) {
if (upf_cfg.enable_bpf_datapath) {
Logger::pfcp_switch().info("Modifying datapath: update QERs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
}
Logger::pfcp_switch().info("Modifying datapath: update QERs");
call_datapath(
NULL, req, NULL, session, spSessionManager,
&SessionManager::updateBPFSession);
update_qer& qer = it;
uint8_t cause_value = CAUSE_VALUE_REQUEST_ACCEPTED;
......@@ -1151,6 +1152,8 @@ void pfcp_switch::handle_pfcp_session_modification_request(
void pfcp_switch::handle_pfcp_session_deletion_request(
std::shared_ptr<itti_n4_session_deletion_request> sreq,
itti_n4_session_deletion_response* resp) {
bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
itti_n4_session_deletion_request* req = sreq.get();
std::shared_ptr<pfcp::pfcp_session> s = {};
......@@ -1165,7 +1168,7 @@ void pfcp_switch::handle_pfcp_session_deletion_request(
pfcp::pfcp_session* session = s.get();
resp->seid = s->cp_fseid.seid;
if (upf_cfg.enable_bpf_datapath) {
if (isBpfAccelerationEnabled) {
Logger::pfcp_switch().info(
"Deleting datapath: delete PDRs + delete FARs");
call_datapath(
......
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