Hi, vlan_start() was increasing packet counts before checking if the packet was successfully enqueued. I made a hunt for similar errors.
Index: net/if_mpe.c =================================================================== RCS file: /cvs/src/sys/net/if_mpe.c,v retrieving revision 1.25 diff -d -u -p -w -r1.25 if_mpe.c --- net/if_mpe.c 28 Jan 2011 14:58:24 -0000 1.25 +++ net/if_mpe.c 20 Aug 2011 04:06:29 -0000 @@ -265,7 +265,7 @@ mpeoutput(struct ifnet *ifp, struct mbuf if (error) { /* mbuf is already freed */ splx(s); - return (error); + goto out; } if_start(ifp); splx(s); Index: net/if_pppx.c =================================================================== RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.9 diff -d -u -p -w -r1.9 if_pppx.c --- net/if_pppx.c 7 Jul 2011 20:42:56 -0000 1.9 +++ net/if_pppx.c 20 Aug 2011 05:37:48 -0000 @@ -1057,6 +1057,10 @@ pppx_if_output(struct ifnet *ifp, struct s = splnet(); IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); + if (error) { + splx(s); + goto out; + } if_start(ifp); splx(s); Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.87 diff -d -u -p -w -r1.87 if_vlan.c --- net/if_vlan.c 18 Feb 2011 17:06:45 -0000 1.87 +++ net/if_vlan.c 20 Aug 2011 03:58:05 -0000 @@ -251,15 +251,15 @@ vlan_start(struct ifnet *ifp) * Send it, precisely as ether_output() would have. * We are already running at splnet. */ - p->if_obytes += m->m_pkthdr.len; - if (m->m_flags & M_MCAST) - p->if_omcasts++; IFQ_ENQUEUE(&p->if_snd, m, NULL, error); if (error) { /* mbuf is already freed */ ifp->if_oerrors++; continue; } + p->if_obytes += m->m_pkthdr.len; + if (m->m_flags & M_MCAST) + p->if_omcasts++; ifp->if_opackets++; if_start(p);