sign: Fix Tx stream stats counted as Rx on some platforms

On platforms that don't support filtering IN/OUT using
pcap_setdirection() - e.g. Windows, adjust Rx stats appropriately
This commit is contained in:
Srivats P 2017-01-09 18:57:38 +05:30
parent 063c607847
commit 13e28cff68
6 changed files with 32 additions and 3 deletions

View File

@ -161,6 +161,14 @@ bool PcapPort::startStreamStatsTracking()
goto _tx_fail; goto _tx_fail;
if (!rxStatsPoller_->start()) if (!rxStatsPoller_->start())
goto _rx_fail; goto _rx_fail;
/*
* If RxPoller receives both IN and OUT packets, packets Tx on this
* port will also be received by it and we consider it to be a Rx (IN)
* packet incorrectly - so adjust Rx stats for this case
* XXX - ideally, RxPoller should do this adjustment, but given our
* design, it is easier to implement in transmitter
*/
transmitter_->adjustRxStreamStats(!rxStatsPoller_->isDirectional());
return true; return true;
_rx_fail: _rx_fail:

View File

@ -30,6 +30,7 @@ PcapRxStats::PcapRxStats(const char *device, StreamStats &portStreamStats)
device_ = QString::fromAscii(device); device_ = QString::fromAscii(device);
stop_ = false; stop_ = false;
state_ = kNotStarted; state_ = kNotStarted;
isDirectional_ = true;
handle_ = NULL; handle_ = NULL;
} }
@ -70,10 +71,13 @@ void PcapRxStats::run()
// NOTE: WinPcap 4.1.1 and above exports a dummy API that returns -1 // NOTE: WinPcap 4.1.1 and above exports a dummy API that returns -1
// but since we would like to work with previous versions of WinPcap // but since we would like to work with previous versions of WinPcap
// also, we assume the API does not exist // also, we assume the API does not exist
isDirectional_ = false;
#else #else
if (pcap_setdirection(handle_, PCAP_D_IN) < 0) if (pcap_setdirection(handle_, PCAP_D_IN) < 0) {
qDebug("RxStats: Error setting IN direction %s: %s\n", qDebug("RxStats: Error setting IN direction %s: %s\n",
qPrintable(device_), pcap_geterr(handle_)); qPrintable(device_), pcap_geterr(handle_));
isDirectional_ = false;
}
#endif #endif
if (pcap_compile(handle_, &bpf, qPrintable(capture_filter), if (pcap_compile(handle_, &bpf, qPrintable(capture_filter),
@ -165,3 +169,8 @@ bool PcapRxStats::isRunning()
{ {
return (state_ == kRunning); return (state_ == kRunning);
} }
bool PcapRxStats::isDirectional()
{
return isDirectional_;
}

View File

@ -34,6 +34,7 @@ public:
bool start(); bool start();
bool stop(); bool stop();
bool isRunning(); bool isRunning();
bool isDirectional();
private: private:
enum State { enum State {
@ -47,6 +48,7 @@ private:
volatile bool stop_; volatile bool stop_;
pcap_t *handle_; pcap_t *handle_;
volatile State state_; volatile State state_;
bool isDirectional_;
}; };
#endif #endif

View File

@ -24,6 +24,7 @@ PcapTransmitter::PcapTransmitter(
StreamStats &portStreamStats) StreamStats &portStreamStats)
: streamStats_(portStreamStats), txThread_(device) : streamStats_(portStreamStats), txThread_(device)
{ {
adjustRxStreamStats_ = false;
memset(&stats_, 0, sizeof(stats_)); memset(&stats_, 0, sizeof(stats_));
txStats_.setTxThreadStats(&stats_); txStats_.setTxThreadStats(&stats_);
txStats_.start(); // TODO: alongwith user transmit start txStats_.start(); // TODO: alongwith user transmit start
@ -43,6 +44,11 @@ bool PcapTransmitter::setRateAccuracy(
return txThread_.setRateAccuracy(accuracy); return txThread_.setRateAccuracy(accuracy);
} }
void PcapTransmitter::adjustRxStreamStats(bool enable)
{
adjustRxStreamStats_ = enable;
}
bool PcapTransmitter::setStreamStatsTracking(bool enable) bool PcapTransmitter::setStreamStatsTracking(bool enable)
{ {
return txThread_.setStreamStatsTracking(enable); return txThread_.setStreamStatsTracking(enable);
@ -115,6 +121,10 @@ void PcapTransmitter::updateTxThreadStreamStats()
streamStats_[guid].tx_pkts += sst.tx_pkts; streamStats_[guid].tx_pkts += sst.tx_pkts;
streamStats_[guid].tx_bytes += sst.tx_bytes; streamStats_[guid].tx_bytes += sst.tx_bytes;
if (adjustRxStreamStats_) {
streamStats_[guid].rx_pkts -= sst.tx_pkts;
streamStats_[guid].rx_bytes -= sst.tx_bytes;
}
} }
txThread->clearStreamStats(); txThread->clearStreamStats();
} }

View File

@ -34,6 +34,7 @@ public:
bool setRateAccuracy(AbstractPort::Accuracy accuracy); bool setRateAccuracy(AbstractPort::Accuracy accuracy);
bool setStreamStatsTracking(bool enable); bool setStreamStatsTracking(bool enable);
void adjustRxStreamStats(bool enable);
void clearPacketList(); void clearPacketList();
void loopNextPacketSet(qint64 size, qint64 repeats, void loopNextPacketSet(qint64 size, qint64 repeats,
@ -55,6 +56,7 @@ private:
PcapTxThread txThread_; PcapTxThread txThread_;
PcapTxStats txStats_; PcapTxStats txStats_;
StatsTuple stats_; StatsTuple stats_;
bool adjustRxStreamStats_;
}; };
#endif #endif

View File

@ -592,10 +592,8 @@ def test_unidir(drone, ports, dut, dut_ports, dut_ip, emul_ports, dgid_list,
# for unidir verify rx on tx port is 0 and vice versa # for unidir verify rx on tx port is 0 and vice versa
# FIXME: failing currently because tx pkts on tx port seem to be # FIXME: failing currently because tx pkts on tx port seem to be
# captured by rxStatsPoller_ on tx port # captured by rxStatsPoller_ on tx port
"""
assert ssd.port[ports.x_num].sguid[guid].rx_pkts == 0 assert ssd.port[ports.x_num].sguid[guid].rx_pkts == 0
assert ssd.port[ports.x_num].sguid[guid].rx_bytes == 0 assert ssd.port[ports.x_num].sguid[guid].rx_bytes == 0
"""
assert ssd.port[ports.y_num].sguid[guid].tx_pkts == 0 assert ssd.port[ports.y_num].sguid[guid].tx_pkts == 0
assert ssd.port[ports.y_num].sguid[guid].tx_bytes == 0 assert ssd.port[ports.y_num].sguid[guid].tx_bytes == 0