PFCP/Sxb Interface Documentation
Packet Forwarding Control Protocol - PGW-C to PGW-U Communication
Table of Contents
- Overview
- Protocol Basics
- PFCP Association Management
- PFCP Session Management
- Packet Processing Rules
- Configuration
- DNS-based UPF Selection
- Message Flows
- Troubleshooting
- Web UI - PFCP Monitoring
- Related Documentation
Overview
The Sxb interface uses the PFCP (Packet Forwarding Control Protocol) for communication between the PGW-C (control plane) and PGW-U (user plane). This separation allows:
- Control Plane (PGW-C) - Handles signaling, session management, policy decisions
- User Plane (PGW-U) - Handles actual packet forwarding at high speed
PFCP Architecture
Protocol Basics
PFCP Version
PGW-C implements PFCP Version 1 (3GPP TS 29.244).
Transport
- Protocol: UDP
- Default Port: 8805
- Message Format: Binary encoded using PFCP specification
Node ID Types
PFCP peers are identified by Node ID, which can be:
- IPv4 Address - Most common
- IPv6 Address
- FQDN (Fully Qualified Domain Name)
PFCP Association Management
Before session management can occur, a PFCP association must be established between PGW-C and PGW-U.
Association Setup Flow
Peer State Management
Each PFCP peer maintains state:
| Field | Description |
|---|---|
is_associated | Boolean indicating association status |
remote_node_id | Peer's Node ID (IP or FQDN) |
remote_ip_address | IP address for communication |
remote_port | UDP port (default 8805) |
heartbeat_period_ms | Heartbeat interval in milliseconds |
missed_heartbeats_consecutive | Count of missed heartbeats |
up_function_features | Supported user plane features |
up_recovery_time_stamp | Peer's recovery timestamp |
Heartbeat Mechanism
Purpose: Detect peer failures and maintain association liveness
Configuration:
# In config/runtime.exs
sxb: %{
local_ip_address: "10.0.0.20"
},
upf_selection: %{
fallback_pool: [
%{remote_ip_address: "10.0.0.21", remote_port: 8805, weight: 100}
]
}
# All UPFs are automatically registered with 5-second heartbeats
Failure Detection:
- Each missed heartbeat increments
missed_heartbeats_consecutive - Typically configured to fail after 3 consecutive misses
- Failed association prevents new sessions to that peer
PFCP Session Management
PFCP sessions are created for each UE PDN connection to program forwarding rules in the user plane.
Session Lifecycle
Session Establishment
When: UE attaches and creates a PDN connection
PGW-C sends to PGW-U:
Session Establishment Request containing:
- SEID (Session Endpoint ID) - Unique session identifier
- Node ID - PGW-C's Node ID
- F-SEID - Fully Qualified SEID (includes IP + SEID)
- PDRs - Packet Detection Rules (typically 2: uplink + downlink)
- FARs - Forwarding Action Rules (typically 2: uplink + downlink)
- QERs - QoS Enforcement Rules (bitrate limits)
- BAR - Buffering Action Rule (for downlink buffering)
PGW-U responds:
Session Establishment Response containing:
- Cause - Success or failure reason
- F-SEID - PGW-U's session endpoint
- Created PDRs - Acknowledgment of created rules
- F-TEID - Fully Qualified TEID for S5/S8 interface
Session Modification
When: QoS changes, policy updates, or bearer modifications occur
Modification can include:
- Adding new PDRs, FARs, QERs
- Removing existing rules
- Updating rule parameters
Session Deletion
When: UE detaches or PDN connection is terminated
Process:
- PGW-C sends Session Deletion Request with SEID
- PGW-U removes all rules and releases resources
- PGW-U responds with Session Deletion Response
F-TEID Allocation
F-TEID (Fully Qualified Tunnel Endpoint Identifier) identifies GTP-U tunnel endpoints for user plane traffic. When establishing a PFCP session, someone must allocate the F-TEID that identifies where the UPF should send uplink traffic. There are two approaches:
Understanding F-TEID Allocation
What's Being Allocated: The F-TEID consists of:
- TEID (Tunnel Endpoint Identifier) - 32-bit number identifying the tunnel
- IP Address - Where to send GTP-U packets (the UPF's IP address)
The Question: Who allocates the TEID value?
Option 1: UPF Allocates (Recommended Default)
- PGW-C says "please allocate a TEID for me" (CHOOSE flag)
- UPF picks a TEID from its local pool and responds with the value
Option 2: PGW-C Allocates (Compatibility Mode)
- PGW-C picks a TEID and tells UPF "use this specific TEID"
- UPF uses the provided TEID without allocation
UPF Allocation (Default - Recommended)
Configuration:
sxb: %{
allocate_uplink_f_teid: false # Default
}
How It Works:
- PGW-C builds PFCP Session Establishment Request with F-TEID CHOOSE flag
- UPF receives request, allocates TEID from its internal pool
- UPF responds with allocated F-TEID (TEID + IP address)
- PGW-C stores allocated F-TEID for session lifetime
Why This is Better (Usually):
✅ Separation of Concerns
- UPF owns user plane = UPF manages user plane identifiers
- No need for PGW-C to track what TEIDs UPF has available
- Each component manages its own resource pool
✅ Multi-PGW-C Scalability
- Multiple PGW-C instances can talk to same UPF without coordination
- No risk of TEID collisions between different PGW-C instances
- UPF ensures uniqueness across all control plane peers
✅ Standard 3GPP Behavior
- CHOOSE flag is defined in 3GPP TS 29.244 for this purpose
- Modern UPF implementations support it
- Follows "let the owner allocate" principle
✅ Simpler Failover
- If PGW-C restarts, UPF still owns TEID namespace
- No need to synchronize TEID allocation state
- UPF can continue using existing TEIDs
When to Use:
- ✅ Production deployments with modern UPFs (default)
- ✅ Multi-PGW-C deployments sharing UPF pools
- ✅ Cloud-native architectures with stateless control planes
- ✅ You want standard 3GPP PFCP behavior
Potential Issues:
- ⚠️ Some legacy or proprietary UPF implementations don't support CHOOSE flag
- ⚠️ If session establishment fails with "mandatory IE missing" or similar, UPF may not support CHOOSE
PGW-C Allocation (Legacy Compatibility)
Configuration:
sxb: %{
allocate_uplink_f_teid: true
}
How It Works:
- PGW-C allocates TEID from local pool during session creation
- PGW-C builds PFCP Session Establishment Request with explicit TEID value
- UPF receives request, uses provided TEID without allocation
- Both PGW-C and UPF track the same TEID value
Why You Might Need This:
✅ UPF Doesn't Support CHOOSE
- Some UPF implementations (especially legacy/proprietary) don't support dynamic allocation
- UPF expects explicit TEID in PFCP Session Establishment Request
- Only workaround for compatibility
✅ Centralized TEID Management
- If you need PGW-C to have full visibility into all allocated TEIDs
- Useful for debugging user plane issues (PGW-C knows exact TEID values)
- Can correlate TEID in packet captures with session state
✅ Deterministic Allocation
- If you need predictable TEID allocation patterns
- Some test environments may require specific TEID ranges
Trade-offs:
⚠️ Coordination Required for Multi-PGW-C
- Multiple PGW-C instances sharing a UPF must avoid TEID collisions
- Requires either:
- Partitioned TEID ranges per PGW-C (complex configuration)
- Shared TEID allocation service (additional infrastructure)
- Accept collision risk with random allocation (low probability)
⚠️ State Synchronization
- PGW-C must track allocated TEIDs to avoid reuse
- TEID pool state lost on PGW-C restart (must rebuild from sessions)
- More complex failover scenarios
⚠️ Non-Standard Behavior
- Not the intended PFCP design pattern
- May not work with all UPF implementations expecting CHOOSE
When to Use:
- ⚠️ Only when UPF doesn't support CHOOSE flag
- ⚠️ Legacy UPF implementations (e.g., some proprietary hardware)
- ⚠️ Specific compatibility requirements
- ⚠️ Debugging scenarios requiring PGW-C TEID visibility
TEID Collision Handling: PGW-C uses random allocation with collision detection:
- TEID range: 1 to 0xFFFFFFFF (4.2 billion values)
- Collision probability: ~0.023% at 1 million sessions
- Automatic retry on collision (transparent to caller)
- TEIDs automatically released when session terminates
How to Choose
Troubleshooting
Symptom: Session establishment fails immediately
Check PFCP logs:
# Look for CHOOSE-related errors
grep -i "choose\|mandatory.*missing" /var/log/pgw_c.log
# Check PFCP Session Establishment Response cause codes
grep "Session Establishment Response" /var/log/pgw_c.log
If UPF rejects CHOOSE flag:
- Error may say "Mandatory IE missing" or "Invalid IE"
- UPF expects explicit F-TEID but received CHOOSE
- Solution: Set
allocate_uplink_f_teid: true
If PGW-C allocation causes issues:
- Very rare - TEID space is huge (4 billion values)
- Check for TEID exhaustion (unlikely below millions of sessions):
# Check registry count
grep "registered_teid_count" /var/log/pgw_c.log
Switching Between Modes:
# Edit config/runtime.exs
sxb: %{
local_ip_address: "10.0.0.20",
allocate_uplink_f_teid: false # Change to true if UPF doesn't support CHOOSE
}
Then restart PGW-C:
systemctl restart pgw_c
Verifying Which Mode is Active: Check PFCP packet captures:
# Capture PFCP traffic
tcpdump -i any -n port 8805 -w pfcp.pcap
# Open in Wireshark and look at Session Establishment Request
# If F-TEID shows "CHOOSE" flags: UPF allocation mode
# If F-TEID shows explicit TEID value: PGW-C allocation mode
Packet Processing Rules
PFCP uses a set of rules to define how the user plane processes packets.
Rule Architecture
PDR (Packet Detection Rule)
Purpose: Identify which packets this rule applies to
Typical PGW-C Configuration:
PDR #1 - Downlink:
PDR ID: 1
Precedence: 100
PDI (Packet Detection Information):
- Source Interface: CORE (Internet side)
- UE IP Address: 100.64.1.42/32
FAR ID: 1 (associated forwarding rule)
PDR #2 - Uplink:
PDR ID: 2
Precedence: 100
PDI (Packet Detection Information):
- Source Interface: ACCESS (SGW side)
- F-TEID: <S5/S8 tunnel endpoint>
FAR ID: 2 (associated forwarding rule)
QER ID: 1 (QoS enforcement)
Key PDR Fields:
- PDR ID - Unique rule identifier (per session)
- Precedence - Rule matching priority (higher = more specific)
- PDI - Matching criteria (interface, IP, TEID, etc.)
- Outer Header Removal - Strip GTP-U header on ingress
- FAR ID - Associated forwarding action
- QER ID - Associated QoS enforcement (optional)
FAR (Forwarding Action Rule)
Purpose: Define what to do with matched packets
FAR #1 - Downlink (Internet → UE):
FAR ID: 1
Apply Action: FORWARD
Forwarding Parameters:
- Destination Interface: ACCESS (to SGW)
- Outer Header Creation: GTP-U/UDP/IPv4
- Remote F-TEID: <SGW S5/S8 tunnel endpoint>
FAR #2 - Uplink (UE → Internet):
FAR ID: 2
Apply Action: FORWARD
Forwarding Parameters:
- Destination Interface: CORE (to Internet)
- (No outer header - plain IP forwarding)
Key FAR Fields:
- FAR ID - Unique rule identifier
- Apply Action - FORWARD, DROP, BUFFER, NOTIFY
- Forwarding Parameters:
- Destination interface (ACCESS/CORE)
- Outer Header Creation (add GTP-U tunnel)
- Network Instance (VRF/routing table)
QER (QoS Enforcement Rule)
Purpose: Enforce bitrate limits and QoS parameters. QERs can also track usage for online charging quota management (see Diameter Gy Interface for credit control).
Example QER:
QER ID: 1
Gate Status: OPEN
Maximum Bitrate:
- Uplink: 100 Mbps
- Downlink: 50 Mbps
Guaranteed Bitrate: (optional, for GBR bearers)
- Uplink: 10 Mbps
- Downlink: 10 Mbps
Key QER Fields:
- QER ID - Unique rule identifier
- Gate Status - OPEN (allow) or CLOSED (block)
- MBR - Maximum Bitrate (uplink/downlink)
- GBR - Guaranteed Bitrate (for dedicated bearers)
- QCI - QoS Class Identifier (affects scheduling)
BAR (Buffering Action Rule)
Purpose: Control downlink packet buffering when UE is idle
Example BAR:
BAR ID: 1
Downlink Data Notification Delay: 100ms
Suggested Buffering Packets Count: 10
Used for: Idle mode DRX (Discontinuous Reception) optimization
Configuration
Basic Sxb Configuration
Edit config/runtime.exs:
config :pgw_c,
sxb: %{
# Local IP address for PFCP communication
local_ip_address: "10.0.0.20",
# Optional: Override default port (8805)
local_port: 8805,
# PFCP request timeout in milliseconds (default: 500ms)
# Time to wait for UPF response before retransmitting
# Should be >= expected UPF processing time to avoid duplicate sessions
request_timeout_ms: 500,
# Number of retry attempts for PFCP requests (default: 3)
# Total maximum wait time = request_timeout_ms * request_attempts
request_attempts: 3,
# Optional: Control F-TEID allocation for user plane
# When false (default): UPF allocates F-TEID (CHOOSE flag)
# When true: PGW-C pre-allocates F-TEID and provides explicit value
# Note: Some UPFs may not support CHOOSE flag and require explicit allocation
allocate_uplink_f_teid: false
},
# UPF Selection - All UPFs defined here are automatically registered
upf_selection: %{
fallback_pool: [
%{
# PGW-U IP address
remote_ip_address: "10.0.0.21",
# PFCP port (default: 8805)
remote_port: 8805,
# Weight for load balancing (100 = normal, 0 = standby)
weight: 100
}
]
}
Request Timeout Configuration
The PFCP interface uses configurable timeouts for Session Establishment, Modification, and Deletion requests to the UPF.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
request_timeout_ms | Integer | 500 | Time in milliseconds to wait for UPF response before retransmitting |
request_attempts | Integer | 3 | Maximum number of transmission attempts before failing the request |
Total Wait Time: request_timeout_ms × request_attempts
Default behavior: 500ms × 3 attempts = 1.5 seconds total maximum wait
Why Timeout Configuration Matters
If request_timeout_ms is set too low relative to UPF processing time:
- PGW-C sends Session Establishment Request
- Timeout expires before UPF responds
- PGW-C retransmits with the same sequence number
- UPF processes both requests and creates duplicate PFCP sessions
- PGW-C receives first response and stores one session ID
- Second session becomes orphaned in the UPF
Tuning Guidelines
| UPF Response Time | Recommended request_timeout_ms | Total Wait Time |
|---|---|---|
| Fast (<100ms) | 200-300ms | 600-900ms (3 attempts) |
| Normal (100-300ms) | 500ms (default) | 1.5s (3 attempts) |
| Slow (300-500ms) | 750-1000ms | 2.25-3s (3 attempts) |
| Very slow (>500ms) | 1500-2000ms | 4.5-6s (3 attempts) |
Recommendation: Set request_timeout_ms to at least 2× the expected UPF response time to avoid retransmission-induced orphan sessions.
Example - Slow UPF
sxb: %{
local_ip_address: "10.0.0.20",
request_timeout_ms: 1000, # 1 second per attempt
request_attempts: 3 # Total: 3 seconds max
}
Diagnosing Timeout Issues
Symptoms of timeout too low:
- UPF reports more PFCP sessions than expected
- Orphan sessions accumulate in UPF over time
- Log messages:
"Session Establishment Request timed out"followed by successful session
How to diagnose:
- Check UPF session count via UPF API or management interface
- Compare with PGW-C active session count
- If UPF has more sessions, orphans exist from retransmissions
Resolution:
- Increase
request_timeout_msto exceed UPF response time - Restart PGW-C to apply new configuration
- Clear orphan sessions from UPF (manual cleanup or UPF restart)
Multiple PGW-U Peers
For load balancing or redundancy:
config :pgw_c,
sxb: %{
local_ip_address: "10.0.0.20"
},
upf_selection: %{
fallback_pool: [
%{remote_ip_address: "10.0.1.21", remote_port: 8805, weight: 50}, # 50% traffic
%{remote_ip_address: "10.0.2.21", remote_port: 8805, weight: 50} # 50% traffic
]
}
# Both UPFs automatically registered with 5-second heartbeats
UPF Selection Configuration

PGW-C uses a three-tier UPF selection system with priority-based rules:
- Static Rules (Highest Priority) - Match based on session attributes
- DNS-Based Selection (Medium Priority) - Location-aware routing via DNS NAPTR queries
- Fallback Pool (Lowest Priority) - Default UPF pool when no rules match
Complete UPF Selection Example
config :pgw_c,
# PFCP Interface
sxb: %{
local_ip_address: "10.0.0.20"
},
# UPF Selection: All UPFs defined here are automatically registered
upf_selection: %{
# =====================================================================
# DNS-Based Selection (Location-Aware Routing)
# =====================================================================
# Queries DNS using User Location Information (ULI)
# Provides dynamic UPF selection based on cell location
dns_enabled: false,
dns_query_priority: [:ecgi, :tai, :rai, :sai, :cgi],
dns_suffix: "epc.3gppnetwork.org",
dns_timeout_ms: 5000,
# =====================================================================
# Static Selection Rules (Evaluated by Priority)
# =====================================================================
# Rules are checked from highest to lowest priority
# First matching rule determines the UPF pool
rules: [
# Rule 1: IMS Traffic - Highest Priority
%{
name: "IMS Traffic",
priority: 20,
match_field: :apn,
match_regex: "^ims",
upf_pool: [
%{remote_ip_address: "10.100.2.21", remote_port: 8805, weight: 80},
%{remote_ip_address: "10.100.2.22", remote_port: 8805, weight: 20}
],
# Optional: PCO overrides for this rule
pco: %{
p_cscf_ipv4_address_list: ["203.0.113.100", "203.0.113.101"]
}
},
# Rule 2: Enterprise APN - High Priority
%{
name: "Enterprise Traffic",
priority: 15,
match_field: :apn,
match_regex: "^(enterprise|corporate)\.apn",
upf_pool: [
%{remote_ip_address: "10.100.3.21", remote_port: 8805, weight: 100}
],
pco: %{
primary_dns_server_address: "192.168.1.10",
secondary_dns_server_address: "192.168.1.11",
ipv4_link_mtu_size: 1500
}
},
# Rule 3: Roaming Subscribers - Medium Priority
%{
name: "Roaming Subscribers",
priority: 10,
match_field: :serving_network_plmn_id,
match_regex: "^(310|311|312|313)", # US networks
upf_pool: [
%{remote_ip_address: "10.100.4.21", remote_port: 8805, weight: 100}
]
},
# Rule 4: Internet Traffic - Lower Priority
%{
name: "Internet Traffic",
priority: 5,
match_field: :apn,
match_regex: "^internet",
upf_pool: [
%{remote_ip_address: "10.100.1.21", remote_port: 8805, weight: 33},
%{remote_ip_address: "10.100.1.22", remote_port: 8805, weight: 33},
%{remote_ip_address: "10.100.1.23", remote_port: 8805, weight: 34}
]
}
],
# =====================================================================
# Fallback Pool (Last Resort)
# =====================================================================
# Used when no rules match and DNS selection fails or is disabled
fallback_pool: [
%{remote_ip_address: "127.0.0.21", remote_port: 8805, weight: 100}
]
}
Supported Match Fields
| Match Field | Description | Example Value |
|---|---|---|
:imsi | International Mobile Subscriber Identity | "310260123456789" |
:apn | Access Point Name | "internet", "ims" |
:serving_network_plmn_id | Serving network PLMN (MCC+MNC) | "310260" (test network) |
:sgw_ip_address | SGW IP address (string format) | "10.0.1.50" |
:uli_tai_plmn_id | Tracking Area PLMN ID | "310260" |
:uli_ecgi_plmn_id | E-UTRAN Cell PLMN ID | "310260" |
UPF Pool and Load Balancing
Each rule can specify a UPF pool with weighted random selection:
upf_pool: [
%{remote_ip_address: "10.100.1.21", remote_port: 8805, weight: 50},
%{remote_ip_address: "10.100.1.22", remote_port: 8805, weight: 30},
%{remote_ip_address: "10.100.1.23", remote_port: 8805, weight: 20}
]
How Weighted Selection Works:
- Calculate total weight: 50 + 30 + 20 = 100
- Generate random number: 0.0 to 100.0
- Select UPF based on cumulative weight ranges:
- 0-50: UPF-1 (50% chance)
- 50-80: UPF-2 (30% chance)
- 80-100: UPF-3 (20% chance)
Use Cases:
- Equal distribution: All weights equal (33, 33, 34)
- Primary/backup: High weight primary (80), low weight backup (20)
- Capacity-based: Weight proportional to UPF capacity
PCO Overrides
Rules can override PCO (Protocol Configuration Options) values:
%{
name: "IMS Traffic",
match_field: :apn,
match_regex: "^ims",
upf_pool: [...],
pco: %{
# Override only specific fields
p_cscf_ipv4_address_list: ["203.0.113.100", "203.0.113.101"],
# Other fields use defaults from main pco config
}
}
Available PCO Override Fields:
primary_dns_server_addresssecondary_dns_server_addressprimary_nbns_server_addresssecondary_nbns_server_addressp_cscf_ipv4_address_listipv4_link_mtu_size
DNS-Based Selection
When enabled, PGW-C performs DNS NAPTR queries based on User Location Information:
upf_selection: %{
dns_enabled: true,
dns_query_priority: [:ecgi, :tai, :rai, :sai, :cgi],
dns_suffix: "epc.3gppnetwork.org",
dns_timeout_ms: 5000
}
Query Priority:
- ECGI (E-UTRAN Cell Global Identifier) - Most specific
- TAI (Tracking Area Identity) - Cell area
- RAI (Routing Area Identity) - 3G/2G area
- SAI (Service Area Identity) - 3G service area
- CGI (Cell Global Identity) - 2G cell
Example DNS Query:
# For ECGI query:
eci-1a2b3c.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org
# For TAI query:
tac-lb64.tac-hb00.tac.epc.mnc999.mcc999.epc.3gppnetwork.org
DNS Selection Process:
- Try queries in priority order (ECGI first, then TAI, etc.)
- If DNS returns candidates, use first result (dynamically registered if needed)
- Select returned UPF
- If no DNS match or DNS disabled, fall through to fallback pool
See DNS-based UPF Selection for detailed information.
DNS-based UPF Selection
Overview
DNS-based UPF selection provides location-aware routing by performing DNS NAPTR queries using User Location Information (ULI) from the UE's current cell.
3GPP Reference: TS 23.003 - DNS procedures for UPF discovery
Benefits:
- Automatic UPF selection based on geographic location
- No manual rule configuration per cell
- Dynamic adaptation to network topology changes
- Reduces backhaul by routing to nearest UPF
How It Works
Configuration
config :pgw_c,
upf_selection: %{
# Enable DNS-based selection
dns_enabled: true,
# Query priority: try ECGI first, then TAI, then RAI, etc.
dns_query_priority: [:ecgi, :tai, :rai, :sai, :cgi],
# DNS suffix for queries
dns_suffix: "epc.3gppnetwork.org",
# DNS query timeout
dns_timeout_ms: 5000,
# Static rules still take precedence over DNS
rules: [...],
# Fallback if DNS fails
fallback_pool: [...]
}
DNS Query Formats
DNS queries are built using User Location Information (ULI) from the GTP-C message:
1. ECGI (E-UTRAN Cell Global Identifier)
Most specific - LTE cell-level routing
Format:
eci-<HEX-ECI>.ecgi.epc.mnc<MNC>.mcc<MCC>.<dns_suffix>
Example:
# Cell ID: 0x1A2B3C (1,715,004 decimal)
# PLMN: MCC=999, MNC=999
eci-1a2b3c.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org
When Used: LTE (4G) networks
2. TAI (Tracking Area Identity)
Cell area - Multiple cells in same tracking area
Format:
tac-lb<LB>.tac-hb<HB>.tac.epc.mnc<MNC>.mcc<MCC>.<dns_suffix>
Example:
# TAC: 0x0064 (100 decimal)
# Low byte: 0x64, High byte: 0x00
tac-lb64.tac-hb00.tac.epc.mnc999.mcc999.epc.3gppnetwork.org
When Used: LTE (4G) tracking areas
3. RAI (Routing Area Identity)
3G/2G routing area
Format:
rac<RAC>.lac-lb<LB>.lac-hb<HB>.lac.rai.mnc<MNC>.mcc<MCC>.<dns_suffix>
Example:
# RAC: 0x0A (10 decimal)
# LAC: 0x1234 (4660 decimal)
rac0a.lac-lb34.lac-hb12.lac.rai.mnc999.mcc999.epc.3gppnetwork.org
When Used: 3G/2G UMTS/GPRS networks
4. SAI (Service Area Identity)
3G service area
Format:
sac<SAC>.lac-lb<LB>.lac-hb<HB>.lac.sai.mnc<MNC>.mcc<MCC>.<dns_suffix>
Example:
# SAC: 0x0001
# LAC: 0x1234
sac0001.lac-lb34.lac-hb12.lac.sai.mnc999.mcc999.epc.3gppnetwork.org
When Used: 3G UMTS service areas
5. CGI (Cell Global Identity)
2G cell-level
Format:
ci<CI>.lac-lb<LB>.lac-hb<HB>.lac.cgi.mnc<MNC>.mcc<MCC>.<dns_suffix>
Example:
# CI: 0x5678
# LAC: 0x1234
ci5678.lac-lb34.lac-hb12.lac.cgi.mnc999.mcc999.epc.3gppnetwork.org
When Used: 2G GSM cells
DNS Response Processing
NAPTR Record Format:
DNS returns NAPTR records pointing to UPF IP addresses:
eci-1a2b3c.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org.
IN NAPTR 10 50 "a" "x-3gpp-upf:x-s5-gtp:x-s8-gtp" "" upf1.epc.mnc999.mcc999.3gppnetwork.org.
upf1.epc.mnc999.mcc999.3gppnetwork.org.
IN A 10.100.1.21
PGW-C Processing:
- Parse NAPTR records to extract UPF IP addresses
- Select first candidate from DNS response
- Dynamically register if not already configured (or implement load-based selection)
Example:
DNS returns: [10.100.1.21, 10.100.5.99, 10.200.3.50]
Selected: 10.100.1.21 (first candidate)
Action: Register dynamically if not in upf_selection
Selection Priority Example
Use Cases
1. Geographic Load Balancing
Scenario: Operator has UPFs in multiple cities
DNS Configuration:
# Chicago cell
eci-aaa.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org → UPF-Chicago (10.1.1.21)
# New York cell
eci-bbb.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org → UPF-NewYork (10.2.1.21)
# Los Angeles cell
eci-ccc.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org → UPF-LosAngeles (10.3.1.21)
Benefit: Users automatically routed to nearest UPF, reducing latency and backhaul
2. Edge Computing
Scenario: MEC (Multi-access Edge Computing) UPFs deployed at cell sites
DNS Configuration:
# Each cell points to local edge UPF
eci-*.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org → Local Edge UPF
Benefit: Ultra-low latency for edge applications
3. Dynamic Network Topology
Scenario: UPF addresses change due to upgrades or maintenance
Benefit: Update DNS records without changing PGW-C configuration
Troubleshooting DNS Selection
DNS Query Failures
Symptoms:
- Log: "DNS UPF selection failed: :nxdomain"
- Sessions fall back to fallback pool
Possible Causes:
- DNS server not configured correctly
- DNS zone not populated for cell IDs
- ULI not present in GTP-C message
Resolution:
# Test DNS query manually
dig eci-1a2b3c.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org NAPTR
# Check PGW-C logs for DNS queries
grep "DNS UPF selection: querying" /var/log/pgw_c.log
# Verify ULI present in session
# Check "uli" field in session state
DNS Returns Unknown UPF
Behavior:
- DNS returns a candidate UPF not in
upf_selection - System automatically attempts dynamic registration
- If PFCP association succeeds, UPF is used for the session
- If PFCP association fails, falls back to fallback pool
Example:
DNS returns: [10.99.1.50]
upf_selection: [10.100.1.21, 10.100.1.22]
Action: Dynamically register 10.99.1.50
- Send PFCP Association Setup
- If success: Use for session
- If timeout: Fall back to fallback pool
Resolution Options:
- Pre-configure in
upf_selectionfor immediate monitoring:
upf_selection: %{
fallback_pool: [
%{remote_ip_address: "10.99.1.50", remote_port: 8805, weight: 100}
]
}
-
Update DNS to return pre-configured UPF IPs
-
Allow dynamic registration (recommended for MEC/edge scenarios)
Query Timeout
Symptoms:
- Log: "DNS UPF selection: query timeout"
- Sessions take longer to establish
Resolution:
upf_selection: %{
dns_timeout_ms: 10000 # Increase timeout to 10 seconds
}
Monitoring DNS Selection
Metrics:
# DNS query success rate
rate(upf_selection_dns_success_total[5m]) / rate(upf_selection_dns_attempts_total[5m])
# DNS query latency
histogram_quantile(0.95, rate(upf_selection_dns_duration_seconds_bucket[5m]))
# Fallback usage (indicates DNS issues)
rate(upf_selection_fallback_used_total[5m])
Logs:
[debug] DNS UPF selection: querying eci-1a2b3c.ecgi.epc.mnc999.mcc999.epc.3gppnetwork.org
[debug] DNS UPF selection: got 2 candidates from DNS
[info] DNS UPF selection: selected 10.100.1.21
Message Flows
Complete Session Establishment Flow
Session Modification Flow
Heartbeat Failure Recovery
Troubleshooting
Common Issues
1. Association Setup Fails
Symptoms:
- Log message: "PFCP Association Setup failed"
- No response to Association Setup Request
Possible Causes:
- PGW-U not reachable (network issue)
- PGW-U not running
- Firewall blocking UDP port 8805
- Incorrect
remote_ip_addressin configuration
Resolution:
# Test connectivity
ping <pgw_u_ip_address>
# Test UDP port
nc -u -v <pgw_u_ip_address> 8805
# Check firewall
iptables -L -n | grep 8805
2. Heartbeats Failing
Symptoms:
- Log: "Consecutive heartbeat failures: 3"
- Association marked as down
Possible Causes:
- Network latency or packet loss
- PGW-U overloaded
- Heartbeat interval too aggressive
Resolution:
The heartbeat period is fixed at 5 seconds with a failure threshold of 3 consecutive missed heartbeats.
3. Session Establishment Fails
Symptoms:
- Create Session Response with error cause
- Log: "PFCP Session Establishment failed"
Possible Causes:
- No PGW-U peers available
- PGW-U resource exhaustion
- Invalid rule configuration
Check:
- Verify at least one peer has
is_associated = true - Check PGW-U logs for errors
- Verify SEID uniqueness
4. Duplicate SEID Errors
Symptoms:
- Session Establishment Response: Cause "Session context not found"
Cause:
- SEID collision (very rare)
- PGW-U restart without PGW-C awareness
Resolution:
- Restart PFCP association (triggers new recovery timestamp)
- PGW-C will detect PGW-U restart and clean up old sessions
Monitoring PFCP Health
Metrics to Monitor:
# PFCP peer association status
pfcp_peer_associated{peer="PGW-U Primary"} 1
# Active PFCP sessions
seid_registry_count 150
# PFCP message rates
rate(sxb_inbound_messages_total[5m])
# PFCP errors
rate(sxb_inbound_errors_total[5m])
# Heartbeat failures
pfcp_consecutive_heartbeat_failures{peer="PGW-U Primary"} 0
Alert Examples:
# Alert on association down
- alert: PFCPAssociationDown
expr: pfcp_peer_associated == 0
for: 1m
annotations:
summary: "PFCP peer {{ $labels.peer }} is down"
# Alert on high session establishment failures
- alert: PFCPSessionEstablishmentFailureHigh
expr: rate(sxb_inbound_errors_total{message_type="session_establishment_response"}[5m]) > 0.1
for: 5m
annotations:
summary: "High PFCP session establishment failure rate"
Web UI - PFCP Monitoring
OmniPGW provides two Web UI pages for monitoring PFCP/Sxb operations in real-time.
UPF/PFCP Peer Status Page
Access: http://<omnipgw-ip>:<web-port>/upf_status

Purpose: Monitor PFCP association status with all configured PGW-U peers
Features:
1. Peer Status Overview
- Associated Count - Number of peers with active PFCP association
- Not Associated Count - Number of peers down or not connected
- Auto-refreshes every 2 seconds
2. Per-Peer Information For each configured PGW-U peer:
- Peer Name - Friendly name from configuration
- IP Address - Remote PGW-U IP
- Association Status - Associated (green) or Not Associated (red)
- Node ID - PFCP Node identifier
- Recovery Timestamp - Last restart time of peer
- Heartbeat Period - Configured heartbeat interval
- Consecutive Missed Heartbeats - Current failure count
- UP Function Features - Capabilities advertised by PGW-U
3. Expandable Details Click any peer to see:
- Full peer configuration
- UP function features bitmap
- Association timestamps
- Complete peer state
PFCP Sessions Page
Access: http://<omnipgw-ip>:<web-port>/pfcp_sessions

Purpose: View active PFCP sessions between OmniPGW and PGW-U
Features:
1. Active Session Count
- Total number of active PFCP sessions
- Updates in real-time
2. Session Information For each PFCP session:
- Session Key - Internal registry key
- Process ID - Session process identifier
- IMSI - Associated subscriber (if available)
- Status - Session state
3. Full Session State Expandable view showing:
- Complete PFCP session context
- PDRs, FARs, QERs, BARs (forwarding rules)
- F-SEIDs (session endpoint identifiers)
- PGW-U peer association
Operational Use Cases
Monitor PFCP Association Health:
1. Open UPF Status page
2. Verify all peers show "Associated"
3. Check missed heartbeat count = 0
4. If peer shows "Not Associated":
- Check peer IP reachability
- Verify peer is running
- Check firewall (UDP 8805)
Troubleshoot Session Establishment Failures:
1. User session fails to establish
2. Check PGW Sessions page - session exists?
3. Check PFCP Sessions page - PFCP session created?
4. If no PFCP session:
- Check UPF Status - is any peer associated?
- Check logs for PFCP errors
5. If PFCP session exists:
- Inspect PDRs/FARs to verify rules programmed
- Issue is likely downstream (PGW-U or network)
Verify Peer Load Distribution:
1. With multiple PGW-U peers configured
2. Check PFCP Sessions page
3. Verify sessions distributed across peers
4. Identify if one peer has disproportionate load
Detect Peer Failures:
- Quick glance at UPF Status page
- Red "Not Associated" badge immediately visible
- Missed heartbeat counter shows degradation before total failure
- Set up monitoring alerts based on Web UI data
Advantages:
- Real-time monitoring - No need to query metrics or SSH
- Visual status - Color-coded associated/not associated
- Peer health trends - Missed heartbeat count shows early warning
- Session-level inspection - See exact PDRs/FARs/QERs programmed
- No tools required - Just a web browser
Related Documentation
Configuration
- Configuration Guide - UPF selection, health monitoring, PFCP configuration
- Session Management - PDN session lifecycle, bearer establishment
Charging and Monitoring
- Diameter Gx Interface - PCC rules that drive PFCP QoS enforcement
- Diameter Gy Interface - Online charging quota management via URRs
- Data CDR Format - CDR generation from PFCP usage reports
- Monitoring Guide - PFCP metrics, session tracking, UPF health alerts
Network Interfaces
- S5/S8 Interface - Control plane bearer management
- UE IP Allocation - UE address assignment via PFCP