diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -460,6 +460,13 @@ "Allow overlap of link-local scope " "zones of a bridge interface and the member interfaces"); +/* log MAC port flapping */ +VNET_DEFINE_STATIC(int, log_mac_flap) = 1; +#define V_log_mac_flap VNET(log_mac_flap) +SYSCTL_INT(_net_link_bridge, OID_AUTO, log_mac_flap, + CTLFLAG_RWTUN | CTLFLAG_VNET, &VNET_NAME(log_mac_flap), 0, + "Log MAC port flapping"); + struct bridge_control { int (*bc_func)(struct bridge_softc *, void *); int bc_argsize; @@ -2773,6 +2780,7 @@ struct bridge_iflist *bif, int setflags, uint8_t flags) { struct bridge_rtnode *brt; + struct bridge_iflist *obif; int error; BRIDGE_LOCK_OR_NET_EPOCH_ASSERT(sc); @@ -2796,7 +2804,7 @@ /* Check again, now that we have the lock. There could have * been a race and we only want to insert this once. */ - if ((brt = bridge_rtnode_lookup(sc, dst, vlan)) != NULL) { + if (bridge_rtnode_lookup(sc, dst, vlan) != NULL) { BRIDGE_RT_UNLOCK(sc); return (0); } @@ -2845,12 +2853,22 @@ } if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && - brt->brt_dst != bif) { + (obif = brt->brt_dst) != bif) { BRIDGE_RT_LOCK(sc); brt->brt_dst->bif_addrcnt--; brt->brt_dst = bif; brt->brt_dst->bif_addrcnt++; BRIDGE_RT_UNLOCK(sc); + + /* TODO also log aging time ? need (time_uptime - brt_create_time) */ + if (V_log_mac_flap) + log(LOG_NOTICE, "%s: mac address %02x:%02x:%02x:%02x:%02x:%02x vlan %d flaps from %s to %s\n", + sc->sc_ifp->if_xname, + brt->brt_addr[0], brt->brt_addr[1], brt->brt_addr[2], + brt->brt_addr[3], brt->brt_addr[4], brt->brt_addr[5], + brt->brt_vlan, + obif->bif_ifp->if_xname, + bif->bif_ifp->if_xname); } if ((flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)