Commit 7aae8847 authored by Franck Messaoudi's avatar Franck Messaoudi

Merge: fix merging conflicts

parents aaac0a0b 4d145df8
......@@ -60,6 +60,9 @@ Namespace = 'oaicicd-core'
// Openshift server URL
server = 'https://api.oai.cs.eurecom.fr:6443'
// Docker build options
dockerBuildOptions = '--no-cache '
//-------------------------------------------------------------------------------
// Pipeline start
pipeline {
......
common-src @ 633af5b5
Subproject commit 548d88125b345920cbeee4c9db7cccbeaa6579ce
Subproject commit 633af5b55bac676decbfdd3f60b1400d0354bb27
......@@ -33,3 +33,4 @@ include_directories(${SRC_TOP_DIR}/gtpv1u)
include_directories(${SRC_TOP_DIR}/udp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils/bstr)
......@@ -285,6 +285,8 @@ ADD_SUBDIRECTORY(${SRC_TOP_DIR}/upf_app/simpleswitch ${CMAKE_CURRENT_BINARY_DIR}
ADD_SUBDIRECTORY(${SRC_TOP_DIR}/gtpv1u ${CMAKE_CURRENT_BINARY_DIR}/gtpv1u)
ADD_SUBDIRECTORY(${SRC_TOP_DIR}/udp ${CMAKE_CURRENT_BINARY_DIR}/udp)
ADD_SUBDIRECTORY(${SRC_TOP_DIR}/upf_app/interfaces ${CMAKE_CURRENT_BINARY_DIR}/interfaces)
ADD_SUBDIRECTORY(${SRC_TOP_DIR}/upf_app/framed_routing ${CMAKE_CURRENT_BINARY_DIR}/framed_routing)
################################################################################
# Specific part for oai_upf folder
......@@ -300,18 +302,24 @@ include_directories(${SRC_TOP_DIR}/pfcp)
include_directories(${SRC_TOP_DIR}/udp)
include_directories(${SRC_TOP_DIR}/upf_app)
include_directories(${SRC_TOP_DIR}/upf_app/bpf)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/pdr)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/include)
include_directories(${SRC_TOP_DIR}/upf_app/app)
include_directories(${SRC_TOP_DIR}/upf_app/interfaces)
include_directories(${SRC_TOP_DIR}/upf_app/simpleswitch)
include_directories(${SRC_TOP_DIR}/upf_app/framed_routing)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/3gpp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/common)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/common_model)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/nrf)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/nas)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/nas/common)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/nas/utils)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/pfcp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils/bstr)
include_directories(${SRC_TOP_DIR}/../build/ext/libbpf)
link_directories(${SRC_TOP_DIR}/../build/ext/libbpf/src)
......@@ -342,7 +350,7 @@ include(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils/utils.cmake)
# folly glog dl double-conversion for FB folly library
target_link_libraries (upf
${ASAN} -Wl,--start-group CN_UTILS
${SRC_TOP_DIR}/../build/ext/libbpf/src/libbpf.so
${SRC_TOP_DIR}/../build/ext/libbpf/src/libbpf.so
APP
SIMPLE_SWITCH
interfaces
......@@ -355,7 +363,7 @@ target_link_libraries (upf
UPF_XDP
UPF_TC
gflags glog dl double-conversion folly fmt spdlog -Wl,--end-group
pthread m rt config++
pthread m rt config++
event boost_system curl yaml-cpp cpr::cpr
)
......
......@@ -26,6 +26,7 @@
#include "upf_config.hpp"
#include "upf_config_yaml.hpp"
#include "sbi_helper.hpp"
#include <pfcp_session_lookup_xdp_user.h>
#include <boost/asio.hpp>
#include <iostream>
......@@ -123,6 +124,10 @@ void setup_bpf() {
Logger::upf_app().info("Non-GTP interface: %s", sUDPInterface.c_str());
UserPlaneComponent::getInstance().setup(sGTPInterface, sUDPInterface);
auto pPFCP_Session_LookupProgram =
UserPlaneComponent::getInstance().getPFCP_Session_LookupProgram();
pPFCP_Session_LookupProgram->setFramedRouting(upf_cfg.enable_fr);
}
//------------------------------------------------------------------------------
......
......@@ -26,6 +26,7 @@ include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/common)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/pfcp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils/bstr)
add_library (UDP STATIC
udp.cpp
......
This diff is collapsed.
......@@ -84,12 +84,6 @@ class SessionManager {
void prepareEbpfSession(
std::shared_ptr<pfcp::pfcp_session> pSession_establishment,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs);
bool extractPdi(std::shared_ptr<pfcp::pfcp_pdr> pdr, pfcp::pdi& pdi);
bool extractSourceIface(
pfcp::pdi& pdi, pfcp::source_interface_t& sourceInterface);
bool extractUeIpv4(pfcp::pdi& pdi, pfcp::ue_ip_address_t& ueIpAddress);
bool getFar(
std::shared_ptr<pfcp::pfcp_session> session,
......@@ -101,10 +95,6 @@ class SessionManager {
std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_qer>& outQer);
bool extractForwardingParams(
std::shared_ptr<pfcp::pfcp_far> far,
pfcp::forwarding_parameters& forwardingParams);
uint32_t retrieveTeid(std::shared_ptr<pfcp::pfcp_session> session);
uint64_t findUplinkTeid(
......
......@@ -5,6 +5,8 @@
#include <pfcp_session_lookup_xdp_user.h>
#include <UserPlaneComponent.h>
#include <net/if.h> // if_nametoindex
#include <framed_routing/FramedRouting.hpp>
#include <framed_routing_bpf.h>
#include <observer/OnStateChangeSessionProgramObserver.h>
#include <spdlog/fmt/ostr.h>
......@@ -203,9 +205,9 @@ pfcp_pdr_t_ SessionProgramManager::createPdr(
// pdr.pdi.application_id = pPdr->pdi.second.application_id;
// pdr.pdi.ethernet_pdu_session_information =
// pPdr->pdi.second.ethernet_packet_filter;
pdr.pdi.qfi.qfi = pPdr->pdi.second.qfi.second.qfi;
// pdr.pdi.framed_route = pPdr->pdi.second.framed_route;
// pdr.pdi.framed_routing = pPdr->pdi.second.framed_routing;
pdr.pdi.qfi.qfi = pPdr->pdi.second.qfi.second.qfi;
pdr.pdi.framed_route = pPdr->pdi.second.framed_route;
pdr.pdi.framed_routing = pPdr->pdi.second.framed_routing;
// pdr.pdi.framed_ipv6_route = pPdr->pdi.second.framed_ipv6_route;
memcpy(
......@@ -466,6 +468,49 @@ bool SessionProgramManager::getQer(
return (pdr->get(qerId) && session->get(qerId.qer_id, outQer));
}
//---------------------------------------------------------------------------------------------------------------
void SessionProgramManager::addFramedRoutes(
uint32_t ueIpAddress,
const std::vector<pfcp::framed_route_t>& framedRoutes) {
auto pPFCP_Session_LookupProgram =
UserPlaneComponent::getInstance().getPFCP_Session_LookupProgram();
for (const auto& framedRoute : framedRoutes) {
Logger::upf_app().info(
"Add framed route to ue_ip mapping %s to UE IP 0x%x",
framedRoute.framed_route, ueIpAddress);
std::stringstream ss(framedRoute.framed_route);
std::string ipsubnetmask;
while (std::getline(ss, ipsubnetmask, ' ')) {
std::pair<uint32_t, uint32_t> ipCidr =
fr::FramedRouting::extractIPCidr(ipsubnetmask);
auto key = framed_routing_key_for_ip_cidr(ipCidr.first, ipCidr.second);
pPFCP_Session_LookupProgram->updateFramedRouteMappingMap(
ueIpAddress, key);
}
}
}
//---------------------------------------------------------------------------------------------------------------
void SessionProgramManager::removeFramedRoutes(
const std::vector<pfcp::framed_route_t>& framedRoutes) {
auto pPFCP_Session_LookupProgram =
UserPlaneComponent::getInstance().getPFCP_Session_LookupProgram();
for (const auto& framedRoute : framedRoutes) {
std::stringstream ss(framedRoute.framed_route);
std::string ipsubnetmask;
Logger::upf_app().info(
"Remove framed route to ue_ip mapping for %s",
framedRoute.framed_route);
while (std::getline(ss, ipsubnetmask, ' ')) {
std::pair<uint32_t, uint32_t> ipCidr =
fr::FramedRouting::extractIPCidr(ipsubnetmask);
auto key = framed_routing_key_for_ip_cidr(ipCidr.first, ipCidr.second);
pPFCP_Session_LookupProgram->removeFramedRoute(key);
}
}
}
//---------------------------------------------------------------------------------------------------------------
void SessionProgramManager::createPipeline(
std::shared_ptr<pfcp::pfcp_session> session) {
......@@ -576,6 +621,19 @@ void SessionProgramManager::createPipeline(
..................
*/
if ((upf_cfg.enable_fr) &&
(sourceInterface.interface_value == INTERFACE_VALUE_CORE)) {
if (ueIpAddress.v4) {
std::vector<pfcp::framed_route_t> framedRoutes;
if (pdi.get(framedRoutes)) {
SessionProgramManager::getInstance().addFramedRoutes(
ueIpAddress.ipv4_address.s_addr, framedRoutes);
}
} else {
Logger::upf_app().warn("Framed Route is not yet supported for Ipv6");
}
}
pdrs[i] = createPdr(pdr);
i++;
}
......@@ -604,6 +662,9 @@ void SessionProgramManager::modifyPipeline(
uint32_t ueIp = retrieveUeIp(session);
uint32_t gnbIp = retrieveGnbIp(session);
pfcp::pdi pdi;
pfcp::source_interface_t sourceInterface;
if (!ueIp) {
logger.error(
"Missing UE IP Address. Handeling this case not implemented yet!");
......@@ -684,7 +745,6 @@ void SessionProgramManager::modifyPipeline(
// Parse the SDF Flow Description
if (pdr->qer_id.first) {
pfcp::pdi pdi;
pfcp::sdf_filter_t sdf;
struct sdf_filtr sdfFilter;
std::string flowDescription;
......@@ -719,6 +779,16 @@ void SessionProgramManager::modifyPipeline(
}
}
if ((upf_cfg.enable_fr) &&
(pdr->get(pdi) && pdi.get(sourceInterface) &&
(sourceInterface.interface_value == INTERFACE_VALUE_CORE))) {
std::vector<pfcp::framed_route_t> framedRoutes;
if (pdi.get(framedRoutes)) {
SessionProgramManager::getInstance().addFramedRoutes(
ueIp, framedRoutes);
}
}
pdrs[i] = createPdr(pdr);
i++;
}
......
......@@ -37,36 +37,29 @@ class SessionProgramManager {
virtual ~SessionProgramManager();
static SessionProgramManager& getInstance();
void setTeidSessionMap(std::shared_ptr<BPFMap> pProgramsMaps);
void create(uint64_t seid);
void remove(uint64_t seid);
void removeAll();
void setOnNewSessionObserver(OnStateChangeSessionProgramObserver* pObserver);
void updateArpTableMap(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t upfIP, uint32_t remoteIP);
uint32_t getRemoteIP(uint32_t upfIP, uint32_t remoteIP);
pfcp_far_t_ createFar(std::shared_ptr<pfcp::pfcp_far> pFar);
pfcp_pdr_t_ createPdr(std::shared_ptr<pfcp::pfcp_pdr> pPdr);
pfcp_qer_t_ createQer(std::shared_ptr<pfcp::pfcp_qer> pQer);
void createPipeline(std::shared_ptr<pfcp::pfcp_session> session);
void modifyPipeline(
std::shared_ptr<pfcp::pfcp_session> session, uint32_t teid);
void modifyPipeline(
std::shared_ptr<pfcp::pfcp_session> session, uint32_t teid_ul,
uint32_t teid_dl);
void addFramedRoutes(
uint32_t ueIpAddress,
const std::vector<pfcp::framed_route_t>& framedRoutes);
void removeFramedRoutes(
const std::vector<pfcp::framed_route_t>& framedRoutes);
void createPipeline(
uint64_t seid, uint32_t teid1, uint8_t sourceInterface,
......@@ -74,63 +67,44 @@ class SessionProgramManager {
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>> pdrs,
bool isModification = false, uint32_t teid2 = 0);
void initializeNextRuleProgIndexKey(
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 storeFarProgramIndexInNextProgRuleIndexMap(
// std::shared_ptr<pfcp::pfcp_far> pFar, const next_rule_prog_index_key&
// key, std::shared_ptr<PFCP_Session_LookupProgram>
// pPFCP_Session_LookupProgram);
void storePduSessionInMap(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t ue_ip_address, uint32_t teid_dl, uint32_t teid_ul,
uint64_t seid);
void storeFARInFARMap(
std::shared_ptr<FARProgram> pFARProgram,
std::shared_ptr<pfcp::pfcp_far> pFar);
void saveSeidWithinFARProgram(
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);
void updateARPTableForN3(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t gNodeBIP, uint32_t upfn3IP, uint32_t seid);
bool getFar(
std::shared_ptr<pfcp::pfcp_session> session,
std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_far>& outFar);
bool getQer(
std::shared_ptr<pfcp::pfcp_session> session,
std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_qer>& outQer);
uint32_t getGnodebIp(std::shared_ptr<pfcp::pfcp_far> pFar);
uint32_t retrieveGnbIp(std::shared_ptr<pfcp::pfcp_session> session);
uint32_t retrieveUeIp(std::shared_ptr<pfcp::pfcp_session> session);
void updatePipeline(
uint64_t seid, uint32_t teid, uint32_t gNBIpAddress, bool isModification);
void removePipeline(uint64_t seid);
std::shared_ptr<SessionPrograms> findSessionPrograms(uint64_t seid);
void sessionIds(
session_id& key, uint64_t seid, uint32_t teid_ul, uint32_t teid_dl);
......@@ -141,16 +115,9 @@ class SessionProgramManager {
int32_t getEmptySlot();
std::shared_ptr<BPFMap> mpTeidSessionMap;
// std::shared_ptr<BPFMap> mpUeIpSessionMap;
// The observer which will be notified when a PFCP_Session_PDR_LookupProgram
// is created.
OnStateChangeSessionProgramObserver* mpOnNewSessionProgramObserver;
std::map<uint32_t, std::shared_ptr<SessionPrograms>> mSessionProgramsMap;
std::array<int64_t, 10> mProgramArray;
struct pduSessionInfo sessionInfo;
};
......
......@@ -120,6 +120,8 @@ class upf_config {
} nf_addr;
bool enable_snat;
bool enable_fr;
std::vector<pdn_cfg_t> pdns;
std::vector<pfcp::node_id_t> smfs;
......@@ -152,6 +154,7 @@ class upf_config {
max_pfcp_sessions(100),
nsf(),
enable_snat(false),
enable_fr(false),
nrf_addr() {
itti.itti_timer_sched_params.sched_priority = 85;
itti.n3_sched_params.sched_priority = 84;
......
......@@ -32,7 +32,8 @@ namespace oai::config {
//------------------------------------------------------------------------------
upf_support_features::upf_support_features(
bool enable_bpf_datapath, bool enable_qos, bool enable_snat) {
bool enable_bpf_datapath, bool enable_qos, bool enable_snat,
bool enable_fr) {
m_config_name = "Supported Features";
m_enable_bpf_datapath = option_config_value(
......@@ -43,6 +44,8 @@ upf_support_features::upf_support_features(
m_enable_snat = option_config_value(
UPF_CONFIG_SUPPORT_FEATURES_ENABLE_SNAT_LABEL, enable_snat);
m_enable_fr =
option_config_value(UPF_CONFIG_SUPPORT_FEATURES_ENABLE_FR, enable_fr);
}
//------------------------------------------------------------------------------
......@@ -59,6 +62,8 @@ void upf_support_features::from_yaml(const YAML::Node& node) {
if (node[UPF_CONFIG_SUPPORT_FEATURES_ENABLE_SNAT]) {
m_enable_snat.from_yaml(node[UPF_CONFIG_SUPPORT_FEATURES_ENABLE_SNAT]);
}
if (node[UPF_CONFIG_SUPPORT_FEATURES_ENABLE_FR])
m_enable_fr.from_yaml(node[UPF_CONFIG_SUPPORT_FEATURES_ENABLE_FR]);
}
//------------------------------------------------------------------------------
......@@ -90,6 +95,13 @@ std::string upf_support_features::to_string(const std::string& indent) const {
out.append(indent).append(fmt::format(
BASE_FORMATTER, INNER_LIST_ELEM,
UPF_CONFIG_SUPPORT_FEATURES_ENABLE_SNAT_LABEL, inner_width, enable_snat));
std::string enable_fr = m_enable_fr.get_value() ? UPF_CONFIG_OPTION_YES_STR :
UPF_CONFIG_OPTION_NO_STR;
out.append(indent).append(fmt::format(
BASE_FORMATTER, INNER_LIST_ELEM, UPF_CONFIG_SUPPORT_FEATURES_ENABLE_FR,
inner_width, enable_fr));
return out;
}
......@@ -98,7 +110,7 @@ upf::upf(
const std::string& name, const std::string& host, const sbi_interface& sbi,
const std::map<std::string, upf_interface_config>& interfaces)
: nf(name, host, sbi),
m_upf_support_features(false, false, false),
m_upf_support_features(false, false, false, false),
m_interfaces(interfaces) {
model::nrf::SnssaiUpfInfoItem item;
item.setSNssai(DEFAULT_SNSSAI);
......@@ -209,6 +221,11 @@ bool upf_support_features::get_option_enable_snat() const {
return m_enable_snat.get_value();
}
//------------------------------------------------------------------------------
bool upf_support_features::get_option_enable_fr() const {
return m_enable_fr.get_value();
}
//------------------------------------------------------------------------------
const upf_support_features& upf::get_support_features() const {
return m_upf_support_features;
......@@ -387,6 +404,7 @@ void upf_config_yaml::to_upf_config(upf_config& cfg) {
upf_local->get_support_features().get_option_enable_bpf_datapath();
cfg.enable_qos = upf_local->get_support_features().get_option_enable_qos();
cfg.enable_snat = upf_local->get_support_features().get_option_enable_snat();
cfg.enable_fr = upf_local->get_support_features().get_option_enable_fr();
auto snssai_upf_list = upf_local->get_upf_info().getSNssaiUpfInfoList();
for (const auto& snssai : snssai_upf_list) {
......
......@@ -37,6 +37,7 @@ constexpr auto UPF_CONFIG_SUPPORT_FEATURES_ENABLE_BPF = "enable_bpf_datapath";
constexpr auto UPF_CONFIG_SUPPORT_FEATURES_ENABLE_BPF_LABEL =
"Enable BPF Datapath";
constexpr auto UPF_CONFIG_SUPPORT_FEATURES_ENABLE_SNAT = "enable_snat";
constexpr auto UPF_CONFIG_SUPPORT_FEATURES_ENABLE_FR = "enable_fr";
constexpr auto UPF_CONFIG_SUPPORT_FEATURES_ENABLE_SNAT_LABEL = "Enable SNAT";
constexpr auto UPF_CONFIG_SUPPORT_FEATURES_ENABLE_QOS = "enable_qos";
......@@ -57,10 +58,12 @@ class upf_support_features : public config_type {
option_config_value m_enable_bpf_datapath{};
option_config_value m_enable_qos{};
option_config_value m_enable_snat{};
option_config_value m_enable_fr{};
public:
explicit upf_support_features(
bool enable_bpf_datapath, bool enable_qos, bool enable_snat);
bool enable_bpf_datapath, bool enable_qos, bool enable_snat,
bool enable_fr);
void from_yaml(const YAML::Node& node) override;
......@@ -68,6 +71,7 @@ class upf_support_features : public config_type {
[[nodiscard]] bool get_option_enable_bpf_datapath() const;
[[nodiscard]] bool get_option_enable_qos() const;
[[nodiscard]] bool get_option_enable_snat() const;
[[nodiscard]] bool get_option_enable_fr() const;
};
class upf_interface_config : public local_interface {
......
......@@ -237,7 +237,7 @@ upf_n4::upf_n4()
up_function_features.udbc = 0;
up_function_features.quoac = 0;
up_function_features.trace = 0;
up_function_features.frrt = 0;
up_function_features.frrt = static_cast<uint16_t>(upf_cfg.enable_fr);
enterprise_specific.enterprise_id = OAI_PRIVATE_ENTERPRISE_NUMBER;
enterprise_specific.proprietary_data = "OAI UPF";
......
......@@ -18,16 +18,8 @@
#define INTERFACE_ENTRIES_MAX 12
#define MAX_UEs 10000
#define MAX_PDRS_PER_SESSION 32
// struct next_rule_prog_index_key {
// teid_t_ teid;
// u8 source_value;
// u32 ipv4_address;
// };
#define MAX_SDF_FITLER_ENTRIES 1000
/*---------------------------------------------------------------------------------------------------------------*/
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_SDF_FITLER_ENTRIES);
......@@ -35,46 +27,6 @@ struct {
__type(value, struct sdf_filtr);
} m_sdf_filter SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
// struct {
// __uint(
// type,
// BPF_MAP_TYPE_PROG_ARRAY); //!< Must have the key and value with 4
// bytes
// __type(key, teid_t_); //!< program identifier.
// __type(value, s32); //!< program which represents the session.
// // TODO: Check how the management works. The size should be equal
// // to the maximum number of sessions.
// __uint(max_entries, MAX_LENGTH); // 10000, //!< TODO: Is it enought?
// } m_teid_session SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
// struct {
// __uint(
// type,
// BPF_MAP_TYPE_PROG_ARRAY); //!< Must have the key and value with 4
// bytes
// __type(key, u32); //!< program identifier.
// __type(value, s32); //!< program which represents the session.
// // TODO Check how the management works. The size should be equal
// // to the maximum number of sessions.
// __uint(max_entries, MAX_UEs); //!< TODO: Is it enought?
// } m_ueip_session SEC(".maps");
// struct {
// __uint(type, BPF_MAP_TYPE_HASH);
// __uint(max_entries, MAX_UEs);
// __type(key, u32); //!< UE IP
// __type(value, u32); //!< PDR
// } m_ue_ip_pdr SEC(".maps");
// struct {
// __uint(type, BPF_MAP_TYPE_HASH);
// __uint(max_entries, MAX_LENGTH); // 10,
// __type(key, struct next_rule_prog_index_key);
// __type(value, pfcp_far_t_); //
// } m_next_rule_prog_index SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, INTERFACE_ENTRIES_MAX);
......@@ -112,4 +64,18 @@ struct {
__type(value, u32); // Value type (0 for false, 1 for true)
} m_qos_enabling SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_UEs);
__type(key, u32); // hash_framed_routing_key
__type(value, u32); // ue_ip
} m_framed_route_mapping SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1); // Single entry for the flag
__type(key, u8); // Key is a constant, e.g., 0
__type(value, u8); // Value indicates if framed routing is enabled
} framed_routing_flag SEC(".maps");
#endif // __PFCP_SESSION_LOOKUP_MAPS_H__
#ifndef OPENAIRINTERFACE_FRAMED_ROUTING_BPF_H
#define OPENAIRINTERFACE_FRAMED_ROUTING_BPF_H
#include <types.h>
#include <stdint.h>
struct FramedRoutingKeyBPF {
uint32_t networkAddress;
uint32_t subnet;
};
static __always_inline uint32_t
hash_framed_routing_key(struct FramedRoutingKeyBPF* key) {
uint32_t hash = 17;
hash = hash * 31 + key->networkAddress;
hash = hash ^ key->subnet;
return hash;
}
static __always_inline struct FramedRoutingKeyBPF
framed_routing_key_for_ip_cidr(uint32_t ip, uint32_t cidr) {
const uint32_t ipv4Size = 32;
// Calculate the subnet address
uint32_t subnet_mask = 0xffffffff << (ipv4Size - cidr);
// Calculate the network address
uint32_t network_address = subnet_mask & ip;
struct FramedRoutingKeyBPF key = {network_address, subnet_mask};
return key;
}
#endif // OPENAIRINTERFACE_FRAMED_ROUTING_BPF_H
......@@ -26,6 +26,7 @@
#include <utils/logger.h>
#include <utils/utils.h>
#include <next_prog_rule_key.h>
#include <framed_routing_bpf.h>
#include "xdp_stats_kern.h"
#include <linux/bpf.h>
......@@ -90,10 +91,8 @@ static __always_inline bool update_dst_mac_address(
memcpy(p_eth->h_dest, map_entry->mac_address, sizeof(p_eth->h_dest));
return true;
}
return false;
}
/*---------------------------------------------------------------------------------------------------------------*/
static __always_inline u32 match_sdf_filter_ipv4(
const struct packet_filter* filter, const struct sdf_filtr* sdf) {
......@@ -108,16 +107,19 @@ static __always_inline u32 match_sdf_filter_ipv4(
/*
* TODO:
* Currently we are only working with Ipv4 packets but the struct are designed
* Currently we are only working with Ipv4 packets but the struct are
designed
* to support both Ipv4 and Ipv6
* For now we only treat IPv4 packets over the datapath/PFCP
}
*/
u32 sdf_src_mask = bpf_htonl((
u32) (sdf->src_addr.mask >> 96)); // get the top 32 bits of 128-bits mask
u32 sdf_dst_mask = bpf_htonl((
u32) (sdf->dst_addr.mask >> 96)); // get the top 32 bits of 128-bits mask
u32 sdf_src_mask =
bpf_htonl((u32) (sdf->src_addr.mask >> 96)); // get the top 32 bits of
// 128-bits mask
u32 sdf_dst_mask =
bpf_htonl((u32) (sdf->dst_addr.mask >> 96)); // get the top 32 bits of
// 128-bits mask
bpf_debug(" Standard IANA-assigned IP protocol numbers:");
......@@ -136,11 +138,13 @@ static __always_inline u32 match_sdf_filter_ipv4(
&sdf_dst_mask, &packet_dst_ip);
bpf_debug(
"( (sdf_sport_lower, sdf_sport_upper), packet_sport ) : ( (%u, %u), %u )",
"( (sdf_sport_lower, sdf_sport_upper), packet_sport ) : ( (%u, %u), %u "
")",
sdf->src_port.lower_bound, sdf->src_port.upper_bound, packet_src_port);
bpf_debug(
"( (sdf_dport_lower, sdf_dport_upper), packet_dport ) : ( (%u, %u), %u )",
"( (sdf_dport_lower, sdf_dport_upper), packet_dport ) : ( (%u, %u), %u "
")",
sdf->dst_port.lower_bound, sdf->dst_port.upper_bound, packet_dst_port);
/*
......@@ -554,8 +558,6 @@ static __always_inline pfcp_pdr_t_* pfcp_session_s_lookup_precedence_over_n3(
static __always_inline u32 apply_rules_matching_pdr_over_n3(
struct xdp_md* ctx, struct ethhdr* ethh,
struct pdrs_per_session key_rules_matching_pdr) {
// void* data = (void*) (long) ctx->data;
// void* data_end = (void*) (long) ctx->data_end;
struct rules_match_pdr* rules = {0};
u64 seid = key_rules_matching_pdr.seid;
......@@ -911,7 +913,7 @@ int xdp_handle_uplink(struct xdp_md* ctx) {
/*
|-----------------------------------------------------------------------|
|--------------------- Apply RUles in Matching PDR ---------------------|
|--------------------- Apply Rules in Matching PDR ---------------------|
|----------------------------- (FARs, QERs) ----------------------------|
|-----------------------------------------------------------------------|
*/
......@@ -1015,7 +1017,7 @@ int xdp_handle_shaping(struct xdp_md* ctx) {
/*
|-----------------------------------------------------------------------|
|--------------------- Apply RUles in Matching PDR ---------------------|
|--------------------- Apply Rules in Matching PDR ---------------------|
|----------------------------- (FARs, QERs) ----------------------------|
|-----------------------------------------------------------------------|
*/
......@@ -1120,7 +1122,7 @@ int xdp_handle_downlink(struct xdp_md* ctx) {
/*
|-----------------------------------------------------------------------|
|--------------------- Apply RUles in Matching PDR ---------------------|
|--------------------- Apply Rules in Matching PDR ---------------------|
|----------------------------- (FARs, QERs) ----------------------------|
|-----------------------------------------------------------------------|
*/
......
include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/common/msg)
include_directories(${SRC_TOP_DIR}/common/utils)
include_directories(${SRC_TOP_DIR}/itti)
include_directories(${SRC_TOP_DIR}/gtpv1u)
include_directories(${SRC_TOP_DIR}/oai_upf)
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}/pfcp)
include_directories(${SRC_TOP_DIR}/udp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/common)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/config)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/common_model)
include(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/nrf/nrf_model.cmake)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils/bstr)
add_library(FRAMED_ROUTING STATIC
FramedRouting.cpp
LocalRouting.cpp
LocalRouting.hpp
)
//
// Created by root on 5/10/24.
//
#include "FramedRouting.hpp"
#include <utility>
#include <sstream>
#include <iostream>
#include <upf_config.hpp>
extern oai::config::upf_config upf_cfg;
namespace fr {
FramedRouting::FramedRouting(std::shared_ptr<LocalRouting> localRouting)
: localRouting(std::move(localRouting)) {}
void FramedRouting::addFramedRoute(
const uint32_t ue_ip, const pfcp::framed_route_s& framed_route_s) {
std::stringstream ss(framed_route_s.framed_route);
std::string ipsubnetmask;
while (std::getline(ss, ipsubnetmask, this->pdi_fr_delimeter)) {
std::pair<uint32_t, uint32_t> ipCidr = this->extractIPCidr(ipsubnetmask);
auto key = createFramedRoutingKey(ipCidr);
auto routing_info = createLocalRoutingInformation(ipCidr);
auto snat_info = createLocalSnatInformation(ipCidr);
this->KeyToIp.insert({key, ue_ip});
localRouting->add_route(routing_info);
localRouting->add_source_snat(snat_info);
}
}
uint32_t FramedRouting::retrieveUEIp(const uint32_t destination_ip) const {
for (uint32_t i = 32; i > 0; --i) {
FramedRoutingKey framedRoutingKey =
createFramedRoutingKey({destination_ip, i});
auto ip = this->KeyToIp.find(framedRoutingKey);
if (ip != KeyToIp.end()) {
return ip->second;
};
};
return 0;
};
uint32_t FramedRouting::retrieveUEIp(
const pfcp::framed_route_s& framed_route_s) const {
std::stringstream ss(framed_route_s.framed_route);
std::string ipsubnetmask;
while (std::getline(ss, ipsubnetmask, this->pdi_fr_delimeter)) {
std::pair<uint32_t, uint32_t> ipCidr = this->extractIPCidr(ipsubnetmask);
FramedRoutingKey framedRoutingKey =
createFramedRoutingKey({ipCidr.first, ipCidr.second});
auto ip = this->KeyToIp.find(framedRoutingKey);
if (ip != KeyToIp.end()) {
return ip->second;
}
}
return 0;
}
void FramedRouting::remove_entry(uint32_t ue_ip) {
for (uint32_t i = 32; i > 0; --i) {
FramedRoutingKey framedRoutingKey = createFramedRoutingKey({ue_ip, i});
auto ip = this->KeyToIp.find(framedRoutingKey);
if (ip != KeyToIp.end()) {
this->KeyToIp.erase(ip);
this->localRouting->delete_route(ip->second);
};
};
}
std::pair<uint32_t, uint32_t> FramedRouting::extractIPCidr(
const std::string& fr_subnet) {
const char subnet_delimeter = '/';
std::string ipSubnet = fr_subnet;
uint32_t ip = 0;
uint32_t cidr = 0;
const std::string ip_substring =
ipSubnet.substr(0, ipSubnet.find(subnet_delimeter));
ip = framedIPToUeIP(ip_substring);
std::reverse(ipSubnet.begin(), ipSubnet.end());
std::string subnet_substring =
ipSubnet.substr(0, ipSubnet.rfind(subnet_delimeter));
cidr = frameSubnetToUInt(subnet_substring);
return std::pair<uint32_t, uint32_t>{ip, cidr};
}
FramedRoutingKey FramedRouting::createFramedRoutingKey(
const std::pair<uint32_t, uint32_t> ipCidr) const {
const uint32_t ipv4Size = 32;
const uint32_t subnet_adress = 0xffffffff << (ipv4Size - ipCidr.second);
const uint32_t networkAdress = subnet_adress & ipCidr.first;
return FramedRoutingKey{networkAdress, subnet_adress};
}
RoutingInformation FramedRouting::createLocalRoutingInformation(
const std::pair<uint32_t, uint32_t>& ipCidr) const {
struct in_addr addr;
addr.s_addr = htonl(ipCidr.first);
std::string destination = inet_ntoa(addr);
uint32_t netmask = ipCidr.second;
std::string device = "tun0";
// todo (phine.tech) use correct DNN
struct in_addr address4_gw = {};
address4_gw.s_addr = upf_cfg.pdns[0].network_ipv4.s_addr + be32toh(1);
std::string gateway_address = inet_ntoa(address4_gw);
return fr::RoutingInformation{destination, netmask, device, gateway_address};
}
SourceNatInformation FramedRouting::createLocalSnatInformation(
const std::pair<uint32_t, uint32_t>& ipCidr) const {
struct in_addr addr;
addr.s_addr = htonl(ipCidr.first);
std::string destination = inet_ntoa(addr);
uint32_t netmask = ipCidr.second;
std::string device = upf_cfg.n6.if_name;
std::string snat_address = oai::utils::conv::toString(upf_cfg.n6.addr4);
return SourceNatInformation{destination, netmask, device, snat_address};
}
} // namespace fr
\ No newline at end of file
//
// Created by root on 5/10/24.
//
#pragma once
#include <cstdint>
#include <memory>
#include <vector>
#include "FramedRoutingHash.h"
#include "pfcp_pdr.hpp"
#include "LocalRouting.hpp"
namespace fr {
class FramedRouting {
public:
FramedRouting() = delete;
explicit FramedRouting(std::shared_ptr<LocalRouting> localRouting);
virtual ~FramedRouting() = default;
[[nodiscard]] uint32_t retrieveUEIp(const uint32_t destination_ip) const;
[[nodiscard]] uint32_t retrieveUEIp(
const pfcp::framed_route_s& framed_route_s) const;
void addFramedRoute(
uint32_t ue_ip, const pfcp::framed_route_s& framed_route_s);
void remove_entry(uint32_t ue_ip);
[[nodiscard]] static uint32_t framedIPToUeIP(const std::string& ip) {
const char delimeter = '.';
uint32_t result = 0;
int shift_counter = 24;
std::string ip_temp;
for (auto i = 0; i < ip.length(); ++i) {
ip_temp += ip.at(i);
if (ip.at(i) == delimeter || i == ip.length() - 1) {
result = result | (std::stoi(ip_temp) << shift_counter);
ip_temp = "";
shift_counter -= 8;
}
}
return result;
};
[[nodiscard]] static uint32_t frameSubnetToUInt(std::string& subnet) {
std::string temp_subnet = "";
if (subnet.length() > 2) {
return 32;
}
for (auto i = subnet.length(); i > 0; i--) {
temp_subnet.push_back(subnet.at(i - 1));
}
return std::stoi(temp_subnet);
};
[[nodiscard]] static std::pair<uint32_t, uint32_t> extractIPCidr(
const std::string& fr_subnet);
private:
const char pdi_fr_delimeter = ' ';
std::shared_ptr<LocalRouting> localRouting;
std::unordered_map<FramedRoutingKey, uint32_t> KeyToIp{};
[[nodiscard]] FramedRoutingKey createFramedRoutingKey(
std::pair<uint32_t, uint32_t> ipCidr) const;
[[nodiscard]] RoutingInformation createLocalRoutingInformation(
const std::pair<uint32_t, uint32_t>& ipCidr) const;
[[nodiscard]] SourceNatInformation createLocalSnatInformation(
const std::pair<uint32_t, uint32_t>& ipCidr) const;
};
} // namespace fr
//
// Created by root on 6/25/24.
//
#pragma once
// todo(kw) maybe call it subnet or similar
struct FramedRoutingKey {
uint32_t networkAdress{};
uint32_t subnet{};
bool operator==(const FramedRoutingKey& other) const {
return (networkAdress == other.networkAdress && subnet == other.subnet);
}
};
template<>
struct std::hash<FramedRoutingKey> {
std::size_t operator()(const FramedRoutingKey& k) const {
std::size_t hash = 17;
hash *= std::hash<uint32_t>()(k.networkAdress);
return hash ^ std::hash<uint32_t>()(k.subnet);
}
};
\ No newline at end of file
//
// Created by root on 7/22/24.
//
#include <fmt/format.h>
#include <arpa/inet.h>
#include <iostream>
#include <logger.hpp>
#include "LocalRouting.hpp"
namespace fr {
void LocalRouting::add_route(const RoutingInformation& routing_information) {
auto original_cerr_streambuf = std::cerr.rdbuf(nullptr);
auto cmd = fmt::format(
"ip route add {}/{} via {} dev tun0", routing_information.destination,
routing_information.netmask, routing_information.gateway_address);
auto rc = system((const char*) cmd.c_str());
if (rc == 0) {
Logger::pfcp_switch().info("Route created");
this->routeInfoToRtEntry.insert(
{routing_information.destination, routing_information});
} else {
Logger::pfcp_switch().warn("Route information not correct or does exists!");
}
}
void LocalRouting::delete_route(const uint32_t& network_address) {
// todo(phine.tech) create function remove dublicated_code
auto original_cerr_streambuf = std::cerr.rdbuf(nullptr);
std::string destination = convert_s_addr_to_string(network_address);
auto routing_info_iterator = this->routeInfoToRtEntry.find(destination);
if (routing_info_iterator != routeInfoToRtEntry.end()) {
const auto routing_information = routing_info_iterator->second;
auto cmd = fmt::format(
"ip route del {}/{} via {} dev tun0", routing_information.destination,
routing_information.netmask, routing_information.gateway_address);
const auto rc = system((const char*) cmd.c_str());
if (rc == 0) {
Logger::pfcp_switch().info("Route deleted");
} else {
Logger::pfcp_switch().warn(
"Route information not correct or does not exists!");
}
}
};
void LocalRouting::add_source_snat(
const SourceNatInformation& source_nat_information) {
const std::string cmd = fmt::format(
"iptables -t nat -A POSTROUTING -s {}/{} -o {} -j SNAT --to "
"{}",
source_nat_information.destination, source_nat_information.netmask,
source_nat_information.device, source_nat_information.snat_address);
const auto rc = system((const char*) cmd.c_str());
if (rc == 0) {
Logger::pfcp_switch().info("Source NAT added");
} else {
Logger::pfcp_switch().warn("Source NAT not correct or does exists!");
}
}
void LocalRouting::delete_ssnat(const uint32_t& network_address) {}
std::string LocalRouting::convert_s_addr_to_string(
const uint32_t& network_address) {
struct in_addr addr;
addr.s_addr = htonl(network_address);
return inet_ntoa(addr);
}
} // namespace fr
\ No newline at end of file
//
// Created by root on 7/22/24.
//
#pragma once
#include <memory>
#include <string>
#include <unordered_map>
namespace fr {
struct RoutingInformation {
std::string destination;
uint32_t netmask = 0;
std::string device;
std::string gateway_address;
};
struct SourceNatInformation {
std::string destination;
uint32_t netmask = 0;
std::string device;
std::string snat_address;
};
// todo (kw) rename class
class LocalRouting {
public:
virtual void add_route(const RoutingInformation& routing_information);
virtual void delete_route(const uint32_t& network_address);
virtual void add_source_snat(
const SourceNatInformation& source_nat_information);
// todo(phine.tech) implement delete if needed
virtual void delete_ssnat(const uint32_t& network_address);
private:
std::unordered_map<std::string, RoutingInformation> routeInfoToRtEntry{};
std::string convert_s_addr_to_string(const uint32_t& network_address);
};
} // namespace fr
......@@ -31,24 +31,6 @@ int is_little_endian2() {
PFCP_Session_LookupProgram::PFCP_Session_LookupProgram(
const std::string& gtpInterface, const std::string& udpInterface)
: mGTPInterface(gtpInterface), mUDPInterface(udpInterface) {
// Open the eBPF skeleton
// auto skel = pfcp_session_lookup_xdp_kernel_c__open();
// if (!skel) {
// std::cerr << "Failed to open eBPF skeleton" << std::endl;
// return;
// }
// // Resize the map BEFORE loading
// struct bpf_map* arp_table_map =
// bpf_object__find_map_by_name(skel->obj, "m_arp_table");
// if (!arp_table_map) {
// std::cerr << "Failed to find map: m_arp_table" << std::endl;
// } else {
// int max_entries = 55; // Set your new desired size
// if (bpf_map__set_max_entries(arp_table_map, max_entries)) {
// std::cerr << "Failed to resize map: m_arp_table" << std::endl;
// }
// }
mpLifeCycle = std::make_shared<PFCP_Session_LookupProgramLifeCycle>(
pfcp_session_lookup_xdp_kernel_c__open,
pfcp_session_lookup_xdp_kernel_c__load,
......@@ -158,12 +140,6 @@ 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;
......@@ -173,30 +149,6 @@ void PFCP_Session_LookupProgram::removeProgramMap(uint32_t 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 {
......@@ -225,32 +177,56 @@ std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getRulesMatchPdrMap()
return mpRulesMatchPdrMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getSessionPdrsMap() const {
return mpSessionPdrsMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getSdfFilterMap() const {
return mpSdfFilterMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getQosEnablingMap() const {
return mpQosEnablingMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getFramedRouteMappingMap() {
return mpFramedRouteMappingMap;
}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::updateFramedRouteMappingMap(
uint32_t ue_ip, FramedRoutingKeyBPF key) {
uint32_t hash_key = hash_framed_routing_key(&key);
Logger::upf_app().debug(
"Update framed routing map with key: %u, value: %u", hash_key, ue_ip);
mpFramedRouteMappingMap->update(hash_key, ue_ip, BPF_ANY);
}
/*---------------------------------------------------------------------------------------------------------------*/
void PFCP_Session_LookupProgram::removeFramedRoute(FramedRoutingKeyBPF key) {
uint32_t hash_key = hash_framed_routing_key(&key);
uint32_t ueip;
if (mpFramedRouteMappingMap->lookup(hash_key, &ueip) == 0) {
mpFramedRouteMappingMap->remove(hash_key);
}
}
void PFCP_Session_LookupProgram::setFramedRouting(bool enable) {
uint8_t value = (enable) ? 1 : 0;
uint8_t key = 0;
mpFramedRouteFlagMap->update(key, value, BPF_ANY);
}
/*---------------------------------------------------------------------------------------------------------------*/
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"));
mpArpTableMap = std::make_shared<BPFMap>(mpMaps->getMap("m_arp_table"));
......@@ -264,6 +240,10 @@ void PFCP_Session_LookupProgram::initializeMaps() {
mpSdfFilterMap = std::make_shared<BPFMap>(mpMaps->getMap("m_sdf_filter"));
mpQosEnablingMap = std::make_shared<BPFMap>(mpMaps->getMap("m_qos_enabling"));
mpFramedRouteMappingMap =
std::make_shared<BPFMap>(mpMaps->getMap("m_framed_route_mapping"));
mpFramedRouteFlagMap =
std::make_shared<BPFMap>(mpMaps->getMap("framed_routing_flag"));
}
/*---------------------------------------------------------------------------------------------------------------*/
......@@ -10,6 +10,7 @@
#include <pfcp_session_lookup_xdp_kernel_skel.h>
#include <wrappers/BPFMap.hpp>
#include "interfaces.h"
#include <framed_routing_bpf.h>
class BPFMaps;
class BPFMap;
......@@ -26,28 +27,19 @@ class PFCP_Session_LookupProgram {
public:
explicit PFCP_Session_LookupProgram(
const std::string& gtpInterface, const std::string& udpInterface);
virtual ~PFCP_Session_LookupProgram();
void setup(bool isQosEnabled);
std::shared_ptr<BPFMaps> getMaps();
void tearDown();
// void updateProgramMap(uint32_t key, uint32_t fd);
void create_upf_interface_map_entry(e_reference_point s);
void removeProgramMap(uint32_t key);
std::shared_ptr<BPFMap> getFramedRouteMappingMap();
void updateFramedRouteMappingMap(uint32_t ue_ip, FramedRoutingKeyBPF key);
void removeFramedRoute(FramedRoutingKeyBPF key);
void setFramedRouting(bool enable);
std::shared_ptr<BPFMap> getEgressInterfaceMap() const;
std::shared_ptr<BPFMap> getArpTableMap() const;
std::shared_ptr<BPFMap> getIfaceMap() const;
// std::shared_ptr<BPFMap> getTeidSessionMap() const;
// std::shared_ptr<BPFMap> getUeIpSessionMap() const;
// std::shared_ptr<BPFMap> getNextProgRuleMap() const;
// std::shared_ptr<BPFMap> getNextProgRuleIndexMap() const;
std::shared_ptr<BPFMap> getTrafficMap() const;
std::shared_ptr<BPFMap> getSessionMappingMap() const;
std::shared_ptr<BPFMap> getRulesMatchPdrMap() const;
......@@ -55,7 +47,6 @@ class PFCP_Session_LookupProgram {
std::shared_ptr<BPFMap> getSdfFilterMap() const;
std::shared_ptr<BPFMap> getQosEnablingMap() const;
std::shared_ptr<BPFMap> getUeQfiTeidMap() const;
// std::shared_ptr<BPFMap> getQosFlowMap() const;
private:
void initializeMaps();
......@@ -66,9 +57,6 @@ class PFCP_Session_LookupProgram {
std::string mUDPInterface;
std::shared_ptr<BPFMaps> mpMaps;
std::shared_ptr<BPFMap> mpTeidSessionMap;
// std::shared_ptr<BPFMap> mpUeIpSessionMap;
// std::shared_ptr<BPFMap> mpNextProgRuleIndexMap;
// std::shared_ptr<BPFMap> mpNextProgRuleMap;
std::shared_ptr<BPFMap> mpSessionMappingMap;
std::shared_ptr<BPFMap> mpEgressInterfaceMap;
std::shared_ptr<BPFMap> mpArpTableMap;
......@@ -77,7 +65,8 @@ class PFCP_Session_LookupProgram {
std::shared_ptr<BPFMap> mpSessionPdrsMap;
std::shared_ptr<BPFMap> mpSdfFilterMap;
std::shared_ptr<BPFMap> mpQosEnablingMap;
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> mpFramedRouteMappingMap;
std::shared_ptr<BPFMap> mpFramedRouteFlagMap;
};
#endif // __PFCP_SESSION_LOOKUP_XDP_USER_H__
......@@ -39,8 +39,11 @@ include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/pfcp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils/bstr)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/common_model)
include_directories(${SRC_TOP_DIR}/upf_app/framed_routing)
include(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/nrf/nrf_model.cmake)
#find_library(FOLLY folly)
add_library (SIMPLE_SWITCH STATIC
......@@ -50,5 +53,7 @@ add_library (SIMPLE_SWITCH STATIC
pfcp_session.cpp
pfcp_switch.cpp
simple_switch.cpp
)
${SRC_TOP_DIR}/upf_app/framed_routing/FramedRouting.cpp
${SRC_TOP_DIR}/upf_app/framed_routing/LocalRouting.cpp
)
......@@ -29,11 +29,13 @@
#include "pfcp_pdr.hpp"
#include "upf_n4.hpp"
#include "logger.hpp"
#include "upf_config.hpp"
using namespace pfcp;
using namespace oai::upf::app;
extern upf_n4* upf_n4_inst;
extern oai::config::upf_config upf_cfg;
//------------------------------------------------------------------------------
bool pfcp_pdr::look_up_pack_in_access(
......@@ -102,7 +104,8 @@ bool pfcp_pdr::look_up_pack_in_core(
// cause ue_ip_address not present ", pdr_id.rule_id);
return false;
}
if (pdi.second.ue_ip_address.second.ipv4_address.s_addr != iph->daddr) {
if (!upf_cfg.enable_fr &&
pdi.second.ue_ip_address.second.ipv4_address.s_addr != iph->daddr) {
// Logger::pfcp_switch().info( "look_up_pack_in_core failed PDR id %4x,
// cause PDR ue_ip_address %8X do not match IP dest %8X of packet ",
// pdr_id.rule_id, pdi.second.ue_ip_address.second.ipv4_address.s_addr,
......
......@@ -33,7 +33,8 @@
#include "endpoint.hpp"
#include "msg_pfcp.hpp"
#include <mutex>
#include <memory>
#include "framed_routing/FramedRouting.hpp"
namespace pfcp {
class pfcp_session;
......@@ -50,7 +51,6 @@ class pfcp_pdr {
std::pair<bool, pfcp::urr_id_t> urr_id;
std::pair<bool, pfcp::qer_id_t> qer_id;
std::pair<bool, pfcp::activate_predefined_rules_t> activate_predefined_rules;
bool notified_cp;
explicit pfcp_pdr(uint64_t lseid)
......
......@@ -33,6 +33,7 @@
#include "pfcp_far.hpp"
#include "pfcp_pdr.hpp"
#include "pfcp_qer.hpp"
#include "framed_routing/FramedRouting.hpp"
namespace pfcp {
......
This diff is collapsed.
......@@ -50,6 +50,8 @@
#include <variant>
#include <pthread.h>
#include "framed_routing/FramedRouting.hpp"
#include "framed_routing/LocalRouting.hpp"
namespace oai {
namespace upf {
......@@ -93,6 +95,11 @@ class pfcp_switch {
#define PFCP_SWITCH_MIN_COMMIT_INTERVAL_MILLISECONDS 50
// switching_data_per_cpu_socket switching_data[];
const std::shared_ptr<fr::LocalRouting> local_routing =
std::make_shared<fr::LocalRouting>();
const std::shared_ptr<fr::FramedRouting> fr =
std::make_shared<fr::FramedRouting>(local_routing);
std::unordered_map<pfcp::fseid_t, std::shared_ptr<pfcp::pfcp_session>>
cp_fseid2pfcp_sessions;
folly::AtomicHashMap<uint64_t, std::shared_ptr<pfcp::pfcp_session>>
......
......@@ -2,6 +2,7 @@
#define __BPFMAP_H__
#include <bpf/bpf.h>
#include <cerrno>
#include <bpf/libbpf.h>
#include "logger.hpp"
......@@ -110,7 +111,9 @@ int BPFMap::update(KeyType& key, ValueType& value, int flags) {
if (updateReturn != 0) {
// FIXME: Maybe Key is not support by fmt.
Logger::upf_app().error("The key cannot be updated in map");
Logger::upf_app().error(
"The key cannot be updated in map: %s (errno: %d, %s)", mName.c_str(),
errno, strerror(errno));
throw std::runtime_error("The BPF map cannot be updated");
} else {
Logger::upf_app().debug("The key is updated in the map: %s", mName.c_str());
......
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