diff options
author | imarom <imarom@cisco.com> | 2016-11-22 15:48:40 +0200 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-11-22 15:48:40 +0200 |
commit | 6c18d6a2173ff2f3ecd031046077cd65d3ed8785 (patch) | |
tree | 8b0ad6ef47bf755a39f53d1b3012cac358bb28ec | |
parent | c14a58893ba5d24057b72e4bc2381541f4558fcc (diff) |
RX features - added timestamp to RX packets
Signed-off-by: imarom <imarom@cisco.com>
3 files changed, 38 insertions, 23 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py index 2e77b492..aef325ef 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py @@ -80,7 +80,7 @@ class Port(object): self.owner = '' self.last_factor_type = None - + self.attr_lock = threading.Lock() # decorator to verify port is up @@ -430,8 +430,8 @@ class Port(object): # save this for TUI self.last_factor_type = mul['type'] - - return self.ok() + + return rc # stop traffic @@ -451,8 +451,9 @@ class Port(object): return self.err(rc.err()) self.state = self.STATE_STREAMS + self.last_factor_type = None - + # timestamp for last tx self.tx_stopped_ts = datetime.now() @@ -580,7 +581,8 @@ class Port(object): # decode the packets for i in range(len(pkts)): - pkts[i] = base64.b64decode(pkts[i]) + pkts[i]['binary'] = base64.b64decode(pkts[i]['binary']) + return pkts @@ -1019,6 +1021,7 @@ class Port(object): # until thread is locked - order is important self.tx_stopped_ts = datetime.now() self.state = self.STATE_STREAMS + self.last_factor_type = None def async_event_port_attr_changed (self, new_attr): @@ -1088,7 +1091,7 @@ class Resolver(object): raise NotImplementedError() # return None for more packets otherwise RC object - def on_pkt_rx (self, pkt, dt): + def on_pkt_rx (self, pkt): raise NotImplementedError() # return value in case of timeout @@ -1156,12 +1159,13 @@ class Resolver(object): if not rc: return rc + # save the start timestamp + self.start_ts = rc.data()['ts'] + # block until traffic finishes while self.port.is_active(): time.sleep(0.01) - self.tx_time = time.time() - return self.wait_for_rx_response() @@ -1173,10 +1177,10 @@ class Resolver(object): while polling > 0: # fetch the queue rx_pkts = self.port.get_rx_queue_pkts() - dt = time.time() - self.tx_time + # for each packet - examine it for pkt in rx_pkts: - rc = self.on_pkt_rx(pkt, dt) + rc = self.on_pkt_rx(pkt) if rc is not None: return rc @@ -1222,8 +1226,8 @@ class ARPResolver(Resolver): # return None in case more packets are needed else the status rc - def on_pkt_rx (self, pkt, dt): - scapy_pkt = Ether(pkt) + def on_pkt_rx (self, pkt): + scapy_pkt = Ether(pkt['binary']) if not 'ARP' in scapy_pkt: return None @@ -1286,8 +1290,8 @@ class PingResolver(Resolver): return [s1] # return None for more packets otherwise RC object - def on_pkt_rx (self, pkt, dt): - scapy_pkt = Ether(pkt) + def on_pkt_rx (self, pkt): + scapy_pkt = Ether(pkt['binary']) if not 'ICMP' in scapy_pkt: return None @@ -1295,13 +1299,16 @@ class PingResolver(Resolver): ip = scapy_pkt['IP'] icmp = scapy_pkt['ICMP'] + + dt = pkt['ts'] - self.start_ts + if icmp.type == 0: # echo reply - return self.port.ok('Reply from {0}: bytes={1}, time={2:.2f}ms, TTL={3}'.format(ip.src, len(pkt), dt * 1000, ip.ttl)) + return self.port.ok('Reply from {0}: bytes={1}, time={2:.2f}ms, TTL={3}'.format(ip.src, len(pkt['binary']), dt * 1000, ip.ttl)) # unreachable elif icmp.type == 3: - return self.port.ok('destination {0} is unreachable'.format(icmp.dst)) + return self.port.ok('Reply from {0}: Destination host unreachable'.format(icmp.src)) else: scapy_pkt.show2() return self.port.err('unknown ICMP reply') diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index c950e011..d4e900ac 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -680,7 +680,8 @@ TrexRpcCmdStartTraffic::_run(const Json::Value ¶ms, Json::Value &result) { } result["result"]["multiplier"] = port->get_multiplier(); - + result["result"]["ts"] = now_sec(); + return (TREX_RPC_CMD_OK); } diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.h b/src/stateless/rx/trex_stateless_rx_port_mngr.h index aa8ba8e9..fd023ea9 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.h +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.h @@ -99,11 +99,17 @@ public: m_raw = (uint8_t *)malloc(m_size); memcpy(m_raw, p, m_size); + + /* save the packet timestamp */ + m_timestamp = now_sec(); } - /* RVO here - no performance impact */ - const std::string to_base64_str() const { - return base64_encode(m_raw, m_size); + /* slow path and also RVO - pass by value is ok */ + Json::Value to_json() { + Json::Value output; + output["ts"] = m_timestamp; + output["binary"] = base64_encode(m_raw, m_size); + return output; } ~RxPacket() { @@ -114,8 +120,9 @@ public: private: - uint8_t *m_raw; - uint16_t m_size; + uint8_t *m_raw; + uint16_t m_size; + dsec_t m_timestamp; }; /** @@ -194,7 +201,7 @@ public: int tmp = m_tail; while (tmp != m_head) { RxPacket *pkt = m_buffer[tmp]; - output.append(pkt->to_base64_str()); + output.append(pkt->to_json()); tmp = next(tmp); } |