Commit d79feb3e authored by Franck Messaoudi's avatar Franck Messaoudi

Init: initiating hte changes

parent 21c74b9b
This diff is collapsed.
This diff is collapsed.
......@@ -14,7 +14,7 @@
class BPFMap;
class OnStateChangeSessionProgramObserver;
class PFCP_Session_LookupProgram;
class PFCP_Session_PDR_LookupProgram;
// class PFCP_Session_PDR_LookupProgram;
class SessionPrograms;
class FARProgram;
......@@ -94,13 +94,13 @@ class SessionProgramManager {
* @return std::shared_ptr<PFCP_Session_PDR_LookupProgram> The program, which
* represents the session.
*/
std::shared_ptr<PFCP_Session_PDR_LookupProgram> findSessionProgram(
uint64_t seid);
// std::shared_ptr<PFCP_Session_PDR_LookupProgram> findSessionProgram(
// uint64_t seid);
/*---------------------------------------------------------------------------------------------------------------*/
void updateArpTableMap(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram, uint32_t upfIP,
uint32_t remoteIP);
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t upfIP, uint32_t remoteIP);
/*---------------------------------------------------------------------------------------------------------------*/
uint32_t getRemoteIP(uint32_t upfIP, uint32_t remoteIP);
......@@ -120,32 +120,35 @@ class SessionProgramManager {
next_rule_prog_index_key& key, uint32_t teid, uint32_t ueIpAddress,
uint8_t sourceInterface);
void addPFCPProgram(
uint64_t seid, std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram);
void addPFCPProgram(
uint64_t seid,
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram);
/*---------------------------------------------------------------------------------------------------------------*/
void storeFarProgramIndexInNextProgRuleIndexMap(
std::shared_ptr<pfcp::pfcp_far> pFar,
const next_rule_prog_index_key& key,
std::shared_ptr<pfcp::pfcp_far> pFar, const next_rule_prog_index_key& key,
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram);
/*---------------------------------------------------------------------------------------------------------------*/
void storeSessionMappingMap(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t ue_ip_address, uint32_t teid_dl);
uint32_t ue_ip_address, uint32_t teid_dl, uint32_t teid_ul,
uint32_t seid);
/*---------------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------------*/
void saveSeidWithinFARProgram(
uint64_t seid, std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint64_t seid,
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
const next_rule_prog_index_key& key);
/*---------------------------------------------------------------------------------------------------------------*/
void updateARPTableForN6(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram, uint32_t dnIP, uint32_t upfn6IP);
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t dnIP, uint32_t upfn6IP);
/*---------------------------------------------------------------------------------------------------------------*/
void updateARPTableForN3(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram, uint32_t gNodeBIP,
uint32_t upfn3IP, uint32_t seid);
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t gNodeBIP, uint32_t upfn3IP, uint32_t seid);
/*---------------------------------------------------------------------------------------------------------------*/
uint32_t getGnodebIp(std::shared_ptr<pfcp::pfcp_far> pFar);
......@@ -158,7 +161,7 @@ void addPFCPProgram(
void removePipeline(uint64_t seid);
std::shared_ptr<SessionPrograms> findSessionPrograms(uint64_t seid);
std::shared_ptr<std::vector<struct pfcpprograms>> pfcpPrograms;
std::shared_ptr<std::vector<struct pfcpprograms>> pfcpPrograms;
private:
/**
......@@ -179,8 +182,8 @@ void addPFCPProgram(
OnStateChangeSessionProgramObserver* mpOnNewSessionProgramObserver;
// The Maps to store the instance of the programs.
std::map<uint32_t, std::shared_ptr<PFCP_Session_PDR_LookupProgram>>
mSessionProgramMap;
// std::map<uint32_t, std::shared_ptr<PFCP_Session_PDR_LookupProgram>>
// mSessionProgramMap;
// The Maps to store the PFCP session deployed in datapath.
std::map<uint32_t, std::shared_ptr<SessionPrograms>> mSessionProgramsMap;
......
#include "SessionPrograms.h"
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
SessionPrograms::SessionPrograms(
struct next_rule_prog_index_key key,
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram)
: mKey(key), mpPFCP_Session_LookupProgram(pPFCP_Session_LookupProgram) {}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
SessionPrograms::~SessionPrograms() {
mpPFCP_Session_LookupProgram->tearDown();
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
struct next_rule_prog_index_key SessionPrograms::getKey() const {
return mKey;
}
/**************************************************************************************************/
std::shared_ptr<PFCP_Session_LookupProgram> SessionPrograms::getPFCPProgram() const {
//---------------------------------------------------------------------------------------------------------------
std::shared_ptr<PFCP_Session_LookupProgram> SessionPrograms::getPFCPProgram()
const {
return mpPFCP_Session_LookupProgram;
}
/**************************************************************************************************/
#include "SignalHandler.h"
#include <UserPlaneComponent.h>
//---------------------------------------------------------------------------------------------------------------
void my_app_signal_handler(int s);
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
SignalHandler& SignalHandler::getInstance() {
static SignalHandler sInstance;
return sInstance;
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
SignalHandler::~SignalHandler() {}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
void SignalHandler::enable() {
signal(SIGINT, SignalHandler::tearDown);
signal(SIGTERM, SignalHandler::tearDown);
signal(SIGSEGV, SignalHandler::tearDown);
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
void SignalHandler::tearDown(int signal) {
UserPlaneComponent::getInstance().tearDown();
// calling the other tear down routine
my_app_signal_handler(signal);
exit(0);
}
/**************************************************************************************************/
#include "UserPlaneComponent.h"
//#include <RulesUtilities.h>
#include <SessionManager.h>
#include <pfcp_session_pdr_lookup_xdp_user.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>
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
UserPlaneComponent::UserPlaneComponent() {
// Set new handlers for libbpf.
#ifdef DEBUG_LIBBPF
......@@ -16,56 +15,56 @@ UserPlaneComponent::UserPlaneComponent() {
#endif
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
UserPlaneComponent::~UserPlaneComponent() {
tearDown();
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
std::shared_ptr<SessionManager> UserPlaneComponent::getSessionManager() const {
return mpSessionManager;
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
std::shared_ptr<PFCP_Session_LookupProgram>
UserPlaneComponent::getPFCP_Session_LookupProgram() const {
return mpPFCP_Session_LookupProgram;
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
std::string UserPlaneComponent::getGTPInterface() const {
return mGTPInterface;
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
std::string UserPlaneComponent::getUDPInterface() const {
return mUDPInterface;
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::onNewSessionProgram(
u_int32_t programId, u_int32_t fileDescriptor) {
mpPFCP_Session_LookupProgram->updateProgramMap(programId, fileDescriptor);
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::onDestroySessionProgram(u_int32_t programId) {
mpPFCP_Session_LookupProgram->removeProgramMap(programId);
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
int UserPlaneComponent::printLibbpfLog(
enum libbpf_print_level lvl, const char* fmt, va_list args) {
return vfprintf(stderr, fmt, args);
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
UserPlaneComponent& UserPlaneComponent::getInstance() {
static UserPlaneComponent sInstance;
return sInstance;
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::setMembers(
const std::string& gtpInterface, const std::string& udpInterface) {
mGTPInterface = gtpInterface;
......@@ -80,7 +79,7 @@ void UserPlaneComponent::setMembers(
}
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::setup(
const std::string& gtpInterface, const std::string& udpInterface) {
setMembers(gtpInterface, udpInterface);
......@@ -91,7 +90,7 @@ void UserPlaneComponent::setup(
mpSessionManager = std::make_shared<SessionManager>();
}
/*---------------------------------------------------------------------------------------------------------------*/
//---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::tearDown() {
mpPFCP_Session_LookupProgram->tearDown();
SessionProgramManager::getInstance().removeAll();
......
......@@ -6,16 +6,13 @@ include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/include)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/pdr)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/far)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/qer)
#include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/urr)
#include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/bar)
#include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/mar)
include_directories(${SRC_TOP_DIR}/upf_app/include)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
add_definitions(-DKERNEL_SPACE)
add_custom_target(upf_xdp_all DEPENDS pfcp_session_lookup_xdp pfcp_session_pdr_lookup_xdp far_xdp)
add_custom_target(upf_xdp_all DEPENDS pfcp_session_lookup_xdp far_xdp)
add_custom_target(upf_tc_all DEPENDS qer_tc)
......@@ -24,7 +21,7 @@ add_custom_target(upf_tc_all DEPENDS qer_tc)
# GENERATE eBPF XDP Skeletons #
###########################################################################
function(xdp arg)
if (${arg} STREQUAL "pfcp_session_lookup" OR ${arg} STREQUAL "pfcp_session_pdr_lookup")
if (${arg} STREQUAL "pfcp_session_lookup")
set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/rules/pdr")
elseif (${arg} STREQUAL "far")
set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/rules/far")
......@@ -44,7 +41,6 @@ function(xdp arg)
endfunction()
xdp(pfcp_session_lookup)
xdp(pfcp_session_pdr_lookup)
xdp(far)
......
......@@ -5,8 +5,8 @@
#include <pfcp/pfcp_pdr.h>
#include <pfcp/pfcp_far.h>
#define SESSION_PDRS_MAX_SIZE 5000 // 10
#define SESSION_FARS_MAX_SIZE 5000 // 10
#define SESSION_PDRS_MAX_SIZE 10000 // 10
#define SESSION_FARS_MAX_SIZE 10000 // 10
typedef struct pfcp_session_s {
seid_t_ seid;
......
......@@ -7,10 +7,10 @@
#include <types.h>
#include "arp_table_maps.h"
#define ARP_ENTRIES_MAX_SIZE 12
#define FAR_TAILS_MAX 1
#define ARP_ENTRIES_MAX_SIZE 10000
#define FAR_TAILS_MAX 10
#define MAX_INTERFACES 10
#define MAX_FAR_PROGRAMS 100
#define MAX_FAR_PROGRAMS 10000
/*---------------------------------------------------------------------------------------------------------------*/
struct {
......
......@@ -13,7 +13,7 @@
#include "interfaces.h"
#include "session_id.h"
#define MAX_LENGTH 5000 // 10
#define MAX_LENGTH 10000 // 10
#define INTERFACE_ENTRIES_MAX 12
#define MAX_UEs 100000
......
......@@ -5,7 +5,7 @@
#include <linux/bpf.h>
#include <types.h>
#define MAX_LENGTH 5000 // 10
#define MAX_LENGTH 10000 // 10
/*
* +------------------------------------------------------+
......
#define KBUILD_MODNAME pfcp_session_lookup_xdp_kernel
// clang-format off
#include <types.h>
// clang-format on
#include <bpf_helpers.h>
#include <bpf_endian.h>
#include <endian.h>
#include <lib/crc16.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <protocols/eth.h>
#include <protocols/gtpu.h>
#include <protocols/ip.h>
#include <protocols/udp.h>
#include <linux/icmp.h>
#include <linux/tcp.h>
#include <pfcp_session_lookup_maps.h>
#include <utils/logger.h>
#include <utils/utils.h>
#include <next_prog_rule_key.h>
#ifdef KERNEL_SPACE
#include <linux/in.h>
#else
#include <netinet/in.h>
#endif
#include <stdio.h>
/* Defines xdp_stats_map */
#include "xdp_stats_kern.h"
#include "xdp_stats_kern_user.h"
struct vlan_hdr {
__be16 h_vlan_TCI;
__be16 h_vlan_encapsulated_proto;
};
/*****************************************************************************************************************/
static __always_inline u32 tail_call_next_prog(
struct xdp_md* ctx, teid_t_ teid, u8 source_value, u32 ipv4_address) {
struct next_rule_prog_index_key map_key;
__builtin_memset(&map_key, 0, sizeof(struct next_rule_prog_index_key));
map_key.teid = teid;
map_key.source_value = source_value;
map_key.ipv4_address = ipv4_address;
u32* index_prog = bpf_map_lookup_elem(&m_next_rule_prog_index, &map_key);
if (index_prog) {
bpf_debug("Value of the eBPF tail call, index_prog = %d", *index_prog);
bpf_tail_call(ctx, &m_next_rule_prog, *index_prog);
}
bpf_debug("BPF tail call was not executed!");
bpf_debug("Check your key and its endianess");
return XDP_DROP;
}
/*---------------------------------------------------------------------------------------------------------------*/
static __always_inline u32
handle_downlink_traffic(struct xdp_md* ctx, u32 ue_ip_address) {
u32* teid_dl = bpf_map_lookup_elem(&m_session_mapping, &ue_ip_address);
if (teid_dl) {
bpf_debug(
"TEID downlink: 0x%x was found for UE IP: 0x%x", ue_ip_address,
*teid_dl);
tail_call_next_prog(ctx, *teid_dl, INTERFACE_VALUE_CORE, ue_ip_address);
}
bpf_debug("BPF tail call was not executed!");
return XDP_PASS;
}
/*---------------------------------------------------------------------------------------------------------------*/
/**
* Uplink SECTION.
*/
/**
* @brief Handle UDP header.
*
* @param ctx The user accessible metadata for xdp packet hook.
* @param udph The UDP header.
* @return u32 The XDP action.
*/
static __always_inline u32
handle_uplink_traffic(struct xdp_md* ctx, struct udphdr* udph) {
void* data = (void*) (long) ctx->data;
void* data_end = (void*) (long) ctx->data_end;
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");
return XDP_DROP;
}
struct ethhdr* ethh_new = data + GTP_ENCAPSULATED_SIZE;
if ((void*) ethh_new + sizeof(*ethh_new) > data_end) {
bpf_debug("Invalid 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");
return XDP_DROP;
}
u32 src_ip_in = 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;
}
// Jump to session context.
tail_call_next_prog(ctx, gtpuh->teid, INTERFACE_VALUE_ACCESS, src_ip_in);
return XDP_PASS;
}
/*---------------------------------------------------------------------------------------------------------------*/
/**
* IP SECTION.
*/
/**
* @brief Handle IPv4 header.
*
* @param ctx The user accessible metadata for xdp packet hook.
* @param iph The IP header.
* @return u32 The XDP action.
*/
static __always_inline u32 ipv4_handle(struct xdp_md* ctx, struct iphdr* iph) {
void* data_end = (void*) (long) ctx->data_end;
u32 ip_dest = iph->daddr;
u8 protocol = iph->protocol;
switch (protocol) {
case IPPROTO_UDP: {
struct udphdr* udph = (struct udphdr*) (iph + 1);
// Check if the UDP header extends beyond the data end.
if ((void*) (udph + 1) > data_end) {
bpf_debug("Invalid UDP packet");
return XDP_DROP;
}
if (bpf_htons(udph->dest) == GTP_UDP_PORT) {
bpf_debug("This is a GTP traffic");
return handle_uplink_traffic(ctx, udph);
}
}
default: {
return handle_downlink_traffic(ctx, ip_dest);
}
}
}
/*---------------------------------------------------------------------------------------------------------------*/
/**
* ETHERNET SECTION.
*/
/**
*
* @brief Parse Ethernet layer 2, extract network layer 3 offset and protocol
* Call next protocol handler (e.g. ipv4).
*
* @param ctx
* @param ethh
* @return u32 The XDP action.
*/
static __always_inline u32 eth_handle(struct xdp_md* ctx, struct ethhdr* ethh) {
void* data_end = (void*) (long) ctx->data_end;
u16 eth_type = bpf_htons(ethh->h_proto);
u64 offset = sizeof(*ethh);
bpf_debug("Debug: eth_type:0x%x", eth_type);
switch (eth_type) {
case ETH_P_IP: {
struct iphdr* iph = (struct iphdr*) ((void*) ethh + offset);
if ((void*) (iph + 1) > data_end) {
bpf_debug("Invalid IPv4 Packet");
return XDP_DROP;
}
return ipv4_handle(ctx, iph);
}
case ETH_P_8021AD: {
bpf_debug("VLAN!! Changing the offset");
struct vlan_hdr* vlan_hdr = (struct vlan_hdr*) (ethh + 1);
offset += sizeof(*vlan_hdr);
if ((void*) (vlan_hdr + 1) <= data_end)
eth_type = bpf_htons(vlan_hdr->h_vlan_encapsulated_proto);
}
case ETH_P_IPV6:
case ETH_P_ARP:
case ETH_P_8021Q:
default: {
bpf_debug("Cannot parse L2: L3off:%llu proto:0x%x", offset, eth_type);
return XDP_PASS;
}
}
}
/*---------------------------------------------------------------------------------------------------------------*/
SEC("xdp")
int xdp_handle_uplink(struct xdp_md* ctx) {
bpf_debug("================< PFCP PDR Sesction >================");
struct ethhdr* ethh = (void*) (long) ctx->data;
if ((void*) (ethh + 1) > (void*) (long) ctx->data_end) {
bpf_debug("Invalid Ethernet header");
return XDP_DROP;
}
return eth_handle(ctx, ethh);
}
/*---------------------------------------------------------------------------------------------------------------*/
SEC("xdp")
int xdp_handle_downlink(struct xdp_md* ctx) {
bpf_debug("================< PFCP PDR Sesction >================");
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");
return XDP_DROP;
}
struct iphdr* iph = (struct iphdr*) ((void*) ethh + offset);
if ((void*) (iph + 1) > data_end) {
bpf_debug("Invalid IPv4 Packet");
return XDP_DROP;
}
u32 ip_dest = iph->daddr;
u32* teid_dl = bpf_map_lookup_elem(&m_session_mapping, &ip_dest);
if (teid_dl) {
bpf_debug(
"TEID downlink: 0x%x was found for UE IP: 0x%x", ip_dest, *teid_dl);
tail_call_next_prog(ctx, *teid_dl, INTERFACE_VALUE_CORE, ip_dest);
}
bpf_debug("BPF tail call was not executed!");
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
/*---------------------------------------------------------------------------------------------------------------*/
\ No newline at end of file
......@@ -7,9 +7,9 @@
#include "filter_key.h"
#include "qos_flow.h"
#define QFI_MAX_ENTRIES 5000
#define FIVE_QI_MAX_ENTRIES 100
#define QOS_FLOWS_MAX_ENTRIES 100
#define QFI_MAX_ENTRIES 10000
#define FIVE_QI_MAX_ENTRIES 10000
#define QOS_FLOWS_MAX_ENTRIES 10000
#define MAX_INTERFACES 10
/*---------------------------------------------------------------------------------------------------------------*/
......
#include "pfcp_session_lookup_xdp_user.h"
#include <SessionManager.h>
#include <bpf/bpf.h> // bpf calls
#include <bpf/libbpf.h> // bpf wrappers
#include <iostream> // cout
#include <stdexcept> // exception
#include <wrappers/BPFMap.hpp>
#include <wrappers/BPFMaps.h>
#include "interfaces.h"
#include "logger.hpp"
/*---------------------------------------------------------------------------------------------------------------*/
int is_little_endian2() {
u32 value = 1;
u8* byte = (u8*) &value;
return (*byte == 1);
}
/*---------------------------------------------------------------------------------------------------------------*/
PFCP_Session_LookupProgram::PFCP_Session_LookupProgram(
const std::string& gtpInterface, const std::string& udpInterface)
: mGTPInterface(gtpInterface), mUDPInterface(udpInterface) {
mpLifeCycle = std::make_shared<PFCP_Session_LookupProgramLifeCycle>(
pfcp_session_lookup_xdp_kernel_c__open,
pfcp_session_lookup_xdp_kernel_c__load,
pfcp_session_lookup_xdp_kernel_c__attach,
pfcp_session_lookup_xdp_kernel_c__destroy);
}
/*---------------------------------------------------------------------------------------------------------------*/
PFCP_Session_LookupProgram::~PFCP_Session_LookupProgram() {}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::setup() {
spSkeleton = mpLifeCycle->open();
initializeMaps();
mpLifeCycle->load();
mpLifeCycle->attach();
// Entry point interface
if (mUDPInterface.empty() || mGTPInterface.empty()) {
Logger::upf_app().error("GTP or UDP interface not defined!");
throw std::runtime_error("GTP or UDP interface not defined!");
}
Logger::upf_app().debug(
"Link UDP interface to interface %s", mUDPInterface.c_str());
mpLifeCycle->link("xdp_handle_downlink", mUDPInterface.c_str());
Logger::upf_app().debug(
"Link GTP interface to interface %s", mGTPInterface.c_str());
mpLifeCycle->link("xdp_handle_uplink", mGTPInterface.c_str());
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMaps> PFCP_Session_LookupProgram::getMaps() {
return mpMaps;
}
/*---------------------------------------------------------------------------------------------------------------*/
// TODO: Check when kill when running.
// It was noted the infinity loop.
void PFCP_Session_LookupProgram::tearDown() {
mpLifeCycle->tearDown();
}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::updateProgramMap(uint32_t key, uint32_t fd) {
mpTeidSessionMap->update(key, fd, BPF_ANY);
}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::removeProgramMap(uint32_t key) {
s32 fd;
// Remove only if exists.
if (mpTeidSessionMap->lookup(key, &fd) == 0) {
mpTeidSessionMap->remove(key);
}
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getTeidSessionMap() const {
return mpTeidSessionMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getUeIpSessionMap() const {
return mpUeIpSessionMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getNextProgRuleMap() const {
return mpNextProgRuleMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getNextProgRuleIndexMap()
const {
return mpNextProgRuleIndexMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getSessionMappingMap()
const {
return mpSessionMappingMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::initializeMaps() {
// Store all maps available in the program.
mpMaps = std::make_shared<BPFMaps>(mpLifeCycle->getBPFSkeleton()->skeleton);
// Warning - The name of the map must be the same of the BPF program.
mpTeidSessionMap = std::make_shared<BPFMap>(mpMaps->getMap("m_teid_session"));
mpUeIpSessionMap = std::make_shared<BPFMap>(mpMaps->getMap("m_ueip_session"));
mpNextProgRuleMap =
std::make_shared<BPFMap>(mpMaps->getMap("m_next_rule_prog"));
mpNextProgRuleIndexMap =
std::make_shared<BPFMap>(mpMaps->getMap("m_next_rule_prog_index"));
mpSessionMappingMap =
std::make_shared<BPFMap>(mpMaps->getMap("m_session_mapping"));
}
/*---------------------------------------------------------------------------------------------------------------*/
#ifndef __PFCP_SESSION_LOOKUP_XDP_USER_H__
#define __PFCP_SESSION_LOOKUP_XDP_USER_H__
#include <ProgramLifeCycle.hpp>
#include <atomic>
#include <linux/bpf.h> // manage maps (e.g. bpf_update*)
#include <memory>
#include <mutex>
#include <signal.h> // signals
#include <pfcp_session_lookup_xdp_kernel_skel.h>
#include <wrappers/BPFMap.hpp>
// #include "qfi_flow_mapping_table.h"
class BPFMaps;
class BPFMap;
class SessionManager;
class RulesUtilities;
using PFCP_Session_LookupProgramLifeCycle =
ProgramLifeCycle<pfcp_session_lookup_xdp_kernel_c>;
/**
* @brief Singleton class to abrastract the UPF bpf program.
*/
class PFCP_Session_LookupProgram {
public:
/**
* @brief Construct a new PFCP_Session_LookupProgram object.
*
*/
explicit PFCP_Session_LookupProgram(
const std::string& gtpInterface, const std::string& udpInterface);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Destroy the PFCP_Session_LookupProgram object
*/
virtual ~PFCP_Session_LookupProgram();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Setup the BPF program.
*
*/
void setup();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the BPFMaps object.
*
* @return std::shared_ptr<BPFMaps> The reference of the BPFMaps.
*/
std::shared_ptr<BPFMaps> getMaps();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Tear downs the BPF program.
*
*/
void tearDown();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Update program int map.
*
* @param key The key which will be inserted the program file descriptor.
* @param fd The file descriptor.
*/
void updateProgramMap(uint32_t key, uint32_t fd);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Remove program in map.
*
* @param key The key which will be remove in the program map.
*/
void removeProgramMap(uint32_t key);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the TEID to session Map object.
*
* @return std::shared_ptr<BPFMap> The TEID to fd map.
*/
std::shared_ptr<BPFMap> getTeidSessionMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the UE IP to session Map object.
*
* @return std::shared_ptr<BPFMap> The UE IP to fd map.
*/
std::shared_ptr<BPFMap> getUeIpSessionMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the NextProgRule Map object.
*
* @return std::shared_ptr<BPFMap> The NextProgRule to fd map.
*/
std::shared_ptr<BPFMap> getNextProgRuleMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the NextProgRuleIndex Map object.
*
* @return std::shared_ptr<BPFMap> The pdi to index map.
*/
std::shared_ptr<BPFMap> getNextProgRuleIndexMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Traffic Map object.
*
* @return std::shared_ptr<BPFMap> The TEID.
*/
std::shared_ptr<BPFMap> getTrafficMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Session Mapping Map object.
*
* @return std::shared_ptr<BPFMap> mpSessionMappingMap;
*/
std::shared_ptr<BPFMap> getSessionMappingMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the UE QFI TEID Map object.
*
* @return std::shared_ptr<BPFMap> mpUeQfiTeidMap;
*/
std::shared_ptr<BPFMap> getUeQfiTeidMap() const;
/**
* @brief Get theQoS Flow Map object.
*
* @return std::shared_ptr<BPFMap> mpQosFlowMap;
*/
std::shared_ptr<BPFMap> getQosFlowMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
private:
/**
* @brief Initialize BPF wrappers maps.
*
*/
void initializeMaps();
// void instrementQfiFlowMappingTable(
// e_resource_type type, uint32_t qos, uint8_t qfi, uint8_t dscp);
/*---------------------------------------------------------------------------------------------------------------*/
// The reference of the bpf maps.
std::shared_ptr<BPFMaps> mpMaps;
/*---------------------------------------------------------------------------------------------------------------*/
// The skeleton of the UPF program generated by bpftool.
// ProgramLifeCycle is the owner of the pointer.
pfcp_session_lookup_xdp_kernel_c* spSkeleton;
/*---------------------------------------------------------------------------------------------------------------*/
// The program eBPF map.
std::shared_ptr<BPFMap> mpTeidSessionMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The program eBPF map.
std::shared_ptr<BPFMap> mpUeIpSessionMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The pdi key to program index map.
std::shared_ptr<BPFMap> mpNextProgRuleIndexMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The next prog rule map.
std::shared_ptr<BPFMap> mpNextProgRuleMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The traffic map.
// std::shared_ptr<BPFMap> mpTrafficMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The session mapping map.
std::shared_ptr<BPFMap> mpSessionMappingMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The UE-QFI-TEID map.
// std::shared_ptr<BPFMap> mpUeQfiTeidMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The QOS Flow map.
// std::shared_ptr<BPFMap> mpQosFlowMap;
/*---------------------------------------------------------------------------------------------------------------*/
// The BPF lifecycle program.
std::shared_ptr<PFCP_Session_LookupProgramLifeCycle> mpLifeCycle;
/*---------------------------------------------------------------------------------------------------------------*/
// The GTP interface.
std::string mGTPInterface;
/*---------------------------------------------------------------------------------------------------------------*/
// The UDP interface.
std::string mUDPInterface;
/*---------------------------------------------------------------------------------------------------------------*/
};
#endif // __PFCP_SESSION_LOOKUP_XDP_USER_H__
......@@ -31,7 +31,8 @@ PFCP_Session_LookupProgram::PFCP_Session_LookupProgram(
}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::create_upf_interface_map_entry(e_reference_point s) {
void PFCP_Session_LookupProgram::create_upf_interface_map_entry(
e_reference_point s) {
struct s_interface iface;
__builtin_memset(&iface, 0, sizeof(s_interface));
......@@ -78,7 +79,6 @@ void PFCP_Session_LookupProgram::setup() {
mpLifeCycle->load();
mpLifeCycle->attach();
Logger::upf_app().debug("Configure redirect interface");
auto udpInterface = UserPlaneComponent::getInstance().getUDPInterface();
auto gtpInterface = UserPlaneComponent::getInstance().getGTPInterface();
......@@ -90,13 +90,12 @@ 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:");
create_upf_interface_map_entry(N3_INTERFACE);
create_upf_interface_map_entry(N6_INTERFACE);
create_upf_interface_map_entry(N4_INTERFACE);
// Entry point interface
if (mUDPInterface.empty() || mGTPInterface.empty()) {
Logger::upf_app().error("GTP or UDP interface not defined!");
......@@ -104,7 +103,7 @@ void PFCP_Session_LookupProgram::setup() {
}
Logger::upf_app().debug(
"Link UDP interface to interface %s", mUDPInterface.c_str());
"Link Non-GTP interface to interface %s", mUDPInterface.c_str());
mpLifeCycle->link("xdp_handle_downlink", mUDPInterface.c_str());
Logger::upf_app().debug(
......@@ -166,7 +165,8 @@ std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getSessionMappingMap()
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getEgressInterfaceMap() const {
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getEgressInterfaceMap()
const {
return mpEgressInterfaceMap;
}
......
#ifndef __PFCP_SESSION_PDR_LOOKUP_XDP_USER_H__
#define __PFCP_SESSION_PDR_LOOKUP_XDP_USER_H__
#include <memory>
#include <map>
#include <pfcp_session_pdr_lookup_xdp_kernel_skel.h>
#include <ProgramLifeCycle.hpp>
using PFCP_Session_PDR_LookupProgramLifeCycle =
ProgramLifeCycle<pfcp_session_pdr_lookup_xdp_kernel_c>;
class BPFMaps;
class BPFMap;
/**
* @brief This class is used to interface with BPF program (Session).
*
*/
class PFCP_Session_PDR_LookupProgram {
public:
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Construct a new Session Program object.
*
*/
PFCP_Session_PDR_LookupProgram(
const std::string& gtpInterface, const std::string& udpInterface);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Destroy the Session Program object.
*
*/
virtual ~PFCP_Session_PDR_LookupProgram();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Setup the program.
*
*/
void setup();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Tear down the program.
*
*/
void tearDown();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Downlink File Descriptor (entry point) object.
*
* @return int The file descriptor of the entry point program.
*/
int getUplinkFileDescriptor() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Uplink File Descriptor (entry point) object.
*
* @return int The file descriptor of the entry point program.
*/
int getDownlinkFileDescriptor() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get PDR maps reference.
*
* @return std::shared_ptr<BPFMap> The PDR map reference.
*/
std::shared_ptr<BPFMap> getPDRMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the FAR Map object.
*
* @return std::shared_ptr<BPFMap> The FAR map.
*/
std::shared_ptr<BPFMap> getFARMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Uplink PDRs Map object.
*
* @return std::shared_ptr<BPFMap> The uplink to PDR map.
*/
std::shared_ptr<BPFMap> getUplinkPDRsMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Downlink PDRs Map object.
*
* @return std::shared_ptr<BPFMap> The uplink to PDR map.
*/
std::shared_ptr<BPFMap> getDownlinkPDRsMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Counter Map object.
*
* @return std::shared_ptr<BPFMap> The counter map.
*/
std::shared_ptr<BPFMap> getCounterMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Egress Interface Map object.
*
* @return std::shared_ptr<BPFMap> The egress interface map.
*/
std::shared_ptr<BPFMap> getEgressInterfaceMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Arp Table Map object.
*
* @return std::shared_ptr<BPFMap> The arp table map.
*/
std::shared_ptr<BPFMap> getArpTableMap() const;
/*---------------------------------------------------------------------------------------------------------------*/
private:
/**
* @brief Initialize BPF maps wrappers references.
*
*/
void initializeMaps();
// The reference of the bpf maps.
std::shared_ptr<BPFMaps> mpMaps;
// The PDR map reference.
std::shared_ptr<BPFMap> mpPDRMap;
// The PDR map reference.
std::shared_ptr<BPFMap> mpFARMap;
// The uplink PDR eBPF map.
std::shared_ptr<BPFMap> mpUplinkPDRsMap;
// The downlink PDR eBPF map.
std::shared_ptr<BPFMap> mpDownlinkPDRsMap;
// The counter packet map.
std::shared_ptr<BPFMap> mpCounterMap;
// The egress interface map.
std::shared_ptr<BPFMap> mpEgressInterfaceMap;
// The arp table map.
std::shared_ptr<BPFMap> mpArpTableMap;
// The BPF lifecycle program.
std::shared_ptr<PFCP_Session_PDR_LookupProgramLifeCycle> mpLifeCycle;
// The GTP interface.
std::string mGTPInterface;
// The UDP interface.
std::string mUDPInterface;
};
#endif // __PFCP_SESSION_PDR_LOOKUP_XDP_USER_H__
......@@ -5,13 +5,13 @@
#include <bpf/libbpf.h>
#include "logger.hpp"
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief This class abstracts the communication with a specific BPF map.
*/
class BPFMap {
public:
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Construct a new BPFMap object.
*
......@@ -20,13 +20,13 @@ class BPFMap {
*/
BPFMap(struct bpf_map* pBPFMap, std::string name);
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Destroy the BPFMap object.
*/
virtual ~BPFMap();
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Lookup a element in a specific position.
* Wrappers the bpf_map_lookup function.
......@@ -38,7 +38,7 @@ class BPFMap {
template<class KeyType>
int lookup(KeyType& key, void* pValue);
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Get the nex element in the map.
* Wrappers the bpf_get_next_key function.
......@@ -50,7 +50,7 @@ class BPFMap {
template<class KeyType>
int get_next_elem(KeyType& key, KeyType& next_key);
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Update a element in a specific position.
* Wrappers the bpf_map_update function.
......@@ -63,7 +63,7 @@ class BPFMap {
template<class KeyType, class ValueType>
int update(KeyType& key, ValueType& value, int flags);
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Remove a element in a specific position.
* Wrappers the bpf_map_delete function.
......@@ -74,7 +74,7 @@ class BPFMap {
template<class KeyType>
int remove(KeyType& key);
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
/**
* @brief Get the Name of the BPF Map.
*
......@@ -82,7 +82,7 @@ class BPFMap {
*/
std::string getName() const;
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
private:
// TODO: Change to unique.
// The bpf map.
......@@ -92,23 +92,15 @@ class BPFMap {
std::string mName;
};
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
template<class KeyType>
int BPFMap::lookup(KeyType& key, void* pValue) {
// Do not put here.
int mapFd = bpf_map__fd(mpBPFMap);
int lookupReturn = bpf_map_lookup_elem(mapFd, &key, pValue);
if (lookupReturn != 0) {
Logger::upf_app().warn(
"The key is not found in the map: %s", mName.c_str());
} else {
Logger::upf_app().debug("The key is found in the map: %s", mName.c_str());
}
return lookupReturn;
int mapFd = bpf_map__fd(mpBPFMap);
return bpf_map_lookup_elem(mapFd, &key, pValue);
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
template<class KeyType, class ValueType>
int BPFMap::update(KeyType& key, ValueType& value, int flags) {
int mapFd = bpf_map__fd(mpBPFMap);
......@@ -124,7 +116,7 @@ int BPFMap::update(KeyType& key, ValueType& value, int flags) {
return updateReturn;
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
template<class KeyType>
int BPFMap::remove(KeyType& key) {
// Do not put here.
......@@ -142,7 +134,7 @@ int BPFMap::remove(KeyType& key) {
return deleteReturn;
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
template<class KeyType>
int BPFMap::get_next_elem(KeyType& key, KeyType& next_key) {
int mapFd = bpf_map__fd(mpBPFMap);
......@@ -156,5 +148,5 @@ int BPFMap::get_next_elem(KeyType& key, KeyType& next_key) {
return ret_val;
}
/**************************************************************************************************/
//---------------------------------------------------------------------------------------------------------------
#endif // __BPFMAP_H__
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