Commit ba57943a authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'feature_sdf_parsing_for_qos' into 'develop'

Feature sdf parsing for qos

See merge request oai/cn5g/oai-cn5g-upf!73
parents 4d145df8 1af68f68
...@@ -131,7 +131,9 @@ WORKDIR /openair-upf/bin ...@@ -131,7 +131,9 @@ WORKDIR /openair-upf/bin
COPY --from=oai-upf-builder \ COPY --from=oai-upf-builder \
/usr/local/sbin/bpftool \ /usr/local/sbin/bpftool \
/openair-upf/build/upf/build/oai_upf \ /openair-upf/build/upf/build/oai_upf \
/openair-upf/build/upf/build/upf_app/bpf/CMakeFiles/qer_tc.dir/rules/qer/qer_tc_kernel.c.o \
/openair-upf/scripts/healthcheck.sh \ /openair-upf/scripts/healthcheck.sh \
/openair-upf/scripts/entrypoint.sh \
./ ./
WORKDIR /usr/local/lib WORKDIR /usr/local/lib
...@@ -173,3 +175,5 @@ HEALTHCHECK --interval=10s \ ...@@ -173,3 +175,5 @@ HEALTHCHECK --interval=10s \
CMD /openair-upf/bin/healthcheck.sh CMD /openair-upf/bin/healthcheck.sh
CMD ["/openair-upf/bin/oai_upf", "-c", "/openair-upf/etc/config.yaml", "-o"] CMD ["/openair-upf/bin/oai_upf", "-c", "/openair-upf/etc/config.yaml", "-o"]
ENTRYPOINT [ "sh", "/openair-upf/bin/entrypoint.sh" ]
\ No newline at end of file
...@@ -22,9 +22,12 @@ ...@@ -22,9 +22,12 @@
# OAI CN Configuration File # OAI CN Configuration File
### This file can be used by all OAI NFs ### This file can be used by all OAI NFs
### Some fields are specific to an NF and will be ignored by other NFs ### Some fields are specific to an NF and will be ignored by other NFs
### The {{ env['ENV_NAME'] }} syntax lets you define these values in a docker-compose file
### If you intend to mount this file or use a bare-metal deployment, please refer to README.md ## NOTE ON YAML ANCHORS ##
### The README.md also defines default values and allowed values for each configuration parameter # We use YAML anchors to ease the configuration and to avoid duplicating parts of the configuration.
# This is especially true for the SNSSAIs, as we have to define them for multiple NFs.
# Please note that the use of anchors is not mandatory, and you can define the SNSSAI in each NF yourself.
# You can read more about anchors here: https://yaml.org/spec/1.2.2/#anchors-and-aliases
############# Common configuration ############# Common configuration
...@@ -35,7 +38,7 @@ log_level: ...@@ -35,7 +38,7 @@ log_level:
# If you enable registration, the other NFs will use the NRF discovery mechanism # If you enable registration, the other NFs will use the NRF discovery mechanism
register_nf: register_nf:
general: yes general: yes
http_version: 2 http_version: 2
############## SBI Interfaces ############## SBI Interfaces
...@@ -74,7 +77,7 @@ nfs: ...@@ -74,7 +77,7 @@ nfs:
n6: n6:
interface_name: demo-n6 interface_name: demo-n6
n9: n9:
interface_name: demo-oai interface_name: demo-n9
port: 2152 port: 2152
udm: udm:
host: oai-udm host: oai-udm
...@@ -100,6 +103,12 @@ nfs: ...@@ -100,6 +103,12 @@ nfs:
port: 8080 port: 8080
api_version: v1 api_version: v1
interface_name: eth0 interface_name: eth0
pcf:
host: oai-pcf
sbi:
port: 8080
api_version: v1
interface_name: eth0
#### Common for UDR and AMF #### Common for UDR and AMF
database: database:
...@@ -125,41 +134,39 @@ snssais: ...@@ -125,41 +134,39 @@ snssais:
############## NF-specific configuration ############## NF-specific configuration
amf: amf:
pid_directory: "/var/run"
amf_name: "OAI-AMF" amf_name: "OAI-AMF"
# This really depends on if we want to keep the "mini" version or not # This really depends on if we want to keep the "mini" version or not
support_features_options: support_features_options:
enable_simple_scenario: no enable_simple_scenario: no # "no" by default with the normal deployment scenarios with AMF/SMF/UPF/AUSF/UDM/UDR/NRF.
# set it to "yes" to use with the minimalist deployment scenario (including only AMF/SMF/UPF) by using the internal AUSF/UDM implemented inside AMF.
# There's no NRF in this scenario, SMF info is taken from "nfs" section.
enable_nssf: no enable_nssf: no
enable_smf_selection: yes enable_smf_selection: yes
use_external_udm: no
relative_capacity: 30 relative_capacity: 30
statistics_timer_interval: 20 #in seconds statistics_timer_interval: 20 # in seconds
emergency_support: false emergency_support: false
served_guami_list: served_guami_list:
- mcc: 208 - mcc: 208
mnc: 95 mnc: 95
amf_region_id: 128 amf_region_id: 01
amf_set_id: 1 amf_set_id: 001
amf_pointer: 1 amf_pointer: 01
- mcc: 460 - mcc: 001
mnc: 11 mnc: 01
amf_region_id: 10 amf_region_id: 01
amf_set_id: 1 amf_set_id: 001
amf_pointer: 1 amf_pointer: 01
plmn_support_list: plmn_support_list:
- mcc: 208 - mcc: 208
mnc: 95 mnc: 95
tac: 0xa000 tac: 0xa000
nssai: nssai:
- sst: 1 - *embb_slice1
- sst: 1 - *embb_slice2
sd: 000001 - *custom_slice
- sst: 222
sd: 00007B
supported_integrity_algorithms: supported_integrity_algorithms:
- "NIA0"
- "NIA1" - "NIA1"
- "NIA0"
- "NIA2" - "NIA2"
supported_encryption_algorithms: supported_encryption_algorithms:
- "NEA0" - "NEA0"
...@@ -169,14 +176,14 @@ amf: ...@@ -169,14 +176,14 @@ amf:
smf: smf:
ue_mtu: 1500 ue_mtu: 1500
support_features: support_features:
use_local_subscription_info: yes # Use infos from local_subscription_info or from UDM use_local_subscription_info: no # Use infos from local_subscription_info or from UDM
use_local_pcc_rules: yes # Use infos from local_pcc_rules or from PCF use_local_pcc_rules: no # Use infos from local_pcc_rules or from PCF
# we resolve from NRF, this is just to configure usage_reporting # we resolve from NRF, this is just to configure usage_reporting
upfs: upfs:
# - host: oai-spgwu - host: 192.168.70.129
- host: oai-upf
config: config:
enable_usage_reporting: no enable_usage_reporting: no
enable_qers: no
ue_dns: ue_dns:
primary_ipv4: "172.21.3.100" primary_ipv4: "172.21.3.100"
primary_ipv6: "2001:4860:4860::8888" primary_ipv6: "2001:4860:4860::8888"
...@@ -185,26 +192,33 @@ smf: ...@@ -185,26 +192,33 @@ smf:
ims: ims:
pcscf_ipv4: "127.0.0.1" pcscf_ipv4: "127.0.0.1"
pcscf_ipv6: "fe80::7915:f408:1787:db8b" pcscf_ipv6: "fe80::7915:f408:1787:db8b"
# the DNN you configure here should be configured in "dnns" # the DNN you configure here should be configured in "dnns"
# follows the SmfInfo datatype from 3GPP TS 29.510
smf_info:
sNssaiSmfInfoList:
- sNssai: *embb_slice1
dnnSmfInfoList:
- dnn: "oai"
- sNssai: *embb_slice2
dnnSmfInfoList:
- dnn: "oai.ipv4"
- sNssai: *custom_slice
dnnSmfInfoList:
- dnn: "default"
local_subscription_infos: local_subscription_infos:
- single_nssai: - single_nssai: *embb_slice1
sst: 1
dnn: "oai" dnn: "oai"
qos_profile: qos_profile:
5qi: 9 5qi: 9
session_ambr_ul: "200Mbps" session_ambr_ul: "200Mbps"
session_ambr_dl: "400Mbps" session_ambr_dl: "400Mbps"
- single_nssai: - single_nssai: *embb_slice2
sst: 1
sd: 1
dnn: "oai.ipv4" dnn: "oai.ipv4"
qos_profile: qos_profile:
5qi: 9 5qi: 9
session_ambr_ul: "100Mbps" session_ambr_ul: "100Mbps"
session_ambr_dl: "200Mbps" session_ambr_dl: "200Mbps"
- single_nssai: - single_nssai: *custom_slice
sst: 222
sd: 123
dnn: "default" dnn: "default"
qos_profile: qos_profile:
5qi: 9 5qi: 9
...@@ -213,12 +227,9 @@ smf: ...@@ -213,12 +227,9 @@ smf:
upf: upf:
support_features: support_features:
enable_bpf_datapath: yes # If "yes": BPF is used as datapath else simpleswitch is used, DEFAULT= no enable_bpf_datapath: yes # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off
enable_qos: no # Only supported for BPF datapath. If "yes" we use qdisc to manage the QoS enable_qos: yes
enable_snat: no # If "no": Source natting is done for UE, DEFAULT= no
remote_n6_gw: oai-ext-dn remote_n6_gw: oai-ext-dn
smfs:
- host: oai-smf # To be used for PFCP association in case of no-NRF
upf_info: upf_info:
sNssaiUpfInfoList: sNssaiUpfInfoList:
- sNssai: *embb_slice1 - sNssai: *embb_slice1
...@@ -235,13 +246,20 @@ upf: ...@@ -235,13 +246,20 @@ upf:
dnns: dnns:
- dnn: "oai" - dnn: "oai"
pdu_session_type: "IPV4" pdu_session_type: "IPV4"
ipv4_subnet: "12.1.1.0/24" ipv4_subnet: "12.1.1.128/25"
- dnn: "oai.ipv4" - dnn: "oai.ipv4"
pdu_session_type: "IPV4" pdu_session_type: "IPV4"
ipv4_subnet: "12.1.2.0/24" ipv4_subnet: "12.1.1.64/26"
- dnn: "default" - dnn: "default"
pdu_session_type: "IPV4" pdu_session_type: "IPV4"
ipv4_subnet: "12.1.3.0/24" ipv4_subnet: "12.1.1.0/26"
- dnn: "ims" - dnn: "ims"
pdu_session_type: "IPV4V6" pdu_session_type: "IPV4V6"
ipv4_subnet: "14.1.1.2/24" ipv4_subnet: "14.1.1.2/24"
pcf:
local_policy:
policy_decisions_path: /openair-pcf/policies/policy_decisions
pcc_rules_path: /openair-pcf/policies/pcc_rules
traffic_rules_path: /openair-pcf/policies/traffic_rules
qos_data_path: /openair-pcf/policies/qos_data
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (the "License"); you may not use this file
# except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.openairinterface.org/?page_id=698
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
# OAI UPF EBPF MAP SIZES Configuration File
###
# This configuration file defines key parameters for optimizing memory allocation and tuning the User Plane Function (UPF). The values set in this file directly impact the size of eBPF maps used for packet processing.
# Configuration Parameters. Each parameter in this file controls a specific aspect of UPF behavior.
# 1. Network Interface Limits
# max_upf_interfaces (Default: 8)
# Specifies the maximum number of network interfaces that UPF can manage.
# Example: Physical/virtual interfaces for GTP-U traffic.
# max_upf_redirect_interfaces (Default: 4)
# Defines the maximum number of interfaces used for traffic redirection.
# Example: Used in PDRs for forwarding packets to specific egress interfaces.
max_upf_interfaces = 8
max_upf_redirect_interfaces = 4
# 2. Session and Rule Limits
# max_pdu_session (Default: 10,000)
# Determines the maximum number of concurrent PDU sessions that UPF can handle.
# Affects the memory allocation for session-related eBPF maps.
# max_pdrs_per_pdu_session (Default: 8)
# Defines the maximum number of Packet Detection Rules (PDRs) that can be applied per PDU session.
# PDRs dictate how packets are processed, forwarded, or dropped.
# max_qos_flows_per_pdu_session (Default: 8)
# Sets the maximum number of QoS flows that a single PDU session can manage.
# Impacts QoS-related eBPF maps (e.g., shaping, policing).
# max_sdf_filters_per_pdu_session (Default: 8)
# Specifies the maximum number of Service Data Flow (SDF) filters per session.
# SDF filters define how traffic is classified within a QoS flow.
max_pdu_session = 10000
max_pdrs_per_pdu_session = 8
max_qos_flows_per_pdu_session = 8
max_sdf_filters_per_pdu_session = 8
# 3. ARP Table Limit
# max_arp_entries (Default: 4)
# Limits the number of ARP table entries stored in eBPF maps.
# Used for resolving MAC addresses in the UPF forwarding path.
max_arp_entries = 1572
# Usage Instructions
# Modify Configuration Values
# Edit the file ebpf_maps.conf to adjust UPF parameters based on deployment needs.
# Example:
# max_pdu_session = 5000
# max_pdrs_per_pdu_session = 16
# Loading the Configuration in Code
# A configuration parser (e.g., ConfigLoader) should read this file and apply the values at runtime.
# Example (C++):
# ConfigLoader config;
# config.loadConfig("upf_config.conf");
# int max_pdu_sessions = config.getValue("max_pdu_session", 10000);
# Memory Optimization
# Ensure the values are optimized to avoid excessive memory usage.
# Example: Reducing max_pdu_session decreases memory footprint.
# Best Practices
# Monitor Resource Usage: Adjust values based on system memory and performance requirements.
# Tune PDU Session Limits: Increase max_pdu_session if handling high session loads.
# Optimize QoS Handling: Set appropriate values for max_qos_flows_per_pdu_session based on traffic characteristics.
#!/bin/sh #!/bin/sh
sudo ip link set dev demo-n3 xdp off sudo ip link set dev enp1s0f0np0 xdp off
sudo ip link set dev demo-n6 xdp off sudo ip link set dev enp1s0f1np1 xdp off
#!/bin/sh
# Mount bpffs and debugfs if not present already
if [ $(/bin/mount | /bin/grep /sys/fs/bpf -c) -eq 0 ]; then
/bin/mount bpffs /sys/fs/bpf -t bpf;
fi
if [ $(/bin/mount | /bin/grep debugfs -c) -eq 0 ]; then
/bin/mount debugfs /sys/kernel/debug -t debugfs;
fi
exec "$@"
#!/bin/bash #!/bin/bash
set -eo pipefail set -eo pipefail
STATUS=0
SGW_PORT_FOR_N3=2152 ######################################################################################################
SGW_PORT_FOR_SX=8805 # Function to check if BPF datapath is enabled
SGW_IP_N3_INTERFACE=$(ifconfig $SGW_INTERFACE_NAME_FOR_N3 | grep inet | awk {'print $2'}) ######################################################################################################
SGW_IP_SX_INTERFACE=$(ifconfig $SGW_INTERFACE_NAME_FOR_SX | grep inet | awk {'print $2'}) check_enable_bpf_datapath() {
if [[ ${ENABLE_BPF_DATAPATH} == "no" ]]; then enable_bpf_datapath=$(cat /openair-upf/etc/*.yaml | grep "enable_bpf_datapath:" | awk '{print $2}')
N3_PORT_STATUS=$(netstat -unpl | grep -o "$SGW_IP_N3_INTERFACE:$SGW_PORT_FOR_N3")
fi # Check if bpf_datapath is set to yes
SX_PORT_STATUS=$(netstat -unpl | grep -o "$SGW_IP_SX_INTERFACE:$SGW_PORT_FOR_SX") if [ "$enable_bpf_datapath" == "yes" ]; then
#Check if entrypoint properly configured the conf file and no parameter is unset (optional) return 0 # BPF Datapath is enabled
NB_UNREPLACED_AT=`cat /openair-upf/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true` else
if [ $NB_UNREPLACED_AT -ne 0 ]; then return 1 # BPF Datapath is not enabled
STATUS=1 fi
echo "Healthcheck error: UNHEALTHY configuration file is not configured properly" }
fi
if [[ ${ENABLE_BPF_DATAPATH} == "no" ]]; then ######################################################################################################
if [[ -z $N3_PORT_STATUS ]]; then # Function to check if BPF QoS enforcement datapath is enabled
STATUS=1 ######################################################################################################
echo "Healthcheck error: UNHEALTHY N3 port $SGW_PORT_FOR_N3 is not listening." check_enable_qos() {
fi enable_qos=$(cat /openair-upf/etc/*.yaml | grep -A 3 "upf:" | grep "enable_qos:" | awk '{print $2}')
fi
# Check if enable_qos is set to yes
if [[ -z $SX_PORT_STATUS ]]; then if [[ "$enable_qos" == "yes" ]]; then
STATUS=1 return 0 # QoS is enabled
echo "Healthcheck error: UNHEALTHY SX port $SGW_PORT_FOR_SX is not listening." else
fi return 1 # QoS is not enabled
fi
exit $STATUS }
######################################################################################################
# Function to retrieve interface from config file
######################################################################################################
get_interface_name() {
local reference_point=$1
# Extract the interface name for the given reference point (n3, n4, n6, etc.) under UPF
interface_name=$(cat /openair-upf/etc/*.yaml | grep -A 16 "upf:" | awk -v ref="$reference_point:" '
$0 ~ ref {found=1}
found && /interface_name:/ {print $2; exit}
')
if [[ -z "$interface_name" ]]; then
echo "Error: interface_name not found for reference point $reference_point."
return 1
fi
echo "$interface_name"
}
######################################################################################################
# Function to check if the configuration file is properly set
######################################################################################################
check_configuration_file() {
NB_UNREPLACED_AT=$(cat /openair-upf/etc/*.yaml | grep -v contact@openairinterface.org | grep -c @ || true)
if [ $NB_UNREPLACED_AT -ne 0 ]; then
echo "Healthcheck error: UNHEALTHY configuration file is not configured properly"
return 1
fi
}
######################################################################################################
# Function to check if the N3 XDP program <xdp_handle_uplink> properly attached
######################################################################################################
check_n3_xdp_program() {
local interface_name="$1"
# Retrieve the XDP program ID associated with the n3 interface
XDP_PROGRAM_ID=$(ip link show dev $interface_name | grep -oP 'prog/xdp id \K\d+')
if [[ -z "$XDP_PROGRAM_ID" ]]; then
echo "Healthcheck error: XDP program ID not found for $interface_name interface."
return 1
fi
# Retrieve the program name associated with the XDP program ID from bpftool
XDP_PROGRAM_NAME=$(/openair-upf/bin/bpftool prog list | grep -w "$XDP_PROGRAM_ID" | awk '{print $4}')
if [[ -z "$XDP_PROGRAM_NAME" ]]; then
echo "Healthcheck error: XDP program name not found for $interface_name interface."
return 1
fi
if [[ "$XDP_PROGRAM_NAME" == "xdp_handle_uplink" ]]; then
echo "xdp_handle_uplink program is correctly linked to $interface_name interface."
else
echo "Healthcheck error: xdp_handle_uplink program not linked to $interface_name interface. Found $XDP_PROGRAM_NAME instead."
return 1
fi
}
######################################################################################################
# Function to check if the N6 XDP program <xdp_handle_downlink> or <xdp_handle_shaping> properly attached
######################################################################################################
check_n6_xdp_program() {
local interface_name="$1"
# Retrieve the XDP program ID associated with the n6 interface
XDP_PROGRAM_ID=$(ip link show dev $interface_name | grep -oP 'prog/xdp id \K\d+')
if [[ -z "$XDP_PROGRAM_ID" ]]; then
echo "Healthcheck error: XDP program ID not found for $interface_name interface."
return 1
fi
# Retrieve the program name associated with the XDP program ID from bpftool
XDP_PROGRAM_NAME=$(/openair-upf/bin/bpftool prog list | grep -w "$XDP_PROGRAM_ID" | awk '{print $4}')
if [[ -z "$XDP_PROGRAM_NAME" ]]; then
echo "Healthcheck error: XDP program name not found for interface_name interface."
return 1
fi
# Check if QoS is enabled
if check_enable_qos; then
# If QoS is enabled, check if the program name is xdp_handle_shaping
if [[ "$XDP_PROGRAM_NAME" == "xdp_handle_shaping" ]]; then
echo "xdp_handle_shaping program is correctly linked to $interface_name interface."
else
echo "Healthcheck error: xdp_handle_shaping program not linked to $interface_name interface. Found $XDP_PROGRAM_NAME instead."
return 1
fi
else
# If QoS is not enabled, check if the program name is xdp_handle_downlink
if [[ "$XDP_PROGRAM_NAME" == "xdp_handle_downlink" ]]; then
echo "xdp_handle_downlink program is correctly linked to $interface_name interface."
else
echo "Healthcheck error: xdp_handle_downlink program not linked to $interface_name interface. Found $XDP_PROGRAM_NAME instead."
return 1
fi
fi
}
######################################################################################################
# Function to check port status
######################################################################################################
check_port_status() {
local interface_name=$1
local port=$2
local ip_interface=$(ifconfig $interface_name | grep inet | awk '{print $2}')
if [[ -z "$ip_interface" ]]; then
echo "Error: Could not retrieve IP address for interface $interface_name."
return 1
fi
# Check if the port is listening on the specified IP interface
if netstat -unpl | grep -q "$ip_interface:$port"; then
echo "Port $port is listening on $ip_interface."
return 0
else
echo "Port $port is NOT listening on $ip_interface."
return 1
fi
}
######################################################################################################
# Main healthcheck function
######################################################################################################
main() {
STATUS=0
N4_PORT=8805
echo "Retrieving interface names..."
N3_INTERFACE=$(get_interface_name "n3")
echo "N3_INTERFACE: $N3_INTERFACE"
N4_INTERFACE=$(get_interface_name "n4")
echo "N4_INTERFACE: $N4_INTERFACE"
N6_INTERFACE=$(get_interface_name "n6")
echo "N6_INTERFACE: $N6_INTERFACE"
if check_configuration_file; then
echo "Configuration file is OK."
if check_enable_bpf_datapath; then
echo "BPF Datapath is enabled."
echo "Checking N3 XDP program..."
check_n3_xdp_program "$N3_INTERFACE"
if [ $? -ne 0 ]; then
STATUS=1
fi
echo "Checking N6 XDP program..."
check_n6_xdp_program "$N6_INTERFACE"
if [ $? -ne 0 ]; then
STATUS=1
fi
echo "Checking N4 Port Status..."
check_port_status "$N4_INTERFACE" "$N4_PORT"
if [ $? -ne 0 ]; then
STATUS=1
fi
else
echo "TODO: Add checking for SPGW-Tiny"
fi
else
echo "Configuration file check failed."
STATUS=1
fi
echo "Final Status: $STATUS"
exit $STATUS
}
######################################################################################################
# Run the main function
######################################################################################################
main
...@@ -157,7 +157,7 @@ set(CMAKE_C_FLAGS ...@@ -157,7 +157,7 @@ set(CMAKE_C_FLAGS
set(CMAKE_C_FLAGS set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP" "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP"
) )
set(CMAKE_C_FLAGS "-Wno-unused-function -Wno-error -Wno-return-type") set(CMAKE_C_FLAGS "-Wno-unused-function -Wno-error -Wno-return-type -Wno-empty-body")
# set a flag for changes in the source code # set a flag for changes in the source code
# these changes are related to hardcoded path to include .h files # these changes are related to hardcoded path to include .h files
...@@ -357,8 +357,7 @@ target_link_libraries (upf ...@@ -357,8 +357,7 @@ target_link_libraries (upf
UDP UDP
GTPV1U GTPV1U
PFCP PFCP
far_xdp #far_xdp
pfcp_session_pdr_lookup_xdp
pfcp_session_lookup_xdp pfcp_session_lookup_xdp
qer_tc qer_tc
UPF_XDP UPF_XDP
......
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
#include <SessionProgramManager.h> #include <SessionProgramManager.h>
#include <UserPlaneComponent.h> #include <UserPlaneComponent.h>
#include "helpers/ConfigLoader.hpp"
using namespace oai::upf::app; using namespace oai::upf::app;
using namespace oai::config; using namespace oai::config;
using namespace oai::utils; using namespace oai::utils;
...@@ -116,13 +118,10 @@ void my_app_signal_handler(int s) { ...@@ -116,13 +118,10 @@ void my_app_signal_handler(int s) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void setup_bpf() { void setup_bpf() {
// std::shared_ptr<RulesUtilities> mpRulesFactory;
// mpRulesFactory = std::make_shared<RulesUtilitiesImpl>();
std::string sGTPInterface = N3_IF_NAME; std::string sGTPInterface = N3_IF_NAME;
std::string sUDPInterface = N6_IF_NAME; std::string sUDPInterface = N6_IF_NAME;
Logger::upf_app().info("GTP interface: %s", sGTPInterface.c_str()); Logger::upf_app().info("GTP interface: %s", sGTPInterface.c_str());
Logger::upf_app().info("UDP interface: %s", sUDPInterface.c_str()); Logger::upf_app().info("Non-GTP interface: %s", sUDPInterface.c_str());
UserPlaneComponent::getInstance().setup(sGTPInterface, sUDPInterface); UserPlaneComponent::getInstance().setup(sGTPInterface, sUDPInterface);
...@@ -134,11 +133,23 @@ void setup_bpf() { ...@@ -134,11 +133,23 @@ void setup_bpf() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int main(int argc, char** argv) { int main(int argc, char** argv) {
// Command line options // Command line options
// std::string configPath =
// "/home/messaoudi/workspace/project-oai-qos/oai-cn5g-upf/etc/"
// "ebpf_maps.conf";
if (!Options::parse(argc, argv)) { if (!Options::parse(argc, argv)) {
std::cout << "Options::parse() failed" << std::endl; std::cout << "Options::parse() failed" << std::endl;
return 1; return 1;
} }
// if (!ConfigLoader::getInstance().loadConfig(configPath)) {
// std::cerr << "Failed to load ebpf map sizes config file" << std::endl;
// return 1; // Exit if config fails
// }
// printFileContents(configPath);
// Logger // Logger
// Config // Config
std::string conf_file_name = Options::getlibconfigConfig(); std::string conf_file_name = Options::getlibconfigConfig();
...@@ -213,7 +224,9 @@ int main(int argc, char** argv) { ...@@ -213,7 +224,9 @@ int main(int argc, char** argv) {
fflush(fp); fflush(fp);
fclose(fp); fclose(fp);
if (upf_cfg.enable_bpf_datapath) { const bool isBpfAccelerationEnabled = upf_cfg.enable_bpf_datapath;
if (isBpfAccelerationEnabled) {
setup_bpf(); setup_bpf();
} }
// once all udp servers initialized // once all udp servers initialized
......
...@@ -26,15 +26,12 @@ include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/common_model.cmake) ...@@ -26,15 +26,12 @@ include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/model/common_model.cmake)
include_directories(${SRC_TOP_DIR}/upf_app/bpf) include_directories(${SRC_TOP_DIR}/upf_app/bpf)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/include) 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/pdr)
#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)
############################################################## ##############################################################
# FAR # # FAR #
############################################################## ##############################################################
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/far) include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/far)
include_directories(${LibNL_INCLUDE_DIR}) # include_directories(${LibNL_INCLUDE_DIR})
include_directories(${SRC_TOP_DIR}/upf_app/app) include_directories(${SRC_TOP_DIR}/upf_app/app)
set(GTP_INTERFACE $ENV{GTP_INTERFACE}) set(GTP_INTERFACE $ENV{GTP_INTERFACE})
...@@ -47,12 +44,12 @@ add_library(UPF_XDP STATIC ...@@ -47,12 +44,12 @@ add_library(UPF_XDP STATIC
SignalHandler.cpp SignalHandler.cpp
helpers/NextHopFinder.cpp helpers/NextHopFinder.cpp
helpers/CmdRunner.cpp helpers/CmdRunner.cpp
helpers/SdfFilterParser.cpp
SessionProgramManager.cpp SessionProgramManager.cpp
SessionManager.cpp SessionManager.cpp
SessionPrograms.cpp SessionPrograms.cpp
programs/pfcp_session_pdr_lookup_xdp_user.cpp
programs/pfcp_session_lookup_xdp_user.cpp programs/pfcp_session_lookup_xdp_user.cpp
programs/far_xdp_user.cpp #programs/far_xdp_user.cpp
programs/BPFProgram.cpp programs/BPFProgram.cpp
wrappers/BPFMaps.cpp wrappers/BPFMaps.cpp
wrappers/BPFMap.cpp wrappers/BPFMap.cpp
...@@ -92,17 +89,16 @@ install( ...@@ -92,17 +89,16 @@ install(
############################################################## ##############################################################
# QER # # QER #
############################################################## ##############################################################
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLibNL.cmake) # include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLibNL.cmake)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/qer) include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/qer)
add_library(UPF_TC STATIC add_library(UPF_TC STATIC
#NetlinkManager.cpp
UserPlaneComponent.cpp UserPlaneComponent.cpp
Configuration.cpp Configuration.cpp
SignalHandler.cpp SignalHandler.cpp
helpers/NextHopFinder.cpp helpers/NextHopFinder.cpp
helpers/SdfFilterParser.cpp
helpers/GetNicInformation.cpp helpers/GetNicInformation.cpp
#helpers/QdiscHelpers.cpp
SessionProgramManager.cpp SessionProgramManager.cpp
SessionManager.cpp SessionManager.cpp
SessionPrograms.cpp SessionPrograms.cpp
...@@ -115,13 +111,9 @@ install( ...@@ -115,13 +111,9 @@ install(
target_link_libraries(UPF_TC target_link_libraries(UPF_TC
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../build/ext/libbpf/src/libbpf.a PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../build/ext/libbpf/src/libbpf.a
${CMAKE_CURRENT_SOURCE_DIR}/../../build/ext/libbpf/src/libbpf.so.1 ${CMAKE_CURRENT_SOURCE_DIR}/../../build/ext/libbpf/src/libbpf.so.1
# PUBLIC upfutils
# PRIVATE spdlog
PRIVATE elf PRIVATE elf
PRIVATE z PRIVATE z
#/usr/lib/x86_64-linux-gnu/libnl-3.so
libnl-3.so libnl-3.so
#/usr/lib/x86_64-linux-gnu/libnl-route-3.so
libnl-route-3.so libnl-route-3.so
) )
...@@ -134,7 +126,7 @@ install( ...@@ -134,7 +126,7 @@ install(
$<BUILD_INTERFACE:${SRC_TOP_DIR}/upf_app/programs> $<BUILD_INTERFACE:${SRC_TOP_DIR}/upf_app/programs>
) )
add_dependencies(UPF_TC upf_tc_all) add_dependencies(UPF_TC upf_xdp_all)
install( install(
TARGETS UPF_TC TARGETS UPF_TC
...@@ -145,12 +137,3 @@ install( ...@@ -145,12 +137,3 @@ install(
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
) )
# Headers:
# * ./*.h -> <prefix>/include/*.h
# install(
# DIRECTORY "./"
# DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
# FILES_MATCHING PATTERN "*.h"
# )
This diff is collapsed.
...@@ -25,189 +25,97 @@ class BPFMap; ...@@ -25,189 +25,97 @@ class BPFMap;
// class PacketDetectionRules; // class PacketDetectionRules;
class SessionBpf; class SessionBpf;
// FIXME: This class compose the UserPlaneComponent. When the program is
// deleted, this class must be updated.
// TODO: SessionRequestHandler? SessionMessageHandler?
// TODO: Decouple PDR and FAR management.
/**
* @brief This class abstracts the communication to manager the session BPF
* maps. It communicate with BPF maps in order to update its PDRs and FARs. This
* class does not validate the input.
*/
class SessionManager { class SessionManager {
public: enum class Direction { Uplink, Downlink };
// Set of PDRs.
// using pdrs_t = std::vector<std::shared_ptr<PacketDetectionRules>>;
/*---------------------------------------------------------------------------------------------------------------*/
/** public:
* @brief Construct a new Session Manager object.
*
*/
SessionManager(); SessionManager();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Destroy the Session Manager object.
*
*/
virtual ~SessionManager(); virtual ~SessionManager();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Create a Session object in BPF map.
*
* @param pSession The session object to be created.
*/
void createSession(std::shared_ptr<SessionBpf> pSession);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Remove a session object from BPF map.
*
* @param seid The session endpoint identifier representing the session to be
* removed.
*/
void removeSession(uint64_t seid); void removeSession(uint64_t seid);
/*---------------------------------------------------------------------------------------------------------------*/ void createBpfSession(
/**
* @brief Creates BPF pipeline.
*
* @param pSession The PFCP session which contains the context that will be
* deployed.
*/
void createBPFSession(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
itti_n4_session_establishment_request* est_req, itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req, itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req); itti_n4_session_deletion_request* del_req);
/*---------------------------------------------------------------------------------------------------------------*/
void updateBpfSession(
/**
* @brief Update a Session object in BPF map.
*
* @param pSession The session object to be updated.
*/
void updateBPFSession(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
itti_n4_session_establishment_request* est_req, itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req, itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req); itti_n4_session_deletion_request* del_req);
/*---------------------------------------------------------------------------------------------------------------*/ void modifyBpfSession(
/** std::shared_ptr<pfcp::pfcp_session> session,
* @brief Remove BPF pipeline. itti_n4_session_establishment_request* est_req,
* itti_n4_session_modification_request* mod_req,
* @param seid The PFCP session which contains the context that will be itti_n4_session_deletion_request* del_req);
* removed.
*/ void removeBpfSession(
void removeBPFSession(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
itti_n4_session_establishment_request* est_req, itti_n4_session_establishment_request* est_req,
itti_n4_session_modification_request* mod_req, itti_n4_session_modification_request* mod_req,
itti_n4_session_deletion_request* del_req); itti_n4_session_deletion_request* del_req);
/*---------------------------------------------------------------------------------------------------------------*/
void createBPFSessionUL( void createBPFSessionUL(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceUl); std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceUl);
/*---------------------------------------------------------------------------------------------------------------*/
void createBPFSessionDL( void createBPFSessionDL(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceDl); std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceDl);
/*---------------------------------------------------------------------------------------------------------------*/
void updateBPFSessionUL( void updateBPFSessionUL(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceUl); std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceUl);
/*---------------------------------------------------------------------------------------------------------------*/
void updateBPFSessionDL( void updateBPFSessionDL(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceDl); std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedenceDl);
/*****************************************************************************************************************/
void processPDRDetails( void processPDRDetails(
std::shared_ptr<pfcp::pfcp_session> pSession, std::shared_ptr<pfcp::pfcp_session> pSession,
std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedence, int interfaceValue, std::shared_ptr<pfcp::pfcp_pdr> pdrHighPrecedence);
const std::string& direction);
/*****************************************************************************************************************/
/**
* @brief Process PDRs to populate uplink and downlink vectors
* @param std::shared_ptr<pfcp::pfcp_session>
*/
void processPDRs(std::shared_ptr<pfcp::pfcp_session> pSession_establishment);
/*****************************************************************************************************************/
/**
* @brief Sort uplink and downlink vectors
* @param std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs_uplink
* @param std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs_downlink
*/
void sortPDRs(
std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs_uplink,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs_downlink);
/*****************************************************************************************************************/
/**
* @brief Create BPF session for specific direction
* @param std::shared_ptr<pfcp::pfcp_session> pSession_establishment
* @param std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs
* @param const std::string& direction
*/
void createSessionDirection(
std::shared_ptr<pfcp::pfcp_session> pSession_establishment,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs,
const std::string& direction);
/*****************************************************************************************************************/ void processPDRs(std::shared_ptr<pfcp::pfcp_session> pSession_establishment);
bool extractPdi(std::shared_ptr<pfcp::pfcp_pdr> pdr, pfcp::pdi& pdi);
/*****************************************************************************************************************/ void sortPDRs(std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdr);
bool extractSourceIface(
pfcp::pdi& pdi, pfcp::source_interface_t& sourceInterface);
/*****************************************************************************************************************/ void prepareEbpfSession(
bool extractUeIpv4(pfcp::pdi& pdi, pfcp::ue_ip_address_t& ueIpAddress); std::shared_ptr<pfcp::pfcp_session> pSession_establishment,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs);
/*---------------------------------------------------------------------------------------------------------------*/ bool getFar(
bool extractFar(
std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_session> session, std::shared_ptr<pfcp::pfcp_session> session,
std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_far>& outFar); std::shared_ptr<pfcp::pfcp_far>& outFar);
/*---------------------------------------------------------------------------------------------------------------*/ bool getQer(
bool extractQer(
std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_session> session, std::shared_ptr<pfcp::pfcp_session> session,
std::vector<std::shared_ptr<pfcp::pfcp_qer>>* outQer); std::shared_ptr<pfcp::pfcp_pdr> pdr,
std::shared_ptr<pfcp::pfcp_qer>& outQer);
/*---------------------------------------------------------------------------------------------------------------*/ uint32_t retrieveTeid(std::shared_ptr<pfcp::pfcp_session> session);
bool extractForwardingParams(
std::shared_ptr<pfcp::pfcp_far> far,
pfcp::forwarding_parameters& forwardingParams);
/*---------------------------------------------------------------------------------------------------------------*/
uint64_t findUplinkTeid( uint64_t findUplinkTeid(
uint64_t seid, uint64_t seid,
const std::vector<std::shared_ptr<pfcp::pfcp_session>>& sessions); const std::vector<std::shared_ptr<pfcp::pfcp_session>>& sessions);
/*---------------------------------------------------------------------------------------------------------------*/
static bool comparePDR( static bool comparePDR(
const std::shared_ptr<pfcp::pfcp_pdr>& first, const std::shared_ptr<pfcp::pfcp_pdr>& first,
const std::shared_ptr<pfcp::pfcp_pdr>& second); const std::shared_ptr<pfcp::pfcp_pdr>& second);
void categorizePDRs(std::shared_ptr<pfcp::pfcp_session> session);
std::shared_ptr<pfcp::pfcp_qer> findQER(
std::shared_ptr<pfcp::pfcp_session> session, uint32_t qer_id);
void setupEbpfPipeline(
std::shared_ptr<pfcp::pfcp_session> session,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs, Direction direction);
std::vector<std::shared_ptr<pfcp::pfcp_session>> sessions; std::vector<std::shared_ptr<pfcp::pfcp_session>> sessions;
/*---------------------------------------------------------------------------------------------------------------*/
std::unordered_map<uint64_t, std::shared_ptr<pfcp::pfcp_session>> std::unordered_map<uint64_t, std::shared_ptr<pfcp::pfcp_session>>
mSeidToSession; mSeidToSession;
}; };
......
This diff is collapsed.
...@@ -6,197 +6,119 @@ ...@@ -6,197 +6,119 @@
#include <map> #include <map>
#include <pfcp_far.hpp> #include <pfcp_far.hpp>
#include <pfcp_qer.hpp> #include <pfcp_qer.hpp>
#include "pfcp_pdr.hpp"
#include <array> #include <array>
#include <pfcp/pfcp_far.h> #include <pfcp/pfcp_far.h>
#include <pfcp/pfcp_pdr.h>
#include <pfcp/pfcp_qer.h>
#include <next_prog_rule_key.h> #include <next_prog_rule_key.h>
#include <session_id.h>
#include <netinet/ether.h> #include <netinet/ether.h>
class BPFMap; class BPFMap;
class OnStateChangeSessionProgramObserver; class OnStateChangeSessionProgramObserver;
class PFCP_Session_LookupProgram; class PFCP_Session_LookupProgram;
class PFCP_Session_PDR_LookupProgram;
class SessionPrograms; class SessionPrograms;
class FARProgram; class FARProgram;
/** struct pfcpprograms {
* @brief This class is used to manager the PFCP Sesssion (eBPF bytecode) in
* kernel space. It store all the BPFProgram that was loaded on the datapath.
*
*/
struct farprograms {
uint64_t seid; uint64_t seid;
std::shared_ptr<FARProgram> pFARProgram; std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram;
};
struct pduSessionInfo {
uint32_t teid_ul;
uint32_t teid_dl;
uint32_t ueIP;
}; };
class SessionProgramManager { class SessionProgramManager {
public: public:
/**
* @brief Destroy the Session Program Manager object.
*
*/
virtual ~SessionProgramManager(); virtual ~SessionProgramManager();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Get the Instance object.
*
* @return SessionProgramManager& The unique instance.
*/
static SessionProgramManager& getInstance(); static SessionProgramManager& getInstance();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Set the Programs Map object.
*
* @param pProgramsMaps The programs wrapper for BPF map.
*/
void setTeidSessionMap(std::shared_ptr<BPFMap> pProgramsMaps); void setTeidSessionMap(std::shared_ptr<BPFMap> pProgramsMaps);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Create a new program related to the SEID.
* The context will be empty.
*
* @param seid The session identifier.
*/
void create(uint64_t seid); void create(uint64_t seid);
/*---------------------------------------------------------------------------------------------------------------*/
void remove(uint64_t seid); void remove(uint64_t seid);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Remove all programs.
*
*/
void removeAll(); void removeAll();
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Set the On New Session Observer object.
*
* @param pObserver The observer which will be notified when a
* PFCP_Session_PDR_LookupProgram is created.
*/
void setOnNewSessionObserver(OnStateChangeSessionProgramObserver* pObserver); void setOnNewSessionObserver(OnStateChangeSessionProgramObserver* pObserver);
/*---------------------------------------------------------------------------------------------------------------*/
/**
* @brief Find the Session Program object.
*
* @param seid The session identifier.
* @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);
/*---------------------------------------------------------------------------------------------------------------*/
void addFarProgram(uint64_t seid, std::shared_ptr<FARProgram> pFARProgram);
/*---------------------------------------------------------------------------------------------------------------*/
void updateArpTableMap( void updateArpTableMap(
std::shared_ptr<FARProgram> pFARProgram, uint32_t upfIP, std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t remoteIP); uint32_t upfIP, uint32_t remoteIP);
/*---------------------------------------------------------------------------------------------------------------*/
uint32_t getRemoteIP(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_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( void addFramedRoutes(
uint32_t ueIpAddress, uint32_t ueIpAddress,
const std::vector<pfcp::framed_route_t>& framedRoutes); const std::vector<pfcp::framed_route_t>& framedRoutes);
/*---------------------------------------------------------------------------------------------------------------*/
void removeFramedRoutes( void removeFramedRoutes(
const std::vector<pfcp::framed_route_t>& framedRoutes); const std::vector<pfcp::framed_route_t>& framedRoutes);
/*---------------------------------------------------------------------------------------------------------------*/
void createPipeline( void createPipeline(
uint64_t seid, uint32_t teid1, uint8_t sourceInterface, uint64_t seid, uint32_t teid1, uint8_t sourceInterface,
uint32_t ueIpAddress, std::shared_ptr<pfcp::pfcp_far> pFar, uint32_t ueIpAddress, std::shared_ptr<pfcp::pfcp_far> pFar,
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer, 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); bool isModification = false, uint32_t teid2 = 0);
/*---------------------------------------------------------------------------------------------------------------*/
void initializeNextRuleProgIndexKey( void initializeNextRuleProgIndexKey(
next_rule_prog_index_key& key, uint32_t teid, uint32_t ueIpAddress, next_rule_prog_index_key& key, uint32_t teid, uint32_t ueIpAddress,
uint8_t sourceInterface); uint8_t sourceInterface);
void addPFCPProgram(
/*---------------------------------------------------------------------------------------------------------------*/ uint64_t seid,
void storeFarProgramIndexInNextProgRuleIndexMap(
std::shared_ptr<FARProgram> pFARProgram,
const next_rule_prog_index_key& key,
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram); std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram);
void storePduSessionInMap(
/*---------------------------------------------------------------------------------------------------------------*/
void storeSessionMappingMap(
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram, std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t ue_ip_address, uint32_t teid_dl, uint32_t teid_ul, uint32_t ue_ip_address, uint32_t teid_dl, uint32_t teid_ul,
uint32_t seid); uint64_t seid);
/*---------------------------------------------------------------------------------------------------------------*/
void storeFARInFARMap( void storeFARInFARMap(
std::shared_ptr<FARProgram> pFARProgram, std::shared_ptr<FARProgram> pFARProgram,
std::shared_ptr<pfcp::pfcp_far> pFar); std::shared_ptr<pfcp::pfcp_far> pFar);
/*---------------------------------------------------------------------------------------------------------------*/
void saveSeidWithinFARProgram( void saveSeidWithinFARProgram(
uint64_t seid, std::shared_ptr<FARProgram> pFARProgram, uint64_t seid,
std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
const next_rule_prog_index_key& key); const next_rule_prog_index_key& key);
/*---------------------------------------------------------------------------------------------------------------*/
void updateARPTableForN6( void updateARPTableForN6(
std::shared_ptr<FARProgram> pFARProgram, uint32_t dnIP, uint32_t upfn6IP); std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t dnIP, uint32_t upfn6IP);
/*---------------------------------------------------------------------------------------------------------------*/
void updateARPTableForN3( void updateARPTableForN3(
std::shared_ptr<FARProgram> pFARProgram, uint32_t gNodeBIP, std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram,
uint32_t upfn3IP, uint64_t seid); 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 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( void updatePipeline(
uint64_t seid, uint32_t teid, uint32_t gNBIpAddress, bool isModification); uint64_t seid, uint32_t teid, uint32_t gNBIpAddress, bool isModification);
/*---------------------------------------------------------------------------------------------------------------*/
void removePipeline(uint64_t seid); void removePipeline(uint64_t seid);
std::shared_ptr<SessionPrograms> findSessionPrograms(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);
// std::shared_ptr<vector><struct farprograms> farPrograms; std::shared_ptr<std::vector<struct pfcpprograms>> pfcpPrograms;
std::shared_ptr<std::vector<struct farprograms>> farPrograms;
private: private:
/**
* @brief Construct a new Session Program Manager object.
*
*/
SessionProgramManager(); SessionProgramManager();
int32_t getEmptySlot(); int32_t getEmptySlot();
std::shared_ptr<BPFMap> mpTeidSessionMap; 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; OnStateChangeSessionProgramObserver* mpOnNewSessionProgramObserver;
// The Maps to store the instance of the programs.
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; std::map<uint32_t, std::shared_ptr<SessionPrograms>> mSessionProgramsMap;
std::array<int64_t, 10> mProgramArray; std::array<int64_t, 10> mProgramArray;
struct pduSessionInfo sessionInfo;
}; };
#endif // __SESSIONPROGRAMMANAGER_H__ #endif // __SESSIONPROGRAMMANAGER_H__
#include "SessionPrograms.h" #include "SessionPrograms.h"
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
SessionPrograms::SessionPrograms( SessionPrograms::SessionPrograms(
struct next_rule_prog_index_key key, struct next_rule_prog_index_key key,
std::shared_ptr<FARProgram> pFARProgram) std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram)
: mKey(key), mpFARProgram(pFARProgram) {} : mKey(key), mpPFCP_Session_LookupProgram(pPFCP_Session_LookupProgram) {}
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
SessionPrograms::~SessionPrograms() { SessionPrograms::~SessionPrograms() {
mpFARProgram->tearDown(); mpPFCP_Session_LookupProgram->tearDown();
} }
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
struct next_rule_prog_index_key SessionPrograms::getKey() const { struct next_rule_prog_index_key SessionPrograms::getKey() const {
return mKey; return mKey;
} }
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
std::shared_ptr<FARProgram> SessionPrograms::getFARProgram() const { std::shared_ptr<PFCP_Session_LookupProgram> SessionPrograms::getPFCPProgram()
return mpFARProgram; const {
return mpPFCP_Session_LookupProgram;
} }
/**************************************************************************************************/
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
#define __SESSIONPROGRAMS_H__ #define __SESSIONPROGRAMS_H__
#include <memory> #include <memory>
#include <far_xdp_user.h> #include <pfcp_session_lookup_xdp_user.h>
#include <unistd.h> #include <unistd.h>
#include <next_prog_rule_key.h> #include <next_prog_rule_key.h>
/** /**
* @brief This class represents the datapath path. It stores the program related * @brief This class represents the Data-Path path. It stores the program
* to a PFCP session. For each session, there might be a QERProgram. The * related to a PFCP session. For each session, there might be a QERProgram. The
* FARProgram is mandatory. * FARProgram is mandatory.
* *
*/ */
...@@ -16,13 +16,13 @@ class SessionPrograms { ...@@ -16,13 +16,13 @@ class SessionPrograms {
public: public:
SessionPrograms( SessionPrograms(
struct next_rule_prog_index_key key, struct next_rule_prog_index_key key,
std::shared_ptr<FARProgram> pFARProgram); std::shared_ptr<PFCP_Session_LookupProgram> pPFCP_Session_LookupProgram);
virtual ~SessionPrograms(); virtual ~SessionPrograms();
struct next_rule_prog_index_key getKey() const; struct next_rule_prog_index_key getKey() const;
std::shared_ptr<FARProgram> getFARProgram() const; std::shared_ptr<PFCP_Session_LookupProgram> getPFCPProgram() const;
private: private:
std::shared_ptr<FARProgram> mpFARProgram; std::shared_ptr<PFCP_Session_LookupProgram> mpPFCP_Session_LookupProgram;
struct next_rule_prog_index_key mKey; struct next_rule_prog_index_key mKey;
}; };
......
#include "SignalHandler.h" #include "SignalHandler.h"
#include <UserPlaneComponent.h> #include <UserPlaneComponent.h>
//---------------------------------------------------------------------------------------------------------------
void my_app_signal_handler(int s); void my_app_signal_handler(int s);
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
SignalHandler& SignalHandler::getInstance() { SignalHandler& SignalHandler::getInstance() {
static SignalHandler sInstance; static SignalHandler sInstance;
return sInstance; return sInstance;
} }
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
SignalHandler::~SignalHandler() {} SignalHandler::~SignalHandler() {}
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
void SignalHandler::enable() { void SignalHandler::enable() {
signal(SIGINT, SignalHandler::tearDown); signal(SIGINT, SignalHandler::tearDown);
signal(SIGTERM, SignalHandler::tearDown); signal(SIGTERM, SignalHandler::tearDown);
signal(SIGSEGV, SignalHandler::tearDown); signal(SIGSEGV, SignalHandler::tearDown);
} }
/**************************************************************************************************/ //---------------------------------------------------------------------------------------------------------------
void SignalHandler::tearDown(int signal) { void SignalHandler::tearDown(int signal) {
UserPlaneComponent::getInstance().tearDown(); UserPlaneComponent::getInstance().tearDown();
// calling the other tear down routine // calling the other tear down routine
my_app_signal_handler(signal); my_app_signal_handler(signal);
exit(0); exit(0);
} }
/**************************************************************************************************/
#include "UserPlaneComponent.h" #include "UserPlaneComponent.h"
//#include <RulesUtilities.h>
#include <SessionManager.h> #include <SessionManager.h>
#include <pfcp_session_pdr_lookup_xdp_user.h>
#include <SessionProgramManager.h> #include <SessionProgramManager.h>
#include <SignalHandler.h> #include <SignalHandler.h>
#include <pfcp_session_lookup_xdp_user.h> #include <pfcp_session_lookup_xdp_user.h>
#include "logger.hpp" #include "logger.hpp"
#include <helpers/GetNicInformation.hpp> #include <helpers/GetNicInformation.hpp>
/*---------------------------------------------------------------------------------------------------------------*/ #include "upf_config.hpp"
using namespace oai::config;
extern upf_config upf_cfg;
//---------------------------------------------------------------------------------------------------------------
UserPlaneComponent::UserPlaneComponent() { UserPlaneComponent::UserPlaneComponent() {
// Set new handlers for libbpf. // Set new handlers for libbpf.
#ifdef DEBUG_LIBBPF #ifdef DEBUG_LIBBPF
...@@ -16,56 +18,56 @@ UserPlaneComponent::UserPlaneComponent() { ...@@ -16,56 +18,56 @@ UserPlaneComponent::UserPlaneComponent() {
#endif #endif
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
UserPlaneComponent::~UserPlaneComponent() { UserPlaneComponent::~UserPlaneComponent() {
tearDown(); tearDown();
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
std::shared_ptr<SessionManager> UserPlaneComponent::getSessionManager() const { std::shared_ptr<SessionManager> UserPlaneComponent::getSessionManager() const {
return mpSessionManager; return mpSessionManager;
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
std::shared_ptr<PFCP_Session_LookupProgram> std::shared_ptr<PFCP_Session_LookupProgram>
UserPlaneComponent::getPFCP_Session_LookupProgram() const { UserPlaneComponent::getPFCP_Session_LookupProgram() const {
return mpPFCP_Session_LookupProgram; return mpPFCP_Session_LookupProgram;
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
std::string UserPlaneComponent::getGTPInterface() const { std::string UserPlaneComponent::getGTPInterface() const {
return mGTPInterface; return mGTPInterface;
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
std::string UserPlaneComponent::getUDPInterface() const { std::string UserPlaneComponent::getUDPInterface() const {
return mUDPInterface; return mUDPInterface;
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::onNewSessionProgram( void UserPlaneComponent::onNewSessionProgram(
u_int32_t programId, u_int32_t fileDescriptor) { u_int32_t programId, u_int32_t fileDescriptor) {
mpPFCP_Session_LookupProgram->updateProgramMap(programId, fileDescriptor); // mpPFCP_Session_LookupProgram->updateProgramMap(programId, fileDescriptor);
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::onDestroySessionProgram(u_int32_t programId) { void UserPlaneComponent::onDestroySessionProgram(u_int32_t programId) {
mpPFCP_Session_LookupProgram->removeProgramMap(programId); mpPFCP_Session_LookupProgram->removeProgramMap(programId);
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
int UserPlaneComponent::printLibbpfLog( int UserPlaneComponent::printLibbpfLog(
enum libbpf_print_level lvl, const char* fmt, va_list args) { enum libbpf_print_level lvl, const char* fmt, va_list args) {
return vfprintf(stderr, fmt, args); return vfprintf(stderr, fmt, args);
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
UserPlaneComponent& UserPlaneComponent::getInstance() { UserPlaneComponent& UserPlaneComponent::getInstance() {
static UserPlaneComponent sInstance; static UserPlaneComponent sInstance;
return sInstance; return sInstance;
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::setMembers( void UserPlaneComponent::setMembers(
const std::string& gtpInterface, const std::string& udpInterface) { const std::string& gtpInterface, const std::string& udpInterface) {
mGTPInterface = gtpInterface; mGTPInterface = gtpInterface;
...@@ -80,18 +82,21 @@ void UserPlaneComponent::setMembers( ...@@ -80,18 +82,21 @@ void UserPlaneComponent::setMembers(
} }
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::setup( void UserPlaneComponent::setup(
const std::string& gtpInterface, const std::string& udpInterface) { const std::string& gtpInterface, const std::string& udpInterface) {
const bool isQosEnabled = upf_cfg.enable_bpf_datapath && upf_cfg.enable_qos;
setMembers(gtpInterface, udpInterface); setMembers(gtpInterface, udpInterface);
SignalHandler::getInstance().enable(); SignalHandler::getInstance().enable();
mpPFCP_Session_LookupProgram->setup();
mpPFCP_Session_LookupProgram->setup(isQosEnabled);
// Pass maps to sessionManager. // Pass maps to sessionManager.
mpSessionManager = std::make_shared<SessionManager>(); mpSessionManager = std::make_shared<SessionManager>();
} }
/*---------------------------------------------------------------------------------------------------------------*/ //---------------------------------------------------------------------------------------------------------------
void UserPlaneComponent::tearDown() { void UserPlaneComponent::tearDown() {
mpPFCP_Session_LookupProgram->tearDown(); mpPFCP_Session_LookupProgram->tearDown();
SessionProgramManager::getInstance().removeAll(); SessionProgramManager::getInstance().removeAll();
......
...@@ -6,16 +6,14 @@ include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/include) ...@@ -6,16 +6,14 @@ 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/pdr)
include_directories(${SRC_TOP_DIR}/upf_app/bpf/rules/far) 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/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}/upf_app/include)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils) include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/utils)
add_definitions(-DKERNEL_SPACE) 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_tc_all DEPENDS qer_tc) add_custom_target(upf_xdp_all DEPENDS pfcp_session_lookup_xdp)
# add_custom_target(upf_tc_all DEPENDS qer_tc)
...@@ -23,7 +21,7 @@ add_custom_target(upf_tc_all DEPENDS qer_tc) ...@@ -23,7 +21,7 @@ add_custom_target(upf_tc_all DEPENDS qer_tc)
# GENERATE eBPF XDP Skeletons # # GENERATE eBPF XDP Skeletons #
########################################################################### ###########################################################################
function(xdp arg) 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") set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/rules/pdr")
elseif (${arg} STREQUAL "far") elseif (${arg} STREQUAL "far")
set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/rules/far") set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/rules/far")
...@@ -43,8 +41,7 @@ function(xdp arg) ...@@ -43,8 +41,7 @@ function(xdp arg)
endfunction() endfunction()
xdp(pfcp_session_lookup) xdp(pfcp_session_lookup)
xdp(pfcp_session_pdr_lookup) #xdp(far)
xdp(far)
......
#ifndef __GATE_STATUS_H__
#define __GATE_STATUS_H__
#include <types.h>
#include <ie/ie_base.h>
// 8.2.7 Gate Status
enum gate_status_e {
/* Request / Initial message */
OPEN = 0,
CLOSED = 1
};
typedef struct gate_status_s {
u8 ul_gate : 2;
u8 dl_gate : 2;
} gate_status_t;
#endif // __GATE_STATUS_H__
\ No newline at end of file
#if !defined(CREATE_QER_H)
#define CREATE_QER_H
#include <ie/ie_base.h>
#include <ie/qer_id.h>
#include <ie/qer_correlation_id.h>
#include <ie/gate_status.h>
#include <ie/guaranteed_bitrate.h>
#include <ie/maximum_bitrate.h>
#include <ie/qos_flow_identifier.h>
#include <ie/reflective_qos.h>
#include <ie/paging_policy_indicator.h>
//------------------------------------------------------------------------------
// Table 7.5.2.5-1: Create QER IE within PFCP Session Establishment Request
typedef struct create_qer_s {
qer_id_t_ qer_id;
qer_correlation_id_t qer_correlation_id;
gate_status_t gate_status;
mbr_t maximum_bitrate;
gbr_t guaranteed_bitrate;
qfi_t qos_flow_identifier;
rqi_t reflective_qos;
paging_policy_indicator_t paging_policy_indicator;
} create_qer_t;
#endif // CREATE_QER_H
#ifndef __GUARANTEED_BITRATE_H__
#define __GUARANTEED_BITRATE_H__
#include <types.h>
#include <ie/ie_base.h>
// 8.2.9 GBR
typedef struct gbr_s {
u64 ul_gbr;
u64 dl_gbr;
} gbr_t;
#endif // __GUARANTEED_BITRATE_H__
\ No newline at end of file
#ifndef __MAXIMUM_BITRATE_H__
#define __MAXIMUM_BITRATE_H__
#include <types.h>
#include <ie/ie_base.h>
// 8.2.8 MBR
typedef struct mbr_s {
u64 ul_mbr;
u64 dl_mbr;
} mbr_t;
#endif // __MAXIMUM_BITRATE_H__
\ No newline at end of file
#ifndef __PAGING_POLICY_INDICATOR_H__
#define __PAGING_POLICY_INDICATOR_H__
#include <types.h>
#include <ie/ie_base.h>
// 8.2.116 Paging Policy Indicator (PPI)
typedef struct paging_policy_indicator_s {
u8 spare : 4;
u8 ppi_value : 4;
} paging_policy_indicator_t;
#endif // __PAGING_POLICY_INDICATOR_H__
\ No newline at end of file
#ifndef __QER_CORRELATION_ID_H__
#define __QER_CORRELATION_ID_H__
#include <types.h>
#include <ie/ie_base.h>
//-------------------------------------
// 8.2.10 QER Correlation ID
typedef struct qer_correlation_id_s {
u32 qer_correlation_id;
} qer_correlation_id_t;
#endif // __QER_CORRELATION_ID_H__
\ No newline at end of file
#ifndef __QOS_FLOW_IDENTIFIER_H__
#define __QOS_FLOW_IDENTIFIER_H__
#include <types.h>
#include <ie/ie_base.h>
// 8.2.89 QFI
typedef struct qfi_s {
u8 spare : 2;
u8 qfi : 6;
// qfi_s() : qfi(0), spare(0) {}
// qfi_s(const u8& q) : qfi(q), spare(0) {}
// qfi_s(const struct qfi_s& q) : qfi(q.qfi), spare(q.spare) {}
// inline bool operator==(const struct qfi_s& rhs) const {
// return ((qfi == rhs.qfi) && (spare == rhs.spare));
// }
// inline bool operator!=(const struct qfi_s& rhs) const {
// return !((qfi == rhs.qfi) && (spare == rhs.spare));
// }
} qfi_t;
#endif // __QOS_FLOW_IDENTIFIER_H__
\ No newline at end of file
#ifndef __REFLECTIVE_QOS_H__
#define __REFLECTIVE_QOS_H__
#include <types.h>
#include <ie/ie_base.h>
/// 8.2.88 RQI
typedef struct rqi_s {
u8 spare : 7;
u8 rqi : 1;
} rqi_t;
#endif // __REFLECTIVE_QOS_H__
\ No newline at end of file
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <types.h> #include <types.h>
#include <ie/ie_base.h> #include <ie/ie_base.h>
#define MAX_FLOW_DESC_LEN 256 // Set a reasonable max length
//------------------------------------- //-------------------------------------
// 8.2.5 SDF Filter // 8.2.5 SDF Filter
typedef struct sdf_filter { typedef struct sdf_filter {
...@@ -16,10 +18,10 @@ typedef struct sdf_filter { ...@@ -16,10 +18,10 @@ typedef struct sdf_filter {
u8 fd : 1; u8 fd : 1;
u16 length_of_flow_description; u16 length_of_flow_description;
// TODO It is a string based on length_of_flow_description. How to solve this? // TODO It is a string based on length_of_flow_description. How to solve this?
u8 flow_description; char flow_description[MAX_FLOW_DESC_LEN];
u8 tos_traffic_class[2]; // 2 octets char tos_traffic_class[2]; // 2 octets
u8 security_parameter_index[4]; // 4 octets char security_parameter_index[4]; // 4 octets
u8 flow_label[3]; // 3 octets char flow_label[3]; // 3 octets
u32 sdf_filter_id; u32 sdf_filter_id;
} sdf_filter_t_; } sdf_filter_t_;
......
...@@ -14,6 +14,5 @@ typedef struct pfcp_far_s { ...@@ -14,6 +14,5 @@ typedef struct pfcp_far_s {
forwarding_parameters_t_ forwarding_parameters; forwarding_parameters_t_ forwarding_parameters;
duplicating_parameters_t_ duplicating_parameters; duplicating_parameters_t_ duplicating_parameters;
bar_id_t_ bar_id; bar_id_t_ bar_id;
} pfcp_far_t_; } pfcp_far_t_;
#endif // __PFCP_FAR_H__ #endif // __PFCP_FAR_H__
#ifndef __PFCP_QER_H__
#define __PFCP_QER_H__
#include <types.h>
#include <ie/group_ie/create_qer.h>
#include <ie/qer_id.h>
#include <ie/qer_correlation_id.h>
#include <ie/gate_status.h>
#include <ie/guaranteed_bitrate.h>
#include <ie/maximum_bitrate.h>
#include <ie/qos_flow_identifier.h>
#include <ie/reflective_qos.h>
#include <ie/paging_policy_indicator.h>
typedef struct pfcp_qer_s {
qer_id_t_ qer_id;
qer_correlation_id_t qer_correlation_id;
gate_status_t gate_status;
mbr_t maximum_bitrate;
gbr_t guaranteed_bitrate;
qfi_t qos_flow_identifier;
rqi_t reflective_qos;
paging_policy_indicator_t paging_policy_indicator;
} pfcp_qer_t_;
#endif // __PFCP_QER_H__
...@@ -6,17 +6,18 @@ ...@@ -6,17 +6,18 @@
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#define UDP_CSUM_OFFSET (sizeof(struct ethhdr) + offsetof(struct udphdr, check)) //#define UDP_CSUM_OFFSET (sizeof(struct ethhdr) + offsetof(struct udphdr,
// check))
// static u32 udp_handle( // static u32 udp_handle(
// struct xdp_md* ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip); // struct xdp_md* ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip);
// static u32 udp_handle( // static u32 udp_handle(
// struct xdp_md* ctx, struct udphdr* udph, u32 dest_ip); // struct xdp_md* ctx, struct udphdr* udph, u32 dest_ip);
static u32 udp_handle( // static u32 udp_handle(
struct xdp_md* p_ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip, // struct xdp_md* p_ctx, struct udphdr* udph, u32 src_ip, u32 dest_ip,
u8 dscp); // u8 dscp);
static u32 handle_uplink_traffic(struct xdp_md* p_ctx, struct udphdr* udph); // static u32 handle_uplink_traffic(struct xdp_md* p_ctx, struct udphdr* udph);
#endif // PROTOCOLS_UDP_H #endif // PROTOCOLS_UDP_H
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
#define MAX_FAR_PROGRAMS 10000 #define MAX_FAR_PROGRAMS 10000
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
struct { // struct {
__uint(type, BPF_MAP_TYPE_HASH); // __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, FAR_TAILS_MAX); // __uint(max_entries, FAR_TAILS_MAX);
__type(key, u8); // __type(key, u8);
__type(value, pfcp_far_t_); // __type(value, pfcp_far_t_);
} m_far SEC(".maps"); // } m_far SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
struct { struct {
...@@ -37,12 +37,12 @@ struct { ...@@ -37,12 +37,12 @@ struct {
} m_arp_table SEC(".maps"); } m_arp_table SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
struct { // struct {
__uint(type, BPF_MAP_TYPE_HASH); // __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_FAR_PROGRAMS); // __uint(max_entries, MAX_FAR_PROGRAMS);
__type(key, u32); // __type(key, u32);
__type(value, u32); // __type(value, u32);
} m_enforcing_qos SEC(".maps"); // } m_enforcing_qos SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
......
...@@ -212,8 +212,8 @@ int far_entry_point(struct xdp_md* ctx) { ...@@ -212,8 +212,8 @@ int far_entry_point(struct xdp_md* ctx) {
void* data = (void*) (long) ctx->data; void* data = (void*) (long) ctx->data;
void* data_end = (void*) (long) ctx->data_end; void* data_end = (void*) (long) ctx->data_end;
u32 key = 0; u32 key = 0;
pfcp_far_t_* p_far = bpf_map_lookup_elem(&m_far, &key); pfcp_far_t_* p_far; //= bpf_map_lookup_elem(&m_far, &key);
if (p_far) { if (p_far) {
struct ethhdr* ethh = data; struct ethhdr* ethh = data;
...@@ -275,24 +275,7 @@ int far_entry_point(struct xdp_md* ctx) { ...@@ -275,24 +275,7 @@ int far_entry_point(struct xdp_md* ctx) {
} else if (dest_interface == INTERFACE_VALUE_ACCESS) { } else if (dest_interface == INTERFACE_VALUE_ACCESS) {
create_outer_header_gtpu_ipv4(ctx, p_far); create_outer_header_gtpu_ipv4(ctx, p_far);
return bpf_redirect_map(&m_redirect_interfaces, DOWNLINK, 0);
uint32_t far_id_key = p_far->far_id.far_id;
uint32_t* enforcing_qos =
bpf_map_lookup_elem(&m_enforcing_qos, &far_id_key);
if (enforcing_qos) {
switch (*enforcing_qos) {
case 0: {
bpf_debug("The packet is redirected to N3 interface");
return bpf_redirect_map(&m_redirect_interfaces, DOWNLINK, 0);
}
case 1: {
bpf_debug("The packet is passed to tc layer");
return XDP_PASS;
}
default: {
}
}
}
} }
} }
......
...@@ -3,60 +3,30 @@ ...@@ -3,60 +3,30 @@
#include <ie/group_ie/create_pdr.h> #include <ie/group_ie/create_pdr.h>
#include <pfcp/pfcp_pdr.h> #include <pfcp/pfcp_pdr.h>
#include <pfcp/pfcp_far.h>
#include <pfcp/pfcp_session.h> #include <pfcp/pfcp_session.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <stdint.h> #include <stdint.h>
#include <ie/teid.h> #include <ie/teid.h>
#include <next_prog_rule_map.h> #include <next_prog_rule_map.h>
#include <next_prog_rule_key.h> #include <next_prog_rule_key.h>
#include <rules_matching_pdr.h>
#include "interfaces.h" #include "interfaces.h"
#include "session_id.h" #include "session_id.h"
#define MAX_LENGTH 10000 #define MAX_LENGTH 10000 // 10
#define INTERFACE_ENTRIES_MAX 12 #define INTERFACE_ENTRIES_MAX 12
#define MAX_UEs 10000 #define MAX_UEs 10000
#define MAX_PDRS_PER_SESSION 32
#define MAX_SDF_FITLER_ENTRIES 1000
/*---------------------------------------------------------------------------------------------------------------*/
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 { struct {
__uint(type, BPF_MAP_TYPE_HASH); __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_LENGTH); // 10, __uint(max_entries, MAX_SDF_FITLER_ENTRIES);
__type(key, struct next_rule_prog_index_key); __type(key, struct session_qfi); // <qfi, seid>
__type(value, u32); __type(value, struct sdf_filtr);
} m_next_rule_prog_index SEC(".maps"); } m_sdf_filter SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
struct { struct {
__uint(type, BPF_MAP_TYPE_HASH); __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, INTERFACE_ENTRIES_MAX); __uint(max_entries, INTERFACE_ENTRIES_MAX);
...@@ -64,7 +34,6 @@ struct { ...@@ -64,7 +34,6 @@ struct {
__type(value, struct s_interface); __type(value, struct s_interface);
} m_upf_interfaces SEC(".maps"); } m_upf_interfaces SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/
struct { struct {
__uint(type, BPF_MAP_TYPE_HASH); __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_LENGTH); __uint(max_entries, MAX_LENGTH);
...@@ -72,8 +41,28 @@ struct { ...@@ -72,8 +41,28 @@ struct {
__type(value, struct session_id); // < teid_ul, teid_dl, seid > __type(value, struct session_id); // < teid_ul, teid_dl, seid >
} m_session_mapping SEC(".maps"); } m_session_mapping SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/ struct {
/* Framed Routing */ __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_LENGTH);
__type(key, u64); // seid
__type(value, pfcp_pdr_t_[MAX_PDRS_PER_SESSION]);
} m_session_pdrs SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(
max_entries,
MAX_LENGTH); // max_rules = max_pdrs_per_pdu_session * max_pdu_session
__type(key, struct pdrs_per_session); // < pdr_id, seid >
__type(value, struct rules_match_pdr); // < FAR, QER, /* MAR, BAR, URR */ >
} m_rules_match_pdr SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_LENGTH); // Store only one entry for the QoS flag
__type(key, u64); // seid
__type(value, u32); // Value type (0 for false, 1 for true)
} m_qos_enabling SEC(".maps");
struct { struct {
__uint(type, BPF_MAP_TYPE_HASH); __uint(type, BPF_MAP_TYPE_HASH);
......
#ifndef __RULES_MATCHING_PDR_H__
#define __RULES_MATCHING_PDR_H__
#include <pfcp/pfcp_far.h>
#include <pfcp/pfcp_qer.h>
struct rules_match_pdr {
pfcp_far_t_ far;
pfcp_qer_t_ qer;
// TODO: add other RUles here !
};
struct pdrs_per_session {
uint16_t pdr_id;
uint64_t seid;
};
// struct sdfs_per_session {
// uint16_t qer_id;
// uint64_t seid;
// };
#endif // __RULES_MATCHING_PDR_H__
#ifndef __SDF_FILTER_H__
#define __SDF_FILTER_H__
#include <types.h>
//#include <linux/in.h>
//#include <linux/ip.h>
//#include <linux/ipv6.h>
//#include <linux/tcp.h>
//#include <linux/udp.h>
/*---------------------------------------------------------------------------------------------------------------*/
static inline uint16_t generate_minor_id(uint64_t seid, uint8_t qfi) {
uint16_t hash = (seid ^ (seid >> 16) ^ (seid >> 32) ^ (seid >> 48));
uint16_t minor_id =
(hash + (qfi * 37)) & 0xFFFF; // Avoid modulo, use bitmask
// Limit minor_id to a max of 9999
minor_id = (minor_id > 9999) ? 9999 : minor_id;
return minor_id ? minor_id : 1; // Ensure nonzero
}
/*---------------------------------------------------------------------------------------------------------------*/
struct ip_subnet {
u8 type;
/*
* 0: any, 1: ip4, 2: ip6
* If type != any, ip field has meaningful value.
* If IPv4 -> lower 32 bits. If IPv6 -> all 128 bits.
*/
u128 ip;
/*
* If type != any, mask field has meaningful value.
* If IPv4 mask -> lower 32 bits. If IPv6 mask -> all 128 bits.
* Should always be applied to matching ip (except type == any).
*/
u128 mask;
};
struct port_range {
__u16 lower_bound; // If not specified in SDF: 0
__u16 upper_bound; // If not specified in SDF: 65535
};
struct packet_filter {
u32 src_ip;
u32 dst_ip;
u16 protocol;
u16 src_port;
u16 dst_port;
// u32 tos;
} __attribute__((aligned(8)));
struct session_qfi {
u64 seid;
u8 qfi;
};
struct sdf_filtr {
u16 protocol;
struct ip_subnet src_addr;
struct port_range src_port;
struct ip_subnet dst_addr;
struct port_range dst_port;
struct session_qfi session;
};
#endif // __SDF_FILTER_H__
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
struct session_id { struct session_id {
u32 teid_ul; u32 teid_ul;
u32 teid_dl; u32 teid_dl;
u32 seid; u64 seid;
}; };
#endif // __SESSION_ID_H__ #endif // __SESSION_ID_H__
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <linux/bpf.h> #include <linux/bpf.h>
#include <types.h> #include <types.h>
#define MAX_LENGTH 10000 #define MAX_LENGTH 10000 // 10
/* /*
* +------------------------------------------------------+ * +------------------------------------------------------+
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
* +--------------------------+---------------------------+ * +--------------------------+---------------------------+
*/ */
struct { // struct {
__uint(type, BPF_MAP_TYPE_PROG_ARRAY); // __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
__uint(max_entries, MAX_LENGTH); // __uint(max_entries, MAX_LENGTH);
__type(key, u32); // __type(key, u32);
__type(value, s32); // __type(value, s32);
} m_next_rule_prog SEC(".maps"); // } m_next_rule_prog SEC(".maps");
// BPF_ANNOTATE_KV_PAIR(m_next_rule_prog, u32, s32); // BPF_ANNOTATE_KV_PAIR(m_next_rule_prog, u32, s32);
......
#ifndef __FILTER_KEY_H__
#define __FILTER_KEY_H__
#include <types.h>
struct filter_key {
u32 src_ip;
u32 dst_ip;
u8 protocol;
u16 dst_port;
u32 tos;
};
struct session_qfi {
u64 seid;
u8 qfi;
};
#endif // __FILTER_KEY_H__
...@@ -4,35 +4,35 @@ ...@@ -4,35 +4,35 @@
#include <bpf_helpers.h> #include <bpf_helpers.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <types.h> #include <types.h>
#include "filter_key.h" #include "sdf_filter.h"
#include "qos_flow.h" #include "qos_flow.h"
#define QFI_MAX_ENTRIES 10000 //#define QFI_MAX_ENTRIES 10000
#define FIVE_QI_MAX_ENTRIES 100 //#define FIVE_QI_MAX_ENTRIES 100
#define QOS_FLOWS_MAX_ENTRIES 10000 #define QOS_FLOWS_MAX_ENTRIES 10000
#define MAX_INTERFACES 10 #define MAX_INTERFACES 10
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
struct { // struct {
__uint(type, BPF_MAP_TYPE_HASH); // __uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, QFI_MAX_ENTRIES); // 10, // __uint(max_entries, QOS_FLOWS_MAX_ENTRIES);
__type(key, struct filter_key); // __type(key, u32);
__type(value, struct session_qfi); // __type(value, struct s_fiveQosFlow);
} m_sdf_filter SEC(".maps"); // } m_qos_flow SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
struct { // struct {
__uint(type, BPF_MAP_TYPE_HASH); // __uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, QOS_FLOWS_MAX_ENTRIES); // __uint(max_entries, 1);
__type(key, u32); // __type(key, u32);
__type(value, struct s_fiveQosFlow); // __type(value, u8);
} m_qos_flow SEC(".maps"); // } m_default_qfi SEC(".maps");
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
struct { struct {
__uint(type, BPF_MAP_TYPE_DEVMAP); __uint(type, BPF_MAP_TYPE_DEVMAP);
__uint(max_entries, MAX_INTERFACES); __uint(max_entries, MAX_INTERFACES);
__type(key, u32); __type(key, u32); // u8?
__type(value, u32); __type(value, u32);
} m_egress_ifindex SEC(".maps"); } m_egress_ifindex SEC(".maps");
......
This diff is collapsed.
...@@ -4,27 +4,34 @@ ...@@ -4,27 +4,34 @@
#include <types.h> #include <types.h>
/* Use uint8_t*/ // /* Use uint8_t*/
struct s_gate { // struct s_gate {
uint8_t ul_gate; // uint8_t ul_gate;
uint8_t dl_gate; // uint8_t dl_gate;
}; // };
struct s_mbr { // struct s_mbr {
uint64_t ul_mbr; // uint64_t ul_mbr;
uint64_t dl_mbr; // uint64_t dl_mbr;
}; // };
struct s_gbr { // struct s_gbr {
uint64_t ul_gbr; // uint64_t ul_gbr;
uint64_t dl_gbr; // uint64_t dl_gbr;
}; // };
// struct s_fiveQosFlow {
// struct s_gate gate;
// struct s_mbr mbr;
// struct s_gbr gbr;
// uint64_t qfi;
// };
struct s_fiveQosFlow { struct s_fiveQosFlow {
struct s_gate gate; uint8_t gate;
struct s_mbr mbr; uint64_t mbr;
struct s_gbr gbr; uint64_t gbr;
uint64_t qfi; uint8_t qfi;
}; };
#endif //__QOS_FLOW_H__ #endif //__QOS_FLOW_H__
\ No newline at end of file
...@@ -192,8 +192,8 @@ static int pcn_l4_csum_replace( ...@@ -192,8 +192,8 @@ static int pcn_l4_csum_replace(
} }
ptr = (__sum16*) ((void*) (long) ctx->data + csum_offset); ptr = (__sum16*) ((void*) (long) ctx->data + csum_offset);
bpf_debug("Here the value of csum_offset %x", (__sum16*) TCP_CSUM_OFFSET); // bpf_debug("Here the value of csum_offset %x", (__sum16*) TCP_CSUM_OFFSET);
bpf_debug("Here the value of ptr %x", *ptr); // bpf_debug("Here the value of ptr %x", *ptr);
if (is_mmzero && !do_mforce && !*ptr) return 0; if (is_mmzero && !do_mforce && !*ptr) return 0;
......
#ifndef CONFIG_LOADER_H
#define CONFIG_LOADER_H
#include <unordered_map>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
class ConfigLoader {
public:
static ConfigLoader& getInstance() {
static ConfigLoader instance; // Singleton instance
return instance;
}
bool loadConfig(const std::string& filename) {
std::ifstream file(filename);
if (!file) {
std::cerr << "Error: Cannot open config file " << filename << std::endl;
return false;
}
std::string line;
while (std::getline(file, line)) {
std::istringstream is_line(line);
std::string key;
if (std::getline(is_line, key, '=')) {
std::string value;
if (std::getline(is_line, value)) {
config[key] = std::stoi(value);
}
}
}
file.close();
return true;
}
int getValue(const std::string& key, int default_value = 0) {
return (config.find(key) != config.end()) ? config[key] : default_value;
}
private:
ConfigLoader() {} // Private constructor
std::unordered_map<std::string, int> config;
};
#endif // CONFIG_LOADER_H
#ifndef CONFIG_MANAGER_HPP
#define CONFIG_MANAGER_HPP
class ConfigManager {
public:
// Returns the singleton instance
static ConfigManager& getInstance();
// Initializes the configuration
void initialize(bool enableBpfDatapath, bool enableQos);
// Checks if BPF datapath is enabled
bool isBpfDatapathEnabled() const;
// Checks if QoS is enabled
bool isQosEnabled() const;
private:
// Private constructor to prevent instantiation
ConfigManager() = default;
// Deleted copy constructor and assignment operator
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
// Configuration variables
bool enable_bpf_datapath = false;
bool enable_qos = false;
};
#endif // CONFIG_MANAGER_HPP
\ No newline at end of file
...@@ -48,7 +48,7 @@ uint64_t NicInformationGetter::retrieveRate(std::string interface) { ...@@ -48,7 +48,7 @@ uint64_t NicInformationGetter::retrieveRate(std::string interface) {
std::istringstream iss(speed); std::istringstream iss(speed);
iss >> rate; iss >> rate;
return rate * 1000; return (rate * 1000);
} }
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
...@@ -63,7 +63,7 @@ uint64_t NicInformationGetter::retrieveCeil(std::string interface) { ...@@ -63,7 +63,7 @@ uint64_t NicInformationGetter::retrieveCeil(std::string interface) {
std::istringstream iss(speed); std::istringstream iss(speed);
iss >> ceil; iss >> ceil;
return ceil * 1000; return (ceil * 1000);
} }
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
......
This diff is collapsed.
#ifndef SDF_FILTER_PARSER_HPP
#define SDF_FILTER_PARSER_HPP
#include <string>
//#include <memory>
#include <netinet/ether.h>
#include <iostream>
#include <optional>
#include <cstdlib>
#include "logger.hpp"
class SdfFilterParser {
public:
// SdfFilterParser();
static std::optional<uint16_t> ParseProtocol(const std::string& protocol);
static std::optional<struct ip_subnet> ParseCidrIp(
const std::string& ipStr, const std::string& maskStr);
static std::optional<struct port_range> ParsePortRange(
const std::string& str);
static std::optional<struct sdf_filtr> ParseSdfFilter(
const std::string& flowDescription);
private:
static std::optional<uint16_t> ParsePort(const std::string& str);
};
#endif // SDF_FILTER_PARSER_HPP
\ No newline at end of file
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
#include <linux/types.h> #include <linux/types.h>
//#pragma once
typedef unsigned __int128 __u128;
typedef __u128 u128;
typedef __u64 u64; typedef __u64 u64;
typedef __s64 s64; typedef __s64 s64;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include <BPFProgram.h> #include <BPFProgram.h>
#include "interfaces.h" #include "interfaces.h"
#include <netlink/netlink.h> // #include <netlink/netlink.h>
#include <netlink/route/qdisc.h> // #include <netlink/route/qdisc.h>
#include <qos_flow.h> #include <qos_flow.h>
#include <pfcp_session.hpp> #include <pfcp_session.hpp>
class BPFMaps; class BPFMaps;
...@@ -59,7 +59,9 @@ class QERProgram : public BPFProgram { ...@@ -59,7 +59,9 @@ class QERProgram : public BPFProgram {
* @param uint64_t * @param uint64_t
* @param struct gtpUTunnel* * @param struct gtpUTunnel*
*/ */
void setup(uint64_t seid, std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer); void setup(
uint64_t seid, std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer,
std::vector<std::shared_ptr<pfcp::pfcp_pdr>> pdrs);
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
/** /**
* @brief Get the BPFMaps object. * @brief Get the BPFMaps object.
...@@ -95,7 +97,8 @@ class QERProgram : public BPFProgram { ...@@ -95,7 +97,8 @@ class QERProgram : public BPFProgram {
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<BPFMap> getQoSFlowMap() const; // std::shared_ptr<BPFMap> getQoSFlowMap() const;
// std::shared_ptr<BPFMap> getDefaultQfiMap() const;
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
...@@ -108,7 +111,13 @@ class QERProgram : public BPFProgram { ...@@ -108,7 +111,13 @@ class QERProgram : public BPFProgram {
// int ifindex, struct qer_tc_kernel_c* obj, const char* section_name); // int ifindex, struct qer_tc_kernel_c* obj, const char* section_name);
// int add_clsact_qdisc(int ifindex, enum bpf_tc_attach_point attach_point); // int add_clsact_qdisc(int ifindex, enum bpf_tc_attach_point attach_point);
bool no_htb_root_qdisc(std::string interface); bool no_htb_root_qdisc(const std::string interface);
bool no_htb_default_class(const std::string interface);
bool no_tc_filter_bpf(const std::string interface);
/*---------------------------------------------------------------------------------------------------------------*/
std::shared_ptr<pfcp::pfcp_qer> retrive_default_qer_with_default_qfi(
std::vector<std::shared_ptr<pfcp::pfcp_qer>> pQer);
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
private: private:
/** /**
...@@ -117,7 +126,12 @@ class QERProgram : public BPFProgram { ...@@ -117,7 +126,12 @@ class QERProgram : public BPFProgram {
*/ */
void initializeMaps(); void initializeMaps();
void storeQosFlow(std::shared_ptr<pfcp::pfcp_qer> pQer); void build_pdr_map(const std::vector<std::shared_ptr<pfcp::pfcp_pdr>>& pdrs);
std::shared_ptr<pfcp::pfcp_pdr> get_pdr_by_qer_id(uint32_t qer_id) const;
std::unordered_map<uint32_t, std::shared_ptr<pfcp::pfcp_pdr>> pdr_map;
// void storeQosFlow(std::shared_ptr<pfcp::pfcp_qer> pQer);
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
// The reference of the bpf maps. // The reference of the bpf maps.
std::shared_ptr<BPFMaps> mpMaps; std::shared_ptr<BPFMaps> mpMaps;
...@@ -136,8 +150,6 @@ class QERProgram : public BPFProgram { ...@@ -136,8 +150,6 @@ class QERProgram : public BPFProgram {
std::shared_ptr<QERProgramLifeCycle> mpLifeCycle; std::shared_ptr<QERProgramLifeCycle> mpLifeCycle;
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
// The SDF Filter map.
std::shared_ptr<BPFMap> mpSdfFilterMap;
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
// The 5G QoS Flow Parameters map. // The 5G QoS Flow Parameters map.
...@@ -145,8 +157,9 @@ class QERProgram : public BPFProgram { ...@@ -145,8 +157,9 @@ class QERProgram : public BPFProgram {
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
// The 5G QoS Flow. // The 5G QoS Flow.
std::shared_ptr<BPFMap> mpQoSFlowMap; // std::shared_ptr<BPFMap> mpQoSFlowMap;
// std::shared_ptr<BPFMap> mpDefaultQfiMap;
/*---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------*/
std::vector<struct s_fiveQosFlow> qosFlowsQfis; std::vector<struct s_fiveQosFlow> qosFlowsQfis;
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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