Debian 13 LACP Bonding: demostrar si la culpa es del switch o del host

¿Te fue útil?

Cuando un bond LACP hace flapping, no falla de forma estridente. Falla como un comité: de forma intermitente, con plausible negación y siempre durante la hora punta. Un minuto tienes un agregado 2×25G sano; al siguiente tu tráfico de almacenamiento queda en un único enlace, TCP retransmite y aparece la frase preferida en el chat: “Debe ser la red”.

Esta es una guía de campo para operadores con Debian 13 que necesitan hacer algo más raro que depurar: probar. Probar si el host se está comportando mal, si el switch está mal configurado o si la capa física está convirtiendo tu LACP en danza interpretativa.

Playbook de diagnóstico rápido

Si solo tienes 15 minutos antes de que alguien sugiera reiniciar el core, haz esto en orden. El objetivo es separar “problema de negociación LACP” de “problema de carrier/PHY” o “la pila de red del host hizo algo raro”.

1) Confirma si es flapping del carrier o del estado LACP

Carrier down/up apunta a óptica/cable/ASIC/driver/firmware. Cambios de estado LACP con carrier estable apuntan a desajuste de configuración, timers, problemas MLAG/stack o pérdida de LACPDU.

cr0x@server:~$ ip -br link show
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eno1             UP             3c:fd:fe:aa:bb:01 <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP>
eno2             UP             3c:fd:fe:aa:bb:02 <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP>
bond0            UP             3c:fd:fe:aa:bb:ff <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP>

Qué significa: Si un esclavo muestra DOWN o carece de LOWER_UP durante la ventana de flap, estás persiguiendo físico/driver. Si los esclavos permanecen UP pero bond0 pierde miembros activos, estás persiguiendo negociación LACP o entrega de LACPDU.

Decisión: Si el carrier cae, salta a los contadores ethtool y a las comprobaciones de capa física. Si el carrier es estable, céntrate en LACPDU, timers y consistencia del switch.

2) Extrae el estado del driver de bonding e indicadores de “último churn”

cr0x@server:~$ cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v6.1.0

Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer3+4
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

802.3ad info
LACP rate: fast
Aggregator selection policy (ad_select): stable
Active Aggregator Info:
        Aggregator ID: 1
        Number of ports: 2
        Actor Key: 17
        Partner Key: 51
        Partner Mac Address: 00:11:22:33:44:55

Slave Interface: eno1
MII Status: up
Speed: 25000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 3c:fd:fe:aa:bb:01
Actor Churn State: churned
Partner Churn State: churned
Actor Churned Count: 3
Partner Churned Count: 3
details actor lacp pdu:
    system priority: 65535
    system mac address: 3c:fd:fe:aa:bb:ff
    port key: 17
    port priority: 255
    port number: 1
details partner lacp pdu:
    system priority: 32768
    system mac address: 00:11:22:33:44:55
    oper key: 51
    port priority: 128
    port number: 49

Slave Interface: eno2
MII Status: up
Speed: 25000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 3c:fd:fe:aa:bb:02
Actor Churn State: churned
Partner Churn State: churned
Actor Churned Count: 3
Partner Churned Count: 3

Qué significa: “Churned” y contadores de churn que aumentan son tu pista principal sobre inestabilidad de negociación LACP o pérdida de LACPDU. Link Failure Count en aumento apunta más a físico/driver. Partner MAC, keys y números de puerto son la identidad del otro lado según la ve el host.

Decisión: Si los contadores de churn aumentan mientras MII permanece up, exige logs del switch y verifica la entrega de LACPDU vía captura.

3) Revisa logs del kernel por resets de NIC, problemas PCIe o eventos de carrier

cr0x@server:~$ journalctl -k -S -30min | egrep -i 'bond0|eno1|eno2|lacp|link up|link down|reset|timeout|tx hang|firmware'
[...]
kernel: bond0: (slave eno1): Enslaving as an active interface with a down link.
kernel: eno1: Link is Down
kernel: eno1: Link is Up - 25Gbps/Full - flow control rx/tx
kernel: bond0: (slave eno1): link status definitely up, 25000 Mbps full duplex
kernel: bond0: (slave eno1): Actor Churn State is churned

Qué significa: El kernel te delatará con gusto. “Link is Down/Up” = carrier. “TX hang/reset/firmware” = lado host. Churn sin link down sugiere desajuste LACP o pérdida de LACPDU.

Decisión: Si ves resets/timeouts, deja de discutir sobre la configuración del switch y empieza a mirar driver/firmware y salud PCIe.

4) Obtén contadores de error en las NIC esclavas

cr0x@server:~$ ethtool -S eno1 | egrep -i 'err|drop|crc|fcs|miss|timeout|reset|align|symbol|disc|over'
rx_crc_errors: 0
rx_fcs_errors: 0
rx_missed_errors: 0
rx_discards: 12
tx_errors: 0
tx_timeout_count: 0

Qué significa: Errores CRC/FCS/símbolo apuntan con fuerza al físico (ópticas, cable, fibra sucia, DAC marginal). Los descartes pueden ser congestión, buffers o comportamiento del switch.

Decisión: Si CRC/FCS aumenta durante los flaps, trata la ruta física como culpable hasta probar lo contrario.

5) Si aún no está claro, captura LACPDUs durante 60 segundos mientras ocurre el problema

Lo explicaré más adelante, pero es la forma más rápida de mostrar “el host envió LACPDU; el switch no respondió” (o viceversa).

Qué significa realmente “flapping LACP”

En Linux bonding modo 802.3ad, “flapping” suele significar que el bond cambia repetidamente qué interfaces esclavas están collect/distribute (colección/distribución). Eso puede ocurrir mientras los enlaces físicos permanecen up. También puede suceder porque los enlaces físicos caen realmente, en cuyo caso LACP solo es el mensajero recibiendo los disparos.

Operativamente verás:

  • Un esclavo repetidamente removido/añadido al agregador activo.
  • MAC de partner o Partner Key cambiando inesperadamente (a menudo por rarezas MLAG/stack).
  • Throughput en sierra, picos de latencia en almacenamiento, retransmisiones TCP y “¿por qué se fue la mitad de mi capacidad?”.

LACP tiene timers. LACP tiene máquinas de estado. LACP también tiene la costumbre de revelar cada inconsistencia que no sabías que existía en tu red. El truco es recopilar evidencia que sobreviva al debate entre equipos: logs, contadores y tramas en la red.

Datos interesantes y contexto (breve y concreto)

  1. LACP está estandarizado como IEEE 802.1AX; documentos antiguos y muchas herramientas aún lo citan como IEEE 802.3ad, que se integró en 802.1AX.
  2. La tasa “fast” de LACP es aproximadamente 1 segundo entre LACPDU; “slow” ronda los 30 segundos. “Fast” detecta problemas más rápido—y amplifica problemas de pérdida de paquetes con más rapidez también.
  3. El bonding de Linux precede la cultura moderna de “pila de red como código”; /proc/net/bonding sigue siendo uno de los archivos de diagnóstico más útiles en el sistema.
  4. Muchos switches tratan LACP como tráfico de plano de control con reglas de colas distintas a las de datos; la congestión o el policing pueden descartar LACPDUs mientras los datos “funcionan bastante bien”.
  5. Las implementaciones MLAG (multi-chassis LAG) difieren ampliamente; algunas manejan identidad de partner y keying de formas que confunden a los hosts durante failovers si la configuración no es perfectamente simétrica.
  6. La política de hash de transmisión importa más de lo que se admite; “layer2” puede fijar flujos de forma extraña en entornos virtualizados, mientras que “layer3+4” puede romper expectativas con NAT o enrutamiento asimétrico.
  7. La agregación de enlaces no suma ancho de banda para un solo flujo TCP a menos que hagas algo especial; la mayoría depende del hashing por flujo.
  8. Carrier up no garantiza una capa física limpia; puedes tener enlace estable con CRC intermitentes que desencadenan churn y retransmisiones de capas superiores.
  9. Algunas offloads de NIC han interactuado mal con bonding históricamente (especialmente con offload de VLAN y ciertas versiones de drivers); el modo de fallo parece “la red es inestable”.

Evidencia del lado del host: comprobaciones en Debian 13 que resisten un postmortem

Debian 13 te da un kernel moderno, systemd y la caja de herramientas Linux habitual. Úsalos como si estuvieras construyendo un expediente, no como si jugaras al whack-a-mole.

Actividad 1: Identifica quién configura el bond (systemd-networkd vs ifupdown)

cr0x@server:~$ systemctl is-active systemd-networkd
inactive
cr0x@server:~$ dpkg -l | egrep 'ifupdown|network-manager|systemd-networkd'
ii  ifupdown  0.8.41  amd64  high level tools to configure network interfaces

Qué significa: Necesitas conocer el plano de control. Si dos gestores pelean, obtendrás “flaps” que son en realidad eventos de reconfiguración.

Decisión: Si más de uno está activo, elige uno y desactiva los demás antes de hacer cualquier otra cosa. Depurar un objetivo móvil es un hobby, no una práctica SRE.

Actividad 2: Muestra la configuración en ejecución del bond desde la vista del kernel

cr0x@server:~$ grep -H . /sys/class/net/bond0/bonding/*
/sys/class/net/bond0/bonding/mode: 802.3ad 4
/sys/class/net/bond0/bonding/lacp_rate: 1
/sys/class/net/bond0/bonding/miimon: 100
/sys/class/net/bond0/bonding/xmit_hash_policy: layer3+4 1
/sys/class/net/bond0/bonding/ad_select: stable 1
/sys/class/net/bond0/bonding/min_links: 1

Qué significa: Esta es la verdad como la aplica el kernel, no lo que dice tu archivo de configuración. lacp_rate “1” es fast.

Decisión: Si miimon es 0 y confías en la detección de carrier del driver, lo estás dejando en manos de las notificaciones del driver. Puede estar bien, pero al menos sé explícito.

Actividad 3: Verifica esclavos y busca coincidencias accidentales VLAN-en-esclavo vs VLAN-en-bond

cr0x@server:~$ ip -d link show bond0
5: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 3c:fd:fe:aa:bb:ff brd ff:ff:ff:ff:ff:ff
    bond mode 802.3ad miimon 100 updelay 0 downdelay 0 lacp_rate 1 ad_select stable xmit_hash_policy layer3+4
cr0x@server:~$ ip -br link show master bond0
eno1             UP             3c:fd:fe:aa:bb:01 <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP>
eno2             UP             3c:fd:fe:aa:bb:02 <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP>

Qué significa: Quieres VLANs encima de bond0, no individualmente en los esclavos (a menos que tengas un diseño específico y la configuración del switch coincida). “ip -d” muestra parámetros del bond y MTU.

Decisión: Si MTU difiere entre esclavos o con el switch, puede que no veas “flaps”, pero sí síntomas parecidos. Arregla la consistencia de MTU temprano.

Actividad 4: Observa el estado del bond en vivo mientras ocurre el flap

cr0x@server:~$ watch -n 1 'grep -E "MII Status|Slave Interface|Aggregator ID|Churn|Link Failure" -n /proc/net/bonding/bond0'
Every 1.0s: grep -E "MII Status|Slave Interface|Aggregator ID|Churn|Link Failure" -n /proc/net/bonding/bond0
5:MII Status: up
18:Active Aggregator Info:
19:        Aggregator ID: 1
20:        Number of ports: 2
34:Slave Interface: eno1
35:MII Status: up
39:Link Failure Count: 0
45:Actor Churn State: churned
46:Partner Churn State: churned
64:Slave Interface: eno2
65:MII Status: up
69:Link Failure Count: 0
75:Actor Churn State: churned
76:Partner Churn State: churned

Qué significa: Buscas transiciones de churn, cambios en el número de puertos y fallos de enlace. Si el número de puertos baja a 1 sin un link-down, LACP es el culpable.

Decisión: Si el bond está estable pero la aplicación tiene problemas, deja de culpar a LACP y empieza a medir pérdida de paquetes y latencia.

Actividad 5: Confirma velocidad/duplex/autoneg de la NIC y busca flapping allí

cr0x@server:~$ ethtool eno1 | egrep -i 'Speed|Duplex|Auto-negotiation|Link detected'
Speed: 25000Mb/s
Duplex: Full
Auto-negotiation: on
Link detected: yes

Qué significa: Cambios inesperados de velocidad, autoneg off en un lado o link detected que se alterna apuntan a físico o desajuste de configuración.

Decisión: Si autoneg está desajustado con el switch, arréglalo antes de discutir timers LACP. LACP no puede negociar sobre un enlace que está discutiendo la física.

Actividad 6: Revisa CRC/FEC/PCS (indicadores de culpabilidad física)

cr0x@server:~$ ethtool --phy-statistics eno1 2>/dev/null | head
PHY statistics for eno1:
Symbol Error During Carrier: 0
Receive Error Count: 0
cr0x@server:~$ ethtool -S eno1 | egrep -i 'crc|fcs|symbol|fec|align|jabber|code|pcs' | head -n 20
rx_crc_errors: 0
rx_fcs_errors: 0

Qué significa: No todos los drivers exponen estadísticas PHY. Pero si ves CRC/symbol/FEC corrigiéndose y aumentando, encontraste un problema físico que puede presentarse como inestabilidad LACP.

Decisión: Si hay errores físicos, sustituye/limpia/recablea primero. Optimizar software sobre una fibra defectuosa es como afinar una base de datos que corre en un disco moribundo.

Broma 1: LACP es un protocolo de relaciones: es estable hasta que alguien deja de comunicarse por un segundo, entonces “necesita hablar”.

Actividad 7: Detecta versión de driver/firmware de la NIC y busca combinaciones conocidas malas en tu parque

cr0x@server:~$ ethtool -i eno1
driver: ice
version: 6.1.0
firmware-version: 4.20 0x8001a3d5
bus-info: 0000:5e:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes

Qué significa: Driver y firmware importan. Mucho. Mantén una pequeña matriz interna de versiones “conocidas buenas” para tu hardware.

Decisión: Si este host es un caso aislado frente al resto del parque (firmware diferente), trátalo como sospechoso. La estandarización es aburrida; lo aburrido es fiable.

Actividad 8: Revisa balance IRQ, ring buffers y paquetes descartados (la starvation del plano de control puede perder LACPDUs)

cr0x@server:~$ nstat -az | egrep -i 'TcpRetransSegs|IpInDiscards|IpInDelivers|UdpInErrors'
TcpRetransSegs            1823               0.0
IpInDiscards              47                 0.0
UdpInErrors               0                  0.0
cr0x@server:~$ ip -s link show eno1 | sed -n '1,6p'
2: eno1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc mq master bond0 state UP mode DEFAULT group default qlen 1000
    link/ether 3c:fd:fe:aa:bb:01 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
    9876543210 1234567 0      14      0       0
    TX:  bytes packets errors dropped carrier collsns
    1234567890 234567  0      0       0       0

Qué significa: Los paquetes RX descartados en la NIC pueden incluir LACPDUs si las cosas están muy mal. Normalmente los LACPDUs son pequeños y raros, pero la starvation ocurre en sistemas sobrecargados.

Decisión: Si el host descarta paquetes mientras la CPU está al máximo o los IRQs están mal asignados, arregla el rendimiento del host primero—especialmente en nodos de almacenamiento con checksum/crypto/compresión intensiva.

Actividad 9: Confirma que la MAC multicast LACP no esté filtrada

Los LACPDUs usan la dirección multicast de slow protocols (01:80:c2:00:00:02). Si tu NIC, bridge o switch la filtra inesperadamente, LACP falla de maneras interesantes.

cr0x@server:~$ ip maddr show dev eno1
2:	eno1
	link  01:00:5e:00:00:01
	link  33:33:00:00:00:01
	link  01:80:c2:00:00:02
	link  33:33:ff:aa:bb:01

Qué significa: Ver 01:80:c2:00:00:02 es un signo tranquilizador. La ausencia no siempre es fatal (algunos drivers no lo muestran bien), pero si falta y las cosas hacen flap, es una pista.

Decisión: Si hay filtrado multicast o características de seguridad especiales activadas (en host o switch), valida explícitamente que permitan tramas de slow-protocols.

Actividad 10: Valida que ambos esclavos tengan ajustes L2 idénticos (MTU, offloads, filtrado VLAN)

cr0x@server:~$ for i in eno1 eno2; do echo "== $i =="; ip -d link show $i | egrep -i 'mtu|vf|vlan|state'; ethtool -k $i | egrep -i 'rx-vlan|tx-vlan|gro|gso|tso' | head -n 12; done
== eno1 ==
2: eno1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc mq master bond0 state UP mode DEFAULT group default qlen 1000
rx-vlan-offload: on
tx-vlan-offload: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
== eno2 ==
3: eno2: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 qdisc mq master bond0 state UP mode DEFAULT group default qlen 1000
rx-vlan-offload: on
tx-vlan-offload: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on

Qué significa: La asimetría es un villano recurrente. Si las offloads difieren, o MTU difiere, tu bond puede comportarse “bien” pero descartar control o datos de forma intermitente bajo carga.

Decisión: Haz que los esclavos sean lo más idénticos posible. Si debes cambiar offloads, cámbialos en ambos y documenta por qué.

Actividad 11: Verifica que STP/bridge no esté comiendo tramas de slow-protocol

Si bond0 forma parte de un bridge (común en hosts de virtualización), revisa configuraciones de filtrado que interactúen con LACP o estado de enlace.

cr0x@server:~$ bridge link show
2: eno1 state UP : <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> master bond0
3: eno2 state UP : <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> master bond0
cr0x@server:~$ bridge -d vlan show | head
port              vlan-id
bond0             10 PVID Egress Untagged
bond0             20

Qué significa: Bridging está bien; confundir bridging con configuración VLAN por puerto no lo está. Mantén tu modelo L2 simple cuando depures LACP.

Decisión: Si el host hace bridging complejo más bonding, simplifica temporalmente (ventana de mantenimiento) para aislar si el propio bond es inestable.

Actividad 12: Ejecuta una prueba de degradación controlada (demuestra que el bond reacciona correctamente)

Así demuestras el comportamiento del host a un equipo de red escéptico: muestra reacciones deterministas a un evento de enlace forzado.

cr0x@server:~$ sudo ip link set dev eno2 down
cr0x@server:~$ cat /proc/net/bonding/bond0 | egrep -A3 'Active Aggregator Info|Number of ports|Slave Interface|MII Status' | head -n 20
Active Aggregator Info:
        Aggregator ID: 1
        Number of ports: 1
Slave Interface: eno1
MII Status: up
Slave Interface: eno2
MII Status: down
cr0x@server:~$ sudo ip link set dev eno2 up

Qué significa: Compruebas que el host elimina/añade limpiamente un esclavo y vuelve a 2 puertos sin tormentas de churn.

Decisión: Si esta prueba controlada genera churn o tarda mucho en reunirse, puede que tengas problemas de configuración en el host (ad_select, lacp_rate desajustado o problemas de temporización).

Evidencia del lado del switch: qué exigir al equipo de redes

Puede que no tengas acceso CLI al switch. Bien. Aun así necesitas hechos del switch, no impresiones. Pide salidas específicas y exige que cubran ambos puertos miembro y la interfaz port-channel.

Esto es lo que quieres, independientemente del proveedor:

  • Estado del port-channel: up/down, miembros agrupados o suspendidos, códigos de motivo.
  • Detalles partner LACP: actor/partner system ID (MAC), keys, números de puerto.
  • Contadores de interfaz: CRC/FCS, errores de símbolo, descartes, frames de pause, transiciones de enlace.
  • Controles de consistencia: lista VLAN, MTU, velocidad/duplex, modo LACP (active/passive), tasa LACP.
  • Estado MLAG/stack si aplica: salud del peer link, consistencia, puertos huérfanos.

Y los quieres correlacionados en el tiempo con las marcas temporales de churn del host.

Qué evidencia del switch implica concluyentemente al switch

  • El switch reporta ID de partner LACP cambiando de un lado a otro mientras la MAC del sistema del host es estable.
  • El switch suspende un miembro por “LACP timeout” pero la captura del host muestra que este transmitía LACPDUs según lo esperado.
  • El switch muestra CRC/FCS en aumento en su contador de puerto mientras el host no lo hace (o viceversa), acotando el segmento malo.
  • Problemas de peer-link MLAG coinciden con los flaps y los logs del switch muestran eventos de renegociación.

Qué evidencia del switch implica al host

  • El switch detecta huecos de LACPDU desde el host (no recibe PDUs) mientras el host está sobrecargado o sufre resets de NIC.
  • El switch reporta que el host envía keys o IDs de puerto inconsistentes entre miembros (a menudo por misbonding, SR-IOV/VF o deriva de configuración).
  • Los logs del switch muestran eventos link down/up que coinciden con los logs del kernel del host y apuntan a óptica/cable.

Captura de paquetes: los LACPDU no mienten (mucho)

Si quieres pruebas que sobrevivan a una revisión de cambios, captura el tráfico de control. Los LACPDUs son tramas Ethernet (EtherType 0x8809) enviadas a 01:80:c2:00:00:02. No son IP. No aparecerán en tus filtros tcpdump a menos que los pidas explícitamente.

Actividad 13: Captura LACPDUs en cada esclavo y en bond0 (y compara)

Haz esto durante una ventana de flap. Captura en los esclavos, porque bond0 puede no ver cada trama como esperas.

cr0x@server:~$ sudo timeout 60 tcpdump -i eno1 -e -vvv -s 0 ether proto 0x8809
tcpdump: listening on eno1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:01:10.123456 00:11:22:33:44:55 > 01:80:c2:00:00:02, ethertype Slow Protocols (0x8809), length 124: LACPv1, length 110
	Actor System 3c:fd:fe:aa:bb:ff, Actor Key 17, Port 1, State 0x3d
	Partner System 00:11:22:33:44:55, Partner Key 51, Port 49, State 0x3f
cr0x@server:~$ sudo timeout 60 tcpdump -i eno2 -e -vvv -s 0 ether proto 0x8809
tcpdump: listening on eno2, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:01:10.223456 00:11:22:33:44:55 > 01:80:c2:00:00:02, ethertype Slow Protocols (0x8809), length 124: LACPv1, length 110
	Actor System 3c:fd:fe:aa:bb:ff, Actor Key 17, Port 2, State 0x3d
	Partner System 00:11:22:33:44:55, Partner Key 51, Port 50, State 0x3f

Qué significa: Deberías ver LACPDUs regulares. Actor System debe coincidir con la MAC de tu bond; Partner System debe coincidir con el system ID LACP del switch. Los números de puerto deben ser estables. Si una interfaz deja de ver LACPDUs entrantes mientras la otra continúa, eso aísla el problema a una ruta física o a un puerto de switch.

Decisión: Si el host está enviando LACPDUs (también puedes capturar salientes) pero no recibe respuestas en una rama, el path switch/puerto/PHY es sospechoso.

Actividad 14: Demuestra que el host transmite LACPDUs (evidencia saliente)

Solo capturar entrantes puede ser engañoso si el switch es el único que habla. Captura direccional observando MACs de origen y temporización; tcpdump en Linux no siempre etiqueta la dirección de forma fiable en todos los drivers, pero las MAC sí.

cr0x@server:~$ sudo timeout 20 tcpdump -i eno1 -e -vv -s 0 ether proto 0x8809 | head
12:02:00.000001 3c:fd:fe:aa:bb:ff > 01:80:c2:00:00:02, ethertype Slow Protocols (0x8809), length 124: LACPv1, length 110
12:02:01.000113 3c:fd:fe:aa:bb:ff > 01:80:c2:00:00:02, ethertype Slow Protocols (0x8809), length 124: LACPv1, length 110

Qué significa: MAC de origen igual a la MAC del bond indica que el host está enviando. Temporización cercana a 1 segundo implica LACP fast.

Decisión: Si el host envía consistentemente pero el switch afirma “no recibí PDUs”, ahora tienes un conflicto objetivo que suele acabar con una captura en el puerto del switch o un deep-dive en contadores ASIC.

Actividad 15: Correlaciona la hora del flap con huecos en LACPDU

cr0x@server:~$ sudo timeout 30 tcpdump -tt -i eno1 -e -s 0 ether proto 0x8809 | awk '{print $1, $2, $3, $4, $5}'
1703851360.000001 3c:fd:fe:aa:bb:ff > 01:80:c2:00:00:02,
1703851361.000104 3c:fd:fe:aa:bb:ff > 01:80:c2:00:00:02,
1703851362.000095 3c:fd:fe:aa:bb:ff > 01:80:c2:00:00:02,

Qué significa: Buscas segundos faltantes. Si ves cadencia de 1 segundo y luego un silencio de varios segundos y el bond hace churn, tienes pérdida del plano de control (host o switch).

Decisión: Silencio con CPU/IRQ estables y sin descartes sugiere filtrado/policing del switch o un fallo físico no lo bastante largo para registrar link down.

Árbol de decisión: switch vs host vs físico

Caso A: Ves “Link is Down/Up” en los logs del host

Más probable: capa física o NIC/driver/firmware. LACP es posterior al estado de enlace.

Prueba:

  • Los timestamps del kernel muestran carrier down/up en un esclavo específico.
  • Contadores ethtool muestran CRC/FCS u otros errores en aumento.
  • Contadores del switch coinciden (transiciones de enlace, errores).

Acción: intercambia cable/DAC/óptica, limpia fibra, cambia a otro puerto del switch, actualiza firmware/driver de la NIC si es un culpable conocido.

Caso B: El carrier se mantiene up, pero cambia la membresía del bond y aumentan los churn

Más probable: inestabilidad de negociación LACP, desajuste o pérdida de tramas del plano de control.

Prueba:

  • /proc/net/bonding muestra estado churned con incrementos.
  • tcpdump muestra LACPDUs faltantes en una rama, o cambios de identidad del partner.
  • Logs del port-channel en el switch muestran miembros “suspendidos” con razones que coinciden con el churn.

Acción: valida modo LACP (active/active es el predeterminado sensato), timers (fast/fast), y simetría de configuración (VLAN/MTU/velocidad) en ambos puertos del switch y ambos esclavos del host.

Caso C: Todo parece estable, pero las apps sufren pérdida/latencia intermitente

Más probable: no es realmente LACP. Piensa en drops de buffer, ECN/storms de pause, desajuste de hashing o congestión upstream.

Prueba:

  • El bond nunca cambia membresía; no hay incrementos de churn; no hay fallos de enlace.
  • Los descartes de interfaz aumentan bajo carga.
  • nstat muestra retransmisiones en aumento mientras el enlace permanece up.

Acción: trátalo como ingeniería de rendimiento: colas, QoS, MTU, ECN, buffers del switch y política de hashing.

Cita (idea parafraseada), atribuida: advertencia de sabor fiabilidad de Richard Feynman: la realidad gana; no puedes negociar con las leyes de la naturaleza.

Tres mini-historias corporativas (anonimizadas)

Mini-historia 1: El incidente causado por una suposición equivocada

Tenían un par de nodos de almacenamiento Debian, cada uno con un bond LACP 2×10G hacia un par top-of-rack ejecutando MLAG. Todo parecía limpio: bonds “up”, port-channels “up” y el incidente empezó como la queja familiar: “las escrituras son espídicas”.

El on-call supuso que era un problema del almacenamiento porque los gráficos mostraban latencia IO. Persiguieron colas de disco, afinamientos de elevator e incluso limitaron un scrub en background. Nada cambió. El equipo de red insistía en que el port-channel estaba estable porque estaba “up/up”. Todos se sentían productivos y nadie tenía razón.

El avance vino de hacer lo aburrido: capturar LACPDUs en ambas interfaces del host. Una rama tenía cadencia limpia de 1 segundo; la otra mostraba ráfagas seguidas de huecos. El carrier nunca cayó. El host no “flappeaba” físicamente; estaba siendo intermitentemente privado de tráfico de control.

Los logs del switch (una vez solicitados con timestamps) mostraron que durante micro-bursts, la cola del plano de control del switch estaba siendo golpeada por una tormenta de otras tramas slow-protocol desde un dispositivo mal configurado downstream. Los LACPDUs no estaban priorizados como el equipo suponía. Habían asumido que “los protocolos de control siempre están protegidos”. En ese entorno, no lo estaban.

La solución no fue un ajuste del kernel. Fue aislar el dispositivo ruidoso y ajustar la política del switch para evitar la starvation de slow-protocols. La lección del postmortem fue contundente: “up/up” no es un SLA, y las suposiciones no son evidencia.

Mini-historia 2: La optimización que salió mal

Un clúster de virtualización quería failover más rápido. Alguien puso LACP en tasa fast en todas partes, bajó miimon a 50ms y ajustó otros timers porque “podemos detectar fallo más rápido”. Lo hicieron durante una renovación de red donde nuevos switches reemplazaron a los viejos, y las pruebas de laboratorio se vieron bien.

En producción, empezaron a ver caídas intermitentes de miembros del bond en hosts bajo carga alta de CPU. No de forma consistente. No en todos los hosts. Solo en los hypervisors más ocupados. Fue el peor tipo de fallo: el que parece un rumor hasta que es un evento de ingresos.

La causa raíz fue una reacción en cadena. LACP fast significaba PDUs más frecuentes. Miimon menor hacía que el bond reaccionara rápidamente a cualquier indicio de problema. Bajo saturación de CPU, un subconjunto de hosts a veces retrasaba el procesamiento de interrupts lo suficiente como para que la gestión efectiva de LACPDU superara la tolerancia de la máquina de estado del switch. Los enlaces estaban físicamente bien. La negociación no.

“Optimizaron” el failover y accidentalmente convirtieron la jitters de scheduling normales en un disparador de outage. Volver a slow rate (o dejar LACP fast pero arreglar afinidad de IRQ y reservar CPU para redes) eliminó los flaps. La solución real fue aislamiento de recursos: mantener el host lo bastante sano para que el tráfico de control se maneje de forma predecible.

Una de las pocas líneas útiles de la revisión: “La velocidad de failover es una característica hasta que se vuelve una sensibilidad.” Si vas rápido, mide jitter y pérdida, no solo throughput medio.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Una firma de servicios financieros ejecutaba Debian en bare metal para una canalización sensible a la latencia. Su red no era sofisticada, pero sí disciplinada. Cada versión de firmware de NIC se registraba. Cada port-channel tenía una plantilla estándar. Cada cambio tenía snapshots de contadores y estado partner LACP antes/después.

Una semana, un rack nuevo entró en servicio y de inmediato empezó a ver churn LACP en un subconjunto de servidores. El equipo de red sospechó de los servidores porque “el resto del tejido está bien”. El equipo de servidores sospechó de los switches porque “los servidores son idénticos”. Clásico.

Entonces la práctica aburrida dio frutos. Compararon el snapshot pre/post de un rack conocido bueno: partner system ID, partner key, member port IDs, contadores de error en baseline. En el rack nuevo, la partner key era distinta en un puerto miembro. Mismo port-channel ID, key operativo distinto. Eso no es “Linux siendo raro”. Eso es un error de consistencia de configuración en el switch.

El equipo de red encontró que un switch en el par MLAG tenía aplicada una plantilla antigua: lista VLAN y LACP key diferían, por lo que el switch alternaba entre agrupar y suspender según cuál peer era primario en ese momento. No fue lo bastante dramático para caer todo el port-channel—solo lo suficiente para churn bajo carga.

Arreglaron la configuración y los flaps pararon. Sin heroísmos. Sin adivinanzas. Solo snapshots baseline y exigencia de simetría. Lo aburrido no es falta de habilidad; es fruto de ella.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: Un esclavo se “suspende” repetidamente en el switch; el host muestra estado churned

Causa raíz: Mismatch de modo/timers LACP (active/passive, fast/slow) o key/VLAN/MTU inconsistente entre puertos miembro.

Solución: Haz simétrico en ambos lados. Usa LACP active en ambos extremos a menos que haya una razón de política para no hacerlo. Alinea lacp_rate. Verifica VLAN/MTU/velocidad idénticas en ambos puertos del switch del bundle.

2) Síntoma: El bond pierde un miembro sin mensajes “Link is Down”

Causa raíz: Pérdida de LACPDU, filtrado de slow-protocol o congestión del plano de control del switch. En MLAG, puede ser inestabilidad del peer-link causando cambios de identidad del partner.

Solución: Captura LACPDUs en ambos esclavos; exige logs del switch con códigos de motivo. Valida salud MLAG/stack y manejo de slow-protocols.

3) Síntoma: Logs del kernel muestran resets de NIC, timeouts o TX hangs durante flaps

Causa raíz: Problema en driver/firmware del host, errores PCIe o rarezas de gestión de energía.

Solución: Actualiza firmware de NIC a tu baseline conocida buena, revisa logs PCIe AER, desactiva ahorro de energía problemático y valida ajustes BIOS para PCIe ASPM si aplica.

4) Síntoma: Errores CRC/FCS aumentan en una interfaz; sigue churn LACP

Causa raíz: Cable/DAC/óptica defectuosa, fibra sucia, transceptor marginal o puerto malo.

Solución: Intercambia componentes físicos en orden controlado (cable primero, luego óptica, luego puerto). Registra qué cambio alteró los contadores. Si no mides, solo estás reorganizando la escena del crimen.

5) Síntoma: Throughput es la mitad de lo esperado, pero no hay flaps

Causa raíz: Desbalance de hashing (un flujo grande), xmit_hash_policy erróneo o distribución upstream que no coincide.

Solución: Confirma patrón de tráfico esperado. Usa hashing layer3+4 para servidores de propósito general. Para protocolos de almacenamiento, valida si empujas muchos flujos o pocos grandes.

6) Síntoma: Flaps solo ocurren durante picos de CPU

Causa raíz: El host no puede procesar tráfico de control con fiabilidad (desbalance IRQ, starvation de CPU, descartes), causando huecos de LACPDU y timeouts.

Solución: Arregla aislamiento de recursos del host: pin IRQs, asegura política irqbalance sensata, incrementa ring buffers si hace falta y evita “optimizaciones” de timers que reducen la tolerancia.

Broma 2: Un port-channel es como una fusión corporativa: si ambas partes no acuerdan el papeleo, obtienes “sinergia” y outages.

Listas de verificación / plan paso a paso

Paso a paso: construye un “paquete de pruebas” para responsabilidad switch vs host

  1. Registra la ventana temporal: timestamps start/end en UTC. Si los equipos no coinciden en hora, no coincidirán en la realidad.
  2. Snapshot del host: captura /proc/net/bonding/bond0 antes, durante y después.
  3. Logs del host: journalctl -k alrededor de la ventana; grep por link y eventos de driver.
  4. Contadores del host: ethtool -S para cada esclavo; ip -s link para descartes.
  5. Verdad de configuración del host: /sys/class/net/bond0/bonding/* más ip -d link show.
  6. Captura LACPDU: 60 segundos en cada esclavo durante la ventana de flap.
  7. Petición al switch: solicita estado de port-channel, códigos de razón por miembro, partner ID/key y contadores por puerto para los mismos timestamps.
  8. Correlaciona: ¿coinciden los timestamps? ¿se comporta mal siempre la misma rama?
  9. Aísla: mueve un cable/óptica/puerto a la vez si sospechas físico; vuelve a probar.
  10. Decide y arregla: comprométete con una hipótesis y valida mediante cambio + medición.

Paso a paso: aislamiento físico sin empeorarlo

  1. Identifica la “rama mala” por churn/contadores/captura (eno1 vs eno2).
  2. Intercambia solo el cable/DAC en esa rama; no cambies ambos a la vez.
  3. Revisa contadores CRC/FCS baseline, luego tras 10 minutos bajo carga.
  4. Si sigue mal, cambia el transceptor, luego mueve el puerto del switch, luego a otra line card si es posible.
  5. Documenta cada cambio con contadores antes/después. Esto evita el folklore de “mejoró de alguna forma”.

Paso a paso: auditoría de simetría de configuración (host + switch)

  • Host: ambos esclavos misma MTU, mismas offloads, misma velocidad/duplex/autoneg, misma clase de driver/firmware.
  • Host: modo bond 802.3ad, ad_select estable, miimon sensato y lacp_rate que coincida con la expectativa del switch.
  • Switch: ambos puertos miembro misma lista VLAN, MTU, modo LACP, lacp_rate y dentro del mismo port-channel.
  • MLAG: ambos switches tienen configuración idéntica de port-channel y el peer-link está sano; no hay inconsistencias “huérfanas”.

Preguntas frecuentes

1) ¿Debian 13 es especial aquí, o esto es solo “cosas de bonding en Linux”?

Mayormente cosas de bonding en Linux. Debian 13 importa porque versiones de kernel/driver cambian comportamientos, y systemd-networkd vs ifupdown cambia cómo ocurre la deriva de configuración.

2) ¿Cuál es el archivo único mejor para mirar problemas LACP en el host?

/proc/net/bonding/bond0. Muestra churn, identidad del partner, keys, números de puerto y contador de fallos de enlace. Es lo más parecido a una grabadora negra.

3) Si el switch dice que el port-channel está up, ¿puede seguir roto?

Sí. “Up” puede significar “algún miembro está en bundled”. Aún puedes tener una rama suspendida, churning o con errores. Pide estado por miembro y razones.

4) ¿Debería usar LACP fast o slow?

Fast si puedes garantizar que el tráfico de control no se descarta y los hosts no están hambrientos; slow si quieres tolerancia. Si usas fast, mide jitter y pérdida, no solo el estado del enlace.

5) ¿Cómo pruebo que el host está enviando LACPDUs?

tcpdump en la interfaz esclava con EtherType 0x8809, comprobando que la MAC origen sea la del bond y que la cadencia coincida con lacp_rate.

6) ¿Cómo pruebo que el switch está enviando LACPDUs de vuelta?

Misma captura, pero busca tramas con origen en la MAC del sistema LACP del switch. Si ves salientes del host pero no entrantes en una rama, es una evidencia fuerte.

7) ¿Un cable malo puede causar flapping LACP sin eventos link down?

Sí. Puedes tener errores y micro-interrupciones que no bajan el carrier lo suficiente para registrar link down, pero sí interrumpen el intercambio de LACPDU y la calidad del tráfico.

8) ¿La política de hashing causa flapping?

No, la política de hashing normalmente causa extrañezas de rendimiento, no churn de negociación LACP. Pero las extrañezas de rendimiento suelen reportarse como “el bond está flappeando”. Verifica con /proc/net/bonding y contadores de churn.

9) ¿Qué pasa si solo un host en el rack flappea y los demás están bien?

Sospecha diferencias en firmware/driver del host, un puerto NIC malo o un cable/óptica defectuosa. Luego sospecha el puerto único del switch. Usa contadores y aislamiento de “rama mala”.

10) ¿Y si múltiples hosts flappean en el mismo par de switches al mismo tiempo?

Sospecha primero problemas del switch: peer-link MLAG, congestión del plano de control, plantilla aplicada mal o bug de software. Pide logs del switch para las mismas marcas temporales y compara comportamiento de partner/key.

Conclusión: próximos pasos prácticos

Cuando los bonds LACP hacen flapping, ganas siendo metódico, no siendo ruidoso. Empieza con la clasificación más simple: flapping de carrier vs churn LACP con carrier estable. Luego recopila los tres tipos de prueba que sobreviven al debate inter-equipos: logs del kernel, contadores y capturas de paquetes.

Próximos pasos que normalmente terminan la discusión:

  • Captura 60 segundos de LACPDUs en cada esclavo durante un flap.
  • Exporta /proc/net/bonding/bond0 antes/durante/después y correlaciona timestamps con los logs del switch.
  • Compara CRC/FCS y descartes en puertos del host y del switch para aislar el segmento malo.
  • Forza un link down/up controlado en un esclavo en ventana de mantenimiento para verificar que el host se comporta de forma determinista.
  • Si hay MLAG, exige evidencia de salud del peer-link y simetría de configuración, no meras garantías.

Haz eso, y dejarás de “depurar” y empezarás a probar. En producción, esa es la diferencia entre arreglar el problema y simplemente moverlo a la próxima semana.

← Anterior
Errores TLS del registro privado de Docker: corrige correctamente las cadenas de certificados
Siguiente →
Vigilancia de archivos en Docker falla en contenedores: arregla la recarga en caliente de forma fiable

Deja un comentario