Simple PFCP Client

March 14, 2026 ยท View on GitHub

This describes how to use a simple PFCP client to configure UPF. This is intended as a preparation for measuring the performance of open source UPFs (Open5GS UPF, free5GC UPF, UPG-VPP, eUPF and OAI-CN5G-UPF).


Sample Configurations and Miscellaneous for Mobile Network


Table of Contents


Simple Overview of PFCP Client, TRex and DUT (UPF)

This describes a simple configuration of PFCP Client, TRex and DUT (UPF). Note that this configuration is implemented with Proxmox VE VMs.

The following minimum configuration was set as a condition.

  • One PFCP client, TRex and DUT (UPF)

The built simulation environment is as follows.

The PFCP client in Python was created using the following.

Each VMs are as follows.

VMSW & RoleIP addressOSCPUMemHDD
VM1Simple PFCP Client192.168.0.111/24Ubuntu 24.0411GB10GB
VM-TGTRex
Traffic Generator
192.168.0.131/24Ubuntu 24.0438GB10GB
VM-DUTeach UPF DUT
(Device Under Test)
192.168.0.151/24Ubuntu 24.0428GB10GB

The network interfaces of each VM are as follows.

VMDeviceModelLinux BridgeIP addressInterfaceUnder
DPDK
VM1ens18VirtIOvmbr110.0.0.111/24(NAPT NW)--
ens19VirtIOmgbr0192.168.0.111/24(Mgmt NW)--
ens20VirtIOvmbr4192.168.14.111/24N4--
VM-TGens18VirtIOvmbr110.0.0.131/24(NAPT NW) down--
ens19VirtIOmgbr0192.168.0.131/24(Mgmt NW)--
ens20VirtIOvmbr3192.168.13.131/24N3x
ens21VirtIOvmbr6192.168.16.152/24N6x
VM-DUTens18VirtIOvmbr110.0.0.151/24(NAPT NW) down--
ens19VirtIOmgbr0192.168.0.151/24(Mgmt NW)--
ens20VirtIOvmbr3192.168.13.151/24N3--
ens21VirtIOvmbr4192.168.14.151/24N4--
ens22VirtIOvmbr6192.168.16.151/24N6--

Linux Bridges of Proxmox VE are as follows.

Linux BridgeNetwork CIDRInterface
vmbr110.0.0.0/24NAPT NW
mgbr0192.168.0.0/24Mgmt NW
vmbr3192.168.13.0/24N3
vmbr4192.168.14.0/24N4
vmbr6192.168.16.0/24N6

UE IP address and TEID are as follows.

UE IP addressUpLink TEIDDownLink TEID
10.45.0.2/240x000000010x00000002

Install Simple PFCP Client

Install required packages

# apt install python3 python3-pip python3-venv

Setup venv

Set venv to ~/venv.

# mkdir ~/venv
# python3 -m venv ~/venv

Note. From now on, when using Python, first type as follows.

# source ~/venv/bin/activate
(venv) root@pfcp:~#

To exit Python venv, do the following.

(venv) root@pfcp:~# deactivate

Install Scapy

# source ~/venv/bin/activate
(venv) root@pfcp:~# pip3 install scapy

Modify pfcp.py

According to 3GPP TS 29.244 - 8.2.118 3GPP Interface Type, add interface types SGi and N6 in pfcp.py as follows.

~/venv/lib/python3.12/site-packages/scapy/contrib/pfcp.py

--- pfcp.py.orig        2024-12-14 06:09:59.763278982 +0900
+++ pfcp.py     2024-12-17 22:00:09.601881929 +0900
@@ -363,6 +363,8 @@
     13: "N3 Untrusted Non-3GPP Access",
     14: "N3 for data forwarding",
     15: "N9",
+    16: "SGi",
+    17: "N6",
 }
 
 

Install pfcp_request.py

Get pfcp_request.py written in Python.

# wget https://github.com/s5uishida/simple_pfcp_client/raw/refs/heads/main/src/pfcp_request.py

Also, referring to 801room/upf_p4_poc/test_script/pfcp_request.py, I wrote this script to configure the open source UPFs - Open5GS UPF, free5GC UPF, UPG-VPP, eUPF and OAI-CN5G-UPF. If using UPF which requires QER in PFCP Session Establishment Request, please refer to pfcp_request_qer.py.

Set parameters in pfcp_request.py

Set the following parameters written in pfcp_request.py.

ItemValue (my environment)
PFCP_CP_IFACE"ens20"
PFCP_CP_IP_V4"192.168.14.111"
PFCP_UP_IP_V4"192.168.14.151"
N3_IP_V4"192.168.13.151"
GNB_IP_V4"192.168.13.131"
UE_IP_V4"10.45.0.2"
UL_TEID1
DL_TEID2
NWI"internet"
APN_DNN"internet"
COUNTER100

If using pfcp_request_qer.py, please set the following additional parameters. The unit is Kbps.

ItemValue (my environment)
UL_MBR200000000
DL_MBR200000000
UL_GBR200000000
DL_GBR200000000

Run pfcp_request.py

First start UPF. Then, to configure UPF, run pfcp_request.py as follows.

# source ~/venv/bin/activate
(venv) root@pfcp:~# python3 pfcp_request.py 
2026-01-17 03:18:58,381 - __main__ - INFO - REQ: <PFCPAssociationSetupRequest  IE_list=[<IE_NodeId  id_type=IPv4 ipv4=192.168.14.111 |>, <IE_RecoveryTimeStamp  timestamp=3977608738 |>, <IE_CPFunctionFeatures  |>] |>
.
Sent 1 packets.
2026-01-17 03:18:58,399 - __main__ - INFO - REQ: <PFCPSessionEstablishmentRequest  IE_list=[<IE_NodeId  id_type=IPv4 ipv4=192.168.14.111 |>, <IE_FSEID  v4=1 seid=0xa0374f94eb52b387 ipv4=192.168.14.111 |>, <IE_CreatePDR  IE_list=[<IE_PDR_Id  id=1 |>, <IE_Precedence  precedence=65535 |>, <IE_PDI  IE_list=[<IE_SourceInterface  interface=Core |>, <IE_NetworkInstance  instance=b'internet' |>, <IE_UE_IP_Address  SD=1 V4=1 ipv4=10.45.0.2 |>, <IE_3GPP_InterfaceType  interface_type=N6 |>] |>, <IE_FAR_Id  id=1 |>] |>, <IE_CreatePDR  IE_list=[<IE_PDR_Id  id=2 |>, <IE_Precedence  precedence=65535 |>, <IE_PDI  IE_list=[<IE_SourceInterface  interface=Access |>, <IE_FTEID  V4=1 TEID=0x1 ipv4=192.168.13.151 |>, <IE_NetworkInstance  instance=b'internet' |>, <IE_UE_IP_Address  SD=0 V4=1 ipv4=10.45.0.2 |>, <IE_SDF_Filter  FD=1 flow_description=b'permit out ip from any to assigned' |>, <IE_QFI  QFI=1 |>, <IE_3GPP_InterfaceType  interface_type=N3 3GPP Access |>] |>, <IE_FAR_Id  id=2 |>, <IE_OuterHeaderRemoval  |>] |>, <IE_CreateFAR  IE_list=[<IE_FAR_Id  id=1 |>, <IE_ApplyAction  FORW=1 |>, <IE_ForwardingParameters  IE_list=[<IE_DestinationInterface  interface=Access |>, <IE_NetworkInstance  instance=b'internet' |>, <IE_OuterHeaderCreation  GTPUUDPIPV4=1 TEID=0x2 ipv4=192.168.13.131 |>, <IE_3GPP_InterfaceType  interface_type=N3 3GPP Access |>] |>] |>, <IE_CreateFAR  IE_list=[<IE_FAR_Id  id=2 |>, <IE_ApplyAction  FORW=1 |>, <IE_ForwardingParameters  IE_list=[<IE_DestinationInterface  interface=Core |>, <IE_NetworkInstance  instance=b'internet' |>, <IE_3GPP_InterfaceType  interface_type=N6 |>] |>] |>, <IE_PDNType  pdn_type=IPv6 |>, <IE_APN_DNN  apn_dnn=b'internet' |>] |>
.
Sent 1 packets.
2026-01-17 03:19:00,901 - __main__ - INFO - REQ: 1
2026-01-17 03:19:00,902 - __main__ - INFO - REQ: <PFCPHeartbeatResponse  IE_list=[<IE_RecoveryTimeStamp  timestamp=3977608738 |>] |>
.
Sent 1 packets.
...

Now that the UPF is ready, you may measure its performance with TRex. The maximum number of times in which PFCP Heartbeat Response can be sent to UPF is the value of the COUNTER parameter. Please change the value as necessary.


I would like to thank the excellent developers and all the contributors of Scapy and 801room/upf_p4_poc/test_script/pfcp_request.py.

Sample Configurations

Changelog (summary)

  • [2026.01.14] Added UE IP address IE to PDI IE in Create PDR IE within PFCP Session Establishment Request for UpLink in pfcp_request.py and pfcp_request_qer.py.
  • [2025.01.25] Added the description of the case when using UPF which requires QER in PFCP Session Establishment Request.
  • [2025.01.16] Initial release.