Index: sys/net/if.h =================================================================== --- sys/net/if.h +++ sys/net/if.h @@ -597,6 +597,7 @@ } ift_feature; typedef struct ifnet * if_t; +typedef struct ifring * ifring_t; typedef void (*if_input_t)(if_t, struct mbuf *); typedef int (*if_transmit_t)(if_t, struct mbuf *); Index: sys/net/if_var.h =================================================================== --- sys/net/if_var.h +++ sys/net/if_var.h @@ -79,6 +79,29 @@ struct ifops ift_ops; }; +struct ifrstat { + uint64_t ifrs_ifinput; + uint64_t ifrs_netisr; + uint64_t ifrs_ether; + uint64_t ifrs_ip; + uint64_t ifrs_ip6; + uint64_t ifrs_udp; + uint64_t ifrs_tcp; +} __aligned(CACHE_LINE_SIZE); + +#define IFRSTAT_ADD(m, name, val) \ +do { \ + if ((m)->m_pkthdr.ifring != NULL) \ + (m)->m_pkthdr.ifring->ifr_stats[curcpu].name += (val); \ +} while (0) +#define IFRSTAT_SUB(m, name, val) IFRSTAT_ADD((m), name, -(val)) +#define IFRSTAT_INC(m, name) IFRSTAT_ADD((m), name, 1) +#define IFRSTAT_DEC(m, name) IFRSTAT_SUB((m), name, 1) + +struct ifring { + struct ifrstat ifr_stats[MAXCPU]; /* Percpu counters */ +}; + /* * Many network stack modules want to store their software context associated * with an interface. We used to give a pointer for everyone, but that yield