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
3ddf55f7
Commit
3ddf55f7
authored
Oct 23, 2025
by
Franck Messaoudi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix: fix m_qos_enabling value within the map
parent
335fec3a
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
356 additions
and
2 deletions
+356
-2
src/upf_app/bpf/rules/far/arp_table_maps.h
src/upf_app/bpf/rules/far/arp_table_maps.h
+12
-0
src/upf_app/bpf/rules/far/far_maps.h
src/upf_app/bpf/rules/far/far_maps.h
+49
-0
src/upf_app/bpf/rules/far/far_xdp_kernel.c
src/upf_app/bpf/rules/far/far_xdp_kernel.c
+287
-0
src/upf_app/bpf/rules/include/pfcp_session_lookup_maps.h
src/upf_app/bpf/rules/include/pfcp_session_lookup_maps.h
+2
-1
src/upf_app/programs/pfcp_session_lookup_xdp_user.cpp
src/upf_app/programs/pfcp_session_lookup_xdp_user.cpp
+6
-1
No files found.
src/upf_app/bpf/rules/far/arp_table_maps.h
0 → 100644
View file @
3ddf55f7
#ifndef __ARP_TABLE_MAP_H__
#define __ARP_TABLE_MAP_H__
#include <types.h>
//#include <stdint.h>
struct
s_arp_mapping
{
uint8_t
mac_address
[
6
];
uint32_t
ipv4_address
;
};
#endif // __ARP_TABLE_MAP_H__
\ No newline at end of file
src/upf_app/bpf/rules/far/far_maps.h
0 → 100644
View file @
3ddf55f7
#ifndef __FAR_MAPS_H__
#define __FAR_MAPS_H__
#include <bpf_helpers.h>
#include <linux/bpf.h>
#include <pfcp/pfcp_far.h>
#include <types.h>
#include "arp_table_maps.h"
#define ARP_ENTRIES_MAX_SIZE 10000
#define FAR_TAILS_MAX 20
#define MAX_INTERFACES 10
#define MAX_FAR_PROGRAMS 10000
/*---------------------------------------------------------------------------------------------------------------*/
// struct {
// __uint(type, BPF_MAP_TYPE_HASH);
// __uint(max_entries, FAR_TAILS_MAX);
// __type(key, u8);
// __type(value, pfcp_far_t_);
// } m_far SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
struct
{
__uint
(
type
,
BPF_MAP_TYPE_DEVMAP
);
__uint
(
max_entries
,
MAX_INTERFACES
);
__type
(
key
,
u32
);
// id
__type
(
value
,
u32
);
// tx port
}
m_redirect_interfaces
SEC
(
".maps"
);
/*---------------------------------------------------------------------------------------------------------------*/
struct
{
__uint
(
type
,
BPF_MAP_TYPE_HASH
);
__uint
(
max_entries
,
ARP_ENTRIES_MAX_SIZE
);
__type
(
key
,
u32
);
// IPv4 address
__type
(
value
,
struct
s_arp_mapping
);
// <IP Address, MAC address>
}
m_arp_table
SEC
(
".maps"
);
/*---------------------------------------------------------------------------------------------------------------*/
// struct {
// __uint(type, BPF_MAP_TYPE_HASH);
// __uint(max_entries, MAX_FAR_PROGRAMS);
// __type(key, u32);
// __type(value, u32);
// } m_enforcing_qos SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
#endif // __FAR_MAPS_H__
src/upf_app/bpf/rules/far/far_xdp_kernel.c
0 → 100644
View file @
3ddf55f7
// clang-format off
#include <types.h>
// clang-format on
#include "xdp_stats_kern.h"
#include <bpf_helpers.h>
#include <endian.h>
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <pfcp/pfcp_far.h>
#include <pfcp/pfcp_pdr.h>
#include <protocols/gtpu.h>
#include <protocols/ip.h>
#include <protocols/tcp.h>
#include <utils/csum.h>
#include <utils/logger.h>
#include <utils/utils.h>
#include <far_maps.h>
#include <interfaces.h>
#include <pfcp_session_lookup_maps.h>
#include <string.h> //Needed for memcpy
#include "bpf_endian.h"
/*****************************************************************************************************************/
static
__always_inline
bool
retrieve_upf_iface_from_map
(
e_reference_point
key
,
u32
*
iface_ip
)
{
struct
s_interface
*
map_element
=
bpf_map_lookup_elem
(
&
m_upf_interfaces
,
&
key
);
if
(
map_element
)
{
*
iface_ip
=
map_element
->
ipv4_address
;
return
true
;
}
return
false
;
}
/*****************************************************************************************************************/
static
__always_inline
bool
update_dst_mac_address
(
u32
ip
,
struct
ethhdr
*
p_eth
)
{
struct
s_arp_mapping
*
map_entry
=
{
0
};
// memset(&map_entry, 0, sizeof(struct s_arp_mapping));
map_entry
=
bpf_map_lookup_elem
(
&
m_arp_table
,
&
ip
);
if
(
map_entry
)
{
memcpy
(
p_eth
->
h_dest
,
map_entry
->
mac_address
,
sizeof
(
p_eth
->
h_dest
));
return
true
;
}
return
false
;
}
/*****************************************************************************************************************/
static
__always_inline
u32
create_outer_header_gtpu_ipv4
(
struct
xdp_md
*
ctx
,
pfcp_far_t_
*
p_far
)
{
// bpf_debug("Create Outer Header GTPU_IPv4");
// bpf_debug("Original Packet: Data/UDP/IP/ETH");
// Adjust space to the left.
if
(
bpf_xdp_adjust_head
(
ctx
,
(
int32_t
)
-
GTP_ENCAPSULATED_SIZE
))
{
return
XDP_DROP
;
}
void
*
data
=
(
void
*
)
(
long
)
ctx
->
data
;
void
*
data_end
=
(
void
*
)
(
long
)
ctx
->
data_end
;
// Retrieve the N3 Interface IP address:
e_reference_point
n3_key
=
N3_INTERFACE
;
u32
n3_ip
;
if
(
!
retrieve_upf_iface_from_map
(
n3_key
,
&
n3_ip
))
{
bpf_debug
(
"N3 interface is missing in UPF map, Drop the packet"
);
return
XDP_DROP
;
}
/*
|----------------------------------------------------------------|
|----------------------- Update ETH header ----------------------|
|----------------------------------------------------------------|
*/
struct
ethhdr
*
ethh
=
data
;
if
((
void
*
)
(
ethh
+
1
)
>
data_end
)
{
bpf_debug
(
"Invalid pointer"
);
return
XDP_DROP
;
}
struct
ethhdr
*
ethh_orig
=
data
+
GTP_ENCAPSULATED_SIZE
;
if
((
void
*
)
(
ethh_orig
+
1
)
>
data_end
)
{
bpf_debug
(
"Invalid Pointer"
);
return
XDP_DROP
;
}
__builtin_memcpy
(
ethh
,
ethh_orig
,
sizeof
(
*
ethh
));
/*
|----------------------------------------------------------------|
|-------------------------- Add IP header -----------------------|
|----------------------------------------------------------------|
*/
struct
iphdr
*
iph
=
(
void
*
)
(
ethh
+
1
);
if
((
void
*
)
(
iph
+
1
)
>
data_end
)
{
return
XDP_DROP
;
}
struct
iphdr
*
p_inner_ip
=
(
void
*
)
iph
+
GTP_ENCAPSULATED_SIZE
;
if
((
void
*
)
(
p_inner_ip
+
1
)
>
data_end
)
{
return
XDP_DROP
;
}
iph
->
version
=
4
;
iph
->
ihl
=
5
;
// No options
iph
->
tos
=
0
;
iph
->
tot_len
=
bpf_htons
(
bpf_ntohs
(
p_inner_ip
->
tot_len
)
+
GTP_ENCAPSULATED_SIZE
);
iph
->
id
=
0
;
// No fragmentation
iph
->
frag_off
=
0x0040
;
// Don't fragment; Fragment offset = 0
iph
->
ttl
=
64
;
iph
->
protocol
=
IPPROTO_UDP
;
iph
->
check
=
0
;
iph
->
saddr
=
n3_ip
;
iph
->
daddr
=
p_far
->
forwarding_parameters
.
outer_header_creation
.
ipv4_address
.
s_addr
;
// bpf_debug("IP SRC: 0x%x, IP DST: 0x%x", iph->saddr, iph->daddr);
/*
|----------------------------------------------------------------|
|-------------------------- Add UDP header ----------------------|
|----------------------------------------------------------------|
*/
struct
udphdr
*
udph
=
(
void
*
)
(
iph
+
1
);
if
((
void
*
)
(
udph
+
1
)
>
data_end
)
{
return
XDP_DROP
;
}
udph
->
source
=
bpf_htons
(
GTP_UDP_PORT
);
udph
->
dest
=
bpf_htons
(
GTP_UDP_PORT
);
// bpf_htons(p_far->forwarding_parameters.outer_header_creation.port_number);
udph
->
len
=
bpf_htons
(
bpf_ntohs
(
p_inner_ip
->
tot_len
)
+
sizeof
(
*
udph
)
+
sizeof
(
struct
gtpuhdr
)
+
sizeof
(
struct
gtpu_extn_pdu_session_container
));
udph
->
check
=
0
;
/*
|----------------------------------------------------------------|
|-------------------------- Add GTP header ----------------------|
|----------------------------------------------------------------|
*/
// Update destination mac address
if
(
!
update_dst_mac_address
(
n3_ip
,
ethh
))
{
bpf_debug
(
"N3's Next Hop MAC address not found! Drop the packet"
);
}
struct
gtpuhdr
*
p_gtpuh
=
(
void
*
)
(
udph
+
1
);
if
((
void
*
)
(
p_gtpuh
+
1
)
>
data_end
)
{
return
XDP_DROP
;
}
u8
flags
=
GTP_EXT_FLAGS
;
__builtin_memcpy
(
p_gtpuh
,
&
flags
,
sizeof
(
u8
));
p_gtpuh
->
message_type
=
GTPU_G_PDU
;
p_gtpuh
->
message_length
=
bpf_htons
(
bpf_ntohs
(
p_inner_ip
->
tot_len
)
+
sizeof
(
struct
gtpu_extn_pdu_session_container
)
+
4
);
p_gtpuh
->
teid
=
bpf_htonl
(
p_far
->
forwarding_parameters
.
outer_header_creation
.
teid
);
p_gtpuh
->
sequence
=
GTP_SEQ
;
p_gtpuh
->
pdu_number
=
GTP_PDU_NUMBER
;
p_gtpuh
->
next_ext_type
=
GTP_NEXT_EXT_TYPE
;
/*
|----------------------------------------------------------------|
|-------------------- Add GTP extension header ------------------|
|----------------------------------------------------------------|
*/
struct
gtpu_extn_pdu_session_container
*
p_gtpu_ext_h
=
(
void
*
)
(
p_gtpuh
+
1
);
if
((
void
*
)
(
p_gtpu_ext_h
+
1
)
>
data_end
)
{
return
XDP_DROP
;
}
p_gtpu_ext_h
->
message_length
=
GTP_EXT_MSG_LEN
;
p_gtpu_ext_h
->
pdu_type
=
GTP_EXT_PDU_TYPE
;
// p_gtpu_ext_h->qfi = GTP_EXT_QFI;
p_gtpu_ext_h
->
qfi
=
GTP_DEFAULT_QFI
;
p_gtpu_ext_h
->
next_ext_type
=
GTP_EXT_NEXT_EXT_TYPE
;
/*
|----------------------------------------------------------------|
|---------------------- Compute L3 CHECKSUM ---------------------|
|----------------------------------------------------------------|
*/
__wsum
l3sum
=
pcn_csum_diff
(
0
,
0
,
(
__be32
*
)
iph
,
sizeof
(
*
iph
),
0
);
int
ret
=
pcn_l3_csum_replace
(
ctx
,
IP_CSUM_OFFSET
,
0
,
l3sum
,
0
);
if
(
ret
)
{
bpf_debug
(
"Checksum Calculation Error %d
\n
"
,
ret
);
}
bpf_debug
(
"Pushes the GTP-Encapsulated Packet: Data/UDP/IP/EXT/GTP/UDP/IP/ETH"
);
return
XDP_PASS
;
}
/*****************************************************************************************************************/
SEC
(
"xdp"
)
int
far_entry_point
(
struct
xdp_md
*
ctx
)
{
bpf_debug
(
"================< FAR Sesction >================"
);
void
*
data
=
(
void
*
)
(
long
)
ctx
->
data
;
void
*
data_end
=
(
void
*
)
(
long
)
ctx
->
data_end
;
u32
key
=
0
;
pfcp_far_t_
*
p_far
;
//= bpf_map_lookup_elem(&m_far, &key);
if
(
p_far
)
{
struct
ethhdr
*
ethh
=
data
;
if
((
void
*
)
(
ethh
+
1
)
>
data_end
)
{
bpf_debug
(
"Invalid pointer"
);
return
XDP_DROP
;
}
// Check if it is a forward action.
u8
dest_interface
=
p_far
->
forwarding_parameters
.
destination_interface
.
interface_value
;
// u16 outer_header_creation =
// p_far->forwarding_parameters.outer_header_creation
// .outer_header_creation_description;
// Check forwarding action
if
(
!
p_far
->
apply_action
.
forw
)
{
bpf_debug
(
"Forward Action Is NOT set"
);
return
XDP_PASS
;
}
if
(
dest_interface
==
INTERFACE_VALUE_CORE
)
{
// Redirect to data network.
bpf_debug
(
"GTP Header Removal ..."
);
struct
ethhdr
*
p_new_eth
=
data
+
GTP_ENCAPSULATED_SIZE
;
if
((
void
*
)
(
p_new_eth
+
1
)
>
data_end
)
{
return
XDP_DROP
;
}
__builtin_memcpy
(
p_new_eth
,
ethh
,
sizeof
(
*
ethh
));
// Retrieve the N6 Interface IP address:
e_reference_point
n6_key
=
N6_INTERFACE
;
u32
n6_ip
;
if
(
!
retrieve_upf_iface_from_map
(
n6_key
,
&
n6_ip
))
{
bpf_debug
(
"N6 interface is missing in UPF map, Drop the packet"
);
return
XDP_DROP
;
}
// Update destination mac address
if
(
!
update_dst_mac_address
(
n6_ip
,
p_new_eth
))
{
bpf_debug
(
"N6's Next Hop MAC address not found! Drop the packet"
);
}
// Adjust head to the right.
if
(
bpf_xdp_adjust_head
(
ctx
,
GTP_ENCAPSULATED_SIZE
))
{
return
XDP_DROP
;
}
bpf_debug
(
"The Packet is redirected for transmission to DN ..."
);
return
bpf_redirect_map
(
&
m_redirect_interfaces
,
UPLINK
,
0
);
bpf_debug
(
"OUTER_HEADER_CREATION_UDP_IPV4 REDIRECT FAILED"
);
}
else
if
(
dest_interface
==
INTERFACE_VALUE_ACCESS
)
{
create_outer_header_gtpu_ipv4
(
ctx
,
p_far
);
return
bpf_redirect_map
(
&
m_redirect_interfaces
,
DOWNLINK
,
0
);
}
}
bpf_debug
(
"FAR Program NOT Found!"
);
return
XDP_DROP
;
}
char
_license
[]
SEC
(
"license"
)
=
"GPL"
;
/*---------------------------------------------------------------------------------------------------------------*/
src/upf_app/bpf/rules/include/pfcp_session_lookup_maps.h
View file @
3ddf55f7
...
...
@@ -20,6 +20,7 @@ const volatile int max_pdu_session SEC(".rodata");
const
volatile
int
max_pdrs_per_pdu_session
SEC
(
".rodata"
);
const
volatile
int
max_sdf_filters_per_pdu_session
SEC
(
".rodata"
);
const
volatile
int
max_arp_entries
SEC
(
".rodata"
);
const
volatile
int
max_qos_enabling
SEC
(
".rodata"
);
struct
{
__uint
(
type
,
BPF_MAP_TYPE_HASH
);
...
...
@@ -58,7 +59,7 @@ struct {
struct
{
__uint
(
type
,
BPF_MAP_TYPE_HASH
);
__uint
(
max_entries
,
1
);
/* max_pdu_session */
__uint
(
max_entries
,
1
);
/* max_
qos_enabling = max_
pdu_session */
__type
(
key
,
u64
);
// seid
__type
(
value
,
u32
);
// Value type (0 for false, 1 for true)
}
m_qos_enabling
SEC
(
".maps"
);
...
...
src/upf_app/programs/pfcp_session_lookup_xdp_user.cpp
View file @
3ddf55f7
...
...
@@ -62,6 +62,8 @@ void PFCP_Session_LookupProgram::configurePfcpSessionLookupMaps(
uint32_t
max_rules_match_pdr
=
upf_cfg
.
max_pdrs_per_pdu_session
*
upf_cfg
.
max_pdu_session
;
uint32_t
max_qos_enabling
=
upf_cfg
.
max_pdu_session
;
bool
ok
=
true
;
ok
&=
configure_map_max_entries
(
skel
->
maps
.
m_upf_interfaces
,
"m_upf_interfaces"
,
...
...
@@ -82,6 +84,8 @@ void PFCP_Session_LookupProgram::configurePfcpSessionLookupMaps(
skel
->
maps
.
m_arp_table
,
"m_arp_table"
,
upf_cfg
.
max_arp_entries
);
ok
&=
configure_map_max_entries
(
skel
->
maps
.
m_rules_match_pdr
,
"m_rules_match_pdr"
,
max_rules_match_pdr
);
ok
&=
configure_map_max_entries
(
skel
->
maps
.
m_qos_enabling
,
"m_qos_enabling"
,
max_qos_enabling
);
if
(
!
ok
)
{
Logger
::
upf_app
().
error
(
"One or more BPF map configurations failed for PFCP Session Lookup "
...
...
@@ -99,6 +103,7 @@ void PFCP_Session_LookupProgram::configurePfcpSessionLookupMaps(
skel
->
rodata
->
max_sdf_filters_per_pdu_session
=
upf_cfg
.
max_sdf_filters_per_pdu_session
;
skel
->
rodata
->
max_arp_entries
=
upf_cfg
.
max_arp_entries
;
skel
->
rodata
->
max_qos_enabling
=
upf_cfg
.
max_pdu_session
;
}
}
...
...
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