diff options
Diffstat (limited to 'src/stateless/dp')
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 62 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.h | 16 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 78 |
3 files changed, 126 insertions, 30 deletions
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index 31c907fa..6450d0f9 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -262,7 +262,11 @@ bool TrexStatelessDpPerPort::pause_traffic(uint8_t port_id){ return (true); } -bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id, const std::string &pcap_filename){ +bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id, + const std::string &pcap_filename, + double ipg_usec, + double speedup, + uint32_t count) { /* push pcap can only happen on an idle port from the core prespective */ assert(m_state == TrexStatelessDpPerPort::ppSTATE_IDLE); @@ -277,7 +281,13 @@ bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id, const std::string &pcap_ uint8_t mac_addr[12]; m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir, mac_addr); - bool rc = pcap_node->create(port_id, pcap_filename, dir, mac_addr); + bool rc = pcap_node->create(port_id, + dir, + mac_addr, + pcap_filename, + ipg_usec, + speedup, + count); if (!rc) { m_core->free_node((CGenNode *)pcap_node); return (false); @@ -287,8 +297,11 @@ bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id, const std::string &pcap_ pcap_node->m_time = m_core->m_cur_time_sec; m_core->m_node_gen.add_node((CGenNode *)pcap_node); - m_state = TrexStatelessDpPerPort::ppSTATE_TRANSMITTING; + /* hold a pointer to the node */ + assert(m_active_pcap_node == NULL); + m_active_pcap_node = pcap_node; + m_state = TrexStatelessDpPerPort::ppSTATE_TRANSMITTING; return (true); } @@ -324,6 +337,19 @@ bool TrexStatelessDpPerPort::stop_traffic(uint8_t port_id, } } + /* check for active PCAP node */ + if (m_active_pcap_node) { + /* when got async stop from outside or duration */ + if (m_active_pcap_node->is_active()) { + m_active_pcap_node->mark_for_free(); + } else { + /* graceful stop - node was put out by the scheduler */ + m_core->free_node( (CGenNode *)m_active_pcap_node); + } + + m_active_pcap_node = NULL; + } + /* active stream should be zero */ assert(m_active_streams==0); m_active_nodes.clear(); @@ -337,6 +363,7 @@ void TrexStatelessDpPerPort::create(CFlowGenListPerThread * core){ m_state=TrexStatelessDpPerPort::ppSTATE_IDLE; m_active_streams=0; m_active_nodes.clear(); + m_active_pcap_node = NULL; } @@ -866,14 +893,19 @@ TrexStatelessDpCore::pause_traffic(uint8_t port_id){ void -TrexStatelessDpCore::push_pcap(uint8_t port_id, int event_id, const std::string &pcap_filename) { +TrexStatelessDpCore::push_pcap(uint8_t port_id, + int event_id, + const std::string &pcap_filename, + double ipg_usec, + double speedup, + uint32_t count) { TrexStatelessDpPerPort * lp_port = get_port_db(port_id); lp_port->set_event_id(event_id); /* delegate the command to the port */ - bool rc = lp_port->push_pcap(port_id, pcap_filename); + bool rc = lp_port->push_pcap(port_id, pcap_filename, ipg_usec, speedup, count); if (!rc) { /* report back that we stopped */ CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(m_core->m_thread_id); @@ -913,7 +945,6 @@ TrexStatelessDpCore::stop_traffic(uint8_t port_id, the scheduler invokes it, it will be free */ TrexStatelessDpPerPort * lp_port = get_port_db(port_id); - if ( lp_port->stop_traffic(port_id,stop_on_id,event_id) == false){ /* nothing to do ! already stopped */ //printf(" skip .. %f\n",m_core->m_cur_time_sec); @@ -961,13 +992,30 @@ TrexStatelessDpCore::barrier(uint8_t port_id, int event_id) { /** * PCAP node */ -bool CGenNodePCAP::create(uint8_t port_id, const std::string &pcap_filename, pkt_dir_t dir, const uint8_t *mac_addr) { +bool CGenNodePCAP::create(uint8_t port_id, + pkt_dir_t dir, + const uint8_t *mac_addr, + const std::string &pcap_filename, + double ipg_usec, + double speedup, + uint32_t count) { std::stringstream ss; m_type = CGenNode::PCAP_PKT; m_flags = 0; m_src_port = 0; m_port_id = port_id; + m_count = count; + + if (ipg_usec != -1) { + /* fixed IPG */ + m_ipg_sec = usec_to_sec(ipg_usec / speedup); + m_speedup = 0; + } else { + /* packet IPG */ + m_ipg_sec = -1; + m_speedup = speedup; + } /* copy MAC addr info */ memcpy(m_mac_addr, mac_addr, 12); diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h index 01033a7c..115f8873 100644 --- a/src/stateless/dp/trex_stateless_dp_core.h +++ b/src/stateless/dp/trex_stateless_dp_core.h @@ -33,7 +33,7 @@ class CFlowGenListPerThread; class CGenNodeStateless; class TrexStreamsCompiledObj; class TrexStream; - +class CGenNodePCAP; class CDpOneStream { public: @@ -70,7 +70,11 @@ public: bool update_traffic(uint8_t port_id, double factor); - bool push_pcap(uint8_t port_id, const std::string &pcap_filename); + bool push_pcap(uint8_t port_id, + const std::string &pcap_filename, + double ipg_usec, + double speedup, + uint32_t count); bool stop_traffic(uint8_t port_id, bool stop_on_id, @@ -97,6 +101,7 @@ public: uint32_t m_active_streams; /* how many active streams on this port */ std::vector<CDpOneStream> m_active_nodes; /* holds the current active nodes */ + CGenNodePCAP *m_active_pcap_node; CFlowGenListPerThread * m_core ; int m_event_id; }; @@ -165,7 +170,12 @@ public: * push a PCAP file on port * */ - void push_pcap(uint8_t port_id, int event_id, const std::string &pcap_filename); + void push_pcap(uint8_t port_id, + int event_id, + const std::string &pcap_filename, + double ipg_usec, + double speedup, + uint32_t count); /** diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index 8ccb5286..a970c1f7 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -398,7 +398,14 @@ public: /** * creates a node from a PCAP file */ - bool create(uint8_t port_id, const std::string &pcap_filename, pkt_dir_t dir, const uint8_t *mac_addr); + bool create(uint8_t port_id, + pkt_dir_t dir, + const uint8_t *mac_addr, + const std::string &pcap_filename, + double ipg_usec, + double speedup, + uint32_t count); + void destroy(); /** @@ -407,36 +414,44 @@ public: * @author imarom (03-May-16) */ void next() { - assert(m_state == PCAP_ACTIVE); + assert(is_active()); /* save the previous packet time */ m_last_pkt_time = m_raw_packet->get_time(); /* advance */ if ( m_reader->ReadPacket(m_raw_packet) == false ){ - m_state = PCAP_EOF; - return; + m_count--; + + /* if its the end - go home... */ + if (m_count == 0) { + m_state = PCAP_INACTIVE; + return; + } + + /* rewind and load the first packet */ + m_reader->Rewind(); + if (!m_reader->ReadPacket(m_raw_packet)) { + m_state = PCAP_INACTIVE; + return; + } } } /** - * return true if the PCAP has next packet - * - */ - bool has_next() { - assert(m_state != PCAP_INVALID); - return (m_state == PCAP_ACTIVE); - } - - /** * return the time for the next scheduling for a packet * */ inline double get_ipg() { assert(m_state != PCAP_INVALID); - return m_raw_packet->get_time() - m_last_pkt_time; - //return 0.00001; + + /* fixed IPG */ + if (m_ipg_sec != -1) { + return m_ipg_sec; + } else { + return ((m_raw_packet->get_time() - m_last_pkt_time) / m_speedup); + } } /** @@ -465,6 +480,17 @@ public: inline void handle(CFlowGenListPerThread *thread) { assert(m_state != PCAP_INVALID); thread->m_node_gen.m_v_if->send_node( (CGenNode *)this); + + // read the next packet + next(); + + if (is_active()) { + m_time += get_ipg(); + thread->m_node_gen.m_p_queue.push((CGenNode *)this); + + } else { + thread->stop_stateless_traffic(get_port_id()); + } } void set_mbuf_dir(pkt_dir_t dir) { @@ -483,12 +509,25 @@ public: return m_port_id; } + void mark_for_free() { + m_state = PCAP_MARKED_FOR_FREE; + } + + bool is_active() { + return (m_state == PCAP_ACTIVE); + } + + bool is_marked_for_free() { + return (m_state == PCAP_MARKED_FOR_FREE); + } + private: enum { PCAP_INVALID = 0, PCAP_ACTIVE, - PCAP_EOF + PCAP_INACTIVE, + PCAP_MARKED_FOR_FREE }; /* cache line 0 */ @@ -496,11 +535,10 @@ private: uint8_t m_mac_addr[12]; uint8_t m_state; - //double m_base_time; - //double m_current_pkt_time; double m_last_pkt_time; - - void * m_cache_mbuf; + double m_speedup; + double m_ipg_sec; + uint32_t m_count; double m_next_time_offset; /* in sec */ |