Index: sys/netgraph/ng_bridge.c =================================================================== --- sys/netgraph/ng_bridge.c +++ sys/netgraph/ng_bridge.c @@ -110,7 +110,7 @@ /* Per-link private data */ struct ng_bridge_link { hook_p hook; /* netgraph hook */ - u_int16_t loopCount; /* loop ignore timer */ + counter_u64_t loopCount; /* loop ignore timer */ unsigned int learnMac : 1, /* autolearn macs */ sendUnknown : 1;/* send unknown macs out */ struct ng_bridge_link_kernel_stats stats; /* link stats */ @@ -394,6 +394,7 @@ if (link == NULL) return (ENOMEM); + link->loopCount = counter_u64_alloc(M_WAITOK); link->stats.recvOctets = counter_u64_alloc(M_WAITOK); link->stats.recvPackets = counter_u64_alloc(M_WAITOK); link->stats.recvMulticasts = counter_u64_alloc(M_WAITOK); @@ -451,7 +452,7 @@ { link_p priv = NG_HOOK_PRIVATE(hook); - priv->loopCount = 0; + counter_u64_zero(priv->loopCount); ng_bridge_clear_link_stats(&priv->stats); return (1); } @@ -719,7 +720,7 @@ } /* Is link disabled due to a loopback condition? */ - if (ctx.incoming->loopCount != 0) { + if (counter_u64_fetch(ctx.incoming->loopCount) != 0) { counter_u64_add(ctx.incoming->stats.loopDrops, 1); NG_FREE_ITEM(item); NG_FREE_M(ctx.m); @@ -770,7 +771,8 @@ } /* Mark link as linka non grata */ - ctx.incoming->loopCount = priv->conf.loopTimeout; + counter_u64_add(ctx.incoming->loopCount, + priv->conf.loopTimeout); counter_u64_add(ctx.incoming->stats.loopDetects, 1); /* Forget all hosts on this link */ @@ -887,6 +889,7 @@ ng_bridge_remove_hosts(priv, link); /* Free associated link information */ + counter_u64_free(link->loopCount); counter_u64_free(link->stats.recvOctets); counter_u64_free(link->stats.recvPackets); counter_u64_free(link->stats.recvMulticasts); @@ -1078,13 +1081,22 @@ node_p node = NG_HOOK_NODE(hook); priv_p priv = NG_NODE_PRIVATE(node); int *counter = arg; - - if (link->loopCount != 0) { - link->loopCount--; - if (link->loopCount == 0 && priv->conf.debugLevel >= 2) { - log(LOG_INFO, "ng_bridge: %s:" - " restoring looped back %s\n", - ng_bridge_nodename(node), NG_HOOK_NAME(hook)); + uint64_t loopCount = counter_u64_fetch(link->loopCount); + + if (loopCount != 0) { + if (loopCount > priv->conf.loopTimeout) { + counter_u64_zero(link->loopCount); + counter_u64_add(link->loopCount, + priv->conf.loopTimeout); + } else if (loopCount > 2) + counter_u64_add(link->loopCount, -1); + else { + counter_u64_zero(link->loopCount); + if (priv->conf.debugLevel >= 2) + log(LOG_INFO, "ng_bridge: %s:" + " restoring looped back %s\n", + ng_bridge_nodename(node), + NG_HOOK_NAME(hook)); } } (*counter)++;