Bucle de capa 2
En resumen: un bucle de capa 2 detrás de un puerto de un bridge de MikroTik
se ve en el log del kernel de Linux aunque el log de RouterOS y su monitor de
puertos sigan limpios, como aquí: received packet on <port> with own address as source address,
con las tramas reflejadas separadas 2,00–2,01 s, que es el
hello interval de STP. El puerto de esa línea es por donde entró la trama
reflejada, no siempre el puerto que el bucle ha dejado aislado, así que compara el
rx de cada puerto del bridge con su tx antes de desenchufar un cable. Aquí el
flujo bajó de 1,49 /s
a 0,03 /s tras actualizar el firmware de los puntos de
acceso de la malla, y una semana después el bucle volvió.
Un fallo real, no provocado. Se encontró por casualidad el 2026-09-12, mientras se medía otra cosa, en el RB5009UG+S+ de producción del propietario (RouterOS 7.24.2, kernel 5.6.3), y se diagnosticó y desapareció ese mismo día. Una semana después volvió. Durante toda su vida, el log de RouterOS y su monitor de puertos informaron de un equipo sano.
Los pasos 1 a 6 son el diagnóstico en el orden en que se hizo. Síguelos en el mismo orden en tu propio router.
Síntoma
Sección titulada «Síntoma»/snapshot traía un flujo constante de events — la fuente kmsg del agente —
a 1,49 /s:
[6] br0: port 2(eth1) entered blocking state[4] br0: received packet on eth1 with own address as source address (addr:00:00:5e:00:53:5d, vlan:0)[6] br0: port 2(eth1) entered learning stateLa dirección de la segunda línea es la del propio router: la MAC de
sfp-sfpplus1, volviendo a entrar en el bridge. Aquí aparece como
00:00:5e:00:53:5d, del bloque que la
RFC 9542 reserva
para documentación (sustituyó a la RFC 7042 en 2024); en tu equipo será la de tu
bridge, y así es como reconoces la línea.
1. Confirmar y contar
Sección titulada «1. Confirmar y contar»Cuenta sucesos por segundo en una ventana lo bastante larga como para ser estable. Una sola línea de log es una anécdota; una tasa es una medida, y te dice después si una corrección funcionó:
curl -s "http://172.30.10.2:9123/snapshot?seconds=120" \ | python3 -c 'import sys, json, collectionsrows=[json.loads(l) for l in sys.stdin if l.strip()]secs=sum(r["dt_ns"] for r in rows)/1e9ev=[e for r in rows for e in r.get("events",[])]print(f"{len(ev)/secs:.2f} events/s over {secs:.0f}s")c=collections.Counter(e["msg"].split("(")[0][:60] for e in ev)for k,v in c.most_common(): print(f" {v:5d} {k}")'?seconds= admite de 1 a 3600, y el agente solo puede devolver lo que su anillo
aún guarda — 60 s con el BUFFER_S por defecto. La longitud de la ventana sale
de sumar el dt_ns de cada muestra, no del número que pediste.
2. Leer los tiempos
Sección titulada «2. Leer los tiempos»Toma los intervalos entre apariciones consecutivas de un mismo mensaje:
# intervalos entre apariciones consecutivas de un mismo mensaje... | python3 -c 'import sys, jsonts=sorted(e["us"]/1e6 for l in sys.stdin if l.strip() for e in json.loads(l).get("events",[]) if "own address" in e["msg"])print([round(ts[i+1]-ts[i],2) for i in range(len(ts)-1)][:12])'us es la marca de tiempo del propio kernel para el registro, en microsegundos
desde el arranque sobre el reloj monótono, no el momento en que el agente lo
leyó, así que los intervalos son los del kernel, no los del muestreador.
Los intervalos entre las tramas reflejadas eran de 2,00–2,01 s, siempre. 2 s es el hello interval de STP, el HelloTime por defecto de RouterOS. Así que el router enviaba una BPDU y recibía de vuelta su propia BPDU: un bucle, no un cliente que se porta mal.
mikroscope doctor, ejecutado por sí solo, hace este recuento por ti
(internal/). Lee una vez el anillo del agente en
marcha e informa de:
WARN layer2-loop, con el puerto, cuando en la ventana han vuelto tres o más tramas con la propia dirección del bridge;stp-churnpara un puerto que STP ha pasado a learning al menos tres veces más de las que lo ha dejado reenviar, salvo que ese puerto tenga ya el hallazgo de dirección propia.
Dos reglas de alerta de internal/ vigilan el
mismo fallo a lo largo del tiempo:
mikroscope-l2-loopsalta con el primer registro de dirección propia, desde el log del kernel que lee el agente;mikroscope-bridge-port-darksalta con un puerto del bridge que lleva diez minutos recibiendo sin que el bridge le envíe nada. Necesita el tier de API.
Véase Comprobaciones de salud y Reglas de alerta.
3. Revisar la vista de RouterOS
Sección titulada «3. Revisar la vista de RouterOS»Revisa de forma explícita el log y el monitor de puertos de RouterOS; la respuesta decide dónde miras después:
/log/print where topics~"bridge" or topics~"stp" or topics~"interface"/interface/bridge/port/monitor [find] onceLas dos volvieron limpias: cero filas de log en esos temas, todos los puertos
designated-port / in-bridge. RouterOS no estaba ocultando el fallo; no
muestra esta clase de sucesos del kernel.
Eso vale para el log y el monitor de puertos, no para todos los contadores que
ofrece la API. Cuando el bucle volvió, del 2026-09-19 al 23, los contadores rx/tx
por puerto que lee el tier de API sí lo mostraron, como un puerto del bridge que
recibe mientras el bridge no le envía nada. Es la regla
mikroscope-bridge-port-dark, contrastada con esos cuatro días. No se comprobó contra el episodio del 2026-09-12.
La línea que habría traído el tema interface es la que se busca cuando uno se
topa con este fallo. RouterOS la ha escrito en su propio log, con los temas
interface,warning, de esta forma:
<port>: bridge port received packet with own address as source address (<MAC>), probably loopEsa forma sale del log de RouterOS de un usuario, publicado en el foro de
MikroTik
el 2017-12-10, con el puerto y la dirección sustituidos; qué versiones de RouterOS
la siguen escribiendo no está establecido aquí. En el router de referencia, con
RouterOS 7.24.2, no apareció ninguna línea así, mientras la del propio kernel,
received packet on eth1 with own address, llegaba cada 2 s.
Además de STP, la defensa de RouterOS contra un bucle es Loop Protect, que envía sus propios paquetes por una interfaz, la desactiva cuando uno de ellos vuelve y lo deja en el log. La página de MikroTik recomienda (R/M)STP antes que Loop Protect en los puertos de un bridge. No intervino en este diagnóstico, y no se afirma que hubiera detectado este bucle.
4. Corroborar
Sección titulada «4. Corroborar»Busca una segunda observación, independiente, fuera del log del kernel. La MAC
del mensaje pertenecía a sfp-sfpplus1, lo que apuntaba al segmento SFP+; las
propias tablas del bridge apuntaban a otro sitio. Cuenta los hosts aprendidos en
cada puerto:
# hosts aprendidos por puerto:foreach p in=[/interface/bridge/port/find] do={ \ :local n [/interface/bridge/port/get $p interface]; \ :put ($n . " hosts=" . [:len [/interface/bridge/host/find interface=$n]]) }| Puerto | MAC aprendidas | Tráfico | edge de RSTP |
|---|---|---|---|
sfp-sfpplus1 |
60 | 23,8 GB rx | true |
ether2 |
0 | 9,15 GB rx / 22,4 M paquetes | false |
| el resto | 0–2 | — | true |
Desliza en horizontal para ver todas las columnas
ether2 estaba pasando 22 millones de paquetes por un enlace sano de 1 Gbps y el
bridge no había aprendido nada detrás de él, que es lo que hace un bridge en
un puerto por el que no deja de ver sus propias direcciones. Era además el único
puerto que recibía BPDU: las dos anomalías, en el mismo puerto.
El log del kernel había dicho eth1, no ether2: el kernel y RouterOS llaman de
forma distinta al mismo puerto. Nombres de puertos
relaciona unos con otros en un solo paso seguro, y explica por qué el agente lo
hace por ti en esta placa.
5. Poner a prueba la hipótesis
Sección titulada «5. Poner a prueba la hipótesis»La hipótesis: el equipo de ether2 tiene un segundo camino hasta el router a
través de los otros AP, que cuelgan del switch. Primero se hicieron dos cambios
en el switch, y ninguno movió la tasa:
| Cambio | Tasa de sucesos |
|---|---|
| línea base | 1,49 /s |
| cambio en el switch 1 | 1,67 /s |
| cambio en el switch 2 | 1,47 /s |
| (banda de ruido) | ±0,2 /s |
Desliza en horizontal para ver todas las columnas
Una lectura más de la misma serie, 1,50 /s, también quedó dentro de esa banda.
Eso descartó el switch con evidencia. Vuelve a medir después de cada cambio, incluso uno que esperas que funcione, y conoce tu banda de ruido antes de interpretar una diferencia.
6. Corregir y confirmar
Sección titulada «6. Corregir y confirmar»Se actualizó el firmware de los AP de la malla (unidades Deco); el cableado no se tocó. Después:
events 9 -> 0.03/s (baseline 1.49/s)y de esos nueve, ninguno era el mensaje del bucle: eran los AP volviendo
(eth1: phy link up, eth1: set isolation from 0 to 1). El mensaje del bucle,
que había aparecido cada 2 s (30 veces por minuto, rodeado del doble de registros
de blocking/learning), apareció cero veces en 300 s.
Confirma con una segunda medida, independiente. Aquí la visión del bridge se volvió coherente:
| Antes | Después | |
|---|---|---|
MAC en ether2 |
0 | 24 |
MAC en sfp-sfpplus1 |
60 | 36 |
edge de ether2 |
false | true |
Desliza en horizontal para ver todas las columnas
Los mismos 60 equipos, repartidos 36/24 en lugar de 60/0. Mientras existió el
bucle, el router aprendía casi todos los equipos en el puerto equivocado; el
coordinador Zigbee 00:4B:12:96:80:33, por ejemplo, pasó del SFP+ a ether2,
donde está. Que encaje una segunda medida no relacionada es lo que
hace de una corrección algo más que una coincidencia en el tiempo. Confirma que
el fallo había desaparecido cuando se midió, no que siga sin aparecer: una semana
después volvió.
Reaparición
Sección titulada «Reaparición»La misma firma reapareció el 2026-09-19, con RouterOS 7.24.4, de nuevo un bucle
de capa 2 por un segundo camino a través de un punto de acceso de la malla, y
duró hasta que ese camino se cortó el 2026-09-23. Durante sus primeras 34 h el puerto al que el
bridge había dejado de entregar tráfico fue sfp-sfpplus1, y después ether2
durante 62 h. Entre las 12:07 y las 18:55 UTC del 2026-09-21 y del 22, ether2
recibió 12 y 13 paquetes por segundo y envió 1; en esas mismas horas del
2026-09-23, tras desaparecer el segundo camino a las 12:06, recibió 192 y envió 178.
La segunda vez hubo dos diferencias:
- Durante la mayor parte de la primera fase, los registros de dirección propia
del log del kernel nombraban
ether2, mientras que el puerto que recibía sin obtener nada de vuelta erasfp-sfpplus1: el mensaje nombra el puerto por el que entró la trama reflejada, no el puerto que el bucle había dejado aislado. - Los contadores por puerto de RouterOS sí lo mostraron, leídos como recepción
sin transmisión. El contraste de
mikroscope-bridge-port-darkcon los datos del 2026-09-19 11:13 al 2026-09-23 22:44 UTC marca esos dos puertos en esos dos tramos y ningún otro.
El almacén InfluxDB de referencia guardó las dos mitades, y el gráfico de abajo
sale de él, hora a hora: arriba los registros de dirección propia del kernel, y
debajo lo que cada uno de los dos puertos recibió y se le envió. Mientras el
puerto aislado era sfp-sfpplus1, los registros llegaban de pocos en pocos cada
hora; en cuanto lo fue ether2, llegaban cada 2 s, como el 2026-09-12.
Un fallo real, no provocado ·
- Un flujo constante y periódico de
eventsdel kernel en reposo, donde el estado sano es cero. received packet on <port> with own address as source address, con la propia MAC del router dentro.- El puerto de ese mensaje es por donde entró la trama reflejada, no
necesariamente el puerto que el bucle ha dejado aislado. Del 2026-09-19 al 20
nombraba
ether2mientrassfp-sfpplus1era el puerto que recibía y no enviaba nada. Compara el rx de cada puerto del bridge con su tx antes de desenchufar un cable. - Tiempos entre llegadas de 2,00–2,01 s: el hello interval de STP.
- Un puerto con mucho tráfico en el que el bridge no ha aprendido ningún host,
con
edge=falsemientras sus vecinos están atrue. /log/printy/interface/, ambos limpios.bridge/ port/ monitor
Conclusiones
Sección titulada «Conclusiones»- Un texto alarmante es una pista; una tasa es evidencia; una tasa antes y después es una conclusión.
- Lee los tiempos entre llegadas. A menudo te nombran el protocolo.
- Prefiere un cambio que discrimine entre hipótesis a un cambio que tal vez lo arregle.
- Desconfía de una corrección que solo tu instrumento principal puede confirmar.
- Sigue vigilando después de la corrección. Una corrección confirmada dice que el fallo no estaba cuando mediste, y este volvió una semana después.