Skip to main content

UE IP Pool Allocation Documentation

IP Address Management for Mobile Devices


Table of Contents

  1. Overview
  2. IP Allocation Concepts
  3. Configuration
  4. Allocation Process
  5. Advanced Topics
  6. Monitoring
  7. Troubleshooting

Overview

The PGW-C allocates IP addresses to UE (User Equipment) devices when they establish PDN (Packet Data Network) connections. This is a critical function that enables mobile devices to communicate with external networks.

Why IP Allocation Matters

Each UE receives a unique IP address from the PGW-C that:

  • Identifies the device on the network
  • Routes traffic to/from the device
  • Enables charging and policy enforcement
  • Persists for the duration of the PDN connection

Supported IP Versions

IP VersionSupportDescription
IPv4✅ FullStandard IPv4 addresses
IPv6✅ FullIPv6 addresses and prefixes
IPv4v6✅ FullDual-stack (both IPv4 and IPv6)

IP Allocation Concepts

PDN Type

When a UE requests a PDN connection, it specifies a PDN Type:

PDN TypeDescriptionAllocated Addresses
IPv4IPv4-only connectionSingle IPv4 address
IPv6IPv6-only connectionIPv6 prefix (e.g., /64)
IPv4v6Dual-stack connectionBoth IPv4 address and IPv6 prefix

Allocation Methods

PGW-C supports two IP allocation methods:

1. Dynamic Allocation (Most Common):

  • PGW-C selects IP from configured pool
  • Random selection to avoid predictability
  • Collision detection ensures uniqueness

2. Static Allocation:

  • UE requests specific IP in GTP-C message
  • PGW-C validates availability
  • Useful for enterprise devices with fixed IPs

APN-Based Subnet Selection

Different APNs (Access Point Names) can use different IP pools:

Benefits:

  • Traffic Segregation - Different APNs route to different networks
  • Policy Differentiation - Apply different policies per APN
  • Capacity Planning - Size pools based on expected usage
  • Billing - Track usage by service type

Address Registry

The Address Registry tracks allocated IPs:

FunctionDescription
RegistrationMaps UE IP → Session Process PID
LookupFind session by UE IP
DeregistrationRelease IP when session ends
Collision DetectionPrevent duplicate allocations

Configuration

Basic Configuration

Edit config/runtime.exs:

config :pgw_c,
ue: %{
subnet_map: %{
# APN "internet" uses two subnets
"internet" => [
"100.64.1.0/24", # 254 usable IPs
"100.64.2.0/24" # 254 usable IPs
],

# APN "ims" uses one subnet
"ims" => [
"100.64.10.0/24"
],

# Default pool for unknown APNs
default: [
"42.42.42.0/24"
]
}
}

Subnet Notation

CIDR Notation: <network>/<prefix_length>

CIDRUsable IPsExample Range
/24254100.64.1.1 - 100.64.1.254
/23510100.64.0.1 - 100.64.1.254
/221022100.64.0.1 - 100.64.3.254
/204094100.64.0.1 - 100.64.15.254
/1665534100.64.0.1 - 100.64.255.254

Notes:

  • Network address (e.g., 100.64.1.0) is not allocated
  • Broadcast address (e.g., 100.64.1.255) is not allocated
  • PGW-C allocates from <network> + 1 to <broadcast> - 1

Multiple Subnets per APN

Load Balancing Across Subnets:

config :pgw_c,
ue: %{
subnet_map: %{
"internet" => [
"100.64.1.0/24",
"100.64.2.0/24",
"100.64.3.0/24",
"100.64.4.0/24"
]
}
}

Selection Method:

  • PGW-C randomly selects one subnet from the list
  • Provides basic load balancing
  • Each session independently selects a subnet

Benefits:

  • Distribute load across multiple subnets
  • Easier capacity expansion (add new subnets)
  • Flexibility for routing policies

Real-World Example

config :pgw_c,
ue: %{
subnet_map: %{
# General internet access
"internet" => [
"100.64.0.0/20" # 4094 IPs for general use
],

# IMS (Voice over LTE)
"ims" => [
"100.64.16.0/22" # 1022 IPs for IMS
],

# Enterprise APN
"enterprise.corp" => [
"10.100.0.0/16" # 65534 IPs for enterprise
],

# IoT devices (low bitrate)
"iot.m2m" => [
"100.64.20.0/22" # 1022 IPs for IoT
],

# Default fallback
default: [
"42.42.42.0/24" # 254 IPs for unknown APNs
]
}
}

IPv6 Configuration

config :pgw_c,
ue: %{
subnet_map: %{
"internet" => [
# IPv4 pools
"100.64.1.0/24"
],
"internet.ipv6" => [
# IPv6 pools (prefix delegation)
"2001:db8:1::/48"
],
default: [
"42.42.42.0/24"
]
}
}

IPv6 Prefix Delegation:

  • UE typically receives a /64 prefix
  • Allows UE to assign multiple IPs (e.g., for tethering)
  • Example: UE receives 2001:db8:1:a::/64

Dual-Stack (IPv4v6) Configuration

config :pgw_c,
ue: %{
subnet_map: %{
"internet" => [
"100.64.1.0/24", # IPv4 pool
"2001:db8:1::/48" # IPv6 pool (will be used for IPv6 allocation)
]
}
}

Dual-Stack Allocation:

  • UE requests PDN Type: IPv4v6
  • PGW-C allocates both IPv4 address and IPv6 prefix
  • Both addresses active simultaneously

Allocation Process

IP allocation occurs during session creation when PGW-C receives a Create Session Request via the S5/S8 interface. See S5/S8 Interface for GTP-C message details and Session Management for session lifecycle.

Step-by-Step: Dynamic IPv4 Allocation

How It Works

Dynamic Allocation Process:

  1. Subnet Lookup: System retrieves configured subnets for the requested APN
  2. Random Selection: One subnet is randomly selected from the available list
  3. IP Generation: A random IP is generated within the subnet range
  4. Uniqueness Check: System verifies the IP hasn't been allocated
  5. Retry Logic: If collision detected, retry up to 100 times with new random IP
  6. Registration: Once unique IP found, it's registered to the session

Key Design Points:

  • Max 100 attempts: Prevents infinite loops when pool is nearly exhausted
  • Random selection: Avoids predictable IP assignment patterns for security
  • Atomic operations: Process-based registry ensures no duplicate allocations
  • Fallback to default: If APN not found in config, uses default pool

Collision Handling

Scenario: Two sessions try to allocate same IP simultaneously

How Collision Prevention Works:

  • Registry processes requests one at a time (serialized)
  • No race conditions possible
  • First request to register an IP succeeds
  • Subsequent requests for same IP are rejected
  • Rejected sessions automatically retry with new random IP

Default Subnet Fallback

Scenario: UE requests unknown APN

Example Configuration:

# Config
subnet_map: %{
"internet" => ["100.64.1.0/24"],
default: ["42.42.42.0/24"]
}

Behavior:

  • UE requests APN: "unknown.apn"
  • System looks for "unknown.apn" in subnet_map
  • Not found, so falls back to default pool
  • Allocates IP from 42.42.42.0/24

Fallback Logic:

  1. First, try to find APN-specific pool in configuration
  2. If not found, use the default pool
  3. If no default configured, allocation fails

Deallocation on Session Termination

Automatic Cleanup:

  • When session process terminates, registry cleans up
  • IP immediately available for new allocations
  • No manual intervention required

Advanced Topics

Pool Exhaustion

Scenario: All IPs in pool are allocated

Pool: 100.64.1.0/24 (254 usable IPs)
Allocated: 254 IPs
New request arrives → Exhaustion

What Happens:

  1. PGW-C attempts 100 random allocations
  2. All attempts find IP already allocated
  3. Returns: {:error, :ue_ip_address_allocation_failed}
  4. Session establishment fails
  5. SGW-C receives error response

Prevention:

# Monitor pool utilization
address_registry_count / total_pool_size > 0.8 # Alert at 80%

# Expand pool before exhaustion
"internet" => [
"100.64.1.0/24",
"100.64.2.0/24", # Add additional subnet
"100.64.3.0/24"
]

Static IP Allocation

Use Case: Enterprise device needs fixed IP

GTP-C Message Format:

Create Session Request
├── IMSI: 310260123456789
├── APN: enterprise.corp
├── PDN Address Allocation (IE)
│ └── PDN Type: IPv4
│ └── IPv4 Address: 10.100.0.50 ← UE requests specific IP

OmniPGW Processing:

  1. Extract Requested IP: Parse PDN Address Allocation IE from request
  2. Validate IP: Check if requested IP is in configured pool for this APN
  3. Check Availability: Verify IP is not already allocated to another session
  4. Allocate or Reject:
    • If available: Allocate requested IP to this session
    • If unavailable: Reject session with appropriate cause code

Possible Results:

  • Success: UE receives exactly the IP address it requested
  • Failure (IP in use): Session rejected - IP already allocated
  • Failure (IP not in pool): Session rejected - IP not in configured range

IPv6 Prefix Delegation

UE requests IPv6:

Create Session Request
├── PDN Type: IPv6

PGW-C allocates /64 prefix:

Allocated Prefix: 2001:db8:1:a::/64

UE can use:
- 2001:db8:1:a::1
- 2001:db8:1:a::2
- ... (18 quintillion addresses)

Benefits:

  • UE can assign multiple IPs (e.g., tethering)
  • Supports SLAAC (Stateless Address Autoconfiguration)
  • Eliminates NAT requirement

Dual-Stack Allocation

UE requests IPv4v6:

Create Session Request
├── PDN Type: IPv4v6

PGW-C allocates both:

IPv4: 100.64.1.42
IPv6: 2001:db8:1:a::/64

Traffic Handling:

  • IPv4 traffic uses IPv4 address
  • IPv6 traffic uses IPv6 prefix
  • Both active simultaneously
  • Separate GTP tunnels (or dual-stack tunnel)

Private vs. Public IP Addresses

Private IP Pools (RFC 1918):

# Not routable on public internet
subnet_map: %{
"internet" => [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
]
}

Requires NAT at PGW-U to access internet

Public IP Pools:

# Routable public IPs (example only)
subnet_map: %{
"internet" => [
"203.0.113.0/24" # Public IP block
]
}

No NAT required - direct internet routing

Recommendation:

  • Use private IPs (RFC 6598): 100.64.0.0/10 (Carrier-Grade NAT)
  • Reserve public IPs for special services only

Monitoring

Web UI - IP Pool Management

OmniPGW provides a real-time web interface for monitoring IP pool allocation and utilization.

Access: http://<omnipgw-ip>:<web-port>/ip_pools

IP Pool Management Interface

Features:

1. Pool Overview

  • Total IPs across all pools
  • Currently allocated addresses
  • Available IPs remaining
  • Real-time utilization percentage

2. Per-APN Pool Status Each configured pool displays:

  • Pool Name - APN identifier (e.g., "default", "ims.something.else", "Internet")
  • APN Label - Configured APN name badge
  • IP Range - CIDR notation showing subnet range
  • Utilization - Visual indicator showing percentage used
  • Allocation Stats:
    • Total: Number of IPs in pool
    • Allocated: Currently assigned IPs
    • Available: Remaining IPs for allocation

3. Real-time Updates

  • Auto-refresh every 2 seconds
  • No page reload required
  • Live utilization tracking

Use Cases:

  • Quick capacity check before maintenance
  • Identify pools approaching exhaustion
  • Verify pool configuration
  • Monitor allocation patterns by APN

Key Metrics

Address Registry Count:

# Current allocated IPs
address_registry_count

# Pool utilization (requires calculation)
address_registry_count / <total_pool_size> * 100

Example:

Pool: 100.64.1.0/24 (254 IPs)
Allocated: 150 IPs
Utilization: 150 / 254 = 59%

Alerts

# Alert on high pool utilization
- alert: UEIPPoolUtilizationHigh
expr: address_registry_count > 200 # For /24 pool
for: 10m
annotations:
summary: "UE IP pool utilization above 80%"
description: "Current: {{ $value }} / 254 IPs allocated"

# Alert on pool exhaustion
- alert: UEIPPoolExhausted
expr: address_registry_count >= 254 # For /24 pool
for: 1m
annotations:
summary: "UE IP pool exhausted - no IPs available"

# Alert on allocation failures
- alert: UEIPAllocationFailures
expr: rate(ue_ip_allocation_failures_total[5m]) > 0
for: 5m
annotations:
summary: "UE IP allocation failures occurring"

Grafana Dashboard

Panel 1: IP Pool Utilization

# Gauge showing percentage
(address_registry_count / 254) * 100

Panel 2: Allocated IPs Over Time

# Time series
address_registry_count

Panel 3: Allocation Rate

# Rate of new allocations
rate(address_registry_count[5m])

Panel 4: Pool Exhaustion Risk

# Days until exhaustion (based on current rate)
(254 - address_registry_count) / rate(address_registry_count[1h])

Troubleshooting

Issue 1: Session Establishment Fails (No IP Available)

Symptoms:

  • Create Session Response: Cause "Request rejected"
  • Log: "UE IP address allocation failed"

Possible Causes:

  1. Pool Exhausted

    # Check current allocation
    curl http://<pgw_c_ip>:42069/metrics | grep address_registry_count
  2. Configuration Error

    # Verify subnet configuration
    config :pgw_c,
    ue: %{
    subnet_map: %{
    "internet" => [
    "100.64.1.0/24" # Ensure valid CIDR
    ]
    }
    }
  3. APN Misconfiguration

    # If APN not found, falls back to default
    # Ensure default pool exists
    subnet_map: %{
    default: ["42.42.42.0/24"]
    }

Resolution:

  • Expand pool: Add more subnets
  • Cleanup stale sessions: Restart PGW-C to release leaked IPs
  • Verify config: Check runtime.exs for typos

Issue 2: IP Address Collision

Symptoms:

  • Two UEs receive same IP (very rare)
  • Routing issues

Cause:

  • Bug in Address Registry (should not happen)

Debug:

# Check for duplicate IPs in logs
grep "already_registered" /var/log/pgw_c.log

Resolution:

  • Should self-correct (second session retries)
  • If persistent, report bug

Issue 3: Wrong IP Pool Used

Symptoms:

  • UE receives IP from unexpected subnet
  • APN "internet" gets IP from "ims" pool

Cause:

  • Incorrect subnet_map configuration

Verify:

# Check exact APN string matching
subnet_map: %{
"internet" => [...], # Case-sensitive
"Internet" => [...] # Different APN!
}

Resolution:

  • Ensure APN names match exactly (case-sensitive)
  • Use default pool for catch-all

Issue 4: IPv6 Allocation Fails

Symptoms:

  • UE requests IPv6, receives error

Possible Causes:

  1. No IPv6 pool configured

    # Missing IPv6 subnets
    subnet_map: %{
    "internet" => [
    "100.64.1.0/24" # Only IPv4
    ]
    }
  2. Invalid IPv6 prefix

    # Too small prefix (should be /48 or larger)
    "internet" => [
    "2001:db8::/128" # Wrong - no room for allocation
    ]

Resolution:

# Add IPv6 pool
subnet_map: %{
"internet" => [
"100.64.1.0/24",
"2001:db8:1::/48" # IPv6 pool
]
}

Issue 5: High Pool Utilization

Symptoms:

  • Nearing pool exhaustion
  • address_registry_count approaching max

Proactive Measures:

  1. Add Subnets:

    "internet" => [
    "100.64.1.0/24", # Existing
    "100.64.2.0/24", # New subnet (adds 254 IPs)
    "100.64.3.0/24" # New subnet (adds 254 IPs)
    ]
  2. Use Larger Subnets:

    # Replace /24 with /22
    "internet" => [
    "100.64.0.0/22" # 1022 usable IPs
    ]
  3. Session Cleanup:

    • Monitor stale sessions
    • Ensure proper Delete Session Request handling

Best Practices

Capacity Planning

Calculate required pool size:

Expected concurrent users: 10,000
Peak concurrency: 30% (3,000 simultaneous sessions)
Growth buffer: 50%
Required IPs: 3,000 * 1.5 = 4,500 IPs

Subnet: /20 (4,094 usable IPs) - Too small
Subnet: /19 (8,190 usable IPs) - Sufficient

Subnet Selection

Recommended:

  • Use 100.64.0.0/10 (RFC 6598 - Carrier-Grade NAT)
  • Provides 4 million IPs
  • Reserved for service provider NAT

Avoid:

  • Public IPs (expensive, limited)
  • Common private ranges that conflict with enterprise VPNs

Configuration Layout

config :pgw_c,
ue: %{
subnet_map: %{
# Primary internet APN - large pool
"internet" => [
"100.64.0.0/18" # 16,382 IPs
],

# IMS - smaller dedicated pool
"ims" => [
"100.64.64.0/22" # 1,022 IPs
],

# Enterprise - medium pool
"enterprise.corp" => [
"100.64.68.0/22" # 1,022 IPs
],

# IoT - large pool for many devices
"iot.m2m" => [
"100.64.72.0/20" # 4,094 IPs
],

# Default - small fallback
default: [
"100.64.127.0/24" # 254 IPs
]
}
}

Configuration

Network Planning

Operations


Back to Operations Guide