From 03d70c4218be1932e4d69dc52bf24106f85dcafb Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Wed, 11 May 2016 10:47:16 +0300 Subject: unit tests + simulator work --- .../regression/stateless_tests/stl_rx_test.py | 69 ++- scripts/exp/stl_vm_enable0_flow_stat-0-ex.erf | Bin 0 -> 880 bytes scripts/exp/stl_vm_enable1_flow_stat-0-ex.erf | Bin 0 -> 6160 bytes src/bp_sim.cpp | 383 ++++++++-------- src/common/captureFile.cpp | 8 +- src/flow_stat.cpp | 9 +- src/flow_stat.h | 1 + src/gtest/trex_stateless_gtest.cpp | 510 +++++++++++---------- src/main_dpdk.cpp | 51 +-- src/pal/linux/mbuf.cpp | 228 ++++----- src/pal/linux/mbuf.h | 2 +- src/pal/linux_dpdk/dpdk22/rte_config.h | 1 - src/rpc-server/commands/trex_rpc_cmd_general.cpp | 12 +- src/stateless/cp/trex_stream.cpp | 5 + src/stateless/dp/trex_stateless_dp_core.cpp | 182 ++++++-- src/stateless/dp/trex_stream_node.h | 4 +- 16 files changed, 816 insertions(+), 649 deletions(-) create mode 100644 scripts/exp/stl_vm_enable0_flow_stat-0-ex.erf create mode 100644 scripts/exp/stl_vm_enable1_flow_stat-0-ex.erf diff --git a/scripts/automation/regression/stateless_tests/stl_rx_test.py b/scripts/automation/regression/stateless_tests/stl_rx_test.py index a5bc115f..a7ff303e 100644 --- a/scripts/automation/regression/stateless_tests/stl_rx_test.py +++ b/scripts/automation/regression/stateless_tests/stl_rx_test.py @@ -7,7 +7,7 @@ class STLRX_Test(CStlGeneral_Test): """Tests for RX feature""" def setUp(self): - per_driver_params = {"rte_vmxnet3_pmd": [1, 50], "rte_ixgbe_pmd": [10, 5000], "rte_i40e_pmd": [80, 5000], + per_driver_params = {"rte_vmxnet3_pmd": [1, 50], "rte_ixgbe_pmd": [30, 5000], "rte_i40e_pmd": [80, 5000], "rte_igb_pmd": [80, 500], "rte_em_pmd": [1, 50], "rte_virtio_pmd": [1, 50]} CStlGeneral_Test.setUp(self) @@ -19,9 +19,10 @@ class STLRX_Test(CStlGeneral_Test): port_info = self.c.get_port_info(ports = self.rx_port)[0] cap = port_info['rx']['caps'] -# print cap; ???? -# if cap != 1: -# self.skip('port {0} does not support RX'.format(self.rx_port)) + print cap + if "flow_stats" not in cap or "latency" not in cap: + self.skip('port {0} does not support RX'.format(self.rx_port)) + self.cap = cap self.rate_percent = per_driver_params[port_info['driver']][0] self.total_pkts = per_driver_params[port_info['driver']][1] @@ -36,9 +37,9 @@ class STLRX_Test(CStlGeneral_Test): CTRexScenario.stl_trex.connect() - def __verify_flow (self, pg_id, total_pkts, pkt_len): - flow_stats = self.c.get_stats()['flow_stats'].get(pg_id) - latency_stats = self.c.get_stats()['latency'].get(pg_id) + def __verify_flow (self, pg_id, total_pkts, pkt_len, stats): + flow_stats = stats['flow_stats'].get(pg_id) + latency_stats = stats['latency'].get(pg_id) if not flow_stats: assert False, "no flow stats available" @@ -46,27 +47,35 @@ class STLRX_Test(CStlGeneral_Test): tx_pkts = flow_stats['tx_pkts'].get(self.tx_port, 0) tx_bytes = flow_stats['tx_bytes'].get(self.tx_port, 0) rx_pkts = flow_stats['rx_pkts'].get(self.rx_port, 0) - drops = latency_stats['err_cntrs']['dropped'] - ooo = latency_stats['err_cntrs']['out_of_order'] - jitter = latency_stats['jitter'] - latency = latency_stats['latency'] - - if drops != 0 or ooo != 0: - pprint.pprint(latency_stats) - tmp='Dropped or out of order packets - dropped: {0}, ooo: {1}'.format(drops, ooo) - assert False, tmp + if latency_stats is not None: + drops = latency_stats['err_cntrs']['dropped'] + ooo = latency_stats['err_cntrs']['out_of_order'] + if drops != 0 or ooo != 0: + pprint.pprint(latency_stats) + tmp='Dropped or out of order packets - dropped: {0}, ooo: {1}'.format(drops, ooo) + assert False, tmp if tx_pkts != total_pkts: pprint.pprint(flow_stats) - assert False, 'TX pkts mismatch - got: {0}, expected: {1}'.format(tx_pkts, total_pkts) + tmp = 'TX pkts mismatch - got: {0}, expected: {1}'.format(tx_pkts, total_pkts) + assert False, tmp if tx_bytes != (total_pkts * pkt_len): pprint.pprint(flow_stats) - assert False, 'TX bytes mismatch - got: {0}, expected: {1}'.format(tx_bytes, (total_pkts * pkt_len)) + tmp = 'TX bytes mismatch - got: {0}, expected: {1}'.format(tx_bytes, (total_pkts * pkt_len)) + assert False, tmp if rx_pkts != total_pkts: pprint.pprint(flow_stats) - assert False, 'RX pkts mismatch - got: {0}, expected: {1}'.format(rx_pkts, total_pkts) + tmp = 'RX pkts mismatch - got: {0}, expected: {1}'.format(rx_pkts, total_pkts) + assert False, tmp + + if "rx_bytes" in self.cap: + rx_bytes = flow_stats['rx_bytes'].get(self.rx_port, 0) + if rx_bytes != (total_pkts * pkt_len): + pprint.pprint(flow_stats) + tmp = 'RX bytes mismatch - got: {0}, expected: {1}'.format(rx_bytes, (total_pkts * pkt_len)) + assert False, tmp # RX itreation @@ -76,10 +85,10 @@ class STLRX_Test(CStlGeneral_Test): self.c.start(ports = [self.tx_port]) self.c.wait_on_traffic(ports = [self.tx_port]) + stats = self.c.get_stats() for exp in exp_list: - self.__verify_flow(exp['pg_id'], exp['total_pkts'], exp['pkt_len']) - + self.__verify_flow(exp['pg_id'], exp['total_pkts'], exp['pkt_len'], stats) # one simple stream on TX --> RX @@ -110,17 +119,18 @@ class STLRX_Test(CStlGeneral_Test): # one simple stream on TX --> RX def test_multiple_streams(self): - num_streams = 128 - total_pkts = int(self.total_pkts / num_streams) + num_latency_streams = 128 + num_flow_stat_streams = 127 + total_pkts = int(self.total_pkts / num_latency_streams) if total_pkts == 0: total_pkts = 1 - percent = float(self.rate_percent) / num_streams + percent = float(self.rate_percent) / num_latency_streams try: streams = [] exp = [] # 10 identical streams - for pg_id in range(1, num_streams): + for pg_id in range(1, num_latency_streams): streams.append(STLStream(name = 'rx {0}'.format(pg_id), packet = self.pkt, @@ -129,6 +139,15 @@ class STLRX_Test(CStlGeneral_Test): exp.append({'pg_id': pg_id, 'total_pkts': total_pkts+pg_id, 'pkt_len': self.pkt.get_pkt_len()}) + for pg_id in range(num_latency_streams + 1, num_latency_streams + num_flow_stat_streams): + + streams.append(STLStream(name = 'rx {0}'.format(pg_id), + packet = self.pkt, + flow_stats = STLFlowStats(pg_id = pg_id), + mode = STLTXSingleBurst(total_pkts = total_pkts+pg_id, percentage = percent))) + + exp.append({'pg_id': pg_id, 'total_pkts': total_pkts+pg_id, 'pkt_len': self.pkt.get_pkt_len()}) + # add both streams to ports self.c.add_streams(streams, ports = [self.tx_port]) diff --git a/scripts/exp/stl_vm_enable0_flow_stat-0-ex.erf b/scripts/exp/stl_vm_enable0_flow_stat-0-ex.erf new file mode 100644 index 00000000..ff2a76f1 Binary files /dev/null and b/scripts/exp/stl_vm_enable0_flow_stat-0-ex.erf differ diff --git a/scripts/exp/stl_vm_enable1_flow_stat-0-ex.erf b/scripts/exp/stl_vm_enable1_flow_stat-0-ex.erf new file mode 100644 index 00000000..85bf5b6f Binary files /dev/null and b/scripts/exp/stl_vm_enable1_flow_stat-0-ex.erf differ diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index ccd62f0e..51023b90 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -24,7 +24,7 @@ limitations under the License. #include "utl_json.h" #include "utl_yaml.h" #include "msg_manager.h" -#include +#include #include #include @@ -64,7 +64,7 @@ void CGlobalMemory::Dump(FILE *fd){ uint32_t c_size=64; uint32_t c_total=0; - int i=0; + int i=0; for (i=0; iMBUF_9k) && (im_socket]=true; m_sockets_enabled++; } - + m_socket_per_dual_if[i]=lp->m_socket; /* learn how many threads per dual-if */ @@ -343,7 +343,7 @@ bool CPlatformSocketInfoConfig::is_sockets_enable(socket_id_t socket){ assert(socketis_sockets_enable(socket) ); } - + socket_id_t CPlatformSocketInfo::max_num_active_sockets(){ return ( m_obj->max_num_active_sockets() ); } @@ -574,7 +574,7 @@ std::string CGlobalInfo::dump_pool_as_json(void){ void CGlobalInfo::free_pools(){ CPlatformSocketInfo * lpSocket =&m_socket; - CRteMemPool * lpmem; + CRteMemPool * lpmem; int i; for (i=0; i<(int)MAX_SOCKETS_SUPPORTED; i++) { if (lpSocket->is_sockets_enable((socket_id_t)i)) { @@ -583,10 +583,10 @@ void CGlobalInfo::free_pools(){ utl_rte_mempool_delete(lpmem->m_mbuf_pool_128); utl_rte_mempool_delete(lpmem->m_mbuf_pool_256); utl_rte_mempool_delete(lpmem->m_mbuf_pool_512); - utl_rte_mempool_delete(lpmem->m_mbuf_pool_1024); - utl_rte_mempool_delete(lpmem->m_mbuf_pool_2048); - utl_rte_mempool_delete(lpmem->m_mbuf_pool_4096); - utl_rte_mempool_delete(lpmem->m_mbuf_pool_9k); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_1024); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_2048); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_4096); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_9k); } utl_rte_mempool_delete(m_mem_pool[0].m_mbuf_global_nodes); } @@ -598,7 +598,7 @@ void CGlobalInfo::init_pools(uint32_t rx_buffers){ CGlobalMemory * lp=&CGlobalInfo::m_memory_cfg; CPlatformSocketInfo * lpSocket =&m_socket; - CRteMemPool * lpmem; + CRteMemPool * lpmem; int i; for (i=0; i<(int)MAX_SOCKETS_SUPPORTED; i++) { @@ -607,7 +607,7 @@ void CGlobalInfo::init_pools(uint32_t rx_buffers){ lpmem->m_pool_id=i; - /* this include the packet from 0-64 this is for small packets */ + /* this include the packet from 0-64 this is for small packets */ lpmem->m_small_mbuf_pool =utl_rte_mempool_create("small-pkt-const", lp->m_mbuf[MBUF_64], CONST_SMALL_MBUF_SIZE, @@ -615,7 +615,7 @@ void CGlobalInfo::init_pools(uint32_t rx_buffers){ assert(lpmem->m_small_mbuf_pool); - + lpmem->m_mbuf_pool_128=utl_rte_mempool_create("_128-pkt-const", lp->m_mbuf[MBUF_128], @@ -736,7 +736,7 @@ std::string double_to_human_str(double num, if (num<0.0) { abs_num=-num; } - int i=0; + int i=0; int max_cnt=sizeof(human_tbl)/sizeof(human_tbl[0]); double div =1.0; double f=1000.0; @@ -880,8 +880,8 @@ void CFlowKey::Clean(){ m_ipaddr2=0; m_port1=0; m_port2=0; - m_ip_proto=0; - m_l2_proto=0; + m_ip_proto=0; + m_l2_proto=0; m_vrfid=0; } @@ -897,7 +897,7 @@ void CPacketDescriptor::Dump(FILE *fd){ fprintf(fd," Isvalid : %d ",IsValidPkt()?1:0); fprintf(fd," IsRtt : %d ",IsRtt()?1:0); fprintf(fd," IsLearn : %d ",IsLearn()?1:0); - + if (IsTcp() ) { fprintf(fd," TCP "); }else{ @@ -907,7 +907,7 @@ void CPacketDescriptor::Dump(FILE *fd){ fprintf(fd," id : %d \n",getId() ); fprintf(fd," flow_ID : %d , max_pkts : %u, max_aging: %d sec , pkt_id : %u, init: %d ( dir:%d dir_max :%d ) bid:%d \n",getFlowId(), - GetMaxPktsPerFlow(), + GetMaxPktsPerFlow(), GetMaxFlowTimeout() , getFlowPktNum(), IsInitSide(), @@ -934,7 +934,7 @@ void CPacketIndication::UpdatePacketPadding(){ void CPacketIndication::RefreshPointers(){ - char *pobase=getBasePtr(); + char *pobase=getBasePtr(); m_ether = (EthernetHeader *) (pobase + m_ether_offset); l3.m_ipv4 = (IPHeader *) (pobase + m_ip_offset); @@ -946,12 +946,12 @@ void CPacketIndication::RefreshPointers(){ } } -// copy ref assume pkt point to a fresh +// copy ref assume pkt point to a fresh void CPacketIndication::Clone(CPacketIndication * obj,CCapPktRaw * pkt){ Clean(); m_cap_ipg = obj->m_cap_ipg; m_packet = pkt; - char *pobase=getBasePtr(); + char *pobase=getBasePtr(); m_flow = obj->m_flow; m_ether = (EthernetHeader *) (pobase + obj->getEtherOffset()); @@ -1105,7 +1105,7 @@ void CPacketParser::Delete(){ } -bool CPacketParser::ProcessPacket(CPacketIndication * pkt_indication, +bool CPacketParser::ProcessPacket(CPacketIndication * pkt_indication, CCapPktRaw * raw_packet){ BP_ASSERT(pkt_indication); pkt_indication->ProcessPacket(this,raw_packet); @@ -1129,7 +1129,7 @@ void CPacketIndication::SetKey(void){ if (is_ipv6()){ uint16_t ipv6_src[8]; uint16_t ipv6_dst[8]; - + l3.m_ipv6->getSourceIpv6(&ipv6_src[0]); l3.m_ipv6->getDestIpv6(&ipv6_dst[0]); ip_src=(ipv6_src[6] << 16) | ipv6_src[7]; @@ -1143,7 +1143,7 @@ void CPacketIndication::SetKey(void){ /* UDP/TCP has same place */ uint16_t src_port = l4.m_udp->getSourcePort(); - uint16_t dst_port = l4.m_udp->getDestPort(); + uint16_t dst_port = l4.m_udp->getDestPort(); if (ip_src > ip_dst ) { m_flow_key.m_ipaddr1 =ip_dst; m_flow_key.m_ipaddr2 =ip_src; @@ -1167,7 +1167,7 @@ uint8_t CPacketIndication::ProcessIpPacketProtocol(CCPacketParserCounters *m_cnt TCPHeader * tcp=0; UDPHeader * udp=0; uint16_t tcp_header_len=0; - + switch (protocol) { case IPHeader::Protocol::TCP : m_desc.SetIsTcp(true); @@ -1176,50 +1176,50 @@ uint8_t CPacketIndication::ProcessIpPacketProtocol(CCPacketParserCounters *m_cnt tcp_header_len = tcp->getHeaderLength(); if ( tcp_header_len > (5*4) ){ - // we have ip option - m_cnt->m_tcp_header_options++; + // we have ip option + m_cnt->m_tcp_header_options++; } *offset += tcp_header_len; - m_cnt->m_tcp++; + m_cnt->m_tcp++; break; case IPHeader::Protocol::UDP : m_desc.SetIsUdp(true); udp =(UDPHeader *)(packetBase +*offset); l4.m_udp = udp; *offset += 8; - m_cnt->m_udp++; + m_cnt->m_udp++; break; case IPHeader::Protocol::AH: - m_cnt->m_non_tcp_udp_ah++; + m_cnt->m_non_tcp_udp_ah++; return (1); break; case IPHeader::Protocol::ESP: - m_cnt->m_non_tcp_udp_esp++; + m_cnt->m_non_tcp_udp_esp++; return (1); break; case IPHeader::Protocol::ICMP: case IPHeader::Protocol::IPV6_ICMP: - m_cnt->m_non_tcp_udp_icmp++; + m_cnt->m_non_tcp_udp_icmp++; return (1); break; case IPHeader::Protocol::GRE: - m_cnt->m_non_tcp_udp_gre++; + m_cnt->m_non_tcp_udp_gre++; return (1); break; case IPHeader::Protocol::IP: - m_cnt->m_non_ip++; + m_cnt->m_non_ip++; return (1); break; default: - m_cnt->m_non_tcp_udp++; + m_cnt->m_non_tcp_udp++; return (1); break; } /* out of packet */ if ( *offset > m_packet->getTotalLen() ) { - m_cnt->m_tcp_udp_pkt_length_error++; + m_cnt->m_tcp_udp_pkt_length_error++; return (1); } return (0); @@ -1245,7 +1245,7 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser, } // check the IP Length if( (uint32_t)(l3.m_ipv4->getTotalLength()+offset) > (uint32_t)( m_packet->getTotalLen()) ){ - m_cnt->m_ip_length_error++; + m_cnt->m_ip_length_error++; return; } @@ -1253,26 +1253,26 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser, uint16_t ip_header_length = l3.m_ipv4->getHeaderLength(); if ( ip_header_length >(5*4) ){ - m_cnt->m_ip_header_options++; + m_cnt->m_ip_header_options++; } if ( (uint32_t)(ip_header_length + offset) > (uint32_t)m_packet->getTotalLen() ) { - m_cnt->m_ip_length_error++; + m_cnt->m_ip_length_error++; return; } offset += ip_header_length; if( l3.m_ipv4->getTimeToLive() ==0 ){ - m_cnt->m_ip_ttl_is_zero_error++; + m_cnt->m_ip_ttl_is_zero_error++; return; } if( l3.m_ipv4->isNotFirstFragment() ) { - m_cnt->m_ip_not_first_fragment_error++; + m_cnt->m_ip_not_first_fragment_error++; return; } - + protocol = l3.m_ipv4->getProtocol(); if (ProcessIpPacketProtocol(m_cnt,protocol,&offset) != 0) { return; @@ -1280,12 +1280,12 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser, uint16_t payload_offset_from_ip = offset-ip_offset; if ( payload_offset_from_ip > l3.m_ipv4->getTotalLength() ) { - m_cnt->m_tcp_udp_pkt_length_error++; + m_cnt->m_tcp_udp_pkt_length_error++; return; } if ( m_packet->pkt_len > MAX_PKT_SIZE ){ - m_cnt->m_tcp_udp_pkt_length_error++; + m_cnt->m_tcp_udp_pkt_length_error++; printf("ERROR packet is too big, not supported jumbo packets that larger than %d \n",MAX_PKT_SIZE); return; } @@ -1294,7 +1294,7 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser, m_packet->pkt_len = l3.m_ipv4->getTotalLength() + getIpOffset(); if (m_packet->pkt_len < 60) { m_packet->pkt_len = 60; } - m_cnt->m_valid_udp_tcp++; + m_cnt->m_valid_udp_tcp++; m_payload_len = l3.m_ipv4->getTotalLength() - (payload_offset_from_ip); m_payload = (uint8_t *)(packetBase +offset); UpdatePacketPadding(); @@ -1313,7 +1313,7 @@ void CPacketIndication::ProcessIpv6Packet(CPacketParser *parser, uint16_t idx; uint8_t protocol; BP_ASSERT(l3.m_ipv6); - + parser->m_counter.m_pkt++; if ( l3.m_ipv6->getVersion() == 6 ){ @@ -1326,7 +1326,7 @@ void CPacketIndication::ProcessIpv6Packet(CPacketParser *parser, // Check length if ((uint32_t)(l3.m_ipv6->getPayloadLen()+offset+l3.m_ipv6->getHeaderLength()) > (uint32_t)( m_packet->getTotalLen()) ){ - m_cnt->m_ipv6_length_error++; + m_cnt->m_ipv6_length_error++; return; } @@ -1348,7 +1348,7 @@ void CPacketIndication::ProcessIpv6Packet(CPacketParser *parser, m_packet->pkt_len = real_pkt_size; if (m_packet->pkt_len < 60) { m_packet->pkt_len = 60; } - m_cnt->m_valid_udp_tcp++; + m_cnt->m_valid_udp_tcp++; m_payload_len = l3.m_ipv6->getPayloadLen(); m_payload = (uint8_t *)(packetBase +offset); @@ -1382,12 +1382,12 @@ bool CPacketIndication::ConvertPacketToIpv6InPlace(CCapPktRaw * pkt, uint8_t l4_proto = ipv4->getProtocol(); ipv6->setNextHdr(l4_proto); ipv6->setHopLimit(64); - + // Update the least signficant 32-bits of ipv6 address // using the ipv4 address ipv6->updateLSBIpv6Src(ipv4->getSourceIp()); ipv6->updateLSBIpv6Dst(ipv4->getDestIp()); - + // Copy rest of packet uint16_t ipv4_offset = offset + ipv4->getHeaderLength(); uint16_t ipv6_offset = offset + ipv6_hdrlen; @@ -1479,10 +1479,10 @@ void CPacketIndication::_ProcessPacket(CPacketParser *parser, m_cnt->m_non_ip++; return; /* Non IP */ } - + if (is_ipv6() == false) { if( (14+20) > (uint32_t)( m_packet->getTotalLen()) ){ - m_cnt->m_ip_length_error++; + m_cnt->m_ip_length_error++; return; } } @@ -1493,7 +1493,7 @@ void CPacketIndication::_ProcessPacket(CPacketParser *parser, fprintf(stderr,"ERROR --ipv6 must be set to process ipv6 packets\n"); exit(-1); } - + // Convert to Ipv6 if requested and not already Ipv6 if ((CGlobalInfo::is_ipv6_enable()) && (is_ipv6() == false )) { if (ConvertPacketToIpv6InPlace(pkt, offset) == false){ @@ -1577,7 +1577,7 @@ void CFlowTableMap::Delete(){ } void CFlowTableMap::remove(const CFlowKey & key ) { - CFlow *lp=lookup(key); + CFlow *lp=lookup(key); if ( lp ) { delete lp; m_stats.m_remove++; @@ -1606,7 +1606,7 @@ CFlow * CFlowTableMap::add(const CFlowKey & key ) { } void CFlowTableMap::remove_all(){ - if ( m_map.empty() ) + if ( m_map.empty() ) return; flow_map_iter_t it; for (it= m_map.begin(); it != m_map.end(); ++it) { @@ -1620,7 +1620,7 @@ uint64_t CFlowTableMap::count(){ return ( m_map.size()); } - + /* * This function will insert an IP option header containing metadata for the * rx-check feature. @@ -1656,7 +1656,7 @@ void CFlowPktInfo::do_generate_new_mbuf_rxcheck(rte_mbuf_t * m, uint16_t move_len = m->data_len - mp1_offset; uint16_t new_mbuf_size = move_len + opt_len; uint16_t mp2_offset = opt_len; - + /* obtain a new mbuf */ rte_mbuf_t * new_mbuf = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), new_mbuf_size); assert(new_mbuf); @@ -1664,14 +1664,14 @@ void CFlowPktInfo::do_generate_new_mbuf_rxcheck(rte_mbuf_t * m, char * move_to = mp2 + mp2_offset; /* move part of packet from first mbuf to new mbuf */ - memmove(move_to, move_from, move_len); + memmove(move_to, move_from, move_len); /* trim first mbuf and set pointer to option header*/ CRx_check_header *rxhdr; uint16_t buf_adjust = move_len; rxhdr = (CRx_check_header *)mp2; m->data_len -= buf_adjust; - + /* insert rx-check data as an IPv4 option header or IPv6 extension header*/ CFlowPktInfo * lp=node->m_pkt_info; CPacketDescriptor * desc=&lp->m_pkt_indication.m_desc; @@ -1683,7 +1683,7 @@ void CFlowPktInfo::do_generate_new_mbuf_rxcheck(rte_mbuf_t * m, uint8_t save_header= ipv6->getNextHdr(); ipv6->setNextHdr(RX_CHECK_V6_OPT_TYPE); ipv6->setHopLimit(TTL_RESERVE_DUPLICATE); - ipv6->setPayloadLen( ipv6->getPayloadLen() + + ipv6->setPayloadLen( ipv6->getPayloadLen() + sizeof(CRx_check_header)); rxhdr->m_option_type = save_header; rxhdr->m_option_len = RX_CHECK_V6_OPT_LEN; @@ -1705,7 +1705,7 @@ void CFlowPktInfo::do_generate_new_mbuf_rxcheck(rte_mbuf_t * m, rxhdr->m_time_stamp = os_get_hr_tick_32(); } rxhdr->m_magic = RX_CHECK_MAGIC; - rxhdr->m_flow_id = node->m_flow_id | ( ( (uint64_t)(desc->getFlowId() & 0xf))<<52 ) ; // include thread_id, node->flow_id, sub_flow in case of multi-flow template + rxhdr->m_flow_id = node->m_flow_id | ( ( (uint64_t)(desc->getFlowId() & 0xf))<<52 ) ; // include thread_id, node->flow_id, sub_flow in case of multi-flow template rxhdr->m_flags = 0; rxhdr->m_aging_sec = desc->GetMaxFlowTimeout(); rxhdr->m_template_id = (uint8_t)desc->getId(); @@ -1714,7 +1714,7 @@ void CFlowPktInfo::do_generate_new_mbuf_rxcheck(rte_mbuf_t * m, if (single_port) { rxhdr->m_pkt_id = desc->getFlowPktNum(); rxhdr->m_flow_size = desc->GetMaxPktsPerFlow(); - + }else{ rxhdr->m_pkt_id = desc->GetDirInfo()->GetPktNum(); rxhdr->m_flow_size = desc->GetDirInfo()->GetMaxPkts(); @@ -1727,7 +1727,7 @@ void CFlowPktInfo::do_generate_new_mbuf_rxcheck(rte_mbuf_t * m, if (likely ( ! m_pkt_indication.is_ipv6()) ) { ipv4->updateCheckSum2((uint8_t *)ipv4, current_opt_len, (uint8_t *)rxhdr, opt_len); } - + /* link new mbuf */ new_mbuf->next = m->next; new_mbuf->nb_segs++; @@ -1754,7 +1754,7 @@ char * CFlowPktInfo::push_ipv4_option_offline(uint8_t bytes){ uint16_t bytes_to_move= m_packet->pkt_len - ip_offset_to_move -bytes; /* move the start of ipv4 options */ - memmove(p+bytes ,p, bytes_to_move); + memmove(p+bytes ,p, bytes_to_move); /* fix all other stuff */ if ( m_pkt_indication.m_udp_tcp_offset ){ @@ -1813,7 +1813,7 @@ char * CFlowPktInfo::push_ipv6_option_offline(uint8_t bytes){ uint16_t bytes_to_move= m_packet->pkt_len - ip_offset_to_move -bytes; /* move the start of ipv4 options */ - memmove(p+bytes ,p, bytes_to_move); + memmove(p+bytes ,p, bytes_to_move); /* fix all other stuff */ if ( m_pkt_indication.m_udp_tcp_offset ){ @@ -1912,7 +1912,7 @@ void CCapFileFlowInfo::save_to_erf(std::string cap_file_name,int pcap){ file_type=LIBPCAP; } - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(file_type,(char *)cap_file_name.c_str()); if (lpWriter == NULL) { fprintf(stderr,"ERROR can't create cap file %s ",(char *)cap_file_name.c_str()); @@ -1953,7 +1953,7 @@ public: dsec_t m_max_aging_sec; dsec_t m_last_pkt; - CTmpFlowPerDirInfo m_per_dir[CS_NUM]; + CTmpFlowPerDirInfo m_per_dir[CS_NUM]; }; typedef CTmpFlowInfo * flow_tmp_t; @@ -2000,9 +2000,9 @@ bool CCapFileFlowInfo::is_valid_template_load_time(std::string & err){ /** - * update global info - * 1. maximum aging - * 2. per sub-flow pkt_num/max-pkt per dir and per global + * update global info + * 1. maximum aging + * 2. per sub-flow pkt_num/max-pkt per dir and per global */ void CCapFileFlowInfo::update_info(){ flow_tmp_map_iter_t iter; @@ -2011,16 +2011,16 @@ void CCapFileFlowInfo::update_info(){ int i; dsec_t ctime=0.0; - // first iteration, lern all the info into a temp flow table + // first iteration, lern all the info into a temp flow table for (i=0; im_pkt_indication.m_desc; uint16_t flow_id = desc->getFlowId(); CPacketDescriptorPerDir * lpCurPacket = desc->GetDirInfo(); - pkt_dir_t dir=desc->IsInitSide()?CLIENT_SIDE:SERVER_SIDE; // with respect to the first sub-flow in the template + pkt_dir_t dir=desc->IsInitSide()?CLIENT_SIDE:SERVER_SIDE; // with respect to the first sub-flow in the template - //update lpFlow + //update lpFlow iter = ft.find(flow_id); if (iter != ft.end() ) { lpFlow=(*iter).second; @@ -2032,7 +2032,7 @@ void CCapFileFlowInfo::update_info(){ } - // main info + // main info lpCurPacket->SetPktNum(lpFlow->m_per_dir[dir].m_pkt_id); lpFlow->m_max_pkts++; lpFlow->m_per_dir[dir].m_pkt_id++; @@ -2042,7 +2042,7 @@ void CCapFileFlowInfo::update_info(){ if (delta > lpFlow->m_max_aging_sec) { lpFlow->m_max_aging_sec = delta; } - // per direction info + // per direction info if (im_pkt_indication.m_cap_ipg; @@ -2056,13 +2056,13 @@ void CCapFileFlowInfo::update_info(){ CPacketDescriptor * desc=&lp->m_pkt_indication.m_desc; uint16_t flow_id = desc->getFlowId(); CPacketDescriptorPerDir * lpCurPacket = desc->GetDirInfo(); - pkt_dir_t dir=desc->IsInitSide()?CLIENT_SIDE:SERVER_SIDE; // with respect to the first sub-flow in the template + pkt_dir_t dir=desc->IsInitSide()?CLIENT_SIDE:SERVER_SIDE; // with respect to the first sub-flow in the template iter = ft.find(flow_id); assert( iter != ft.end() ); lpFlow=(*iter).second; - if ( (lpFlow->m_per_dir[0].m_pkt_id >0) && + if ( (lpFlow->m_per_dir[0].m_pkt_id >0) && (lpFlow->m_per_dir[1].m_pkt_id >0) ) { /* we have both dir */ lp->m_pkt_indication.m_desc.SetBiPluginEnable(true); @@ -2085,7 +2085,7 @@ void CCapFileFlowInfo::update_info(){ } } - if ( ft.empty() ) + if ( ft.empty() ) return; flow_tmp_map_iter_t it; @@ -2164,7 +2164,7 @@ enum CCapFileFlowInfo::load_cap_file_err CCapFileFlowInfo::load_cap_file(std::st /* check that we don't have reserve TTL for duplication */ uint8_t ttl = pkt_indication.getTTL(); - if ( (ttl == TTL_RESERVE_DUPLICATE) || + if ( (ttl == TTL_RESERVE_DUPLICATE) || (ttl == (TTL_RESERVE_DUPLICATE-1)) ) { pkt_indication.setTTL(TTL_RESERVE_DUPLICATE-4); } @@ -2227,7 +2227,7 @@ enum CCapFileFlowInfo::load_cap_file_err CCapFileFlowInfo::load_cap_file(std::st if ( multi_flow_enable ==false ){ if (lpflow == first_flow) { - // add to + // add to bool init_side= ((lpflow->is_fif_swap?true:false) == pkt_indication.m_desc.IsSwapTuple())?true:false; pkt_indication.m_desc.SetInitSide( init_side ); @@ -2283,7 +2283,7 @@ enum CCapFileFlowInfo::load_cap_file_err CCapFileFlowInfo::load_cap_file(std::st - if ( lp->m_pkt_indication.m_desc.IsInitSide() != + if ( lp->m_pkt_indication.m_desc.IsInitSide() != lp_prev->m_pkt_indication.m_desc.IsInitSide()) { lp_prev->m_pkt_indication.m_desc.SetRtt(true); } @@ -2439,7 +2439,7 @@ void CCapFileFlowInfo::RemoveAll(){ lp->Delete(); delete lp; } - // free all the pointers + // free all the pointers m_flow_pkts.clear(); } @@ -2482,14 +2482,14 @@ void operator >> (const YAML::Node& node, CFlowYamlDpPkt & fi) { } void operator >> (const YAML::Node& node, CVlanYamlInfo & fi) { - + uint32_t tmp; if ( node.FindValue("enable") ){ node["enable"] >> tmp ; fi.m_enable=tmp; node["vlan0"] >> tmp; fi.m_vlan_per_port[0] = tmp; - node["vlan1"] >> tmp; + node["vlan1"] >> tmp; fi.m_vlan_per_port[1] = tmp; } } @@ -2502,14 +2502,14 @@ void operator >> (const YAML::Node& node, CFlowYamlInfo & fi) { if ( node.FindValue("client_pool") ){ node["client_pool"] >> fi.m_client_pool_name; }else{ - fi.m_client_pool_name = "default"; + fi.m_client_pool_name = "default"; } if ( node.FindValue("server_pool") ){ node["server_pool"] >> fi.m_server_pool_name; }else{ - fi.m_server_pool_name = "default"; + fi.m_server_pool_name = "default"; } - + node["cps"] >> fi.m_k_cps; fi.m_k_cps = fi.m_k_cps/1000.0; double t; @@ -2553,7 +2553,7 @@ void operator >> (const YAML::Node& node, CFlowYamlInfo & fi) { fi.m_one_app_server_was_set = false; fi.m_one_app_server = false; - if ( utl_yaml_read_ip_addr(node, + if ( utl_yaml_read_ip_addr(node, "server_addr", fi.m_server_addr) ){ try { @@ -2606,7 +2606,7 @@ void operator >> (const YAML::Node& node, CFlowsYamlInfo & flows_info) { }else{ flows_info.m_tuple_gen_was_set =false; } - + // m_ipv6_set will be true if and only if both src_ipv6 // and dst_ipv6 are provided. These are used to set // the most significant 96-bits of the IPv6 address; the @@ -2630,7 +2630,7 @@ void operator >> (const YAML::Node& node, CFlowsYamlInfo & flows_info) { const YAML::Node & node =src_ipv6_info; node[i] >> fi; flows_info.m_src_ipv6.push_back(fi); - } + } } }else{ flows_info.m_ipv6_set=false; @@ -2645,7 +2645,7 @@ void operator >> (const YAML::Node& node, CFlowsYamlInfo & flows_info) { const YAML::Node & node =dst_ipv6_info; node[i] >> fi; flows_info.m_dst_ipv6.push_back(fi); - } + } } }else{ flows_info.m_ipv6_set=false; @@ -2710,15 +2710,15 @@ void operator >> (const YAML::Node& node, CFlowsYamlInfo & flows_info) { const YAML::Node & node =mac_info; node[i] >> fi; flows_info.m_mac_base.push_back(fi); - } + } const YAML::Node& cap_info = node["cap_info"]; for(unsigned i=0;i> fi; - fi.m_client_pool_idx = + fi.m_client_pool_idx = flows_info.m_tuple_gen.get_client_pool_id(fi.m_client_pool_name); - fi.m_server_pool_idx = + fi.m_server_pool_idx = flows_info.m_tuple_gen.get_server_pool_id(fi.m_server_pool_name); flows_info.m_vec.push_back(fi); } @@ -2795,19 +2795,19 @@ void CFlowsYamlInfo::Dump(FILE *fd){ /* - -example for YAML file - + +example for YAML file + - duration : 10.0 - cap_info : + cap_info : - name: hey1.pcap cps : 12.0 ipg : 0.0001 - name: hey2.pcap cps : 11.0 ipg : 0.0001 - - + + */ bool CFlowsYamlInfo::verify_correctness(uint32_t num_threads) { @@ -2937,7 +2937,7 @@ void CFlowStats::Clear(){ m_bytes=0.0; m_cps=0.0; m_mb_sec=0.0; - m_mB_sec=0.0; + m_mB_sec=0.0; m_c_flows=0.0; m_pps =0.0; m_total_Mbytes=00 ; @@ -2986,7 +2986,7 @@ void CFlowStats::Dump(FILE *fd){ (unsigned long long)m_flows); } -bool CFlowGeneratorRecPerThread::Create(CTupleGeneratorSmart * global_gen, +bool CFlowGeneratorRecPerThread::Create(CTupleGeneratorSmart * global_gen, CFlowYamlInfo * info, CFlowsYamlInfo * yaml_flow_info, CCapFileFlowInfo * flow_info, @@ -2996,7 +2996,7 @@ bool CFlowGeneratorRecPerThread::Create(CTupleGeneratorSmart * global_gen, BP_ASSERT(info); m_thread_id =thread_id ; - tuple_gen.Create(global_gen, info->m_client_pool_idx, + tuple_gen.Create(global_gen, info->m_client_pool_idx, info->m_server_pool_idx); CTupleGenYamlInfo * lpt; lpt = &yaml_flow_info->m_tuple_gen; @@ -3008,7 +3008,7 @@ bool CFlowGeneratorRecPerThread::Create(CTupleGeneratorSmart * global_gen, ); tuple_gen.SetW(info->m_w); - + m_id =_id; @@ -3055,7 +3055,7 @@ void CFlowGeneratorRecPerThread::getFlowStats(CFlowStats * stats){ }else{ c_flow_windows_sec = t_pkt * m_info->m_ipg_sec; } - + double c_flows = cps*c_flow_windows_sec*m_flow_info->get_total_flows(); double pps =cps*t_pkt; @@ -3137,9 +3137,9 @@ void CFlowGeneratorRec::fixup_ipg_if_needed(void){ m_flow_info.update_pcap_mode(); } - if ( (m_flows_info->m_cap_mode) && + if ( (m_flows_info->m_cap_mode) && (m_flows_info->m_cap_ipg_min_set) && - (m_flows_info->m_cap_overide_ipg_set) + (m_flows_info->m_cap_overide_ipg_set) ){ m_flow_info.update_min_ipg(m_flows_info->m_cap_ipg_min, m_flows_info->m_cap_overide_ipg); @@ -3171,7 +3171,7 @@ bool CFlowGeneratorRec::Create(CFlowYamlInfo * info, printf("\n ERROR template file is not valid '%s' \n",err.c_str()); return (false); } - m_flow_info.update_info(); + m_flow_info.update_info(); return (true); }else{ return (false); @@ -3255,7 +3255,7 @@ void CNodeGenerator::remove_all(CFlowGenListPerThread * thread){ } } -int CNodeGenerator::open_file(std::string file_name, +int CNodeGenerator::open_file(std::string file_name, CPreviewMode * preview_mode){ BP_ASSERT(m_v_if); m_preview_mode =*preview_mode; @@ -3332,7 +3332,7 @@ bool CFlowGenListPerThread::Create(uint32_t thread_id, //printf(" create thread %d %s socket: %d \n",m_core_id,name,socket_id); m_node_pool = utl_rte_mempool_create_non_pkt(name, - CGlobalInfo::m_memory_cfg.get_each_core_dp_flows(), + CGlobalInfo::m_memory_cfg.get_each_core_dp_flows(), sizeof(CGenNode), 128, 0 , @@ -3376,7 +3376,7 @@ bool CFlowGenListPerThread::Create(uint32_t thread_id, get_total_kcps(i,false)*1000, tuple_gen->m_server_pool[i].m_is_bundling); } - + init_from_global(portion); @@ -3466,7 +3466,7 @@ void CFlowGenListPerThread::defer_client_port_free(CGenNode *p){ void CFlowGenListPerThread::init_from_global(CIpPortion& portion){ /* copy generator , it is the same */ m_yaml_info =m_flow_list->m_yaml_info; - + /* copy first the flow info */ int i; for (i=0; i<(int)m_flow_list->m_cap_gen.size(); i++) { @@ -3529,12 +3529,12 @@ static void free_map_flow_id_to_node(CGenNode *p){ void CFlowGenListPerThread::Delete(){ - // free all current maps + // free all current maps m_flow_id_to_node_lookup.remove_all(free_map_flow_id_to_node); // free object m_flow_id_to_node_lookup.Delete(); - m_smart_gen.Delete(); + m_smart_gen.Delete(); m_node_gen.Delete(); Clean(); m_cpu_cp_u.Delete(); @@ -3569,7 +3569,6 @@ void CNodeGenerator::dump_json(std::string & json){ json+="\"unknown\":0}}" ; } - void CNodeGenerator::add_exit_node(CFlowGenListPerThread * thread, dsec_t max_time){ @@ -3988,9 +3987,6 @@ CNodeGenerator::handle_slow_messages(uint8_t type, } - - - void CFlowGenListPerThread::Dump(FILE *fd){ fprintf(fd,"yaml info "); m_yaml_info.Dump(fd); @@ -4005,6 +4001,8 @@ void CFlowGenListPerThread::Dump(FILE *fd){ } + + void CFlowGenListPerThread::DumpStats(FILE *fd){ m_stats.dump(fd); } @@ -4038,10 +4036,10 @@ double CFlowGenListPerThread::get_longest_flow(uint8_t pool_idx, bool is_client) double longest_flow = 0.0; for (i=0;i<(int)m_cap_gen.size(); i++) { CFlowGeneratorRecPerThread * lp=m_cap_gen[i]; - if (is_client && + if (is_client && lp->m_info->m_client_pool_idx != pool_idx) continue; - if (!is_client && + if (!is_client && lp->m_info->m_server_pool_idx != pool_idx) continue; double tmp_len; @@ -4073,10 +4071,10 @@ double CFlowGenListPerThread::get_total_kcps(uint8_t pool_idx, bool is_client){ double total=0.0; for (i=0; i<(int)m_cap_gen.size(); i++) { CFlowGeneratorRecPerThread * lp=m_cap_gen[i]; - if (is_client && + if (is_client && lp->m_info->m_client_pool_idx != pool_idx) continue; - if (!is_client && + if (!is_client && lp->m_info->m_server_pool_idx != pool_idx) continue; total +=lp->m_info->m_k_cps; @@ -4109,10 +4107,10 @@ void CFlowGenListPerThread::inc_current_template(void){ int CFlowGenListPerThread::generate_flows_roundrobin(bool *done){ // round robin - + CFlowGeneratorRecPerThread * cur; bool found=false; - // try current + // try current int i; *done = true; for (i=0;i<(int)m_cap_gen.size();i++ ) { @@ -4163,7 +4161,7 @@ void CFlowGenListPerThread::terminate_nat_flows(CGenNode *p){ m_stats.m_nat_flow_timeout++; m_stats.m_nat_lookup_remove_flow_id++; m_flow_id_to_node_lookup.remove_no_lookup(p->get_short_fid()); - free_last_flow_node( p); + free_last_flow_node( p); } @@ -4174,7 +4172,7 @@ void CFlowGenListPerThread::handle_latency_pkt_msg(CGenNodeLatencyPktInfo * msg) struct rte_mbuf * m; m=msg->m_pkt; rte_pktmbuf_dump(stdout,m, rte_pktmbuf_pkt_len(m)); - #endif + #endif /* update timestamp */ struct rte_mbuf * m; @@ -4323,7 +4321,7 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name, dsec_t c_stop_sec = m_cur_time_sec + m_yaml_info.m_duration_sec; m_stop_time_sec =c_stop_sec; m_cur_flow_id =1; - m_cur_template =(m_thread_id % m_cap_gen.size()); + m_cur_template =(m_thread_id % m_cap_gen.size()); m_stats.clear(); fprintf(stdout," Generating erf file ... \n"); @@ -4346,7 +4344,7 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name, CGenNode::DumpHeader(stdout); } #endif - + m_node_gen.flush_file(c_stop_sec,d_time_flow, false,this,old_offset); @@ -4452,7 +4450,7 @@ int CFlowGenList::load_from_yaml(std::string file_name, printf(" mac addr is not valid \n"); exit(0); } - + if (m_yaml_info.m_ipv6_set == true) { // Copy the most significant 96-bits from yaml data for (idx=0; idx<6; idx++){ @@ -4546,7 +4544,7 @@ void CFlowGenList::DumpPktSize(){ int i; for (i=0; i<(int)m_cap_gen.size(); i++) { CFlowGeneratorRec * lp=m_cap_gen[i]; - lp->m_flow_info.dump_pkt_sizes(); + lp->m_flow_info.dump_pkt_sizes(); } } @@ -4688,7 +4686,7 @@ float CPPSMeasure::add(uint64_t pkts){ CBwMeasure::CBwMeasure() { reset(); } - + void CBwMeasure::reset(void) { m_start=false; m_last_time_msec=0; @@ -4735,8 +4733,8 @@ double CBwMeasure::add(uint64_t size) { */ bool CParserOption::is_valid_opt_val(int val, int min, int max, const std::string &opt_name) { if (val < min || val > max) { - std::cerr << "Value " << val << " for option " << opt_name << " is out of range. Should be (" << min << "-" << max << ")." << std::endl; - return false; + std::cerr << "Value " << val << " for option " << opt_name << " is out of range. Should be (" << min << "-" << max << ")." << std::endl; + return false; } return true; @@ -4798,7 +4796,7 @@ void CTupleGlobalGenerator::Delete(){ #endif -static uint32_t get_rand_32(uint32_t MinimumRange , +static uint32_t get_rand_32(uint32_t MinimumRange , uint32_t MaximumRange ); @@ -4834,7 +4832,7 @@ void CTupleTemplateGenerator::Dump(FILE *fd){ } -bool CTupleTemplateGenerator::Create(CTupleGlobalGenerator * global_gen, +bool CTupleTemplateGenerator::Create(CTupleGlobalGenerator * global_gen, uint16_t w, uint16_t wlength, uint32_t _id, @@ -4932,7 +4930,7 @@ static uint32_t get_rand_32(uint32_t MinimumRange, uint32_t Range; if ((Range = MaximumRange - MinimumRange) == 0xffffffff) { - return RandomNumber; + return RandomNumber; } return (uint32_t)(((Range + 1) / TWO_POWER_32_BITS * RandomNumber) + MinimumRange ); } @@ -4945,7 +4943,7 @@ int CNullIF::send_node(CGenNode * node){ rte_mbuf_t * buf=lp->generate_new_mbuf(node); //rte_pktmbuf_dump(buf, buf->pkt_len); //sending it ?? - // free it here as if driver does + // free it here as if driver does rte_pktmbuf_free(buf); #endif return (0); @@ -4975,7 +4973,6 @@ int CErfIFStl::update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p){ return (0); } - int CErfIFStl::send_sl_node(CGenNodeStateless *node_sl) { pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir(); @@ -4985,16 +4982,32 @@ int CErfIFStl::send_sl_node(CGenNodeStateless *node_sl) { fill_raw_packet(m,(CGenNode *)node_sl,dir); }else{ m=node_sl->get_cache_mbuf(); + bool is_const = false; if (m) { - /* cache packet */ - fill_raw_packet(m,(CGenNode *)node_sl,dir); - /* can't free the m, it is cached*/ + is_const = true; }else{ - m=node_sl->alloc_node_with_vm(); assert(m); + } + + if (node_sl->is_stat_needed()) { + uint16_t hw_id = node_sl->get_stat_hw_id(); + if (hw_id >= MAX_FLOW_STATS) { + rte_mbuf_t *mi; + struct flow_stat_payload_header *fsp_head; + mi = node_sl->alloc_flow_stat_mbuf(m, fsp_head, is_const); + fsp_head->seq = 0x12345678; + fsp_head->hw_id = hw_id - MAX_FLOW_STATS; + fsp_head->magic = FLOW_STAT_PAYLOAD_MAGIC; + fsp_head->time_stamp = 0x8899aabbccddeeff; + fill_raw_packet(m,(CGenNode *)node_sl,dir); + rte_pktmbuf_free(mi); + } + } else { fill_raw_packet(m,(CGenNode *)node_sl,dir); - rte_pktmbuf_free(m); + if (! is_const) { + rte_pktmbuf_free(m); + } } } /* check that we have mbuf */ @@ -5004,7 +5017,6 @@ int CErfIFStl::send_sl_node(CGenNodeStateless *node_sl) { return (rc); } - int CErfIFStl::send_pcap_node(CGenNodePCAP *pcap_node) { rte_mbuf_t *m = pcap_node->get_pkt(); if (!m) { @@ -5021,6 +5033,11 @@ int CErfIFStl::send_pcap_node(CGenNodePCAP *pcap_node) { return (rc); } +/* + * This is the simulation stateless send_node. + * in simulation (bp-sim-64) it is called instead of CCoreEthIFStateless::send_node + * Purpose is to test the mbuf manipulation functions which are the same in simulation and "real" code + */ int CErfIFStl::send_node(CGenNode * _no_to_use){ if ( m_preview_mode->getFileWrite() ) { @@ -5122,7 +5139,7 @@ void CTcpSeq::update(uint8_t *p, CFlowPktInfo *pkt_info, int16_t s_size){ void on_node_first(uint8_t plugin_id,CGenNode * node, - CFlowYamlInfo * template_info, + CFlowYamlInfo * template_info, CTupleTemplateGeneratorSmart * tuple_gen, CFlowGenListPerThread * flow_gen){ @@ -5157,7 +5174,7 @@ public: void CPluginCallbackSimple::on_node_first(uint8_t plugin_id, CGenNode * node, - CFlowYamlInfo * template_info, + CFlowYamlInfo * template_info, CTupleTemplateGeneratorSmart * tuple_gen, CFlowGenListPerThread * flow_gen ){ //printf(" on on_node_first callback %d node %x! \n",(int)plugin_id,node); @@ -5199,7 +5216,7 @@ void CPluginCallbackSimple::on_node_last(uint8_t plugin_id,CGenNode * node){ node->m_template_info->m_client_pool_idx,node->m_tuple_gen); flow_gen->defer_client_port_free(is_tcp,node->m_src_idx,lpP->rtp_client_1, node->m_template_info->m_client_pool_idx, node->m_tuple_gen); - + assert(lpP); delete lpP; node->m_plugin_info=0; @@ -5265,7 +5282,7 @@ rte_mbuf_t * CPluginCallbackSimple::http_plugin(uint8_t plugin_id, replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 8; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5282,7 +5299,7 @@ rte_mbuf_t * CPluginCallbackSimple::http_plugin(uint8_t plugin_id, eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5337,7 +5354,7 @@ rte_mbuf_t * CPluginCallbackSimple::dyn_pyload_plugin(uint8_t plugin_id, /* fast filter */ for (i=0; im_num; i++) { if (lpt->m_pkt_ids[i] == pkt_num ) { - //add a program here + //add a program here dyn_cmd.m_cmd = VM_DYN_PYLOAD; dyn_cmd.m_ptr= &lpt->m_program[i]; dyn_cmd.m_flags = 0; @@ -5345,14 +5362,14 @@ rte_mbuf_t * CPluginCallbackSimple::dyn_pyload_plugin(uint8_t plugin_id, dyn_cmd.m_ip.v4=node->m_src_ip; eop_cmd.m_cmd = VM_EOP; - program[0] = &dyn_cmd; + program[0] = &dyn_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; } } } - // only for the first flow + // only for the first flow }else{ fprintf (stderr," only one flow is allowed for dynamic pyload change \n"); exit(-1); @@ -5413,7 +5430,7 @@ rte_mbuf_t * CPluginCallbackSimple::sip_voice_plugin(uint8_t plugin_id,CGenNode ((INET_PORTSTRLEN * 2) - 9); // Mark as IPv6 and set the upper 96-bits - via_replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + via_replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ via_replace_cmd.m_ip.v6[idx] = CGlobalInfo::m_options.m_src_ipv6[idx]; via_replace_cmd.m_ip_via.v6[idx] = CGlobalInfo::m_options.m_src_ipv6[idx]; @@ -5443,7 +5460,7 @@ rte_mbuf_t * CPluginCallbackSimple::sip_voice_plugin(uint8_t plugin_id,CGenNode eop_cmd.m_cmd = VM_EOP; - program[0] = &via_replace_cmd; + program[0] = &via_replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5468,7 +5485,7 @@ rte_mbuf_t * CPluginCallbackSimple::sip_voice_plugin(uint8_t plugin_id,CGenNode ((INET_PORTSTRLEN * 2) - 9); // Mark as IPv6 and set the upper 96-bits - via_replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + via_replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ via_replace_cmd.m_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; via_replace_cmd.m_ip_via.v6[idx] = CGlobalInfo::m_options.m_src_ipv6[idx]; @@ -5499,7 +5516,7 @@ rte_mbuf_t * CPluginCallbackSimple::sip_voice_plugin(uint8_t plugin_id,CGenNode eop_cmd.m_cmd = VM_EOP; - program[0] = &via_replace_cmd; + program[0] = &via_replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5584,7 +5601,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 9; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5595,7 +5612,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5616,7 +5633,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 9; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5627,7 +5644,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5653,7 +5670,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * ((INET_PORTSTRLEN * 2) - 8); // Mark as IPv6 and set the upper 96-bits - replace_port_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_port_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_port_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5670,7 +5687,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_port_cmd; + program[0] = &replace_port_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5699,7 +5716,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_port_cmd; + program[0] = &replace_port_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5726,7 +5743,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * ((INET_PORTSTRLEN * 2) - 8); // Mark as IPv6 and set the upper 96-bits - replace_port_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_port_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_port_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5743,7 +5760,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_port_cmd; + program[0] = &replace_port_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5773,7 +5790,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_port_cmd; + program[0] = &replace_port_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5797,7 +5814,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 9; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5808,7 +5825,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5832,7 +5849,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 9; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5843,7 +5860,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5867,7 +5884,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 9; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5878,7 +5895,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -5901,7 +5918,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * replace_cmd.m_add_pkt_len = (INET6_ADDRSTRLEN + 2) - 9; // Mark as IPv6 and set the upper 96-bits - replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; + replace_cmd.m_flags |= CMiniVMCmdBase::MIN_VM_V6; for (uint8_t idx=0; idx<6; idx++){ replace_cmd.m_server_ip.v6[idx] = CGlobalInfo::m_options.m_dst_ipv6[idx]; } @@ -5912,7 +5929,7 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode * eop_cmd.m_cmd = VM_EOP; - program[0] = &replace_cmd; + program[0] = &replace_cmd; program[1] = &eop_cmd; flow_info.vm_program = program; @@ -6049,9 +6066,9 @@ inline int cp_pkt_len(char *to,char *from,uint16_t from_offset,uint16_t len){ return (len); } -/* not including the to_offset +/* not including the to_offset - 0 1 + 0 1 x */ @@ -6071,7 +6088,7 @@ int CMiniVM::mini_vm_dyn_payload( CMiniVMDynPyload * cmd){ /* copy payload */ memcpy(p,original_l7_ptr,len); if ( ( dyn->m_pyld_offset+ (dyn->m_len*4)) < ( len-4) ){ - // we can change the packet + // we can change the packet int i; uint32_t *l=(uint32_t *)(p+dyn->m_pyld_offset); for (i=0; im_len; i++) { @@ -6337,7 +6354,7 @@ bool CSimplePacketParser::Parse(){ m_option_offset=0; uint8_t protocol = 0; - + // Retrieve the protocol type from the packet switch( m_ether->getNextProtocol() ) { case EthernetHeader::Protocol::IP : @@ -6388,10 +6405,10 @@ bool CSimplePacketParser::Parse(){ } -/* free the right object. - it is classic to use virtual function but we can't do it here and we don't even want to use callback function - as we want to save space and in most cases there is nothing to free. - this might be changed in the future +/* free the right object. + it is classic to use virtual function but we can't do it here and we don't even want to use callback function + as we want to save space and in most cases there is nothing to free. + this might be changed in the future */ void CGenNodeBase::free_base(){ if ( m_type == FLOW_PKT ) { diff --git a/src/common/captureFile.cpp b/src/common/captureFile.cpp index 4c50bcb2..b3035e8a 100755 --- a/src/common/captureFile.cpp +++ b/src/common/captureFile.cpp @@ -121,13 +121,13 @@ bool CCapPktRaw::Compare(CCapPktRaw * obj,int dump,double dsec){ if (pkt_len != obj->pkt_len) { if ( dump ){ - printf(" ERROR len is not eq \n"); + printf(" ERROR: len is not eq. First len is %d, second is %d \n", pkt_len, obj->pkt_len); } return (false); } if ( getInterface() != obj->getInterface() ){ - printf(" ERROR original packet from if=%d and cur packet from if=%d \n",getInterface(),obj->getInterface()); + printf(" ERROR: original packet from if=%d and cur packet from if=%d \n",getInterface(),obj->getInterface()); return (false); } @@ -135,7 +135,7 @@ bool CCapPktRaw::Compare(CCapPktRaw * obj,int dump,double dsec){ CPktNsecTimeStamp t2(obj->time_sec,obj->time_nsec); if ( t1.diff(t2) > dsec ){ if ( dump ){ - printf(" ERROR diff of 1 msec in time \n"); + printf(" ERROR: diff of 1 msec in time \n"); } return (false); } @@ -144,7 +144,7 @@ bool CCapPktRaw::Compare(CCapPktRaw * obj,int dump,double dsec){ return (true); }else{ if ( dump ){ - fprintf(stdout," ERROR buffer not the same \n"); + fprintf(stdout," ERROR: buffers not the same \n"); fprintf(stdout," B1 \n"); fprintf(stdout," ---------------\n"); utl_DumpBuffer(stdout,raw,pkt_len,0); diff --git a/src/flow_stat.cpp b/src/flow_stat.cpp index b2c3f487..e0a6f3ff 100644 --- a/src/flow_stat.cpp +++ b/src/flow_stat.cpp @@ -387,6 +387,10 @@ CFlowStatHwIdMap::CFlowStatHwIdMap() { m_map = NULL; } +CFlowStatHwIdMap::~CFlowStatHwIdMap() { + delete[] m_map; +} + void CFlowStatHwIdMap::create(uint16_t size) { m_map = new uint32_t[size]; assert (m_map != NULL); @@ -457,8 +461,7 @@ CFlowStatRuleMgr::CFlowStatRuleMgr() { } CFlowStatRuleMgr::~CFlowStatRuleMgr() { - if (m_parser) - delete m_parser; + delete m_parser; } void CFlowStatRuleMgr::create() { @@ -498,7 +501,7 @@ int CFlowStatRuleMgr::compile_stream(const TrexStream * stream, CFlowStatParser if (parser->parse(stream->m_pkt.binary, stream->m_pkt.len) != 0) { // if we could not parse the packet, but no stat count needed, it is probably OK. if (stream->m_rx_check.m_enabled) { - throw TrexFStatEx("Failed parsing given packet for flow stat. Probably bad packet format." + throw TrexFStatEx("Failed parsing given packet for flow stat. Please consult the manual for supported packet types for flow stat." , TrexException::T_FLOW_STAT_BAD_PKT_FORMAT); } else { return 0; diff --git a/src/flow_stat.h b/src/flow_stat.h index 5bfab44a..850f9aea 100644 --- a/src/flow_stat.h +++ b/src/flow_stat.h @@ -341,6 +341,7 @@ class CFlowStatUserIdMap { class CFlowStatHwIdMap { public: CFlowStatHwIdMap(); + ~CFlowStatHwIdMap(); void create(uint16_t size); friend std::ostream& operator<<(std::ostream& os, const CFlowStatHwIdMap& cf); uint16_t find_free_hw_id(); diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index d5e36944..06ddbc6c 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -100,7 +100,7 @@ void CPcapLoader::update_ip_src(uint32_t ip_addr){ m_pkt_indication.l3.m_ipv4->setSourceIp(ip_addr); m_pkt_indication.l3.m_ipv4->updateCheckSum(); } -} +} void CPcapLoader::clone_packet_into_stream(TrexStream * stream){ @@ -186,7 +186,7 @@ TEST_F(basic_vm, vm0) { vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(20) ); vm.add_instruction( new StreamVmInstructionFlowMan( "var1",8, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",14, 0,true) ); @@ -199,7 +199,7 @@ TEST_F(basic_vm, vm1) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) ); @@ -222,7 +222,7 @@ TEST_F(basic_vm, vm2) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) ); @@ -238,7 +238,7 @@ TEST_F(basic_vm, vm2) { vm.Dump(stdout); - uint8_t test_udp_pkt[14+20+4+4]={ + uint8_t test_udp_pkt[14+20+4+4]={ 0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00, 0x08,0x00, @@ -260,32 +260,32 @@ TEST_F(basic_vm, vm2) { StreamDPVmInstructionsRunner runner; - uint8_t ex[]={5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3}; + uint8_t ex[]={5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3}; uint32_t random_per_thread=0; int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -300,7 +300,7 @@ TEST_F(basic_vm, vm3) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) ); @@ -317,7 +317,7 @@ TEST_F(basic_vm, vm3) { vm.Dump(stdout); #define PKT_TEST_SIZE (14+20+4+4) - uint8_t test_udp_pkt[PKT_TEST_SIZE]={ + uint8_t test_udp_pkt[PKT_TEST_SIZE]={ 0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00, 0x08,0x00, @@ -339,33 +339,33 @@ TEST_F(basic_vm, vm3) { StreamDPVmInstructionsRunner runner; - uint8_t ex[]={5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3}; + uint8_t ex[]={5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3}; uint32_t random_per_thread=0; int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -386,7 +386,7 @@ TEST_F(basic_vm, vm4) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1", 8 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,false) ); @@ -403,7 +403,7 @@ TEST_F(basic_vm, vm4) { vm.Dump(stdout); #define PKT_TEST_SIZE (14+20+4+4) - uint8_t test_udp_pkt[PKT_TEST_SIZE]={ + uint8_t test_udp_pkt[PKT_TEST_SIZE]={ 0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00, 0x08,0x00, @@ -425,33 +425,33 @@ TEST_F(basic_vm, vm4) { StreamDPVmInstructionsRunner runner; - uint8_t ex[]={5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3}; + uint8_t ex[]={5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3}; uint32_t random_per_thread=0; int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -478,7 +478,7 @@ TEST_F(basic_vm, vm5) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */, @@ -505,7 +505,7 @@ TEST_F(basic_vm, vm5) { vm.Dump(stdout); #define PKT_TEST_SIZE (14+20+4+4) - uint8_t test_udp_pkt[PKT_TEST_SIZE]={ + uint8_t test_udp_pkt[PKT_TEST_SIZE]={ 0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00, 0x08,0x00, @@ -527,75 +527,75 @@ TEST_F(basic_vm, vm5) { StreamDPVmInstructionsRunner runner; - uint8_t ex[]={5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 1, - 2, - 3}; - - uint8_t ex_tos[]={0x18, - 0x17, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - }; + uint8_t ex[]={5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 1, + 2, + 3}; + + uint8_t ex_tos[]={0x18, + 0x17, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + }; uint32_t random_per_thread=0; int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -621,7 +621,7 @@ TEST_F(basic_vm, vm6) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000001,0x10000001,0x100000fe) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000001,0x10000001,0x100000fe) ); vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */, @@ -650,7 +650,7 @@ TEST_F(basic_vm, vm6) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm6.pcap"); assert(lpWriter); @@ -663,7 +663,7 @@ TEST_F(basic_vm, vm6) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -718,7 +718,7 @@ TEST_F(basic_vm, vm7) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm7.pcap"); assert(lpWriter); @@ -731,7 +731,7 @@ TEST_F(basic_vm, vm7) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -793,7 +793,7 @@ TEST_F(basic_vm, vm_mask1) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask1.pcap"); assert(lpWriter); @@ -806,7 +806,7 @@ TEST_F(basic_vm, vm_mask1) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -847,7 +847,7 @@ TEST_F(basic_vm, vm_mask2) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask2.pcap"); assert(lpWriter); @@ -860,7 +860,7 @@ TEST_F(basic_vm, vm_mask2) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -900,7 +900,7 @@ TEST_F(basic_vm, vm_mask3) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask3.pcap"); assert(lpWriter); @@ -913,7 +913,7 @@ TEST_F(basic_vm, vm_mask3) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -953,7 +953,7 @@ TEST_F(basic_vm, vm_mask4) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask4.pcap"); assert(lpWriter); @@ -966,7 +966,7 @@ TEST_F(basic_vm, vm_mask4) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -1006,7 +1006,7 @@ TEST_F(basic_vm, vm_mask5) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask5.pcap"); assert(lpWriter); @@ -1019,7 +1019,7 @@ TEST_F(basic_vm, vm_mask5) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -1060,7 +1060,7 @@ TEST_F(basic_vm, vm_mask6) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask6.pcap"); assert(lpWriter); @@ -1073,7 +1073,7 @@ TEST_F(basic_vm, vm_mask6) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -1130,7 +1130,7 @@ TEST_F(basic_vm, vm8) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm8.pcap"); assert(lpWriter); @@ -1143,7 +1143,7 @@ TEST_F(basic_vm, vm8) { int i; for (i=0; i<20; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -1208,7 +1208,7 @@ TEST_F(basic_vm, vm9) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm9.pcap"); assert(lpWriter); @@ -1221,7 +1221,7 @@ TEST_F(basic_vm, vm9) { int i; for (i=0; i<30; i++) { runner.run(&random_per_thread, - program_size, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -1263,7 +1263,7 @@ TEST_F(basic_vm, vm10) { CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm9.pcap"); assert(lpWriter); @@ -1275,9 +1275,9 @@ TEST_F(basic_vm, vm10) { int i; for (i=0; i<30; i++) { - + runner.run(&random_per_thread, - lpDpVm->get_program_size(), + lpDpVm->get_program_size(), lpDpVm->get_program(), lpDpVm->get_bss(), (uint8_t*)pcap.m_raw.raw); @@ -1364,7 +1364,7 @@ TEST_F(basic_vm, vm_syn_attack) { CPcapLoader pcap; pcap.load_pcap_file("stl/yaml/syn_packet.pcap",0); - + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/stl_syn_attack.pcap"); assert(lpWriter); @@ -1376,9 +1376,9 @@ TEST_F(basic_vm, vm_syn_attack) { int i; for (i=0; i<30; i++) { - + runner.run(&random_per_thread, - lpDpVm->get_program_size(), + lpDpVm->get_program_size(), lpDpVm->get_program(), lpDpVm->get_bss(), (uint8_t*)pcap.m_raw.raw); @@ -1431,7 +1431,7 @@ void run_vm_program( StreamVm & vm, for (i=0; iget_program_size(), + lpDpVm->get_program_size(), lpDpVm->get_program(), lpDpVm->get_bss(), (uint8_t*)pcap.m_raw.raw); @@ -1468,7 +1468,7 @@ TEST_F(basic_vm, vm_inc_size_64_128) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", - 2, // size var must be 16bit size + 2, // size var must be 16bit size StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 127, 128, @@ -1497,7 +1497,7 @@ TEST_F(basic_vm, vm_random_size_64_128) { srand(0x1234); vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", - 2, // size var must be 16bit size + 2, // size var must be 16bit size StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, 0, 128, @@ -1531,7 +1531,7 @@ TEST_F(basic_vm, vm_random_size_64_127_128) { srand(0x1234); vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", - 2, // size var must be 16bit size + 2, // size var must be 16bit size StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, 127, 128, @@ -1570,7 +1570,7 @@ TEST_F(basic_vm, vm_random_size_500b_0_9k) { srand(0x1234); vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", - 2, // size var must be 16bit size + 2, // size var must be 16bit size StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, 0, 0, @@ -1598,7 +1598,7 @@ TEST_F(basic_vm, vm_random_size_500b_0_9k) { ////////////////////////////////////////////////////// - + #define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b)) @@ -1615,8 +1615,8 @@ public: /** - * Queue of RPC msgs for test - * + * Queue of RPC msgs for test + * * @author hhaim */ @@ -1652,7 +1652,7 @@ public: /* only if both port are idle we can exit */ void add_command(CFlowGenListPerThread * core, - TrexStatelessCpToDpMsgBase * msg, + TrexStatelessCpToDpMsgBase * msg, double time){ CGenNodeCommand *node = (CGenNodeCommand *)core->create_node() ; @@ -1686,7 +1686,7 @@ protected: class CBasicStlSink { - + public: CBasicStlSink(){ m_core=0; @@ -1700,7 +1700,7 @@ public: /** * handler for DP to CP messages - * + * * @author imarom (19-Nov-15) */ class DpToCpHandler { @@ -1838,7 +1838,7 @@ public: TrexStatelessCpToDpMsgBase * m_msg; CNodeRing *m_ring_from_cp; - CBasicStlMsgQueue m_msg_queue; + CBasicStlMsgQueue m_msg_queue; CFlowGenList fl; }; @@ -1899,7 +1899,7 @@ TEST_F(basic_stl, basic_pause_resume0) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -1909,10 +1909,10 @@ TEST_F(basic_stl, basic_pause_resume0) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vector objs; assert(compile.compile(port_id, streams, objs)); @@ -1975,7 +1975,7 @@ void CBBStartStopDelay2::call_after_init(CBasicStl * m_obj){ streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 1, objs[0], 10.0 /*sec */ ); @@ -2010,7 +2010,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay2) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2020,10 +2020,10 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay2) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); @@ -2088,7 +2088,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay1) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2098,10 +2098,10 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay1) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); @@ -2139,7 +2139,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop3) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2149,10 +2149,10 @@ TEST_F(basic_stl, single_pkt_bb_start_stop3) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); @@ -2190,7 +2190,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop2) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2200,10 +2200,10 @@ TEST_F(basic_stl, single_pkt_bb_start_stop2) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); @@ -2243,7 +2243,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2253,10 +2253,10 @@ TEST_F(basic_stl, single_pkt_bb_start_stop) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); @@ -2326,11 +2326,11 @@ TEST_F(basic_stl, simple_prog4) { stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; - stream2->set_multi_burst(5, + stream2->set_multi_burst(5, 3, 2000000.0); - // next stream is 100 - loop + // next stream is 100 - loop stream2->m_next_stream_id=100; @@ -2395,11 +2395,11 @@ TEST_F(basic_stl, simple_prog3) { stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; - stream2->set_multi_burst(5, + stream2->set_multi_burst(5, 3, 2000000.0); - // next stream is 100 - loop + // next stream is 100 - loop stream2->m_next_stream_id=100; @@ -2608,7 +2608,7 @@ TEST_F(basic_stl, single_pkt) { TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2618,10 +2618,10 @@ TEST_F(basic_stl, single_pkt) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); @@ -2671,7 +2671,7 @@ void test_mac_replace(bool replace_src_by_pkt, streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); @@ -2775,18 +2775,22 @@ TEST_F(basic_stl, multi_pkt1) { class CEnableVm { public: void run(bool full_packet,double duration,uint16_t cache ); + CEnableVm() { + m_pg_id = -1; + } public: std::string m_input_packet; //"cap2/udp_64B.pcap" std::string m_out_file; //"exp/stl_vm_enable0"; + int32_t m_pg_id; // if >= 0, pg_id for flow stat testing }; void CEnableVm::run(bool full_packet,double duration=10.0,uint16_t cache=0){ - + CFlowStatRuleMgr rule_mgr; CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); - po->out_file =m_out_file; + po->out_file =m_out_file; TrexStreamsCompiler compile; @@ -2801,7 +2805,7 @@ void CEnableVm::run(bool full_packet,double duration=10.0,uint16_t cache=0){ } stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -2814,18 +2818,26 @@ void CEnableVm::run(bool full_packet,double duration=10.0,uint16_t cache=0){ uint16_t pkt_size=pcap.m_raw.pkt_len; vm_build_program_seq(stream1->m_vm,pkt_size, false); - #if 0 +#if 0 if ( full_packet ){ EXPECT_EQ(stream1->m_vm_prefix_size,pkt_size); }else{ EXPECT_EQ(stream1->m_vm_prefix_size,35); } - #endif +#endif + + if (m_pg_id >= 0) { + stream1->m_rx_check.m_enabled = true; + stream1->m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD; + stream1->m_rx_check.m_pg_id = m_pg_id; + rule_mgr.init_stream(stream1); //different rule_mgr object, but we just want to init fields in stream + } else { + stream1->m_rx_check.m_enabled = false; + } - streams.push_back(stream1); - // stream - clean + // stream - clean std::vector objs; assert(compile.compile(port_id,streams, objs) ); @@ -2867,6 +2879,14 @@ TEST_F(basic_stl, vm_enable0) { vm_test.run(true); } +TEST_F(basic_stl, vm_enable0_flow_stat) { + + CEnableVm vm_test; + vm_test.m_out_file = "exp/stl_vm_enable0_flow_stat"; + vm_test.m_input_packet = "cap2/udp_64B.pcap"; + vm_test.m_pg_id = 5; + vm_test.run(true); +} TEST_F(basic_stl, vm_enable1) { @@ -2876,7 +2896,17 @@ TEST_F(basic_stl, vm_enable1) { vm_test.run(false); } +#if 0 +//??? does not work. need to check +TEST_F(basic_stl, vm_enable1_flow_stat) { + CEnableVm vm_test; + vm_test.m_out_file = "exp/stl_vm_enable1_flow_stat"; + vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap"; + vm_test.m_pg_id = 5; + vm_test.run(false); +} +#endif TEST_F(basic_stl, vm_enable2) { @@ -2931,7 +2961,7 @@ TEST_F(basic_stl, multi_pkt2) { streams.push_back(stream2); - // stream - clean + // stream - clean uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs, 1, 5.0)); @@ -2963,7 +2993,7 @@ TEST_F(basic_stl, multi_burst1) { TrexStream * stream1 = new TrexStream(TrexStream::stMULTI_BURST,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); - stream1->set_multi_burst(5, + stream1->set_multi_burst(5, 3, 2000000.0); @@ -2995,8 +3025,8 @@ TEST_F(basic_stl, multi_burst1) { /********************************************* Itay Tests Start *************************************/ /** - * check that continous stream does not point to another stream - * (makes no sense) + * check that continous stream does not point to another stream + * (makes no sense) */ TEST_F(basic_stl, compile_bad_1) { @@ -3020,7 +3050,7 @@ TEST_F(basic_stl, compile_bad_1) { /** * check for streams pointing to non exsistant streams - * + * * @author imarom (16-Nov-15) */ TEST_F(basic_stl, compile_bad_2) { @@ -3055,9 +3085,9 @@ TEST_F(basic_stl, compile_bad_2) { } /** - * check for "dead streams" in the mesh - * a streams that cannot be reached - * + * check for "dead streams" in the mesh + * a streams that cannot be reached + * * @author imarom (16-Nov-15) */ TEST_F(basic_stl, compile_bad_3) { @@ -3083,7 +3113,7 @@ TEST_F(basic_stl, compile_bad_3) { stream->m_next_stream_id = -1; stream->m_self_start = false; stream->set_rate(TrexStreamRate::RATE_PPS,52.0); - + streams.push_back(stream); /* stream 3 */ @@ -3157,7 +3187,7 @@ TEST_F(basic_stl, compile_with_warnings) { stream->m_next_stream_id = 1928; stream->m_self_start = true; stream->set_rate(TrexStreamRate::RATE_PPS,52.0); - + streams.push_back(stream); /* stream 3 */ @@ -3251,7 +3281,7 @@ public: EXPECT_TRUE(event->get_event_id() == m_event_id); EXPECT_TRUE(event->get_port_id() == 0); - + } private: @@ -3275,7 +3305,7 @@ TEST_F(basic_stl, dp_stop_event) { TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,0); stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->set_single_burst(100); - + stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; @@ -3285,10 +3315,10 @@ TEST_F(basic_stl, dp_stop_event) { pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); - + streams.push_back(stream1); - // stream - clean + // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); @@ -3305,7 +3335,7 @@ TEST_F(basic_stl, dp_stop_event) { EXPECT_EQ_UINT32(1, res?1:0); delete stream1 ; - + } TEST_F(basic_stl, graph_generator1) { @@ -3324,7 +3354,7 @@ TEST_F(basic_stl, graph_generator1) { stream->m_pkt.len = 512; stream->m_next_stream_id = 2; - + streams.push_back(stream); @@ -3362,7 +3392,7 @@ TEST_F(basic_stl, graph_generator1) { } delete obj; -} +} TEST_F(basic_stl, graph_generator2) { @@ -3374,7 +3404,7 @@ TEST_F(basic_stl, graph_generator2) { stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 1); stream->m_enabled = true; stream->m_self_start = true; - + stream->set_rate(TrexStreamRate::RATE_PPS,1000); @@ -3407,7 +3437,7 @@ TEST_F(basic_stl, graph_generator2) { EXPECT_EQ(obj->get_max_pps(), 1000.0); EXPECT_EQ(obj->get_max_bps_l2(), (1000 * (128 + 4) * 8)); - + for (auto stream : streams) { delete stream; @@ -3442,7 +3472,7 @@ public: m_stream = stream; m_stream->m_enabled = true; m_stream->m_self_start = true; - + pcap.clone_packet_into_stream(stream); } @@ -3576,7 +3606,7 @@ TEST_F(basic_stl, vm_split_flow_var_small_range) { split.set_stream(&stream); split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 0, 1, 0); - + split.run(8, 4); } @@ -3605,7 +3635,7 @@ TEST_F(basic_stl, vm_split_client_var) { split.set_stream(&stream); split.set_client_var_as_split(0x10000001, 0x100000fe, 5000, 5050); - + split.run(8, 7); @@ -3730,7 +3760,7 @@ TEST_F(flow_stat, add_del_stream) { TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); TrexStream stream2(TrexStream::stSINGLE_BURST, 0, 0); TrexStream stream3(TrexStream::stSINGLE_BURST, 0, 0); - + stream.m_rx_check.m_enabled = true; stream.m_rx_check.m_rule_type = 7; @@ -3745,7 +3775,7 @@ TEST_F(flow_stat, add_del_stream) { } catch (TrexFStatEx e) { assert(e.type() == TrexException::T_FLOW_STAT_NO_STREAMS_EXIST); } - + try { rule_mgr.add_stream(&stream); } catch (TrexFStatEx e) { @@ -3792,18 +3822,16 @@ TEST_F(flow_stat, add_del_stream) { rule_mgr.del_stream(&stream2); } catch (TrexFStatEx e) { assert(e.type() == TrexException::T_FLOW_STAT_DEL_NON_EXIST); - } + } // do not want the destructor to try to free it - stream.m_pkt.binary = NULL; + stream.m_pkt.binary = NULL; stream2.m_pkt.binary = NULL; stream3.m_pkt.binary = NULL; } -TEST_F(flow_stat, start_stop_stream) { - // try starting with no add - // try starting more than 128 streams - // check that ip_id is changed for streams with no flow stat - // check that ip_id is changed for streams with flow stat IP_ID, PAYLOAD +TEST_F(flow_stat, alloc_mbuf_const) { + CGenNodeStateless cg; + cg.alloc_flow_stat_mbuf_test_const(); } diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index b0fd3180..fe450de3 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -1166,7 +1166,7 @@ public: /* this object is per core / per port / per queue - each core will have 2 ports to send too + each core will have 2 ports to send to port0 port1 @@ -1733,7 +1733,9 @@ public: virtual int close_file(void){ return (flush_tx_queue()); } - __attribute__ ((noinline)) void send_node_flow_stat(CGenNode * node); + __attribute__ ((noinline)) int send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * node_sl + , CCorePerPort * lp_port + , CVirtualIFPerSideStats * lp_stats, bool is_const); virtual int send_node(CGenNode * node); virtual void send_one_pkt(pkt_dir_t dir, rte_mbuf_t *m); @@ -1785,7 +1787,7 @@ protected: class CCoreEthIFStateless : public CCoreEthIF { public: virtual int send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * node_sl, CCorePerPort * lp_port - , CVirtualIFPerSideStats * lp_stats); + , CVirtualIFPerSideStats * lp_stats, bool is_const); virtual int send_node(CGenNode * node); protected: int handle_slow_path_node(CGenNode *node); @@ -2007,7 +2009,7 @@ void CCoreEthIF::update_mac_addr(CGenNode * node,uint8_t *p){ } int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * node_sl, CCorePerPort * lp_port - , CVirtualIFPerSideStats * lp_stats) { + , CVirtualIFPerSideStats * lp_stats, bool is_const) { // Defining this makes 10% percent packet loss. 1% packet reorder. # ifdef ERR_CNTRS_TEST static int temp=1; @@ -2015,29 +2017,23 @@ int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * no #endif uint16_t hw_id = node_sl->get_stat_hw_id(); - rte_mbuf *m_lat, *mi; + rte_mbuf *mi; + struct flow_stat_payload_header *fsp_head = NULL; if (hw_id >= MAX_FLOW_STATS) { + flush_tx_queue(); // payload rule hw_ids are in the range right above ip id rules uint16_t hw_id_payload = hw_id - MAX_FLOW_STATS; if (hw_id_payload > max_stat_hw_id_seen_payload) { max_stat_hw_id_seen_payload = hw_id_payload; } - // alloc mbuf just for the latency header - m_lat = CGlobalInfo::pktmbuf_alloc( get_socket_id(), sizeof(struct flow_stat_payload_header)); - if ( unlikely(m_lat == 0)) { - return -1; - } - char *p = rte_pktmbuf_append(m_lat, sizeof(struct flow_stat_payload_header)); - struct flow_stat_payload_header *fsp_head = (struct flow_stat_payload_header *)p; + + mi = node_sl->alloc_flow_stat_mbuf(m, fsp_head, is_const); fsp_head->seq = lp_stats->m_seq_num[hw_id_payload]; - fsp_head->time_stamp = os_get_hr_tick_64(); - // ??? maybe following two lines can be done offline fsp_head->hw_id = hw_id_payload; fsp_head->magic = FLOW_STAT_PAYLOAD_MAGIC; lp_stats->m_seq_num[hw_id_payload]++; - #ifdef ERR_CNTRS_TEST if (temp % 10 == 0) { fsp_head->seq = lp_stats->m_seq_num[hw_id_payload]++; @@ -2046,21 +2042,6 @@ int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * no fsp_head->seq = lp_stats->m_seq_num[hw_id_payload] - 4; } #endif - - if (rte_pktmbuf_is_contiguous(m)) { - // We have only the const mbuf - mi = CGlobalInfo::pktmbuf_alloc_small(get_socket_id()); - assert(mi); - rte_pktmbuf_attach(mi, m); - rte_pktmbuf_trim(mi, sizeof(struct flow_stat_payload_header)); - utl_rte_pktmbuf_add_after2(mi, m_lat); - } else { - // Field engine (vm) case. - rte_pktmbuf_trim(m, sizeof(struct flow_stat_payload_header)); - utl_rte_pktmbuf_add_last(m, m_lat); - mi = m; - } - } else { // ip id rule if (hw_id > max_stat_hw_id_seen) { @@ -2072,7 +2053,13 @@ int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * no lp_s->add_pkts(1); lp_s->add_bytes(mi->pkt_len); - send_pkt(lp_port, mi, lp_stats); + if (hw_id >= MAX_FLOW_STATS) { + fsp_head->time_stamp = os_get_hr_tick_64(); + send_pkt(lp_port, mi, lp_stats); + flush_tx_queue(); + } else { + send_pkt(lp_port, mi, lp_stats); + } return 0; } @@ -2105,7 +2092,7 @@ int CCoreEthIFStateless::send_node(CGenNode * no) { } if (unlikely(node_sl->is_stat_needed())) { - return send_node_flow_stat(m, node_sl, lp_port, lp_stats); + return send_node_flow_stat(m, node_sl, lp_port, lp_stats, node_sl->get_cache_mbuf() ? true:false); } else { send_pkt(lp_port,m,lp_stats); } diff --git a/src/pal/linux/mbuf.cpp b/src/pal/linux/mbuf.cpp index d6fdf461..846c776c 100755 --- a/src/pal/linux/mbuf.cpp +++ b/src/pal/linux/mbuf.cpp @@ -19,10 +19,16 @@ See the License for the specific language governing permissions and limitations under the License. */ +/* + * This file is compiled only for simulation. + * Since in simulation, we do not use DPDK libraries, all mbuf functions needed for simulation are duplictated here. + * with some small changes. + */ + #include "mbuf.h" #include #include -#include +#include #include #include "sanb_atomic.h" @@ -47,7 +53,7 @@ void utl_rte_pktmbuf_check(struct rte_mbuf *m){ } rte_mempool_t * utl_rte_mempool_create_non_pkt(const char *name, - unsigned n, + unsigned n, unsigned elt_size, unsigned cache_size, uint32_t _id , @@ -62,7 +68,7 @@ rte_mempool_t * utl_rte_mempool_create_non_pkt(const char *name, } rte_mempool_t * utl_rte_mempool_create(const char *name, - unsigned n, + unsigned n, unsigned elt_size, unsigned cache_size, uint32_t _id, @@ -90,7 +96,7 @@ uint16_t rte_mbuf_refcnt_update(rte_mbuf_t *m, int16_t value) { utl_rte_pktmbuf_check(m); uint32_t a=sanb_atomic_add_return_32_old(&m->refcnt_reserved, value); - return (a); + return (a); } @@ -99,10 +105,10 @@ uint16_t rte_mbuf_refcnt_update(rte_mbuf_t *m, int16_t value) void rte_pktmbuf_reset(struct rte_mbuf *m) { utl_rte_pktmbuf_check(m); - m->next = NULL; - m->pkt_len = 0; - m->nb_segs = 1; - m->in_port = 0xff; + m->next = NULL; + m->pkt_len = 0; + m->nb_segs = 1; + m->in_port = 0xff; m->refcnt_reserved=1; #if RTE_PKTMBUF_HEADROOM > 0 @@ -112,7 +118,7 @@ void rte_pktmbuf_reset(struct rte_mbuf *m) m->data_off = RTE_PKTMBUF_HEADROOM ; #endif - m->data_len = 0; + m->data_len = 0; } @@ -151,9 +157,9 @@ void rte_pktmbuf_free_seg(rte_mbuf_t *m){ if ( md != m ) { rte_pktmbuf_detach(m); if (rte_mbuf_refcnt_update(md, -1) == 0) { - free(md); - } - + free(md); + } + } free(m); @@ -164,112 +170,116 @@ void rte_pktmbuf_free_seg(rte_mbuf_t *m){ void rte_pktmbuf_free(rte_mbuf_t *m){ - rte_mbuf_t *m_next; + rte_mbuf_t *m_next; utl_rte_pktmbuf_check(m); - while (m != NULL) { - m_next = m->next; - rte_pktmbuf_free_seg(m); - m = m_next; - } + while (m != NULL) { + m_next = m->next; + rte_pktmbuf_free_seg(m); + m = m_next; + } } static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m) { - struct rte_mbuf *m2 = (struct rte_mbuf *)m; + struct rte_mbuf *m2 = (struct rte_mbuf *)m; utl_rte_pktmbuf_check(m); - while (m2->next != NULL) - m2 = m2->next; - return m2; + while (m2->next != NULL) + m2 = m2->next; + return m2; } static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m) { - return m->data_off; + return m->data_off; } static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m) { - return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) - - m->data_len); + return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) - + m->data_len); } char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len) { - void *tail; - struct rte_mbuf *m_last; - utl_rte_pktmbuf_check(m); + void *tail; + struct rte_mbuf *m_last; + utl_rte_pktmbuf_check(m); - m_last = rte_pktmbuf_lastseg(m); - if (len > rte_pktmbuf_tailroom(m_last)) - return NULL; + m_last = rte_pktmbuf_lastseg(m); + if (len > rte_pktmbuf_tailroom(m_last)) + return NULL; - tail = (char*) m_last->buf_addr + m_last->data_len; - m_last->data_len = (uint16_t)(m_last->data_len + len); - m->pkt_len = (m->pkt_len + len); - return (char*) tail; + tail = (char*) m_last->buf_addr + m_last->data_len; + m_last->data_len = (uint16_t)(m_last->data_len + len); + m->pkt_len = (m->pkt_len + len); + return (char*) tail; } char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len) { - utl_rte_pktmbuf_check(m); + utl_rte_pktmbuf_check(m); - if (len > m->data_len) - return NULL; + if (len > m->data_len) + return NULL; - m->data_len = (uint16_t)(m->data_len - len); - m->data_off += len; - m->pkt_len = (m->pkt_len - len); - return (char *)m->buf_addr + m->data_off; + m->data_len = (uint16_t)(m->data_len - len); + m->data_off += len; + m->pkt_len = (m->pkt_len - len); + return (char *)m->buf_addr + m->data_off; } int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len) { - struct rte_mbuf *m_last; + struct rte_mbuf *m_last; utl_rte_pktmbuf_check(m); - m_last = rte_pktmbuf_lastseg(m); - if (len > m_last->data_len) - return -1; + m_last = rte_pktmbuf_lastseg(m); + if (len > m_last->data_len) + return -1; - m_last->data_len = (uint16_t)(m_last->data_len - len); - m->pkt_len = (m->pkt_len - len); - return 0; + m_last->data_len = (uint16_t)(m_last->data_len - len); + m->pkt_len = (m->pkt_len - len); + return 0; } +int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m) +{ + return (m->nb_segs == 1); +} static void rte_pktmbuf_hexdump(const void *buf, unsigned int len) { - unsigned int i, out, ofs; - const unsigned char *data = (unsigned char *)buf; + unsigned int i, out, ofs; + const unsigned char *data = (unsigned char *)buf; #define LINE_LEN 80 - char line[LINE_LEN]; - - printf(" dump data at 0x%p, len=%u\n", data, len); - ofs = 0; - while (ofs < len) { - out = snprintf(line, LINE_LEN, " %08X", ofs); - for (i = 0; ofs+i < len && i < 16; i++) - out += snprintf(line+out, LINE_LEN - out, " %02X", - data[ofs+i]&0xff); - for (; i <= 16; i++) - out += snprintf(line+out, LINE_LEN - out, " "); - for (i = 0; ofs < len && i < 16; i++, ofs++) { - unsigned char c = data[ofs]; - if (!isascii(c) || !isprint(c)) - c = '.'; - out += snprintf(line+out, LINE_LEN - out, "%c", c); - } - printf("%s\n", line); - } + char line[LINE_LEN]; + + printf(" dump data at 0x%p, len=%u\n", data, len); + ofs = 0; + while (ofs < len) { + out = snprintf(line, LINE_LEN, " %08X", ofs); + for (i = 0; ofs+i < len && i < 16; i++) + out += snprintf(line+out, LINE_LEN - out, " %02X", + data[ofs+i]&0xff); + for (; i <= 16; i++) + out += snprintf(line+out, LINE_LEN - out, " "); + for (i = 0; ofs < len && i < 16; i++, ofs++) { + unsigned char c = data[ofs]; + if (!isascii(c) || !isprint(c)) + c = '.'; + out += snprintf(line+out, LINE_LEN - out, "%c", c); + } + printf("%s\n", line); + } } @@ -295,30 +305,30 @@ void rte_exit(int exit_code, const char *format, ...){ void rte_pktmbuf_dump(const struct rte_mbuf *m, unsigned dump_len) { - unsigned int len; - unsigned nb_segs; - - - printf("dump mbuf at 0x%p, phys=0x%p, buf_len=%u\n", - m, m->buf_addr, (unsigned)m->buf_len); - printf(" pkt_len=%u, nb_segs=%u, " - "in_port=%u\n", m->pkt_len, - (unsigned)m->nb_segs, (unsigned)m->in_port); - nb_segs = m->nb_segs; - - while (m && nb_segs != 0) { - - printf(" segment at 0x%p, data=0x%p, data_len=%u\n", - m, m->buf_addr, (unsigned)m->data_len); - len = dump_len; - if (len > m->data_len) - len = m->data_len; - if (len != 0) - rte_pktmbuf_hexdump(m->buf_addr, len); - dump_len -= len; - m = m->next; - nb_segs --; - } + unsigned int len; + unsigned nb_segs; + + + printf("dump mbuf at 0x%p, phys=0x%p, buf_len=%u\n", + m, m->buf_addr, (unsigned)m->buf_len); + printf(" pkt_len=%u, nb_segs=%u, " + "in_port=%u\n", m->pkt_len, + (unsigned)m->nb_segs, (unsigned)m->in_port); + nb_segs = m->nb_segs; + + while (m && nb_segs != 0) { + + printf(" segment at 0x%p, data=0x%p, data_len=%u\n", + m, m->buf_addr, (unsigned)m->data_len); + len = dump_len; + if (len > m->data_len) + len = m->data_len; + if (len != 0) + rte_pktmbuf_hexdump(m->buf_addr, len); + dump_len -= len; + m = m->next; + nb_segs --; + } } @@ -337,25 +347,25 @@ rte_mbuf_t * utl_rte_pktmbuf_add_after2(rte_mbuf_t *m1,rte_mbuf_t *m2){ void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md) { - rte_mbuf_refcnt_update(md, 1); - mi->buf_addr = md->buf_addr; - mi->buf_len = md->buf_len; - mi->data_off = md->data_off; + rte_mbuf_refcnt_update(md, 1); + mi->buf_addr = md->buf_addr; + mi->buf_len = md->buf_len; + mi->data_off = md->data_off; - mi->next = NULL; + mi->next = NULL; mi->data_len = md->data_len; - mi->pkt_len = mi->data_len; - mi->nb_segs = 1; + mi->pkt_len = mi->data_len; + mi->nb_segs = 1; } void rte_pktmbuf_detach(struct rte_mbuf *m) { - const struct rte_mempool *mp = m->pool; - void *buf = RTE_MBUF_TO_BADDR(m); - uint32_t buf_len = mp->elt_size - sizeof(*m); + const struct rte_mempool *mp = m->pool; + void *buf = RTE_MBUF_TO_BADDR(m); + uint32_t buf_len = mp->elt_size - sizeof(*m); - m->buf_addr = buf; - m->buf_len = (uint16_t)buf_len; + m->buf_addr = buf; + m->buf_len = (uint16_t)buf_len; #if RTE_PKTMBUF_HEADROOM > 0 m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ? @@ -365,7 +375,7 @@ void rte_pktmbuf_detach(struct rte_mbuf *m) #endif - m->data_len = 0; + m->data_len = 0; } @@ -403,7 +413,7 @@ uint64_t rte_rand(void){ void test_pkt_mbuf(){ rte_mempool_t * mp1=utl_rte_mempool_create("big-const", - CONST_NB_MBUF, + CONST_NB_MBUF, CONST_MBUF_SIZE, 32); rte_mbuf_t * m1 = rte_pktmbuf_alloc(mp1); @@ -411,7 +421,7 @@ void test_pkt_mbuf(){ char *p=rte_pktmbuf_append(m1, 10); int i; - + for (i=0; i<10;i++) { p[i]=i; } diff --git a/src/pal/linux/mbuf.h b/src/pal/linux/mbuf.h index 50f00b94..174c757d 100755 --- a/src/pal/linux/mbuf.h +++ b/src/pal/linux/mbuf.h @@ -97,7 +97,7 @@ char *rte_pktmbuf_append(rte_mbuf_t *m, uint16_t len); char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len); int rte_pktmbuf_trim(rte_mbuf_t *m, uint16_t len); - +int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m); void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md); diff --git a/src/pal/linux_dpdk/dpdk22/rte_config.h b/src/pal/linux_dpdk/dpdk22/rte_config.h index e1f5cb23..8670743b 100644 --- a/src/pal/linux_dpdk/dpdk22/rte_config.h +++ b/src/pal/linux_dpdk/dpdk22/rte_config.h @@ -58,7 +58,6 @@ #undef RTE_ETHDEV_QUEUE_STAT_CNTRS #define RTE_ETHDEV_QUEUE_STAT_CNTRS 16 #undef RTE_ETHDEV_RXTX_CALLBACKS -#define RTE_ETHDEV_RXTX_CALLBACKS 1 #undef RTE_NIC_BYPASS #undef RTE_LIBRTE_EM_PMD #define RTE_LIBRTE_EM_PMD 1 diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index 27376fe4..fa6340b9 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -255,7 +255,17 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { section["ports"][i]["pci_addr"] = pci_addr; section["ports"][i]["numa"] = numa; - section["ports"][i]["rx"]["caps"] = port->get_rx_caps(); + uint16_t caps = port->get_rx_caps(); + section["ports"][i]["rx"]["caps"] = Json::arrayValue; + if (caps & TrexPlatformApi::IF_STAT_IPV4_ID) { + section["ports"][i]["rx"]["caps"].append("flow_stats"); + } + if (caps & TrexPlatformApi::IF_STAT_PAYLOAD) { + section["ports"][i]["rx"]["caps"].append("latency"); + } + if (caps & TrexPlatformApi::IF_STAT_IPV4_ID) { + section["ports"][i]["rx"]["caps"].append("rx_bytes"); + } section["ports"][i]["rx"]["counters"] = port->get_rx_count_num(); diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp index 6959476c..0e3d83e8 100644 --- a/src/stateless/cp/trex_stream.cpp +++ b/src/stateless/cp/trex_stream.cpp @@ -155,6 +155,11 @@ TrexStream::TrexStream(uint8_t type, } TrexStream::~TrexStream() { + if (m_rx_check.m_enabled) { + try { + get_stateless_obj()->m_rx_flow_stat.del_stream(this); + } catch (TrexFStatEx) {} + } if (m_pkt.binary) { delete [] m_pkt.binary; } diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index 8bb89ee9..763bf3e2 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -177,7 +177,7 @@ void CGenNodeStateless::refresh(){ m_state = CGenNodeStateless::ss_ACTIVE; /* refresh init value */ -#if 0 +#if 0 /* TBD should add a JSON varible for that */ refresh_vm_bss(); #endif @@ -185,7 +185,7 @@ void CGenNodeStateless::refresh(){ void CGenNodeCommand::free_command(){ - + assert(m_cmd); m_cmd->on_node_remove(); delete m_cmd; @@ -211,16 +211,105 @@ std::string CGenNodeStateless::get_stream_state_str(stream_state_t stream_state) return(res); } -rte_mbuf_t * CGenNodeStateless::alloc_flow_stat_mbuf(rte_mbuf_t *m) { - //????????? temp implementation. Just copy the entire mbuf - rte_mbuf_t *m_new = CGlobalInfo::pktmbuf_alloc( get_socket_id(), m->data_len ); - /* TBD remove this, should handle cases of error */ - assert(m_new); - char *p = rte_pktmbuf_mtod(m, char*); - char *p_new = rte_pktmbuf_append(m_new, m->data_len); - memcpy(p_new , p, m->data_len); +/* + * Allocate mbuf for flow stat (and latency) info sending + * m - Original mbuf (can be complicated mbuf data structure) + * fsp_head - return pointer in which the flow stat info should be filled + * is_const - is the given mbuf const + * return new mbuf structure in which the fsp_head can be written. If needed, orginal mbuf is freed. + */ +rte_mbuf_t * CGenNodeStateless::alloc_flow_stat_mbuf(rte_mbuf_t *m, struct flow_stat_payload_header *&fsp_head + , bool is_const) { + rte_mbuf_t *m_ret = NULL, *m_lat = NULL; + uint16_t fsp_head_size = sizeof(struct flow_stat_payload_header); + + if (is_const) { + // const mbuf case + if (rte_pktmbuf_data_len(m) > 128) { + m_ret = CGlobalInfo::pktmbuf_alloc_small(get_socket_id()); + assert(m_ret); + // alloc mbuf just for the latency header + m_lat = CGlobalInfo::pktmbuf_alloc( get_socket_id(), fsp_head_size); + assert(m_lat); + fsp_head = (struct flow_stat_payload_header *)rte_pktmbuf_append(m_lat, fsp_head_size); + rte_pktmbuf_attach(m_ret, m); + rte_pktmbuf_trim(m_ret, sizeof(struct flow_stat_payload_header)); + utl_rte_pktmbuf_add_after2(m_ret, m_lat); + return m_ret; + } else { + // Short packet. Just copy all bytes. + m_ret = CGlobalInfo::pktmbuf_alloc( get_socket_id(), rte_pktmbuf_data_len(m) ); + assert(m_ret); + char *p = rte_pktmbuf_mtod(m, char*); + char *p_new = rte_pktmbuf_append(m_ret, rte_pktmbuf_data_len(m)); + memcpy(p_new , p, rte_pktmbuf_data_len(m)); + fsp_head = (struct flow_stat_payload_header *)(p_new + rte_pktmbuf_data_len(m) - fsp_head_size); + rte_pktmbuf_free(m); + return m_ret; + } + } else { + // Field engine (vm) + if (rte_pktmbuf_is_contiguous(m)) { + // one, r/w mbuf + char *p = rte_pktmbuf_mtod(m, char*); + fsp_head = (struct flow_stat_payload_header *)(p + rte_pktmbuf_data_len(m) - fsp_head_size); + return m; + } else { + // r/w --> read only. Should do something like: + // Alloc indirect,. make r/w->indirect point to read_only) -> new fsp_header + // for the mean time, just copy the entire packet. + m_ret = CGlobalInfo::pktmbuf_alloc( get_socket_id(), rte_pktmbuf_pkt_len(m) ); + assert(m_ret); + char *p_new = rte_pktmbuf_append(m_ret, rte_pktmbuf_pkt_len(m)); + rte_mbuf_t *m_free = m; + while (m != NULL) { + char *p = rte_pktmbuf_mtod(m, char*); + memcpy(p_new, p, m->data_len); + p_new += m->data_len; + m = m->next; + } + p_new = rte_pktmbuf_mtod(m_ret, char*); + fsp_head = (struct flow_stat_payload_header *)(p_new + rte_pktmbuf_data_len(m_ret) - fsp_head_size); + rte_pktmbuf_free(m_free); + return m_ret; + } + } +} - return m_new; +// test the const case of alloc_flow_stat_mbuf. The more complicated non const case is tested in the simulation. +bool CGenNodeStateless::alloc_flow_stat_mbuf_test_const() { + rte_mbuf_t *m, *m_test; + uint16_t sizes[2] = {64, 500}; + uint16_t size; + struct flow_stat_payload_header *fsp_head; + char *p; + + set_socket_id(0); + for (int test_num = 0; test_num < sizeof(sizes)/sizeof(sizes[0]); test_num++) { + size = sizes[test_num]; + m = CGlobalInfo::pktmbuf_alloc(get_socket_id(), size); + p = rte_pktmbuf_append(m, size); + for (int i = 0; i < size; i++) { + p[i] = (char)i; + } + m_test = alloc_flow_stat_mbuf(m, fsp_head, true); + p = rte_pktmbuf_mtod(m_test, char*); + assert(rte_pktmbuf_pkt_len(m_test) == size); + for (int i = 0; i < rte_pktmbuf_pkt_len(m_test) - sizeof(*fsp_head); i++) { + assert(p[i] == (char)i); + } + // verify fsp_head points correctly + if (size > 128) { // should match threshould in alloc_flow_stat_mbuf + assert(rte_pktmbuf_data_len(m_test) == size - sizeof(*fsp_head)); + assert(rte_pktmbuf_data_len(m_test->next) == sizeof(*fsp_head)); + assert((char *)fsp_head == rte_pktmbuf_mtod((m_test->next), char*)); + } else { + assert(rte_pktmbuf_data_len(m_test) == size); + assert (((char *)fsp_head) + sizeof (*fsp_head) == p + rte_pktmbuf_data_len(m_test)); + } + rte_pktmbuf_free(m_test); + } + return true; } rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ @@ -235,14 +324,14 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ /* TBD remove this, should handle cases of error */ assert(m); char *p=rte_pktmbuf_append(m, prefix_size); - memcpy( p ,m_original_packet_data_prefix, prefix_size); + memcpy( p ,m_original_packet_data_prefix, prefix_size); /* run the VM program */ StreamDPVmInstructionsRunner runner; runner.run( (uint32_t*)m_vm_flow_var, - m_vm_program_size, + m_vm_program_size, m_vm_program, m_vm_flow_var, (uint8_t*)p); @@ -330,7 +419,7 @@ bool TrexStatelessDpPerPort::resume_traffic(uint8_t port_id){ assert(m_state == TrexStatelessDpPerPort::ppSTATE_PAUSE); for (auto dp_stream : m_active_nodes) { - CGenNodeStateless * node =dp_stream.m_node; + CGenNodeStateless * node =dp_stream.m_node; assert(node->get_port_id() == port_id); assert(node->is_pause() == true); node->set_pause(false); @@ -341,11 +430,11 @@ bool TrexStatelessDpPerPort::resume_traffic(uint8_t port_id){ bool TrexStatelessDpPerPort::update_traffic(uint8_t port_id, double factor) { - assert( (m_state == TrexStatelessDpPerPort::ppSTATE_TRANSMITTING || + assert( (m_state == TrexStatelessDpPerPort::ppSTATE_TRANSMITTING || (m_state == TrexStatelessDpPerPort::ppSTATE_PAUSE)) ); for (auto dp_stream : m_active_nodes) { - CGenNodeStateless * node = dp_stream.m_node; + CGenNodeStateless * node = dp_stream.m_node; assert(node->get_port_id() == port_id); node->update_rate(factor); @@ -360,7 +449,7 @@ bool TrexStatelessDpPerPort::pause_traffic(uint8_t port_id){ assert(m_state == TrexStatelessDpPerPort::ppSTATE_TRANSMITTING); for (auto dp_stream : m_active_nodes) { - CGenNodeStateless * node =dp_stream.m_node; + CGenNodeStateless * node =dp_stream.m_node; assert(node->get_port_id() == port_id); assert(node->is_pause() == false); node->set_pause(true); @@ -416,7 +505,7 @@ bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id, bool TrexStatelessDpPerPort::stop_traffic(uint8_t port_id, - bool stop_on_id, + bool stop_on_id, int event_id){ @@ -434,7 +523,7 @@ bool TrexStatelessDpPerPort::stop_traffic(uint8_t port_id, } for (auto dp_stream : m_active_nodes) { - CGenNodeStateless * node =dp_stream.m_node; + CGenNodeStateless * node =dp_stream.m_node; assert(node->get_port_id() == port_id); if ( node->get_state() == CGenNodeStateless::ss_ACTIVE) { node->mark_for_free(); @@ -549,12 +638,12 @@ bool TrexStatelessDpCore::set_stateless_next_node(CGenNodeStateless * cur_node, /** - * in idle state loop, the processor most of the time sleeps - * and periodically checks for messages - * + * in idle state loop, the processor most of the time sleeps + * and periodically checks for messages + * * @author imarom (01-Nov-15) */ -void +void TrexStatelessDpCore::idle_state_loop() { const int SHORT_DELAY_MS = 2; @@ -578,7 +667,7 @@ TrexStatelessDpCore::idle_state_loop() { } else { delay(LONG_DELAY_MS); } - + } } @@ -592,10 +681,10 @@ void TrexStatelessDpCore::quit_main_loop(){ /** - * scehduler runs when traffic exists - * it will return when no more transmitting is done on this - * core - * + * scehduler runs when traffic exists + * it will return when no more transmitting is done on this + * core + * * @author imarom (01-Nov-15) */ void @@ -616,7 +705,7 @@ TrexStatelessDpCore::start_scheduler() { } -void +void TrexStatelessDpCore::run_once(){ idle_state_loop(); @@ -644,7 +733,7 @@ TrexStatelessDpCore::start() { } /* only if both port are idle we can exit */ -void +void TrexStatelessDpCore::schedule_exit(){ CGenNodeCommand *node = (CGenNodeCommand *)m_core->create_node() ; @@ -660,7 +749,7 @@ TrexStatelessDpCore::schedule_exit(){ } -void +void TrexStatelessDpCore::add_global_duration(double duration){ if (duration > 0.0) { CGenNode *node = m_core->create_node() ; @@ -717,7 +806,7 @@ void TrexStatelessDpCore::update_mac_addr(TrexStream * stream, } /* take from cfg_file */ - if ( (ov_src == false) && + if ( (ov_src == false) && (ov_dst == TrexStream::stCFG_FILE) ){ m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir,(uint8_t*)raw_pkt); @@ -808,7 +897,7 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, node->m_time = m_core->m_cur_time_sec + stream->get_start_delay_sec(); pkt_dir_t dir = m_core->m_node_gen.m_v_if->port_id_to_dir(stream->m_port_id); - node->m_flags = 0; + node->m_flags = 0; node->m_src_port =0; node->m_original_packet_data_prefix = 0; @@ -823,7 +912,7 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, node->set_socket_id(m_core->m_node_gen.m_socket_id); /* build a mbuf from a packet */ - + uint16_t pkt_size = stream->m_pkt.len; const uint8_t *stream_pkt = stream->m_pkt.binary; @@ -874,14 +963,14 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, /* allocate const mbuf */ rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), pkt_size); assert(m); - + char *p = rte_pktmbuf_append(m, pkt_size); assert(p); /* copy the packet */ memcpy(p,stream_pkt,pkt_size); - + update_mac_addr(stream,node,dir,p); - + /* set the packet as a readonly */ node->set_cache_mbuf(m); @@ -924,7 +1013,7 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, if ( lpDpVm->is_pkt_size_var() ) { - // mark the node as varible size + // mark the node as varible size node->set_var_pkt_size(); } @@ -965,7 +1054,7 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, } void -TrexStatelessDpCore::start_traffic(TrexStreamsCompiledObj *obj, +TrexStatelessDpCore::start_traffic(TrexStreamsCompiledObj *obj, double duration, int event_id) { @@ -1030,7 +1119,7 @@ bool TrexStatelessDpCore::are_all_ports_idle(){ } -void +void TrexStatelessDpCore::resume_traffic(uint8_t port_id){ TrexStatelessDpPerPort * lp_port = get_port_db(port_id); @@ -1039,7 +1128,7 @@ TrexStatelessDpCore::resume_traffic(uint8_t port_id){ } -void +void TrexStatelessDpCore::pause_traffic(uint8_t port_id){ TrexStatelessDpPerPort * lp_port = get_port_db(port_id); @@ -1047,7 +1136,6 @@ TrexStatelessDpCore::pause_traffic(uint8_t port_id){ lp_port->pause_traffic(port_id); } - void TrexStatelessDpCore::push_pcap(uint8_t port_id, int event_id, @@ -1082,8 +1170,7 @@ TrexStatelessDpCore::push_pcap(uint8_t port_id, m_state = TrexStatelessDpCore::STATE_PCAP_TX; } - -void +void TrexStatelessDpCore::update_traffic(uint8_t port_id, double factor) { TrexStatelessDpPerPort * lp_port = get_port_db(port_id); @@ -1094,7 +1181,7 @@ TrexStatelessDpCore::update_traffic(uint8_t port_id, double factor) { void TrexStatelessDpCore::stop_traffic(uint8_t port_id, - bool stop_on_id, + bool stop_on_id, int event_id) { /* we cannot remove nodes not from the top of the queue so for every active node - make sure next time @@ -1104,7 +1191,6 @@ TrexStatelessDpCore::stop_traffic(uint8_t port_id, if ( lp_port->stop_traffic(port_id,stop_on_id,event_id) == false){ return; } - /* flush the TX queue before sending done message to the CP */ m_core->flush_tx_queue(); @@ -1119,9 +1205,9 @@ TrexStatelessDpCore::stop_traffic(uint8_t port_id, /** * handle a message from CP to DP - * + * */ -void +void TrexStatelessDpCore::handle_cp_msg(TrexStatelessCpToDpMsgBase *msg) { msg->handle(this); delete msg; diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index 4edf3a06..605ef6a0 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -390,7 +390,9 @@ public: return (m_src_port); } - rte_mbuf_t * alloc_flow_stat_mbuf(rte_mbuf_t *); //temp ??? + rte_mbuf_t * alloc_flow_stat_mbuf(rte_mbuf_t *m, struct flow_stat_payload_header * &fsp_head + , bool is_const); + bool alloc_flow_stat_mbuf_test_const(); rte_mbuf_t * alloc_node_with_vm(); void free_stl_node(); -- cgit 1.2.3-korg