Chapter 0: Welcome

Welcome to the PFCP Endpoint (PEP) microservice learning guide. PEP is the control-plane brain of the User Plane β€” it terminates PFCP from the SMF, manages associations and sessions, and pushes forwarding rules to the data-plane.

Who is this for? Developers joining the PEP team. Assumes telecom background and basic C knowledge.

Repository at a Glance

pfcp-endpoint/
β”œβ”€β”€ src/                    # Main application source
β”‚   β”œβ”€β”€ pep_main.c          # Entry point
β”‚   β”œβ”€β”€ pep.c               # Top-level PEP module
β”‚   β”œβ”€β”€ pep_ctrl.c          # Controller module
β”‚   β”œβ”€β”€ pfcp.c              # PFCP protocol codec
β”‚   β”œβ”€β”€ pep_association_engine.c  # Association management (392K!)
β”‚   β”œβ”€β”€ pep_session_engine.c     # Session management (661K!)
β”‚   β”œβ”€β”€ pep_internal_session_engine.c  # Internal sessions
β”‚   β”œβ”€β”€ gtp_path_supervisor.c    # GTP path monitoring
β”‚   β”œβ”€β”€ path_supervisor.c        # PFCP path supervision
β”‚   β”œβ”€β”€ lep_client_engine.c      # LEP (data-plane) client
β”‚   β”œβ”€β”€ ext_adapter.c            # External adapter
β”‚   β”œβ”€β”€ config/             # Configuration parsing
β”‚   β”œβ”€β”€ network-instance/   # Network instance management
β”‚   β”œβ”€β”€ pfdm/              # PFD Management
β”‚   β”œβ”€β”€ pfcp-common/       # Shared PFCP utilities
β”‚   β”œβ”€β”€ db-mux/            # Database multiplexer
β”‚   β”œβ”€β”€ common/            # Common utilities
β”‚   β”œβ”€β”€ session/           # Session client
β”‚   β”œβ”€β”€ types/             # Type definitions
β”‚   β”œβ”€β”€ pvtb/             # PVTB (buffering)
β”‚   └── blocked-pools-manager/
β”œβ”€β”€ libs/                   # Local libraries
β”‚   β”œβ”€β”€ action/            # Action command framework
β”‚   β”œβ”€β”€ cli/               # CLI agent
β”‚   β”œβ”€β”€ cm/                # CM mediator/broker
β”‚   β”œβ”€β”€ fen/               # FEN adapter
β”‚   β”œβ”€β”€ fm/                # Fault Management
β”‚   └── partitioner/       # Session partitioning
β”œβ”€β”€ tests/                  # All tests
β”‚   β”œβ”€β”€ ut/                # Unit tests
β”‚   β”œβ”€β”€ sft/               # Signal Flow Tests
β”‚   β”œβ”€β”€ fixture/           # SFT test fixtures/simulators
β”‚   β”œβ”€β”€ mock/              # Mocks
β”‚   β”œβ”€β”€ veto/              # System tests (VETO)
β”‚   └── toads/             # TOADS integration tests
β”œβ”€β”€ include/                # Public headers
β”œβ”€β”€ flatbuffers/            # FlatBuffer schemas
β”œβ”€β”€ up-common/              # Shared libraries (submodule)
β”œβ”€β”€ Makefile                # Developer shortcuts (if exists)
β”œβ”€β”€ CMakeLists.txt          # Build system
β”œβ”€β”€ Jenkinsfile*            # CI/CD pipelines
└── ruleset2.0.yaml         # Bob build rules

Chapter 1: PFCP & the Control Plane

PFCP Recap (from the UPF perspective)

You already know PFCP from the data-plane guide. But PEP is the other side β€” it's the service that terminates PFCP messages from the SMF and translates them into data-plane configuration.

SMF (5G) / SGW-C+PGW-C (4G) β”‚ β”‚ PFCP (UDP port 8805) β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PFCP ENDPOINT (PEP) β”‚ ◄── THIS MICROSERVICE β”‚ β”‚ β”‚ β€’ Terminates PFCP β”‚ β”‚ β€’ Manages associations β”‚ β”‚ β€’ Manages sessions β”‚ β”‚ β€’ Allocates TEIDs/SEIDsβ”‚ β”‚ β€’ Pushes config to DP β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ JSON/FlatBuffers (internal) β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ DATA PLANE (DP) β”‚ β”‚ (packet forwarding) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key PFCP Concepts in PEP

ConceptPEP's Role
AssociationManages the PFCP association with each SMF (heartbeat, features, recovery)
SessionHandles session establishment/modification/deletion, translates PDRs/FARs/QERs
SEIDAllocates Session Endpoint Identifiers (unique per session)
TEIDAllocates Tunnel Endpoint Identifiers for GTP-U tunnels
HeartbeatMonitors SMF liveness via PFCP heartbeat request/response
RecoveryDetects SMF restart (recovery timestamp) and cleans up stale sessions
PFD ManagementHandles Packet Flow Description provisioning from SMF

Chapter 2: PEP's Role in PCG

Where PEP Sits

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PCG Kubernetes Cluster β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ SMF │────►│ PFCP │────►│ Data Plane β”‚ β”‚ β”‚ β”‚(external)β”‚PFCP β”‚ Endpoint β”‚JSON/ β”‚ (forwarding)β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ (PEP) β”‚FBs β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β–Ό β–Ό β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ CM Mediator β”‚ β”‚ Redis β”‚ β”‚ UE-IP Alloc β”‚ β”‚ β”‚ β”‚ (config) β”‚ β”‚ (state) β”‚ β”‚ (IP pools) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

PEP's Responsibilities

Chapter 3: Neighboring Services

ServiceInterfacePurpose
SMFPFCP (N4)Receives session/association requests
Data PlaneLEP (internal REST/FBs)Pushes forwarding rules
CM MediatorREST (JSON)Receives configuration
Redis (KV DB)Redis protocolSession state persistence, geo-redundancy
UE-IP AllocatorInternal APIIP address pool management
NWCMAgRPCNetwork instance configuration
Routing AgentgRPCRoute announcements for UE IPs
PM ServerPrometheusMetrics scraping
Log TransformerstdoutStructured logging

πŸ“ Quiz 1 β€” Context

Q1: What is PEP's primary role?

Q2: What does SEID stand for?

Q3: How does PEP detect an SMF restart?

Q4: Where does PEP persist session state for geo-redundancy?

Q5: What protocol does PEP use to push rules to the data-plane?

Chapter 4: High-Level Architecture

Single-Threaded Event-Driven

Unlike the data-plane (multi-threaded, CPU-pinned), PEP is primarily single-threaded and event-driven using the EVL event loop. It handles thousands of PFCP messages per second without threads β€” all via async I/O and callbacks.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ pfcp-endpoint process β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ EVL Event Loop β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ PFCP Socket β”‚ β”‚ Association Engine β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ (UDP 8805) β”‚ β”‚ β€’ SMF associations β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚ β€’ Heartbeat timers β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Recovery handling β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ PFCP Codec β”‚ β”‚ Session Engine β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ (decode/ β”‚ β”‚ β€’ PDR/FAR/QER/URR mgmt β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ encode) β”‚ β”‚ β€’ SEID/TEID allocation β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β€’ Config push to DP β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ REST/HTTP β”‚ β”‚ Path Supervisor β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ (health,CM) β”‚ β”‚ β€’ PFCP heartbeat β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β€’ GTP echo β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Source Files

FileSizePurpose
pep_session_engine.c661KSession lifecycle (the largest file!)
pep_association_engine.c392KAssociation management
gtp_path_supervisor.c230KGTP-U path monitoring
pep_internal_session_engine.c219KInternal session handling
pfcp.c185KPFCP protocol codec
path_supervisor.c124KPFCP path supervision
pep.c110KTop-level PEP module
pep_main.c94KEntry point, initialization
pep_ctrl.c87KController (config, OAM)

Chapter 5: Association Engine

What is a PFCP Association?

Before an SMF can create sessions, it must establish a PFCP Association with the UPF. This is like a "handshake" that negotiates features and starts heartbeat monitoring.

SMF                              PEP (UPF)
 β”‚                                β”‚
 │── Association Setup Request ──►│  (features, node ID, recovery TS)
 │◄── Association Setup Response ─│  (accepted, UP features, TEID ranges)
 β”‚                                β”‚
 │── Heartbeat Request ──────────►│  (every N seconds)
 │◄── Heartbeat Response ─────────│
 β”‚                                β”‚
 │── Association Release Req ────►│  (graceful teardown)
 │◄── Association Release Resp ───│

Association Engine Responsibilities

Code: src/pep_association_engine.c (392K lines) + src/pep_internal_association_engine.c

Chapter 6: Session Engine

Session Lifecycle

SMF sends PFCP Session Establishment Request β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PEP Session Engine β”‚ β”‚ β”‚ β”‚ 1. Validate request (IEs, mandatory) β”‚ β”‚ 2. Allocate SEID (local identifier) β”‚ β”‚ 3. Allocate TEIDs (for GTP tunnels) β”‚ β”‚ 4. Allocate UE IP (from pool) β”‚ β”‚ 5. Build data-plane config β”‚ β”‚ 6. Push to data-plane via LEP client β”‚ β”‚ 7. Persist to Redis (geo-red) β”‚ β”‚ 8. Send response to SMF β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Concepts

Chapter 7: Path Supervision

PFCP Path Supervision

PEP monitors the PFCP path to each SMF using heartbeat messages. If heartbeats fail, the association is considered dead and sessions are cleaned up.

// path_supervisor.c handles:
// - Sending heartbeat requests on timer
// - Tracking response timeouts
// - Declaring path failure after N retries
// - Triggering association cleanup on failure

GTP Path Supervision

PEP also monitors GTP-U paths (to gNBs) using GTP Echo Request/Response. This detects transport failures between the UPF and radio access network.

Code: src/gtp_path_supervisor.c (230K!) β€” One of the largest modules. Handles echo scheduling, failure detection, and reporting to SMF via PFCP Session Report.

πŸ“ Quiz 2 β€” Architecture

Q1: Is PEP multi-threaded like the data-plane?

Q2: What is the largest source file in PEP?

Q3: What must happen before an SMF can create sessions?

Q4: What does the GTP path supervisor monitor?

Q5: What happens when PEP detects an SMF recovery timestamp change?

Chapter 8: PFCP Protocol Handling

The PFCP Codec

src/pfcp.c (185K) implements the PFCP message encoder/decoder per 3GPP TS 29.244. It handles:

PFCP Resource Encoder

src/pfcp_resource_encoder.c (64K) encodes PFCP resources (TEIDs, network instance info) into the format expected by the data-plane.

Chapter 9: Network Instances

The src/network-instance/ module manages network instances (DNNs/APNs). Each network instance has:

Key files: nw_instance_engine.c (108K), nw_instance_id_engine.c (69K), nw_instance_id_allocator.c, nw_instance_id_cache.c.

Chapter 10: PFD Management

The src/pfdm/ module handles Packet Flow Description Management β€” the SMF can provision application detection rules (PFDs) that the UPF uses for DPI-less traffic classification.

Key components: pfdm_engine.c, pfdm_provision_handler.c, pfdm_delete_handler.c, pfdm_request_handler.c, pfdm_state_data.c.

Chapter 11: DB Mux & Geo-Redundancy

DB Multiplexer

The src/db-mux/ module abstracts database operations, allowing PEP to work with multiple Redis instances for geo-redundancy.

Geo-Redundancy

PEP persists session state to Redis so that if a PEP pod dies, another can take over. The common/src/db_module.c and common/src/db_tracker_adapter.c handle this.

Sequence Number Allocator

common/src/seqno_allocator.c β€” Generates unique sequence numbers for PFCP messages, persisted across restarts via Redis.

πŸ“ Quiz 3 β€” Subsystems

Q1: What does the PFCP codec in pfcp.c do?

Q2: What is PFD Management used for?

Q3: Why does PEP persist state to Redis?

Q4: What does the DB Mux module abstract?

Q5: What does the NWID represent?

Chapter 12: Module Lifecycle

PEP follows the same module lifecycle pattern as data-plane (create β†’ start β†’ stop β†’ delete). See the data-plane guide Chapter 12 for the full pattern. The same rules apply: start must not fail, stop must be callable before start completes, on_stopped_cb means safe to delete.

// PEP module example (from pep.h)
pep_t* pep_create(pep_options_t* options, evl_t* evl, ...);
void   pep_start(pep_t* pep, on_started_cb, ctx);
void   pep_stop(pep_t* pep, on_stopped_cb, ctx);
void   pep_delete(pep_t* pep);

Chapter 13: Config Handling

Configuration Sources

Config Flow

CM Mediator β†’ JSON β†’ pep_config_json_parser β†’ pep_config β†’ pep_ctrl_config β†’ modules

Chapter 14: LEP Client & Ext Adapter

LEP Client

The LEP (Local Endpoint) Client (lep_client_engine.c, 59K) is how PEP pushes session configuration to the data-plane. It serializes rules into FlatBuffers and sends them over an internal connection.

External Adapter

ext_adapter.c (56K) handles communication with external services (UE-IP allocator, routing agent, etc.).

πŸ“ Quiz 4 β€” Code Patterns

Q1: What is the LEP client used for?

Q2: What serialization format does PEP use to talk to data-plane?

Q3: What is the primary config source in PCG mode?

Q4: Which module lifecycle rule applies to PEP?

Q5: What does pep_options.c handle?

Chapter 15: up-common & EVL

PEP uses the same up-common submodule as data-plane. Key libraries: EVL (event loop), timers, mbox, RCU, HTTP, Redis client, TLS, logging, metrics. See data-plane guide Chapters 15-17 for details.

Chapter 16: Local Libraries

PEP has its own libs/ directory with service-specific libraries:

LibraryPurpose
libs/action/Action command framework (operational commands)
libs/cli/CLI agent for troubleshooting commands
libs/cm/CM mediator/broker integration
libs/fen/FEN (Front-End Node) adapter
libs/fm/Fault Management (alarm raising/clearing)
libs/partitioner/Session partitioning across PEP instances
libs/async_retry_agent/Retry logic for async operations

Chapter 17: Flatbuffers & PFCP Codec

FlatBuffers

PEP uses FlatBuffers (Google's zero-copy serialization) to communicate with the data-plane. Schemas are in flatbuffers/. This is more efficient than JSON for high-frequency session updates.

PFCP Codec Libraries

The src/pfcp-common/ module contains shared PFCP utilities:

πŸ“ Quiz 5 β€” Libraries

Q1: What is the partitioner library used for?

Q2: Why use FlatBuffers instead of JSON for DP communication?

Q3: What does the FM library handle?

Q4: What does load_ctrl.c report?

Q5: What shared library provides the event loop?

Chapter 18: Build System

Same as data-plane: CMake + Bob + up-common 3PP system. The top-level CMakeLists.txt builds the pfcp-endpoint executable and links all modules.

# Key build commands (similar to data-plane)
$ bob/bob init-dev
$ bob/bob generate:3pp          # Download 3PP dependencies
$ bob/bob -p build-dir=builds/san generate:cmake
$ bob/bob -p build-dir=builds/san build:cpp test:cpp

Build variants: builds/san (sanitizers), builds/assert, builds/debug, builds/release, builds/cov.

Chapter 19: Unit & SFT Tests

Test Organization

tests/
β”œβ”€β”€ ut/                 # Unit tests (test single modules with mocks)
β”‚   β”œβ”€β”€ pep_ut_session_engine.c      (725K!)
β”‚   β”œβ”€β”€ pep_ut_association_engine.c  (216K)
β”‚   β”œβ”€β”€ pep_ut_pfcp.c               (64K)
β”‚   └── ...
β”œβ”€β”€ sft/                # Signal Flow Tests (multi-module integration)
β”‚   β”œβ”€β”€ pep_sft_sessions.c          (273K)
β”‚   β”œβ”€β”€ pep_sft_associations.c      (98K)
β”‚   β”œβ”€β”€ pep_sft_pfdm.c             (470K!)
β”‚   └── ...
β”œβ”€β”€ fixture/            # SFT simulators
β”‚   β”œβ”€β”€ pep_sft_fix.c              (165K - main fixture)
β”‚   β”œβ”€β”€ pep_sft_sim_data_plane.c   (simulates DP)
β”‚   β”œβ”€β”€ pep_sft_sim_control_plane.c (simulates SMF)
β”‚   └── pep_sft_sim_lep.c          (simulates LEP)
β”œβ”€β”€ mock/               # Mock implementations
└── utils/              # Test utilities

Uses the same ET test framework from up-common.

Chapter 20: VETO & TOADS

VETO (System Test)

tests/veto/ contains Python-based system tests that run against a real PCG deployment. They use TRex traffic generator and test end-to-end PFCP flows.

TOADS

tests/toads/ is a container-based integration test framework (similar to data-plane's contest). It runs PEP in a Docker container with simulated peers.

πŸ“ Quiz 6 β€” Build & Test

Q1: What is the SFT fixture's role?

Q2: What is TOADS?

Q3: Which test file is the largest?

Q4: What does pep_sft_sim_control_plane.c simulate?

Q5: What build tool orchestrates the build?

Chapter 21: CI Pipelines

Same pipeline structure as data-plane:

Chapter 22: Docker & Helm

PEP is deployed as eric-pc-up-pfcp-endpoint in Kubernetes. The Dockerfile builds a minimal image with the pfcp-endpoint binary. Helm chart is in charts/.

Key differences from data-plane: PEP does NOT need DPDK, SR-IOV, or hugepages. It's a standard network service using regular kernel sockets (UDP for PFCP).

Chapter 23: Day-to-Day Workflow

Same Gerrit workflow as data-plane. Key commands:

# Build and test
$ bob/bob -p build-dir=builds/san generate:cmake
$ bob/bob -p build-dir=builds/san build:cpp test:cpp

# Run specific test
$ bob/bob -p build-dir=builds/san -p cpp-target=pep_ut_session_engine_SUITE test:cpp

# Build image
$ bob/bob -p build-dir=builds/release build image package
πŸ’‘ Tip: The session engine test (725K lines!) takes a while. Use -p cpp-target= to run specific suites during development.

πŸ“ Quiz 7 β€” CI/CD & Deploy

Q1: Does PEP need DPDK or SR-IOV?

Q2: What triggers the PreCodeReview pipeline?

Q3: What is the Helm chart name for PEP?

Q4: What does JenkinsfilePra produce?

Q5: How do you run only the association engine unit test?

πŸŽ“ Congratulations!

You've completed the PFCP Endpoint Learning Guide.

24 chapters β€’ 7 quizzes β€’ From PFCP fundamentals to daily workflow

Start with the SFT tests β€” they show you exactly how PEP interacts with SMF and data-plane. πŸš€