Chapter 6: PCG UPF Architecture — PEP, Data-Plane, Valkey
The Big Picture
┌─────────────────────────────────────────────┐
│ PCG Pod (Kubernetes) │
SMF ──PFCP──► │ │
│ ┌────────────────────────────────────────┐ │
│ │ pfcp-endpoint (PEP) │ │
│ │ │ │
│ │ • Receives PFCP messages from SMF │ │
│ │ • Parses PFCP, runs state machine │ │
│ │ • Stores session blob in Valkey │ │
│ │ • Forwards rules to data-plane │ │
│ │ • Handles retransmissions │ │
│ └──────────────┬─────────────────────────┘ │
│ │ internal (mbox/ITC) │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ data-plane (DP) │ │
│ │ │ │
│ │ • Installs forwarding rules (PDRs) │ │
│ │ • Manages TEIDs, UEIP, L2TP keys │ │
│ │ • Stores per-bearer state in Valkey │ │
│ │ • Handles user-plane traffic (GTP-U) │ │
│ │ • CGNAT, DPI, firewall, etc. │ │
│ └──────────────┬─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ Valkey Cluster (Redis-compatible) │ │
│ │ 6 nodes: 3 masters + 3 replicas │ │
│ │ │ │
│ │ Stores: sessions, TEIDs, UEIP, │ │
│ │ CGNAT maps, retransmissions │ │
│ └────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Why Two Separate Processes?
- PEP: handles PFCP signaling (control plane). Relatively low rate but complex state machines.
- DP: handles user-plane traffic (data plane). Extremely high throughput (millions of packets/sec). Also handles the DB writes for session state.
- They communicate via ITC (Inter-Thread Communication) / mbox (mailbox) — shared memory message passing within the pod.
The PFCP Session Lifecycle
// 1. SMF sends PFCP Session Establishment Request
// 2. PEP receives it, parses, creates session context
// 3. PEP stores session blob in Valkey (one key)
// 4. PEP sends rules to DP via mbox
// 5. DP installs rules, stores TEIDs/UEIP/etc in Valkey (multiple keys)
// 6. DP signals completion back to PEP
// 7. PEP sends PFCP Session Establishment Response to SMF
// The DB writes in step 5 are what PCPB-25616 optimizes!
DB Access Patterns
| Component | DB Library | Pattern | Feature Change |
|---|---|---|---|
| PEP session store | db-proxy → db-mux | One blob per session (single SET/GET) | Migrate to db-mux (CPU savings) |
| PEP retransmission | db-proxy → db-mux | Lookup on each request | Migrate to db-mux |
| DP session rules | db-proxy → db-mux | Multiple keys per session (TEID, UEIP, etc.) | Migrate + MSET batching |
| DP CGNAT | db-proxy | Already batches internally | No change planned |
Shared Library: up-common
up-common is the shared library used by both PEP and DP. It contains:
- EVL — the event loop
- db-proxy — old Redis client wrapper
- db-mux — new Redis client wrapper
- evlsock — socket abstraction (TCP, TLS, HTTP)
- hiredis — vendored Redis C client (in 3pp/)
Key Takeaways
- PEP handles PFCP signaling, DP handles user-plane + DB writes for session state
- Both use Valkey (Redis) for persistent state, accessed via up-common libraries
- The feature optimizes DP's DB writes (multiple keys per session → MSET)
- PEP's DB access is already efficient (one blob per session) — just migrating library
- up-common is the shared foundation (EVL, db-proxy, db-mux, hiredis)