Saltar al contenido principal

Guía de Configuración de OmniPGW

Referencia Completa para la Configuración de runtime.exs

por Omnitouch Network Services


Tabla de Contenidos

  1. Descripción General
  2. Estructura del Archivo de Configuración
  3. Configuración de Métricas
  4. Configuración de Diameter/Gx
  5. Configuración de S5/S8
  6. Configuración de Gn/Gp (GGSN)
  7. Configuración de Sxb/PFCP
  8. Configuración del Pool de IP de UE
  9. Configuración de PCO
  10. Configuración de la Interfaz Web
  11. Ejemplo Completo
  12. Validación de la Configuración

Descripción General

OmniPGW utiliza configuración en tiempo de ejecución definida en config/runtime.exs. Este archivo se evalúa en el inicio de la aplicación y permite una configuración dinámica basada en variables de entorno o fuentes externas.

Filosofía de Configuración

Principios Clave:

  • Fuente Única de Verdad - Toda la configuración en un solo archivo
  • Seguridad de Tipo - Configuración validada al inicio
  • Flexibilidad de Entorno - Soporte para desarrollo, pruebas, producción
  • Valores Predeterminados Claros - Valores predeterminados sensatos con sobrescrituras explícitas

Estructura del Archivo de Configuración

Ubicación del Archivo

pgw_c/
├── config/
│ ├── config.exs # Configuración base (importa runtime.exs)
│ ├── dev.exs # Configuración específica de desarrollo
│ ├── prod.exs # Configuración específica de producción
│ └── runtime.exs # ← Archivo de configuración principal

Estructura de Nivel Superior

# config/runtime.exs
import Config

config :logger, level: :info

config :pgw_c,
metrics: %{...},
diameter: %{...},
s5s8: %{...},
sxb: %{...},
ue: %{...},
pco: %{...}

Secciones de Configuración


Configuración de Métricas

Propósito

Configurar el exportador de métricas de Prometheus para monitorear OmniPGW.

Bloque de Configuración

config :pgw_c,
metrics: %{
# Habilitar/deshabilitar exportador de métricas
enabled: true,

# Dirección IP para enlazar el servidor HTTP
ip_address: "0.0.0.0",

# Puerto para el endpoint de métricas
port: 9090,

# Cada cuánto tiempo sondear los registros (milisegundos)
registry_poll_period_ms: 10_000
}

Parámetros

ParámetroTipoPredeterminadoDescripción
enabledBooleanotrueHabilitar exportador de métricas
ip_addressCadena (IP)"0.0.0.0"Dirección de enlace (0.0.0.0 = todas las interfaces)
portEntero9090Puerto HTTP para el endpoint /metrics
registry_poll_period_msEntero10_000Intervalo de sondeo para conteos de registro

Ejemplos

Producción - Enlazar a IP específica:

metrics: %{
enabled: true,
ip_address: "10.0.0.20", # Red de gestión
port: 9090,
registry_poll_period_ms: 5_000 # Sondear cada 5 segundos
}

Desarrollo - Solo localhost:

metrics: %{
enabled: true,
ip_address: "127.0.0.1",
port: 42069, # Puerto no estándar
registry_poll_period_ms: 10_000
}

Deshabilitar métricas:

metrics: %{
enabled: false
}

Accediendo a Métricas

# Endpoint predeterminado
curl http://<ip_address>:<port>/metrics

# Ejemplo
curl http://10.0.0.20:9090/metrics

Ver: Guía de Monitoreo y Métricas para documentación detallada sobre métricas.


Configuración de Diameter/Gx

Propósito

Configurar el protocolo Diameter para la interfaz Gx (comunicación PCRF).

Bloque de Configuración

config :pgw_c,
diameter: %{
# Dirección IP para escuchar conexiones Diameter
listen_ip: "0.0.0.0",

# Identidad Diameter de OmniPGW (Origin-Host)
host: "omnipgw.epc.mnc001.mcc001.3gppnetwork.org",

# Dominio Diameter de OmniPGW (Origin-Realm)
realm: "epc.mnc001.mcc001.3gppnetwork.org",

# Lista de pares PCRF
peer_list: [
%{
# Identidad Diameter PCRF
host: "pcrf.epc.mnc001.mcc001.3gppnetwork.org",

# Dominio PCRF
realm: "epc.mnc001.mcc001.3gppnetwork.org",

# Dirección IP PCRF
ip: "10.0.0.30",

# Iniciar conexión con PCRF
initiate_connection: true
}
]
}

Parámetros

ParámetroTipoRequeridoDescripción
listen_ipCadena (IP)Dirección de escucha Diameter
hostCadena (FQDN)Origin-Host de OmniPGW (debe ser FQDN)
realmCadena (Dominio)Origin-Realm de OmniPGW
peer_listListaConfiguraciones de pares PCRF

Configuración de Pares:

ParámetroTipoRequeridoDescripción
hostCadena (FQDN)Identidad Diameter PCRF
realmCadena (Dominio)Dominio PCRF
ipCadena (IP)Dirección IP PCRF
initiate_connectionBooleanoSi OmniPGW se conecta a PCRF

Formato FQDN

Las identidades Diameter DEBEN ser FQDN:

# CORRECTO
host: "omnipgw.epc.mnc001.mcc001.3gppnetwork.org"

# INCORRECTO
host: "omnipgw" # No es un FQDN
host: "10.0.0.20" # IP no permitida

Formato 3GPP:

<hostname>.epc.mnc<MNC>.mcc<MCC>.3gppnetwork.org

Ejemplos:
- omnipgw.epc.mnc001.mcc001.3gppnetwork.org (MCC=001, MNC=001)
- pgw-c.epc.mnc260.mcc310.3gppnetwork.org (MCC=310, MNC=260 - T-Mobile EE. UU.)

Ejemplos

Un solo PCRF:

diameter: %{
listen_ip: "0.0.0.0",
host: "omnipgw.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
peer_list: [
%{
host: "pcrf.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
ip: "10.0.0.30",
initiate_connection: true
}
]
}

Múltiples PCRFs (Redundancia):

diameter: %{
listen_ip: "0.0.0.0",
host: "omnipgw.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
peer_list: [
%{
host: "pcrf-primary.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
ip: "10.0.1.30",
initiate_connection: true
},
%{
host: "pcrf-backup.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
ip: "10.0.2.30",
initiate_connection: true
}
]
}

Conexión Iniciada por PCRF:

diameter: %{
listen_ip: "0.0.0.0",
host: "omnipgw.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
peer_list: [
%{
host: "pcrf.epc.mnc001.mcc001.3gppnetwork.org",
realm: "epc.mnc001.mcc001.3gppnetwork.org",
ip: "10.0.0.30",
initiate_connection: false # Esperar a que PCRF se conecte
}
]
}

Ver: Documentación de la Interfaz Diameter Gx


Configuración de S5/S8

Propósito

Configurar la interfaz GTP-C para la comunicación con SGW-C.

Bloque de Configuración

config :pgw_c,
s5s8: %{
# Dirección IPv4 local para la interfaz S5/S8
local_ipv4_address: "10.0.0.20",

# Opcional: Dirección IPv6 local
local_ipv6_address: nil,

# Opcional: Sobrescribir el puerto GTP-C predeterminado (2123)
local_port: 2123,

# Tiempo de espera de solicitud GTP-C en milisegundos (predeterminado: 500ms)
# Tiempo de espera por intento al esperar respuestas GTP-C
request_timeout_ms: 500,

# Número de intentos de reintento para solicitudes GTP-C (predeterminado: 3)
# Tiempo máximo total de espera = request_timeout_ms * request_attempts
request_attempts: 3
}

Parámetros

ParámetroTipoPredeterminadoDescripción
local_ipv4_addressCadena (IPv4)RequeridoDirección IPv4 de la interfaz S5/S8
local_ipv6_addressCadena (IPv6)nilDirección IPv6 de la interfaz S5/S8 (opcional)
local_portEntero2123Puerto UDP para GTP-C (puerto estándar 2123)
request_timeout_msEntero500Tiempo de espera por intento de reintento en milisegundos
request_attemptsEntero3Número de intentos de reintento antes de rendirse

Detalles del Protocolo

  • Protocolo: GTP-C Versión 2
  • Transporte: UDP
  • Puerto Estándar: 2123
  • Dirección: Recibe de SGW-C

Ejemplos

Solo IPv4 (Común):

s5s8: %{
local_ipv4_address: "10.0.0.20"
}

IPv4 + IPv6 Dual-Stack:

s5s8: %{
local_ipv4_address: "10.0.0.20",
local_ipv6_address: "2001:db8::20"
}

Puerto Personalizado (No Estándar):

s5s8: %{
local_ipv4_address: "10.0.0.20",
local_port: 2124 # Puerto personalizado
}

Red de Alta Latencia:

s5s8: %{
local_ipv4_address: "10.0.0.20",
request_timeout_ms: 1500, # 1.5 segundos por intento
request_attempts: 3 # Total: 4.5 segundos como máximo
}

Configuración de Tiempo de Espera

La interfaz S5/S8 utiliza tiempos de espera configurables para transacciones de solicitud/respuesta GTP-C (Crear Solicitud de Bearer, Eliminar Solicitud de Bearer).

Cálculo del Tiempo Total de Espera:

Tiempo Máximo Total de Espera = request_timeout_ms × request_attempts
Predeterminado: 500ms × 3 = 1.5 segundos

Directrices de Ajuste:

Latencia de RedTiempo de Espera RecomendadoTiempo Total de Espera
Baja latencia (<50ms)200-300ms600-900ms
Normal (50-150ms)500ms (predeterminado)1.5s
Alta latencia (>150ms)1000-2000ms3-6s
Satélite/inestable2000-3000ms6-9s

Cuándo Ajustar:

  • Aumentar el tiempo de espera si se ven frecuentes errores de "Solicitud de Bearer creada a tiempo de espera" pero Wireshark muestra que las respuestas llegan
  • Disminuir el tiempo de espera para una detección de fallos más rápida en entornos de baja latencia
  • Aumentar los intentos de reintento para redes poco fiables con pérdida de paquetes

Comportamiento del Tiempo de Espera:

  • En caso de tiempo de espera, se registra un error: "Solicitud de Bearer creada a tiempo de espera"
  • Error de Diameter devuelto al PCRF: Código de Resultado 5012 (UNABLE_TO_COMPLY)
  • El Bearer permanece en almacenamiento temprano para limpieza cuando llega Charging-Rule-Remove

Planificación de Red

Selección de Dirección IP:

  • Utilizar una red de gestión/señalización dedicada
  • Asegurar la accesibilidad desde todos los nodos SGW-C
  • Considerar redundancia (VRRP/HSRP) para HA

Reglas de Firewall:

# Permitir GTP-C desde SGW-C
iptables -A INPUT -p udp --dport 2123 -s <sgw_c_network> -j ACCEPT

Configuración de Gn/Gp (GGSN)

Propósito

Configurar la interfaz GTP-C v1 para la comunicación con SGSNs, habilitando la funcionalidad de GGSN para redes 2G/3G.

Bloque de Configuración

config :pgw_c,
gn: %{
# Dirección IPv4 local para la interfaz Gn
local_ipv4_address: "10.0.0.20",

# Opcional: Dirección IPv6 local (la mayoría de las redes 2G/3G son solo IPv4)
local_ipv6_address: nil,

# Puerto GTP-C (compartido con S5/S8)
local_port: 2123
},

# Servidores DNS devueltos en PCO (compartidos con S5/S8)
dns: %{
primary_ipv4: {8, 8, 8, 8},
secondary_ipv4: {8, 8, 4, 4}
}

Parámetros

ParámetroTipoPredeterminadoDescripción
local_ipv4_addressCadena (IPv4)RequeridoDirección IPv4 de la interfaz Gn (dirección GGSN)
local_ipv6_addressCadena (IPv6)nilDirección IPv6 de la interfaz Gn (opcional, raramente utilizada)
local_portEntero2123Puerto UDP para GTP-C v1 (compartido con S5/S8)

Parámetros DNS

ParámetroTipoPredeterminadoDescripción
primary_ipv4Tupla{8, 8, 8, 8}Servidor DNS primario para la respuesta PCO
secondary_ipv4Tupla{8, 8, 4, 4}Servidor DNS secundario para la respuesta PCO

Detalles del Protocolo

  • Protocolo: GTP-C Versión 1 (3GPP TS 29.060)
  • Transporte: UDP
  • Puerto Est��ndar: 2123 (compartido con GTP-C v2)
  • Dirección: Recibe de SGSNs

Coexistencia con S5/S8

OmniPGW puede operar como PGW (4G) y GGSN (2G/3G) simultáneamente:

  • Ambas interfaces comparten el puerto UDP 2123
  • La versión GTP se detecta automáticamente a partir de los encabezados de mensaje
  • La misma dirección IP puede servir tanto tráfico 4G como 2G/3G
  • Infraestructura compartida: pools de IP, UPF/PFCP, carga en línea

Ver: Documentación de la Interfaz Gn/Gp


Configuración de Sxb/PFCP

Propósito

Configurar la interfaz PFCP para la comunicación con PGW-U (Plano de Usuario).

Bloque de Configuración

config :pgw_c,
sxb: %{
# Dirección IP local para la comunicación PFCP
local_ip_address: "10.0.0.20",

# Opcional: Sobrescribir el puerto PFCP predeterminado (8805)
local_port: 8805
}

Parámetros

ParámetroTipoPredeterminadoDescripción
local_ip_addressCadena (IP)RequeridoDirección de escucha PFCP
local_portEntero8805Puerto UDP PFCP

Importante:

  • Todos los pares UPF se registran automáticamente desde la configuración de upf_selection (reglas + pool de respaldo) al inicio
  • Los UPFs registrados automáticamente utilizan valores predeterminados sensatos:
    • Nombre generado automáticamente: "UPF-<ip>:<port>"
    • Asociación PFCP pasiva (esperar a que UPF inicie)
    • Intervalo de latido de 5 segundos
  • Las reglas de selección de UPF y los pools se configuran en la sección separada upf_selection. Ver Estrategias de Selección de UPF a continuación.
  • Se admite el registro dinámico de UPF para UPFs descubiertos por DNS que no están en la configuración

Ejemplos

Configuración Mínima:

sxb: %{
local_ip_address: "10.0.0.20"
}

# Todos los UPFs en upf_selection se registrarán automáticamente con:
# - Nombre generado automáticamente: "UPF-10.0.0.21:8805"
# - Asociación PFCP pasiva (esperar a que UPF se conecte)
# - Intervalo de latido de 5 segundos

Puerto PFCP Personalizado:

sxb: %{
local_ip_address: "10.0.0.20",
local_port: 8806 # Puerto PFCP no estándar
}

Ejemplo Completo con Selección de UPF:

sxb: %{
local_ip_address: "10.0.0.20"
},
upf_selection: %{
rules: [
%{
name: "Pool IMS",
priority: 10,
match_field: :apn,
match_regex: ~r/^ims$/,
upf_pool: [
%{remote_ip_address: "10.0.1.21", remote_port: 8805, weight: 100},
%{remote_ip_address: "10.0.1.22", remote_port: 8805, weight: 100}
]
}
],
fallback_pool: [
%{remote_ip_address: "10.0.2.21", remote_port: 8805, weight: 100}
]
}
# Todos los 3 UPFs (10.0.1.21, 10.0.1.22, 10.0.2.21) se registran automáticamente

Selección Basada en DNS (Registro Dinámico):

sxb: %{
local_ip_address: "10.0.0.20"
},
upf_selection: %{
dns_enabled: true,
dns_query_priority: [:ecgi, :tai],
dns_suffix: "epc.3gppnetwork.org",
fallback_pool: [
%{remote_ip_address: "10.0.2.21", remote_port: 8805, weight: 100}
]
}
# Los UPFs descubiertos por DNS se registrarán dinámicamente en el primer uso

Estrategias de Selección de UPF

Importante: La configuración de selección de UPF se ha simplificado. Todos los pares UPF se registran automáticamente desde la configuración de upf_selection.

Estructura de Configuración

La selección de UPF se configura en la sección upf_selection que define:

  1. Reglas Estáticas - Enrutamiento basado en patrones con pools de balanceo de carga
  2. Configuraciones DNS - Descubrimiento dinámico de UPF basado en ubicación
  3. Pool de Respaldo - Pool predeterminado cuando no hay coincidencias de reglas y DNS falla

Orden de Prioridad de Selección

  1. Reglas Estáticas (Mayor Prioridad) - Enrutamiento basado en patrones con pools de balanceo de carga
  2. Selección Basada en DNS (Menor Prioridad) - Descubrimiento dinámico de UPF basado en ubicación
  3. Pool de Respaldo (Menor Prioridad) - Pool predeterminado cuando no hay coincidencias de reglas y DNS falla

Flujo de Decisión de Selección de UPF

Campos de Coincidencia Disponibles

Las reglas estáticas pueden coincidir en cualquiera de estos atributos de sesión:

Campo de CoincidenciaDescripciónPatrón de Ejemplo
:imsiIdentidad Internacional del Suscriptor Móvil^313380.* (operador de EE. UU.)
:apnNombre del Punto de Acceso / DNN^internet\. o ^ims\.
:serving_network_plmn_idIdentificador de red de servicio^313380$
:sgw_ip_addressDirección IP de SGW^10\.100\..*
:uli_tai_plmn_idID de PLMN del Área de Seguimiento^313.*
:uli_ecgi_plmn_idID de PLMN de la Celda E-UTRAN^313.*

Comparación de Métodos de Selección

MétodoCuándo UsarProsContras
Grupos de UPFDespliegues de producciónBalanceo de carga, HA, pesos flexiblesRequiere múltiples UPFs
Basado en APNDiferenciación de serviciosEnrutar IMS/Internet por separadoConfiguración estática
Basado en IMSIEscenarios de itineranciaEnrutamiento geográficoComplejidad de regex
Basado en DNSMEC/Computación en el bordeDinámico, consciente de la ubicaciónRequiere infraestructura DNS
Pool de RespaldoRed de seguridadSiempre tener un UPFPuede no ser óptimo
Modo de PruebaProbar configuracionesPruebas segurasSin tráfico real

Flujo Completo de Establecimiento de Sesión

Este diagrama muestra el flujo completo de establecimiento de sesión incluyendo la selección de UPF y la población de PCO:

Puntos Clave de Decisión:

  1. Prioridad de Selección de UPF:

    • Reglas Estáticas (Coincidencia de Patrón) → Descubrimiento DNS → Pool de Respaldo
    • Filtrado de salud aplicado en todas las etapas
    • Lógica Activa/Standby para alta disponibilidad
    • Ver: Interfaz PFCP para detalles de comunicación de UPF
  2. Prioridad de Población de PCO:

    • Sobrescritura de PCO de Regla → Descubrimiento DNS de P-CSCF → Configuración Global de PCO
    • Fusión por campo (las reglas sobrescriben campos específicos, global proporciona valores predeterminados)
    • Ver: Configuración de PCO para parámetros detallados de PCO
  3. Prioridad de Descubrimiento de P-CSCF:

    • FQDN por Regla → Descubrimiento DNS Global → PCO Estático de Regla → PCO Estático Global
    • Ver: Monitoreo de P-CSCF para métricas de descubrimiento y seguimiento de salud
  4. Integración de Carga:

    • PCRF determina si se requiere carga en línea (Grupo de Calificación + Online=1)
    • OCS concede cuota antes del establecimiento de la sesión
    • PGW-C rastrea la cuota y solicita más a través de CCR-Update
    • Ver: Interfaz Diameter Gx y Interfaz Diameter Gy para detalles de carga

Ejemplo Completo de Configuración

Aquí hay un ejemplo completo que muestra la selección de UPF de múltiples pools con registro automático de pares:

config :pgw_c,
# Interfaz PFCP - Todos los UPFs se registran automáticamente desde upf_selection
sxb: %{
local_ip_address: "127.0.0.20"
},

# Lógica de Selección de UPF - Todos los UPFs definidos aquí se registran automáticamente
upf_selection: %{
# Configuraciones de selección basadas en DNS
dns_enabled: false,
dns_query_priority: [:ecgi, :tai, :rai, :sai, :cgi],
dns_suffix: "epc.3gppnetwork.org",
dns_timeout_ms: 5000,

# Reglas de selección estática (evaluadas en orden de prioridad)
rules: [
# Regla 1: Tráfico IMS - Mayor Prioridad
%{
name: "Tráfico IMS",
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}
]
},

# Regla 2: APN Empresarial
%{
name: "Tráfico Empresarial",
priority: 15,
match_field: :apn,
match_regex: "^(enterprise|corporate)\.apn",
upf_pool: [
%{remote_ip_address: "10.100.3.21", remote_port: 8805, weight: 100}
]
},

# Regla 3: Tráfico de Internet - Balanceado
%{
name: "Tráfico de Internet",
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}
]
}
],

# Pool de Respaldo - Usado cuando no hay coincidencias de reglas y DNS falla
fallback_pool: [
%{remote_ip_address: "127.0.0.21", remote_port: 8805, weight: 100}
]
}

Características Clave

Formato Actual:

  • Registro Automático: Todos los UPFs de upf_selection se registran automáticamente al inicio
  • Configuración Centralizada: Toda la selección de UPF y configuración de pares en una sección
  • Pools Requeridos: Todas las reglas utilizan el formato upf_pool (incluso para un solo UPF)
  • Fallback Estructurado: fallback_pool dedicado con distribución ponderada
  • Integración DNS: Configuraciones DNS junto con reglas de selección
  • Registro Dinámico: UPFs descubiertos por DNS se registran automáticamente en el primer uso
  • Monitoreo de Salud: Todos los UPFs configurados se monitorean con latidos de 5 segundos

Migración desde el Formato Anterior:

  • Eliminado: campo sxb.peer_list (ya no es necesario)
  • Eliminado: selection_list incrustado en configuraciones de pares
  • Todas las definiciones de UPF ahora van en las reglas y el pool de respaldo de upf_selection

Cómo Funcionan los Pools de UPF:

  1. Selección Consciente de Salud: Solo los UPFs saludables reciben tráfico

    • Saludable = Asociación PFCP activa + menos de 3 latidos consecutivos perdidos
    • Los UPFs no saludables se filtran automáticamente
    • Se recurre a todos los UPFs si ninguno es saludable (fallo rápido)
  2. Soporte Activo/Standby: Usar weight: 0 para UPFs de standby

    • UPFs Activos (peso > 0): Reciben tráfico cuando son saludables
    • UPFs de Standby (peso == 0): Solo reciben tráfico cuando todos los UPFs activos están caídos
    • Los UPFs de standby se tratan como weight: 1 cuando se activan
  3. Selección Aleatoria Ponderada: Cada sesión se asigna aleatoriamente a un UPF saludable basado en pesos

    • En el ejemplo anterior: 70% van a .21, 20% a .22, 10% a .23
    • Peso más alto = más sesiones asignadas a ese UPF
    • Pesos iguales = distribución equitativa
  4. Registro Automático: Todos los UPFs en pools se registran automáticamente al inicio

    • Nombres generados automáticamente: "UPF-<ip>:<port>"
    • Configuraciones predeterminadas: asociación PFCP pasiva, latidos de 5 segundos
    • Seguimiento de salud inmediato para todos los UPFs configurados

Selección Consciente de Salud con Activo/Standby

Ejemplo de Selección Aleatoria Ponderada:

Pool: [
UPF-A: peso 50, saludable ✓
UPF-B: peso 30, saludable ✓
UPF-C: peso 20, saludable ✓
]

Peso Total: 50 + 30 + 20 = 100

Rangos de Peso:
UPF-A: 0-49 (50%)
UPF-B: 50-79 (30%)
UPF-C: 80-99 (20%)

Número aleatorio: 63 → Selecciona UPF-B
Número aleatorio: 15 → Selecciona UPF-A
Número aleatorio: 91 → Selecciona UPF-C

Ejemplo de Failover Activo/Standby:

Pool Inicial: [
UPF-A: peso 100, saludable ✓ (Activo)
UPF-B: peso 0, saludable ✓ (Standby)
]

Escenario 1: UPF-A Saludable
→ Usar Pool Activo: [UPF-A: 100]
→ Todo el tráfico a UPF-A

Escenario 2: UPF-A Falla
→ No hay UPFs activos saludables
→ Activar Standby: [UPF-B: 1]
→ Todo el tráfico se transfiere a UPF-B
→ Registrar: "Todos los UPFs activos caídos, activando UPFs de standby"

Escenario 3: Ambos No Saludables
→ No hay UPFs saludables
→ Usar pool completo: [UPF-A: 100, UPF-B: 0]
→ Seleccionar con pesos (intentar conexión, puede fallar)
→ Registrar: "No hay UPFs saludables en el pool, usando pool completo como respaldo"

Patrones de Peso Comunes:

# Distribución equitativa (25% cada uno)
upf_pool: [
%{remote_ip_address: "10.0.1.1", remote_port: 8805, weight: 1},
%{remote_ip_address: "10.0.1.2", remote_port: 8805, weight: 1},
%{remote_ip_address: "10.0.1.3", remote_port: 8805, weight: 1},
%{remote_ip_address: "10.0.1.4", remote_port: 8805, weight: 1}
]

# Carga primaria/respaldo (90% / 10%)
upf_pool: [
%{remote_ip_address: "10.0.1.21", remote_port: 8805, weight: 90},
%{remote_ip_address: "10.0.1.22", remote_port: 8805, weight: 10}
]

# Activo/Standby (100% primario, 0% standby hasta que el primario falle)
upf_pool: [
%{remote_ip_address: "10.0.1.21", remote_port: 8805, weight: 100}, # Activo
%{remote_ip_address: "10.0.1.22", remote_port: 8805, weight: 0} # Standby (solo cuando el activo está caído)
]

# Resultado: Activo recibe 100%. Si el activo falla, los standby reciben 50/50%.

# Pruebas A/B (50% / 50%)
upf_pool: [
%{remote_ip_address: "10.0.1.100", remote_port: 8805, weight: 50}, # Versión antigua
%{remote_ip_address: "10.0.1.200", remote_port: 8805, weight: 50} # Nueva versión
]

Casos de Uso:

  • Failover Activo/Standby: Usar weight: 0 para UPFs de standby calientes que solo se activan cuando los primarios fallan
  • HA Consciente de Salud: Failover automático cuando los UPFs pierden asociación PFCP o fallan latidos
  • Escalado Horizontal: Distribuir carga entre múltiples UPFs para aumentar la capacidad
  • Alta Disponibilidad: Distribución automática previene la sobrecarga de un solo UPF
  • Despliegues Graduales: Usar pesos para implementaciones canarias (por ejemplo, 95% antiguo, 5% nuevo)
  • Optimización de Costos: Enrutar más tráfico a UPFs de mayor capacidad
  • Distribución Geográfica: Balancear sesiones entre UPFs de borde

Sobrescrituras de PCO (Opciones de Configuración de Protocolo):

Cada regla de selección de UPF puede especificar opcionalmente valores de PCO personalizados que sobrescriben la configuración de PCO predeterminada para sesiones coincidentes. Esto permite que diferentes APNs o tipos de tráfico reciban diferentes parámetros de red.

Cómo Funcionan las Sobrescrituras de PCO:

  1. Sobrescrituras Parciales: Solo especificar los campos de PCO que desea sobrescribir
  2. Fallback Predeterminado: Los campos no especificados utilizan valores de la configuración principal de pco
  3. Específico de Regla: Cada regla puede tener diferentes sobrescrituras de PCO
  4. Fusión de Prioridad: PCO de regla tiene prioridad sobre PCO global

Jerarquía de Población de PCO

Orden de Prioridad para Cada Campo de PCO:

  1. Sobrescritura de PCO de Regla (Mayor Prioridad)
  2. Descubrimiento DNS de P-CSCF (solo para direcciones P-CSCF)
  3. Configuración Global de PCO (Menor Prioridad / Respaldo)

Ejemplo: La Regla IMS Sobrescribe DNS, La Regla Empresarial Sobrescribe Todo

Sesión IMS (coincidida con la regla "Tráfico IMS"):
├─ Servidores DNS: DE GLOBAL (no sobrescrito en la regla)
├─ P-CSCF: DE DESCUBRIMIENTO DNS (p_cscf_discovery_fqdn establecido en la regla)
│ └─ Respaldo: DE LA REGLA si DNS falla
└─ MTU: DE GLOBAL (no sobrescrito en la regla)

Sesión Empresarial (coincidida con la regla "Tráfico Empresarial"):
├─ Servidores DNS: DE LA REGLA (192.168.1.10, 192.168.1.11)
├─ P-CSCF: DE GLOBAL (no sobrescrito en la regla)
└─ MTU: DE LA REGLA (1500)

Sesión Predeterminada (sin regla coincidente):
├─ Servidores DNS: DE GLOBAL
├─ P-CSCF: DE GLOBAL o DNS si el descubrimiento global está habilitado
└─ MTU: DE GLOBAL

Campos de Sobrescritura de PCO Disponibles:

  • primary_dns_server_address - Dirección IP del servidor DNS primario
  • secondary_dns_server_address - Dirección IP del servidor DNS secundario
  • primary_nbns_server_address - Dirección IP del servidor WINS primario
  • secondary_nbns_server_address - Dirección IP del servidor WINS secundario
  • p_cscf_ipv4_address_list - Lista de direcciones IP de servidores P-CSCF (para IMS) - Ver Configuración de PCO y Monitoreo de P-CSCF para descubrimiento dinámico de P-CSCF
  • ipv4_link_mtu_size - Tamaño de MTU en bytes

Descubrimiento de P-CSCF por Regla:

Además de las sobrescrituras de PCO, las reglas de selección de UPF pueden especificar el descubrimiento dinámico de P-CSCF:

  • p_cscf_discovery_fqdn - (Cadena) FQDN para descubrimiento de P-CSCF basado en DNS (por ejemplo, "pcscf.mnc380.mcc313.3gppnetwork.org")

Cuando se establece este parámetro:

  1. PGW-C realiza una búsqueda DNS para el FQDN especificado durante el establecimiento de la sesión
  2. El servidor DNS devuelve una lista de direcciones IP de P-CSCF
  3. Las direcciones P-CSCF descubiertas se envían a UE a través de PCO
  4. Si la búsqueda DNS falla, se recurre a p_cscf_ipv4_address_list de la sobrescritura de PCO (si se especifica) o a la configuración global de PCO
  5. Ver Monitoreo de P-CSCF para tasas de éxito/fallo de descubrimiento

Esto es particularmente útil para:

  • APNs IMS - Diferentes redes IMS con diferentes servidores P-CSCF
  • Despliegues multi-inquilino - Diferentes empresas con infraestructura dedicada de P-CSCF
  • Enrutamiento geográfico - DNS devuelve el P-CSCF más cercano según la ubicación de UE
  • Alta disponibilidad - DNS devuelve automáticamente solo servidores P-CSCF saludables

Ejemplo: Tráfico IMS con P-CSCF Personalizado:

rules: [
%{
name: "Tráfico IMS",
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}
],
# Descubrimiento de P-CSCF: Consultar dinámicamente DNS para direcciones de P-CSCF
# La búsqueda DNS devuelve las IPs actuales de P-CSCF basadas en este FQDN
p_cscf_discovery_fqdn: "pcscf.mnc380.mcc313.3gppnetwork.org",
# Las sesiones IMS obtienen servidores P-CSCF personalizados (usados como respaldo si DNS falla)
pco: %{
p_cscf_ipv4_address_list: ["10.101.2.100", "10.101.2.101"]
# DNS, NBNS, MTU usarán valores predeterminados de la configuración principal de pco
}
}
]

Ejemplo: Tráfico Empresarial con DNS Personalizado:

rules: [
%{
name: "Tráfico Empresarial",
priority: 15,
match_field: :apn,
match_regex: "^(enterprise|corporate)\.apn",
upf_pool: [
%{remote_ip_address: "10.100.3.21", remote_port: 8805, weight: 100}
],
# Las sesiones empresariales obtienen DNS corporativo y MTU personalizado
pco: %{
primary_dns_server_address: "192.168.1.10",
secondary_dns_server_address: "192.168.1.11",
ipv4_link_mtu_size: 1500
# P-CSCF, NBNS usarán valores predeterminados de la configuración principal de pco
}
}
]

Ejemplo: Sobrescritura Completa (Todos los Campos de PCO):

rules: [
%{
name: "APN IoT - Totalmente Personalizado",
priority: 10,
match_field: :apn,
match_regex: "^iot\.m2m",
upf_pool: [
%{remote_ip_address: "10.100.5.21", remote_port: 8805, weight: 100}
],
# Las sesiones IoT obtienen PCO completamente personalizado
pco: %{
primary_dns_server_address: "8.8.8.8",
secondary_dns_server_address: "8.8.4.4",
primary_nbns_server_address: "10.0.0.100",
secondary_nbns_server_address: "10.0.0.101",
p_cscf_ipv4_address_list: [], # Sin P-CSCF para IoT
ipv4_link_mtu_size: 1280 # MTU más pequeño para dispositivos restringidos
}
}
]

Casos de Uso:

  • IMS/VoLTE: Proporcionar servidores P-CSCF específicos de operador para servicios de voz
  • APNs Empresariales: Enrutar tráfico corporativo a través de servidores DNS de la empresa
  • IoT/M2M: Usar DNS público y MTU optimizado para dispositivos de bajo ancho de banda
  • Itinerancia: Proporcionar servidores DNS locales para suscriptores visitantes
  • Diferenciación de Servicios: Diferentes parámetros de red por tipo de servicio

Selección de UPF Basada en DNS:

Habilitar la selección dinámica de UPF basada en la Información de Ubicación del Usuario (ULI) utilizando consultas NAPTR de DNS. Las configuraciones DNS ahora se configuran dentro de la sección upf_selection.

Nota: Esto proporciona selección de UPF basada en geografía o topología. Ver Interfaz PFCP para configuración de asociación PFCP con UPFs descubiertos dinámicamente y Gestión de Sesiones para flujos de establecimiento de sesiones.

upf_selection: %{
# Habilitar selección basada en DNS
dns_enabled: true,

# Tipos de ubicación para consultar en orden de prioridad
dns_query_priority: [:ecgi, :tai, :rai, :sai, :cgi],

# Sufijo DNS para consultas NAPTR 3GPP
dns_suffix: "epc.3gppnetwork.org",

# Tiempo de espera de consulta DNS en milisegundos
dns_timeout_ms: 5000,

# ... reglas y fallback_pool ...
}

La selección basada en DNS funciona de la siguiente manera:

  1. Prioridad: La selección DNS se utiliza solo cuando NO coinciden reglas estáticas (menor prioridad)
  2. Generación de Consulta: Construye consultas NAPTR de DNS basadas en la ubicación de UE:
    • Consulta ECGI: eci-<hex>.ecgi.epc.mnc&lt;MNC>.mcc&lt;MCC>.epc.3gppnetwork.org
    • Consulta TAI: tac-lb<hex>.tac-hb<hex>.tac.epc.mnc&lt;MNC>.mcc&lt;MCC>.epc.3gppnetwork.org
    • Las consultas RAI, SAI, CGI siguen un formato similar a 3GPP TS 23.003
  3. Jerarquía de Respaldo: Intenta cada tipo de ubicación en orden de prioridad hasta que se encuentre una coincidencia
  4. Coincidencia de Pares: Los resultados de DNS se filtran contra la lista de pares configurados
  5. Selección: Elige el par coincidente (actualmente la primera coincidencia, la selección basada en carga vendrá pronto)

Ejemplo de Registros DNS (configurar en su servidor DNS):

; Registro NAPTR para TAC 100 en PLMN 313-380
tac-lb64.tac-hb00.tac.epc.mnc380.mcc313.epc.3gppnetwork.org IN NAPTR 10 50 "a" "x-3gpp-upf:x-sxb" "" upf-edge-1.example.com.

; Registro A para el UPF
upf-edge-1.example.com IN A 10.100.1.21

Casos de Uso:

  • Computación en el Borde (MEC): Enrutar sesiones a los UPFs de borde más cercanos geográficamente
  • Descubrimiento Dinámico de UPF: Agregar/quitar UPFs de su red sin reconfigurar PGW-C
  • Balanceo de Carga: Distribuir carga entre UPFs según la ubicación
  • Segmentación de Red: Enrutar diferentes segmentos a diferentes UPFs por ubicación

Monitoreo de Salud de UPF

Selección Consciente de Salud Automática: El PGW-C monitorea continuamente la salud de todos los UPFs y excluye automáticamente los UPFs no saludables de la selección.

Criterios de Verificación de Salud

Un UPF se considera saludable cuando se cumplen TODAS las siguientes condiciones:

  1. Asociación PFCP Activa: El UPF tiene una asociación PFCP establecida
  2. Responsividad de Latido: Menos de 3 latidos consecutivos perdidos
  3. Proceso Vivo: El proceso de GenServer del par UPF está en ejecución

Un UPF se considera no saludable si CUALQUIERA de las siguientes es verdadera:

  • La asociación PFCP no está establecida (associated: false)
  • 3 o más tiempos de espera de latidos consecutivos
  • El proceso de par UPF ha fallado o no responde

Mecanismo de Monitoreo

Para UPFs Configurados (en upf_selection):

  • El seguimiento de salud comienza inmediatamente al arrancar
  • La asociación PFCP se monitorea continuamente
  • Los latidos se envían cada 5 segundos
  • El contador missed_heartbeats_consecutive rastrea fallos consecutivos
  • Todos los UPFs de las reglas y el pool de respaldo se registran automáticamente

Para UPFs Descubiertos por DNS (registro dinámico):

  • Se asume que son saludables hasta el primer intento de sesión
  • Se registran automáticamente en el primer uso
  • El seguimiento de salud comienza después del registro

Comportamiento de Selección

Modo Activo/Standby (cuando se usa weight: 0):

  1. Filtrar solo UPFs saludables
  2. Separar en activos (peso > 0) y standby (peso == 0)
  3. Usar UPFs activos si alguno es saludable
  4. Activar UPFs de standby (tratar como peso 1) si todos los activos son no saludables
  5. Recurre al pool completo si no existen UPFs saludables

Modo Balanceado por Carga (todos los pesos > 0):

  1. Filtrar solo UPFs saludables
  2. Realizar selección aleatoria ponderada entre UPFs saludables
  3. Recurre al pool completo si no existen UPFs saludables

Registro:

[debug] Usando pool de UPF activo (2/3 UPFs saludables, 1 standby)
[info] Todos los UPFs activos caídos, activando UPFs de standby (1 UPFs de standby, tratando peso 0 como 1)
[warning] No hay UPFs saludables en el pool (3 en total), usando pool completo como respaldo

Verificando la Salud de UPF

Programáticamente:

# Verificar si un UPF específico es saludable
iex> PGW_C.PFCP_Node.is_peer_healthy?({10, 100, 1, 21})
true

# Obtener información detallada de salud
iex> PGW_C.PFCP_Node.get_peer_health({10, 100, 1, 21})
%{
associated: true,
missed_heartbeats: 0,
healthy: true,
registered: true
}

A través de la Interfaz Web:

  • Navegar a /upf_selection en el panel de control
  • Ver el estado de salud en tiempo real para todos los UPFs en cada pool
  • Insignias de estado: ✅ Activo-UP, ⏸️ Standby-Listo, ❌ Activo-CAÍDO, 🟡 No Asociado
  • Insignias de rol: ACTIVO (peso > 0), STANDBY (peso == 0), DINÁMICO (descubierto por DNS, no en config)
  • Contador de fallos de latido mostrado para UPFs asociados

Mejores Prácticas de Monitoreo de Salud

  1. Configurar UPFs en upf_selection: Todos los UPFs en reglas y pools de respaldo se monitorean automáticamente

    upf_selection: %{
    rules: [
    %{
    name: "Tráfico de Internet",
    priority: 10,
    match_field: :apn,
    match_regex: "^internet",
    upf_pool: [
    %{remote_ip_address: "10.100.1.21", remote_port: 8805, weight: 100}
    ]
    }
    ],
    fallback_pool: [
    %{remote_ip_address: "10.100.2.21", remote_port: 8805, weight: 100}
    ]
    }
    # Todos los UPFs automáticamente obtienen:
    # - Latidos de 5 segundos
    # - Monitoreo de salud desde el inicio
    # - Nombres generados automáticamente
  2. Usar UPFs de standby: Configurar standby calientes con weight: 0 para failover automático

    upf_pool: [
    %{remote_ip_address: "10.1.1.1", remote_port: