#5g #telecom #networking #pfcp

rs-pfcp

High-performance Rust implementation of PFCP (Packet Forwarding Control Protocol) for 5G networks with 100% 3GPP TS 29.244 Release 18 compliance

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

Apache-2.0

2MB
48K SLoC

rs-pfcp

Rust Crates.io Documentation License

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

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

Reference Documentation

๐Ÿ”’ 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:

  1. Check CHANGELOG.md for breaking changes
  2. Run cargo update -p rs-pfcp
  3. Fix compiler errors (we prefer compile-time breaks over runtime breaks)
  4. 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