64bit stats support added for Linux if supported by the kernel and driver
Fixes issue 70
This commit is contained in:
parent
ac7e378939
commit
b617c44e61
@ -3,6 +3,8 @@ CONFIG += qt ver_info
|
|||||||
QT += network script
|
QT += network script
|
||||||
QT -= gui
|
QT -= gui
|
||||||
DEFINES += HAVE_REMOTE WPCAP
|
DEFINES += HAVE_REMOTE WPCAP
|
||||||
|
linux*:system(grep -q IFLA_STATS64 /usr/include/linux/if_link.h): \
|
||||||
|
DEFINES += HAVE_IFLA_STATS64
|
||||||
INCLUDEPATH += "../rpc"
|
INCLUDEPATH += "../rpc"
|
||||||
win32 {
|
win32 {
|
||||||
CONFIG += console
|
CONFIG += console
|
||||||
|
@ -40,6 +40,15 @@ QList<LinuxPort*> LinuxPort::allPorts_;
|
|||||||
LinuxPort::StatsMonitor *LinuxPort::monitor_;
|
LinuxPort::StatsMonitor *LinuxPort::monitor_;
|
||||||
|
|
||||||
const quint32 kMaxValue32 = 0xffffffff;
|
const quint32 kMaxValue32 = 0xffffffff;
|
||||||
|
const quint64 kMaxValue64 = 0xffffffffffffffffULL;
|
||||||
|
|
||||||
|
#ifdef HAVE_IFLA_STATS64
|
||||||
|
#define X_IFLA_STATS IFLA_STATS64
|
||||||
|
typedef struct rtnl_link_stats64 x_rtnl_link_stats;
|
||||||
|
#else
|
||||||
|
#define X_IFLA_STATS IFLA_STATS
|
||||||
|
typedef struct rtnl_link_stats x_rtnl_link_stats;
|
||||||
|
#endif
|
||||||
|
|
||||||
LinuxPort::LinuxPort(int id, const char *device)
|
LinuxPort::LinuxPort(int id, const char *device)
|
||||||
: PcapPort(id, device)
|
: PcapPort(id, device)
|
||||||
@ -62,7 +71,10 @@ LinuxPort::LinuxPort(int id, const char *device)
|
|||||||
qDebug("adding dev to all ports list <%s>", device);
|
qDebug("adding dev to all ports list <%s>", device);
|
||||||
allPorts_.append(this);
|
allPorts_.append(this);
|
||||||
|
|
||||||
maxStatsValue_ = 0xffffffff;
|
// A port can support either 32 or 64 bit stats - we will attempt
|
||||||
|
// to guess this for each port and initialize this variable at
|
||||||
|
// run time when the counter wraps around
|
||||||
|
maxStatsValue_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxPort::~LinuxPort()
|
LinuxPort::~LinuxPort()
|
||||||
@ -332,6 +344,7 @@ void LinuxPort::StatsMonitor::procStats()
|
|||||||
AbstractPort::PortStats *stats = portStats[index];
|
AbstractPort::PortStats *stats = portStats[index];
|
||||||
if (stats)
|
if (stats)
|
||||||
{
|
{
|
||||||
|
// TODO: fix the pps/Bps calc similar to netlink stats
|
||||||
stats->rxPps =
|
stats->rxPps =
|
||||||
((rxPkts >= stats->rxPkts) ?
|
((rxPkts >= stats->rxPkts) ?
|
||||||
rxPkts - stats->rxPkts :
|
rxPkts - stats->rxPkts :
|
||||||
@ -378,6 +391,7 @@ void LinuxPort::StatsMonitor::procStats()
|
|||||||
int LinuxPort::StatsMonitor::netlinkStats()
|
int LinuxPort::StatsMonitor::netlinkStats()
|
||||||
{
|
{
|
||||||
QHash<uint, PortStats*> portStats;
|
QHash<uint, PortStats*> portStats;
|
||||||
|
QHash<uint, quint64*> portMaxStatsValue;
|
||||||
QHash<uint, OstProto::LinkState*> linkState;
|
QHash<uint, OstProto::LinkState*> linkState;
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_nl local;
|
struct sockaddr_nl local;
|
||||||
@ -555,6 +569,8 @@ _retry:
|
|||||||
if (strcmp(port->name(), ifname) == 0)
|
if (strcmp(port->name(), ifname) == 0)
|
||||||
{
|
{
|
||||||
portStats[uint(ifi->ifi_index)] = &(port->stats_);
|
portStats[uint(ifi->ifi_index)] = &(port->stats_);
|
||||||
|
portMaxStatsValue[uint(ifi->ifi_index)] =
|
||||||
|
&(port->maxStatsValue_);
|
||||||
linkState[uint(ifi->ifi_index)] = &(port->linkState_);
|
linkState[uint(ifi->ifi_index)] = &(port->linkState_);
|
||||||
|
|
||||||
if (setPromisc(port->name()))
|
if (setPromisc(port->name()))
|
||||||
@ -640,43 +656,76 @@ _retry_recv:
|
|||||||
rtaLen = len - NLMSG_LENGTH(sizeof(*ifi));
|
rtaLen = len - NLMSG_LENGTH(sizeof(*ifi));
|
||||||
while (RTA_OK(rta, rtaLen))
|
while (RTA_OK(rta, rtaLen))
|
||||||
{
|
{
|
||||||
// TODO: IFLA_STATS64
|
if (rta->rta_type == X_IFLA_STATS)
|
||||||
if (rta->rta_type == IFLA_STATS)
|
|
||||||
{
|
{
|
||||||
struct rtnl_link_stats *rtnlStats =
|
x_rtnl_link_stats *rtnlStats =
|
||||||
(struct rtnl_link_stats*) RTA_DATA(rta);
|
(x_rtnl_link_stats*) RTA_DATA(rta);
|
||||||
AbstractPort::PortStats *stats = portStats[ifi->ifi_index];
|
AbstractPort::PortStats *stats = portStats[ifi->ifi_index];
|
||||||
|
quint64 *maxStatsValue = portMaxStatsValue[ifi->ifi_index];
|
||||||
OstProto::LinkState *state = linkState[ifi->ifi_index];
|
OstProto::LinkState *state = linkState[ifi->ifi_index];
|
||||||
|
|
||||||
if (!stats)
|
if (!stats)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
stats->rxPps =
|
if (rtnlStats->rx_packets >= stats->rxPkts) {
|
||||||
((rtnlStats->rx_packets >= stats->rxPkts) ?
|
stats->rxPps = (rtnlStats->rx_packets - stats->rxPkts)
|
||||||
rtnlStats->rx_packets - stats->rxPkts :
|
|
||||||
rtnlStats->rx_packets + (kMaxValue32
|
|
||||||
- stats->rxPkts))
|
|
||||||
/ kRefreshFreq_;
|
/ kRefreshFreq_;
|
||||||
stats->rxBps =
|
}
|
||||||
((rtnlStats->rx_bytes >= stats->rxBytes) ?
|
else {
|
||||||
rtnlStats->rx_bytes - stats->rxBytes :
|
if (*maxStatsValue == 0) {
|
||||||
rtnlStats->rx_bytes + (kMaxValue32
|
*maxStatsValue = stats->rxPkts > kMaxValue32 ?
|
||||||
- stats->rxBytes))
|
kMaxValue64 : kMaxValue32;
|
||||||
|
}
|
||||||
|
stats->rxPps = ((*maxStatsValue - stats->rxPkts)
|
||||||
|
+ rtnlStats->rx_packets)
|
||||||
/ kRefreshFreq_;
|
/ kRefreshFreq_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtnlStats->rx_bytes >= stats->rxBytes) {
|
||||||
|
stats->rxBps = (rtnlStats->rx_bytes - stats->rxBytes)
|
||||||
|
/ kRefreshFreq_;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (*maxStatsValue == 0) {
|
||||||
|
*maxStatsValue = stats->rxBytes > kMaxValue32 ?
|
||||||
|
kMaxValue64 : kMaxValue32;
|
||||||
|
}
|
||||||
|
stats->rxBps = ((*maxStatsValue - stats->rxBytes)
|
||||||
|
+ rtnlStats->rx_bytes)
|
||||||
|
/ kRefreshFreq_;
|
||||||
|
}
|
||||||
|
|
||||||
stats->rxPkts = rtnlStats->rx_packets;
|
stats->rxPkts = rtnlStats->rx_packets;
|
||||||
stats->rxBytes = rtnlStats->rx_bytes;
|
stats->rxBytes = rtnlStats->rx_bytes;
|
||||||
stats->txPps =
|
|
||||||
((rtnlStats->tx_packets >= stats->txPkts) ?
|
if (rtnlStats->tx_packets >= stats->txPkts) {
|
||||||
rtnlStats->tx_packets - stats->txPkts :
|
stats->txPps = (rtnlStats->tx_packets - stats->txPkts)
|
||||||
rtnlStats->tx_packets + (kMaxValue32
|
|
||||||
- stats->txPkts))
|
|
||||||
/ kRefreshFreq_;
|
/ kRefreshFreq_;
|
||||||
stats->txBps =
|
}
|
||||||
((rtnlStats->tx_bytes >= stats->txBytes) ?
|
else {
|
||||||
rtnlStats->tx_bytes - stats->txBytes :
|
if (*maxStatsValue == 0) {
|
||||||
rtnlStats->tx_bytes + (kMaxValue32
|
*maxStatsValue = stats->txPkts > kMaxValue32 ?
|
||||||
- stats->txBytes))
|
kMaxValue64 : kMaxValue32;
|
||||||
|
}
|
||||||
|
stats->txPps = ((*maxStatsValue - stats->txPkts)
|
||||||
|
+ rtnlStats->tx_packets)
|
||||||
/ kRefreshFreq_;
|
/ kRefreshFreq_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtnlStats->tx_bytes >= stats->txBytes) {
|
||||||
|
stats->txBps = (rtnlStats->tx_bytes - stats->txBytes)
|
||||||
|
/ kRefreshFreq_;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (*maxStatsValue == 0) {
|
||||||
|
*maxStatsValue = stats->txBytes > kMaxValue32 ?
|
||||||
|
kMaxValue64 : kMaxValue32;
|
||||||
|
}
|
||||||
|
stats->txBps = ((*maxStatsValue - stats->txBytes)
|
||||||
|
+ rtnlStats->tx_bytes)
|
||||||
|
/ kRefreshFreq_;
|
||||||
|
}
|
||||||
|
|
||||||
stats->txPkts = rtnlStats->tx_packets;
|
stats->txPkts = rtnlStats->tx_packets;
|
||||||
stats->txBytes = rtnlStats->tx_bytes;
|
stats->txBytes = rtnlStats->tx_bytes;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user