Go-Rust PFCP Interoperability Testing
September 6, 2025 · View on GitHub
This directory contains Go implementations of the PFCP session client and server using the go-pfcp library v0.0.24 to test cross-compatibility with the Rust rs-pfcp library.
Purpose
The goal is to verify that the Rust rs-pfcp implementation can correctly communicate with other PFCP implementations, specifically:
- Rust server ↔ Go client: Test if Go client can communicate with Rust server
- Go server ↔ Rust client: Test if Rust client can communicate with Go server
- Message format compatibility: Ensure both implementations follow 3GPP TS 29.244 correctly
Prerequisites
- Go (version 1.21 or later)
- Rust (for running the Rust examples)
Setup
# Initialize Go modules and download dependencies
cd go-interop
go mod tidy
Building
# Build Go session server
go build -o session-server session-server.go
# Build Go session client
go build -o session-client session-client.go
# Build simple server (for basic parsing tests)
go build -o simple-server simple-server.go
Usage
Go Session Server
# Start Go server on default address (127.0.0.1:8805)
./session-server
# Start Go server on custom address
./session-server --addr "0.0.0.0:8806"
Go Session Client
# Connect to default server (127.0.0.1:8805) with 1 session
./session-client
# Connect to custom server with multiple sessions
./session-client -address "192.168.1.100" -port 8806 -sessions 3
Cross-Compatibility Testing
Test 1: Rust Server ↔ Go Client
# Terminal 1: Start Rust server
cd ..
cargo run --example session-server -- --interface lo --port 8805
# Terminal 2: Run Go client
cd go-interop
./session-client -sessions 2
Test 2: Go Server ↔ Rust Client
# Terminal 1: Start Go server
cd go-interop
./session-server -addr "127.0.0.1:8805"
# Terminal 2: Run Rust client
cd ..
cargo run --example session-client -- --sessions 2
Test 3: Cross-Network Testing
# Terminal 1: Start Go server on network interface
./session-server -addr "192.168.1.100:8805"
# Terminal 2: Run Rust client from different machine/interface
cargo run --example session-client -- --address "192.168.1.100" --sessions 1
Expected Message Flow
Both implementations should support this complete PFCP session flow:
-
Association Setup Request/Response
- Establish PFCP association between control and user plane
- Exchange Node IDs and recovery timestamps
-
Session Establishment Request/Response
- Create PFCP session with traffic forwarding rules
- Include Create PDR and Create FAR IEs
- Server responds with Created PDR containing allocated F-TEIDs
-
Session Report Request/Response (automatic after 2s)
- Server simulates quota exhaustion
- Sends usage report with Volume Threshold trigger
- Client acknowledges with RequestAccepted cause
-
Session Modification Request/Response
- Update existing session parameters
- Modify PDR precedence values
-
Session Deletion Request/Response
- Clean session termination
- Remove all associated forwarding rules
Message Compatibility Details
Information Elements (IEs) Tested
- Node ID: IPv4 node identification
- F-SEID: Session endpoint identifier with IPv4 address
- Create PDR: Packet detection rules with precedence
- Created PDR: Response with allocated F-TEID
- Create FAR: Forwarding action rules
- Usage Report: Volume threshold exhaustion
- Cause: Success/failure indication
Protocol Features Verified
- 3GPP TS 29.244 compliance: Both implementations follow standard
- Binary compatibility: Message marshaling/unmarshaling
- Sequence number handling: Proper request/response correlation
- SEID management: Session endpoint identifier tracking
- Error handling: Proper cause code responses
Troubleshooting
Common Issues
-
Port already in use
# Kill existing processes pkill session-server pkill session-client # Or use different port ./session-server -addr "127.0.0.1:8806" -
Module dependency errors
cd go-interop go mod tidy go mod download -
Network interface issues
# Use loopback interface for local testing ./session-server -addr "127.0.0.1:8805" ./session-client -address "127.0.0.1"
Debug Output
Both implementations provide detailed logging:
- Message type and direction
- Session ID tracking
- IE content parsing
- Error conditions
Enable verbose output by checking the console logs from both client and server.
Implementation Notes
Differences from Rust Version
- Command-line arguments: Go uses different flag names for consistency with go-pfcp examples
- Network binding: Go version uses simpler address binding
- Error handling: Go-style error handling vs Rust's Result types
- Memory management: Go garbage collection vs Rust ownership
Compatibility Considerations
- Endianness: Both use network byte order (big-endian)
- IE encoding: Both follow 3GPP TLV format
- Message structure: Identical PFCP header and payload format
- Sequence numbers: Compatible numbering schemes
Validation
Success criteria for cross-compatibility:
✅ Association establishment: Both can establish PFCP associations
✅ Session lifecycle: Complete session create/modify/delete flow
✅ Usage reporting: Quota exhaustion detection and reporting
✅ Binary protocol: Identical wire format and parsing
✅ Error handling: Proper cause codes and error responses
Contributing
To add more test scenarios:
- Add new message types to both server and client
- Test edge cases and error conditions
- Validate against 3GPP specification compliance
- Add performance benchmarks for large session counts
This interoperability testing ensures that rs-pfcp can integrate seamlessly with other PFCP implementations in real 5G network deployments.