9 releases
| 0.2.0 | Dec 3, 2025 |
|---|---|
| 0.1.7 | Nov 15, 2025 |
| 0.1.5 | Oct 25, 2025 |
| 0.1.0 | Sep 25, 2025 |
#445 in Network programming
2MB
48K
SLoC
rs-pfcp
A high-performance Rust implementation of the PFCP (Packet Forwarding Control Protocol) for 5G networks, providing 100% compliance with 3GPP TS 29.244 Release 18 specification.
๐ What is PFCP?
PFCP is the critical communication protocol between Control Plane and User Plane functions in 5G networks:
- SMF (Session Management Function) โ UPF (User Plane Function)
- Manages packet forwarding rules, traffic steering, and usage reporting
- Essential for 5G service orchestration, QoS enforcement, and network slicing
โจ Key Features
- ๐ 100% 3GPP TS 29.244 Release 18 Compliance - 139+ Information Elements implemented with complete core session management
- ๐ฅ High Performance - Zero-copy binary protocol implementation with Rust's memory safety
- ๐งช Battle Tested - 1,942 comprehensive tests with full round-trip serialization validation
- ๐ ๏ธ Developer Friendly - Ergonomic builder APIs with convenience methods and direct marshaling
- ๐ Production Ready - Message comparison, YAML/JSON display, network interface support, and robust examples
Ergonomic Builder API
Build and send PFCP messages in just 2-3 lines:
// Session responses with convenience methods
let response = SessionEstablishmentResponseBuilder::accepted(seid, seq)
.fseid(upf_seid, upf_ip)
.marshal()?;
// Or with cause values
let response = SessionModificationResponseBuilder::new(seid, seq)
.cause_accepted()
.marshal();
// Requests with type-safe builders
let request = AssociationSetupRequestBuilder::new(seq)
.node_id(Ipv4Addr::new(10, 0, 0, 1))
.recovery_time_stamp(SystemTime::now())
.marshal();
Protocol Coverage
- โ 25/25 Message Types (100% coverage) - All core session and association management
- โ 139+ Information Elements implemented (272+ enum variants defined) - Complete 3GPP TS 29.244 Release 18 core IEs
- โ Advanced Features - Network slicing (S-NSSAI), multi-access support, F-TEID with CHOOSE flags, QoS enforcement, usage reporting, Ethernet PDU sessions
- โ 5G Core Integration - Session establishment, modification, deletion, and comprehensive usage reporting with quota management
๐โโ๏ธ Quick Start
Installation
Add to your Cargo.toml:
[dependencies]
rs-pfcp = "0.1.7"
Basic Usage
use rs_pfcp::message::session_establishment_request::SessionEstablishmentRequestBuilder;
use rs_pfcp::message::session_establishment_response::SessionEstablishmentResponseBuilder;
use std::net::Ipv4Addr;
// Create a session establishment request with ergonomic builders
let request_bytes = SessionEstablishmentRequestBuilder::new(session_id, sequence_number)
.node_id(Ipv4Addr::new(10, 0, 0, 1)) // Direct IP address
.fseid(0x123456789ABCDEF0, my_ip_addr) // SEID + IP
.create_pdrs(vec![pdr.to_ie()])
.create_fars(vec![far.to_ie()])
.marshal()?; // Direct marshaling
// Send over network
socket.send(&request_bytes)?;
// Parse received messages and respond
let parsed_msg = rs_pfcp::message::parse(&received_bytes)?;
match parsed_msg.msg_type() {
MsgType::SessionEstablishmentRequest => {
// Handle session establishment
println!("Received session establishment for SEID: {:016x}",
parsed_msg.seid().unwrap_or(0));
// Create response with convenience methods
let response_bytes = SessionEstablishmentResponseBuilder::accepted(seid, sequence)
.fseid(upf_seid, upf_ip)
.marshal()?;
socket.send(&response_bytes)?;
}
_ => {} // Handle other message types
}
Message Comparison & Validation
Compare PFCP messages for testing, debugging, and validation:
use rs_pfcp::comparison::MessageComparator;
// Test mode - ignore transient fields (sequence, timestamps)
let result = MessageComparator::new(&msg1, &msg2)
.test_mode()
.compare()?;
if result.is_match {
println!("โ Messages match functionally");
} else {
println!("Differences found:");
for mismatch in &result.ie_mismatches {
println!(" - {:?}: {:?}", mismatch.ie_type, mismatch.reason);
}
}
// Semantic comparison with timestamp tolerance
let result = MessageComparator::new(&msg1, &msg2)
.semantic_mode() // Compare F-TEID, UE IP by meaning
.timestamp_tolerance(5) // 5 second tolerance
.ignore_sequence()
.compare()?;
// Generate detailed diff
let result = MessageComparator::new(&msg1, &msg2)
.generate_diff(true)
.compare()?;
if let Some(diff) = result.diff {
println!("{}", diff); // YAML-formatted differences
}
Features:
- Multiple comparison modes - Strict, semantic, test, and audit presets
- Semantic comparison - F-TEID, UE IP Address compared by function, not bytes
- Timestamp tolerance - Configurable window for timestamp comparison
- Flexible IE filtering - Ignore specific IEs, focus on subsets, or handle timestamps
- Detailed reporting - Match statistics, mismatch details, YAML diffs
Network Examples
The library includes comprehensive examples for real-world scenarios:
# Run PFCP heartbeat server
cargo run --example heartbeat-server -- --interface lo --port 8805
# Run session client connecting to UPF
cargo run --example session-client -- --address 127.0.0.1 --sessions 5
# Analyze captured PFCP traffic
cargo run --example pcap-reader -- --pcap traffic.pcap --format yaml
# Demo message comparison and validation
cargo run --example message-comparison # All demos
cargo run --example message-comparison semantic # Specific demo
# Demo quota exhaustion reporting
cd examples && ./test_session_report.sh lo
๐๏ธ Architecture
Core Components
rs-pfcp/
โโโ src/ie/ # Information Elements (139+ types)
โ โโโ f_teid.rs # F-TEID with 3GPP compliant CHOOSE flags
โ โโโ pdn_type.rs # PDN connection types (IPv4/IPv6/Non-IP)
โ โโโ snssai.rs # 5G Network Slicing identifiers
โ โโโ ethernet_*.rs # Ethernet PDU session support (10 IEs)
โ โโโ ...
โโโ src/message/ # PFCP Messages (25 types)
โ โโโ session_*.rs # Session lifecycle management
โ โโโ association_*.rs # Node association handling
โ โโโ heartbeat.rs # Keep-alive mechanism
โโโ src/comparison/ # Message comparison framework
โ โโโ builder.rs # Fluent comparison API
โ โโโ semantic.rs # Semantic comparison (F-TEID, UE IP, timestamps)
โ โโโ options.rs # Configuration options
โ โโโ result.rs # Result types and statistics
โโโ examples/ # Production-ready examples
โโโ session-server/ # UPF simulator
โโโ session-client/ # SMF simulator
โโโ pcap-reader/ # Traffic analysis tool
Key Design Principles
- Type Safety - Rust's type system prevents protocol errors at compile time
- Zero Copy - Efficient binary serialization without unnecessary allocations
- Builder Patterns - Intuitive construction of complex PFCP messages
- Error Handling - Comprehensive error types with proper cause codes
- Testing - Every marshal/unmarshal operation verified with round-trip tests
๐ Documentation
Quick Links
| Document | Purpose |
|---|---|
| Documentation Hub | Complete documentation index |
| API Guide | Comprehensive API reference and usage patterns |
| Comparison Guide | Message comparison, testing, and validation |
| IE Support | Complete Information Element implementation status |
| Messages Reference | Message types, usage patterns, and code examples |
| Examples Guide | Running and understanding example applications |
Guides & Tutorials
- Comparison Guide - Testing and validating PFCP messages
- Deployment Guide - Production deployment strategies
- Session Report Demo - Quota management walkthrough
- Git Hooks Setup - Development workflow automation
Reference Documentation
- 3GPP Compliance - Detailed compliance verification
- IE Compliance - Information Element compliance details
- API Documentation - Full API reference on docs.rs
๐ API Stability
rs-pfcp is currently pre-1.0 (version 0.1.x), meaning the API may change between minor versions. We follow Semantic Versioning and document all breaking changes in the CHANGELOG.
Current Status:
- Version: 0.1.7
- MSRV: Rust 1.90.0
- Spec Compliance: 3GPP TS 29.244 Release 18
- Stability: Pre-1.0 (API evolving)
Upgrade Guide
When upgrading between versions:
- Check CHANGELOG.md for breaking changes
- Run
cargo update -p rs-pfcp - Fix compiler errors (we prefer compile-time breaks over runtime breaks)
- Test your integration
For detailed API stability guarantees and version roadmap, see docs/API-STABILITY.md.
Writing Future-Proof Code
โ DO: Use builder patterns, trait methods, and public constructors โ DON'T: Access struct fields directly or depend on internal modules
We provide migration guides for all breaking changes and deprecate features before removing them.
๐ง Development
Build and Test
# Build the library
cargo build
# Run all tests (1,942 tests)
cargo test
# Run specific test category
cargo test ie::f_teid # Test F-TEID implementation
cargo test message::heartbeat # Test heartbeat messages
# Check code formatting and linting
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
# Generate documentation
cargo doc --no-deps --document-private-items --all-features
Example Workflows
# Test complete session lifecycle
cargo run --example session-server -- --interface lo --port 8805 &
cargo run --example session-client -- --address 127.0.0.1 --sessions 3
# Analyze protocol compliance
cargo run --example pcap-reader -- --pcap captured.pcap --format json --pfcp-only
# Benchmark performance
cargo test --release -- --ignored bench_
๐ Real-World Usage
5G Network Integration
// SMF establishing session with UPF
let session_request = SessionEstablishmentRequestBuilder::new(seid, seq)
.node_id(smf_node_id)
.fseid(session_fseid)
.create_pdrs(vec![
// Uplink PDR - match user traffic
CreatePdr::builder()
.pdr_id(PdrId::new(1))
.precedence(Precedence::new(100))
.pdi(uplink_pdi)
.far_id(FarId::new(1))
.build()?,
// Downlink PDR - match network traffic
CreatePdr::builder()
.pdr_id(PdrId::new(2))
.precedence(Precedence::new(200))
.pdi(downlink_pdi)
.far_id(FarId::new(2))
.build()?,
])
.create_fars(vec![
// Uplink FAR - forward to data network
CreateFar::builder()
.far_id(FarId::new(1))
.apply_action(ApplyAction::FORW)
.forwarding_parameters(ForwardingParameters::new(
DestinationInterface::Core,
Some(network_instance)
))
.build()?,
// Downlink FAR - forward to access network
CreateFar::builder()
.far_id(FarId::new(2))
.apply_action(ApplyAction::FORW)
.forwarding_parameters(ForwardingParameters::new(
DestinationInterface::Access,
None
))
.build()?,
])
.build()?;
Usage Reporting & Quota Management
// Handle quota exhaustion reports from UPF
match message.msg_type() {
MsgType::SessionReportRequest => {
if let Some(usage_report) = message.find_ie(IeType::UsageReport) {
let triggers = usage_report.usage_report_trigger();
if triggers.contains(UsageReportTrigger::VOLTH) {
println!("๐ Volume quota exhausted for session {:016x}",
message.seid().unwrap());
// Grant additional quota or terminate session
let response = SessionReportResponseBuilder::new(
message.seid().unwrap(),
message.sequence(),
Cause::new(CauseValue::RequestAccepted)
).build()?;
}
}
}
}
๐ค Contributing
We welcome contributions! This library is actively maintained and we're happy to help with:
- ๐ Bug Reports - Protocol compliance issues, performance problems
- ๐ก Feature Requests - Additional 3GPP features, improved APIs
- ๐ Documentation - Examples, tutorials, architectural guides
- ๐งช Testing - Real-world scenarios, edge cases, performance benchmarks
๐ License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
๐ Acknowledgments
- Inspired by the excellent go-pfcp library
- Built according to 3GPP TS 29.244 Release 18 specification
- Developed with โค๏ธ for the 5G networking community
Ready to build next-generation 5G networks with Rust? Check out our examples to get started! ๐
Dependencies
~3.5โ5MB
~96K SLoC