Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
oai-upf-6g
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
oai-upf-6g
Commits
c947e23b
Commit
c947e23b
authored
Nov 26, 2024
by
Lukas Rotheneder
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(upf): draft framed routing for ebpf
parent
cbac0e14
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
88 additions
and
53 deletions
+88
-53
src/upf_app/SessionManager.cpp
src/upf_app/SessionManager.cpp
+21
-3
src/upf_app/SessionProgramManager.cpp
src/upf_app/SessionProgramManager.cpp
+5
-2
src/upf_app/bpf/rules/include/pfcp_session_lookup_maps.h
src/upf_app/bpf/rules/include/pfcp_session_lookup_maps.h
+1
-25
src/upf_app/bpf/rules/pdr/framed_routing_bpf.h
src/upf_app/bpf/rules/pdr/framed_routing_bpf.h
+31
-0
src/upf_app/bpf/rules/pdr/pfcp_session_lookup_xdp_kernel.c
src/upf_app/bpf/rules/pdr/pfcp_session_lookup_xdp_kernel.c
+15
-15
src/upf_app/programs/pfcp_session_lookup_xdp_user.cpp
src/upf_app/programs/pfcp_session_lookup_xdp_user.cpp
+5
-4
src/upf_app/programs/pfcp_session_lookup_xdp_user.h
src/upf_app/programs/pfcp_session_lookup_xdp_user.h
+2
-2
src/upf_app/simpleswitch/pfcp_switch.cpp
src/upf_app/simpleswitch/pfcp_switch.cpp
+1
-1
src/upf_app/wrappers/BPFMap.hpp
src/upf_app/wrappers/BPFMap.hpp
+7
-1
No files found.
src/upf_app/SessionManager.cpp
View file @
c947e23b
...
...
@@ -306,7 +306,7 @@ void SessionManager::createSessionDirection(
if
(
!
pdrs
.
empty
())
{
auto
pdrHighPrecedence
=
pdrs
.
front
();
logger
.
debug
(
"The
$s PDR %d
has the Highest Precedence"
,
direction
,
"The
%s PDR %u
has the Highest Precedence"
,
direction
,
pdrHighPrecedence
->
pdr_id
.
rule_id
);
if
(
direction
==
"Uplink"
)
{
createBPFSessionUL
(
pSession_establishment
,
pdrHighPrecedence
);
...
...
@@ -398,6 +398,8 @@ void SessionManager::processPDRDetails(
std
::
vector
<
std
::
shared_ptr
<
pfcp
::
pfcp_qer
>>
pQer
;
logger
.
debug
(
"upf_cfg.enable_fr: %s, %s PDR"
,
upf_cfg
.
enable_fr
?
"true"
:
"false"
,
direction
);
if
(
upf_cfg
.
enable_fr
&&
direction
==
"Downlink"
)
{
//TODO check
if
(
ueIpAddress
.
v4
){
std
::
vector
<
pfcp
::
framed_route_t
>
framedRoutes
;
...
...
@@ -467,7 +469,7 @@ void SessionManager::updateBPFSession(
auto
pdrHighPrecedenceDl
=
pSession
->
pdrs_downlink
[
0
];
Logger
::
upf_app
().
debug
(
"The Downlink PDR %
d
has the Highest Precedence"
,
"The Downlink PDR %
u
has the Highest Precedence"
,
pdrHighPrecedenceDl
->
pdr_id
.
rule_id
);
Logger
::
upf_app
().
debug
(
...
...
@@ -484,7 +486,7 @@ void SessionManager::updateBPFSession(
auto
pdrHighPrecedenceUl
=
pSession
->
pdrs_uplink
[
0
];
Logger
::
upf_app
().
debug
(
"The Uplink PDR %
d
has the Highest Precedence"
,
"The Uplink PDR %
u
has the Highest Precedence"
,
pdrHighPrecedenceUl
->
pdr_id
.
rule_id
);
Logger
::
upf_app
().
debug
(
...
...
@@ -587,6 +589,22 @@ void SessionManager::updateBPFSessionDL(
// pSession->qerIDsPerPDR.qers;
// std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer = pSession->qers;
auto
&
logger
=
Logger
::
upf_app
();
logger
.
debug
(
"upf_cfg.enable_fr: %s, Downlink PDR"
,
upf_cfg
.
enable_fr
?
"true"
:
"false"
);
if
(
upf_cfg
.
enable_fr
)
{
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"
);
}
}
if
(
teid_ul
)
{
SessionProgramManager
::
getInstance
().
createPipeline
(
seidul
,
fteid
.
teid
,
INTERFACE_VALUE_CORE
,
...
...
src/upf_app/SessionProgramManager.cpp
View file @
c947e23b
...
...
@@ -6,6 +6,7 @@
#include <pfcp_session_lookup_xdp_user.h>
#include <UserPlaneComponent.h>
#include <net/if.h> // if_nametoindex
#include <framed_routing_bpf.h>
#include <observer/OnStateChangeSessionProgramObserver.h>
// #include <pfcp/pfcp_far.h>
...
...
@@ -296,17 +297,19 @@ void SessionProgramManager::addFramedRoutes(uint32_t ueIpAddress, std::vector<pf
uint32_t
cidr
=
0
;
const
std
::
string
ip_substring
=
ipsubnetmask
.
substr
(
0
,
ipsubnetmask
.
find
(
subnet_delimeter
));
ip
=
FramedRouting
::
framedIPToUeIP
(
ip_substring
);
ip
=
fr
::
FramedRouting
::
framedIPToUeIP
(
ip_substring
);
std
::
reverse
(
ipsubnetmask
.
begin
(),
ipsubnetmask
.
end
());
std
::
string
subnet_substring
=
ipsubnetmask
.
substr
(
0
,
ipsubnetmask
.
rfind
(
subnet_delimeter
));
cidr
=
FramedRouting
::
frameSubnetToUInt
(
subnet_substring
);
cidr
=
fr
::
FramedRouting
::
frameSubnetToUInt
(
subnet_substring
);
Logger
::
upf_app
().
debug
(
"Framed Route Subnet: %s -> IP %u, cidr %u"
,
framedRoute
.
framed_route
,
ip
,
cidr
);
auto
key
=
framed_routing_key_for_ip_cidr
(
ip
,
cidr
);
//auto routing_info = createLocalRoutingInformation(ipCidr);
//auto snat_info = createLocalSnatInformation(ipCidr);
pPFCP_Session_LookupProgram
->
updateFramedRouteMappingMap
(
ueIpAddress
,
key
);
Logger
::
upf_app
().
debug
(
"Framed Routing map is updated!"
);
//localRouting->add_route(routing_info);
//localRouting->add_source_snat(snat_info);
}
...
...
src/upf_app/bpf/rules/include/pfcp_session_lookup_maps.h
View file @
c947e23b
...
...
@@ -173,33 +173,9 @@ struct {
/*---------------------------------------------------------------------------------------------------------------*/
/* Framed Routing */
struct
FramedRoutingKeyBPF
{
uint32_t
networkAddress
;
uint32_t
subnet
;
};
static
__always_inline
__u32
hash_framed_routing_key
(
struct
FramedRoutingKeyBPF
*
key
)
{
__u32
hash
=
17
;
hash
=
hash
*
31
+
key
->
networkAddress
;
hash
=
hash
^
key
->
subnet
;
return
hash
;
}
static
__always_inline
struct
FramedRoutingKeyBPF
framed_routing_key_for_ip_cidr
(
__u32
ip
,
__u32
cidr
)
{
const
__u32
ipv4Size
=
32
;
// Calculate the subnet address
__u32
subnet_mask
=
0xffffffff
<<
(
ipv4Size
-
cidr
);
// Calculate the network address
__u32
network_address
=
subnet_mask
&
ip
;
struct
FramedRoutingKeyBPF
key
=
{
network_address
,
subnet_mask
};
return
key
;
}
struct
{
__uint
(
type
,
BPF_MAP_TYPE_HASH
);
__uint
(
max_entries
,
MAX_
LENGTH
);
__uint
(
max_entries
,
MAX_
UEs
);
__type
(
key
,
u32
);
// hash_framed_routing_key
__type
(
value
,
u32
);
// ue_ip
}
m_framed_route_mapping
SEC
(
".maps"
);
...
...
src/upf_app/bpf/rules/pdr/framed_routing_bpf.h
0 → 100644
View file @
c947e23b
#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
src/upf_app/bpf/rules/pdr/pfcp_session_lookup_xdp_kernel.c
View file @
c947e23b
...
...
@@ -19,6 +19,7 @@
#include <utils/logger.h>
#include <utils/utils.h>
#include <next_prog_rule_key.h>
#include <framed_routing_bpf.h>
#ifdef KERNEL_SPACE
#include <linux/in.h>
...
...
@@ -65,25 +66,27 @@ static __always_inline u32 tail_call_next_prog(
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
);
bpf_debug
(
"Handle downlink traffic for UE IP: 0x%x, as u32: %u"
,
ue_ip_address
,
ue_ip_address
);
if
(
teid_dl
)
{
bpf_debug
(
"TEID downlink: 0x%x was found for UE IP: 0x%x"
,
ue_ip_address
,
*
teid_dl
);
"TEID downlink: 0x%x was found for UE IP: 0x%x"
,
*
teid_dl
,
ue_ip_address
);
tail_call_next_prog
(
ctx
,
*
teid_dl
,
INTERFACE_VALUE_CORE
,
ue_ip_address
);
}
else
{
uint32_t
big_endian_ue_ip
=
__builtin_bswap32
(
ue_ip_address
);
bpf_debug
(
"No TEID found, try to find FramedRoute entry for big endian address %u"
,
big_endian_ue_ip
);
#pragma clang loop unroll(full)
for
(
in
t
i
=
32
;
i
>
0
;
i
--
)
{
struct
FramedRoutingKeyBPF
key
=
framed_routing_key_for_ip_cidr
(
ue_ip_address
,
i
);
u32
fr_key
=
hash_framed_routing_key
(
&
key
);
u
32
*
fr_ue_ip
=
bpf_map_lookup_elem
(
&
m_framed_route_mapping
,
&
fr_key
);
for
(
uint32_
t
i
=
32
;
i
>
0
;
i
--
)
{
struct
FramedRoutingKeyBPF
key
=
framed_routing_key_for_ip_cidr
(
big_endian_ue_ip
,
i
);
uint32_t
fr_key
=
hash_framed_routing_key
(
&
key
);
bpf_debug
(
"Check framed route table with key %u (for cidr %u)"
,
fr_key
,
i
);
u
int32_t
*
fr_ue_ip
=
bpf_map_lookup_elem
(
&
m_framed_route_mapping
,
&
fr_key
);
if
(
fr_ue_ip
)
{
bpf_debug
(
"Framed Route detected for IP: 0x%x. UE IP: 0x%x"
,
fr_ue_ip
,
ue_ip_address
);
u32
*
teid_dl
=
bpf_map_lookup_elem
(
&
m_session_mapping
,
&
fr_ue_ip
);
"Framed Route detected for IP: 0x%x. UE IP: 0x%x"
,
fr_ue_ip
,
big_endian_ue_ip
);
u32
*
teid_dl
=
bpf_map_lookup_elem
(
&
m_session_mapping
,
fr_ue_ip
);
if
(
teid_dl
)
{
bpf_debug
(
"TEID downlink: 0x%x was found for Framed Route IP: 0x%x"
,
*
teid_dl
,
ue_ip_address
);
bpf_debug
(
"TEID downlink: 0x%x was found for Framed Route IP: 0x%x"
,
*
teid_dl
,
big_endian_ue_ip
);
tail_call_next_prog
(
ctx
,
*
teid_dl
,
INTERFACE_VALUE_CORE
,
*
fr_ue_ip
);
}
}
...
...
@@ -169,11 +172,8 @@ static __always_inline u32 ipv4_handle(struct xdp_md* ctx, struct iphdr* iph) {
u32
ip_dest
=
iph
->
daddr
;
bpf_debug
(
"UE IP: 0x%x"
,
ip_dest
);
if
(
ip_dest
==
0x0301010c
)
{
ip_dest
=
ip_dest
-
0x01000000
;
bpf_debug
(
"New UE IP: 0x%x"
,
ip_dest
);
}
u8
protocol
=
iph
->
protocol
;
bpf_debug
(
"Protocol: 0x%x"
,
protocol
);
switch
(
protocol
)
{
case
IPPROTO_UDP
:
{
...
...
src/upf_app/programs/pfcp_session_lookup_xdp_user.cpp
View file @
c947e23b
...
...
@@ -8,7 +8,6 @@
#include <wrappers/BPFMaps.h>
#include "interfaces.h"
#include "logger.hpp"
#include <pfcp_session_lookup_maps.h>
/*---------------------------------------------------------------------------------------------------------------*/
int
is_little_endian2
()
{
...
...
@@ -112,8 +111,10 @@ std::shared_ptr<BPFMap> PFCP_Session_LookupProgram::getFramedRouteMappingMap() {
}
/*---------------------------------------------------------------------------------------------------------------*/
void
PFCP_Session_LookupProgram
::
updateFramedRouteMappingMap
(
uint32_t
ue_ip
,
FramedRoutingKey
key
)
{
__u32
hash_key
=
hash_framed_routing_key
(
&
key
);
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 FramedRoutingMappingMap with key: %u, value: %u"
,
hash_key
,
ue_ip
);
mpFramedRouteMappingMap
->
update
(
hash_key
,
ue_ip
,
BPF_ANY
);
}
...
...
@@ -137,7 +138,7 @@ void PFCP_Session_LookupProgram::initializeMaps() {
mpSessionMappingMap
=
std
::
make_shared
<
BPFMap
>
(
mpMaps
->
getMap
(
"m_session_mapping"
));
mpFramedRouteMappingMap
=
std
::
make_shared
<
BPFMap
>
(
mpMaps
->
getMap
(
"m_
ueip_session
"
));
std
::
make_shared
<
BPFMap
>
(
mpMaps
->
getMap
(
"m_
framed_route_mapping
"
));
}
/*---------------------------------------------------------------------------------------------------------------*/
src/upf_app/programs/pfcp_session_lookup_xdp_user.h
View file @
c947e23b
...
...
@@ -8,8 +8,8 @@
#include <mutex>
#include <signal.h> // signals
#include <pfcp_session_lookup_xdp_kernel_skel.h>
#include "pfcp_session_lookup_maps.h"
#include <wrappers/BPFMap.hpp>
#include <framed_routing_bpf.h>
// #include "qfi_flow_mapping_table.h"
class
BPFMaps
;
...
...
@@ -144,7 +144,7 @@ class PFCP_Session_LookupProgram {
std
::
shared_ptr
<
BPFMap
>
getFramedRouteMappingMap
();
void
updateFramedRouteMappingMap
(
uint32_t
ue_ip
,
FramedRoutingKey
key
);
void
updateFramedRouteMappingMap
(
uint32_t
ue_ip
,
FramedRoutingKey
BPF
key
);
void
removeFramedRoute
(
uint32_t
key
);
...
...
src/upf_app/simpleswitch/pfcp_switch.cpp
View file @
c947e23b
...
...
@@ -628,7 +628,7 @@ void pfcp_switch::add_pfcp_dl_pdr_by_ue_ip(
uint32_t
,
std
::
shared_ptr
<
std
::
vector
<
std
::
shared_ptr
<
pfcp
::
pfcp_pdr
>>>>
entry
(
ue_ip
,
pdrs
);
ue_ipv4_hbo2pfcp_pdr
.
insert
(
entry
);
if
(
upf_cfg
.
enable_fr
&&
pdr
->
pdi
.
second
.
framed_route
.
first
)
{
if
(
!
upf_cfg
.
enable_bpf_datapath
&&
upf_cfg
.
enable_fr
&&
pdr
->
pdi
.
second
.
framed_route
.
first
)
{
Logger
::
pfcp_switch
().
info
(
"fr_ue_ip %4x "
,
ue_ip
);
Logger
::
pfcp_switch
().
info
(
"framed routing ip: "
+
...
...
src/upf_app/wrappers/BPFMap.hpp
View file @
c947e23b
...
...
@@ -2,6 +2,7 @@
#define __BPFMAP_H__
#include <bpf/bpf.h>
#include <cerrno>
#include <bpf/libbpf.h>
#include "logger.hpp"
...
...
@@ -116,7 +117,12 @@ 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
());
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment