diff options
Diffstat (limited to 'src/stateless/rx')
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.cpp | 16 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.h | 2 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_port_mngr.cpp | 86 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_port_mngr.h | 55 |
4 files changed, 131 insertions, 28 deletions
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp index 9898e8b9..31fef68f 100644 --- a/src/stateless/rx/trex_stateless_rx_core.cpp +++ b/src/stateless/rx/trex_stateless_rx_core.cpp @@ -85,12 +85,12 @@ void CRxCoreStateless::create(const CRxSlCfg &cfg) { /* create per port manager */ for (int i = 0; i < m_max_ports; i++) { const TRexPortAttr *port_attr = get_stateless_obj()->get_platform_api()->getPortAttrObj(i); - m_rx_port_mngr[i].create(cfg.m_ports[i], + m_rx_port_mngr[i].create(port_attr, + cfg.m_ports[i], m_rfc2544, &m_err_cntrs, &m_cpu_dp_u, - cfg.m_num_crc_fix_bytes, - port_attr); + cfg.m_num_crc_fix_bytes); } } @@ -189,6 +189,7 @@ void CRxCoreStateless::handle_work_stage() { /* set the next sync time to */ dsec_t sync_time_sec = now_sec() + (1.0 / 1000); + dsec_t tick_time_sec = now_sec() + 1.0; while (m_state == STATE_WORKING) { process_all_pending_pkts(); @@ -197,8 +198,11 @@ void CRxCoreStateless::handle_work_stage() { if ( (now - sync_time_sec) > 0 ) { periodic_check_for_cp_messages(); + } + + if ( (now - tick_time_sec) > 0) { port_manager_tick(); - sync_time_sec = now + (1.0 / 1000); + tick_time_sec = now + 1.0; } rte_pause(); @@ -211,6 +215,8 @@ void CRxCoreStateless::start() { m_monitor.create("STL RX CORE", 1); TrexWatchDog::getInstance().register_monitor(&m_monitor); + recalculate_next_state(); + while (m_state != STATE_QUIT) { switch (m_state) { case STATE_IDLE: @@ -334,7 +340,7 @@ CRxCoreStateless::disable_latency() { recalculate_next_state(); } -const RXPortManager & +RXPortManager & CRxCoreStateless::get_rx_port_mngr(uint8_t port_id) { assert(port_id < m_max_ports); return m_rx_port_mngr[port_id]; diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h index cd16bb8a..96e511b4 100644 --- a/src/stateless/rx/trex_stateless_rx_core.h +++ b/src/stateless/rx/trex_stateless_rx_core.h @@ -151,7 +151,7 @@ class CRxCoreStateless { void enable_latency(); void disable_latency(); - const RXPortManager &get_rx_port_mngr(uint8_t port_id); + RXPortManager &get_rx_port_mngr(uint8_t port_id); private: void handle_cp_msg(TrexStatelessCpToRxMsgBase *msg); diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp index af312700..e36f825d 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp @@ -23,6 +23,7 @@ #include "common/captureFile.h" #include "trex_stateless_rx_core.h" #include "common/Network/Packet/Arp.h" +#include "pkt_gen.h" /************************************** * latency RX feature @@ -507,16 +508,16 @@ protected: }; RXServer::RXServer() { - m_port_attr = NULL; m_io = NULL; + m_src_addr = NULL; m_port_id = 255; } void -RXServer::create(const TRexPortAttr *port_attr, CPortLatencyHWBase *io) { - m_port_attr = port_attr; - m_io = io; - m_port_id = port_attr->get_port_id(); +RXServer::create(uint8_t port_id, CPortLatencyHWBase *io, const CManyIPInfo *src_addr) { + m_port_id = port_id; + m_io = io; + m_src_addr = src_addr; } @@ -538,7 +539,7 @@ void RXServer::handle_icmp(RXPktParser &parser) { /* maybe not for us... */ - if (parser.m_ipv4->getDestIp() != m_port_attr->get_src_ipv4()) { + if (!m_src_addr->exists(parser.m_ipv4->getDestIp())) { return; } @@ -578,6 +579,7 @@ RXServer::handle_icmp(RXPktParser &parser) { void RXServer::handle_arp(RXPktParser &parser) { + MacAddress src_mac; /* only ethernet format supported */ if (parser.m_arp->getHrdType() != ArpHdr::ARP_HDR_HRD_ETHER) { @@ -595,7 +597,7 @@ RXServer::handle_arp(RXPktParser &parser) { } /* are we the target ? if not - go home */ - if (parser.m_arp->getTip() != m_port_attr->get_src_ipv4()) { + if (!m_src_addr->lookup(parser.m_arp->getTip(), 0, src_mac)) { return; } @@ -612,14 +614,14 @@ RXServer::handle_arp(RXPktParser &parser) { response_parser.m_arp->setOp(ArpHdr::ARP_HDR_OP_REPLY); /* fix the MAC addresses */ - response_parser.m_ether->mySource = m_port_attr->get_src_mac(); + response_parser.m_ether->mySource = src_mac; response_parser.m_ether->myDestination = parser.m_ether->mySource; /* fill up the fields */ /* src */ - response_parser.m_arp->m_arp_sha = m_port_attr->get_src_mac(); - response_parser.m_arp->setSip(m_port_attr->get_src_ipv4()); + response_parser.m_arp->m_arp_sha = src_mac; + response_parser.m_arp->setSip(parser.m_arp->getTip()); /* dst */ response_parser.m_arp->m_arp_tha = parser.m_arp->m_arp_sha; @@ -655,6 +657,44 @@ RXServer::duplicate_mbuf(const rte_mbuf_t *m) { } /************************************** + * Gratidious ARP + * + *************************************/ +void +RXGratARP::create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr) { + m_io = io; + m_port_id = port_id; + m_src_addr = src_addr; +} + +void +RXGratARP::send_next_grat_arp() { + uint8_t src_mac[ETHER_ADDR_LEN]; + + const COneIPInfo *ip_info = m_src_addr->get_next_loop(); + if (!ip_info) { + return; + } + + rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc_small(CGlobalInfo::m_socket.port_to_socket(m_port_id)); + assert(m); + + uint8_t *p = (uint8_t *)rte_pktmbuf_append(m, ip_info->get_grat_arp_len()); + ip_info->get_mac(src_mac); + uint16_t vlan = ip_info->get_vlan(); + + /* for now only IPv4 */ + assert(ip_info->ip_ver() == COneIPInfo::IP4_VER); + uint32_t sip = ((COneIPv4Info *)ip_info)->get_ip(); + + CTestPktGen::create_arp_req(p, sip, sip, src_mac, vlan, m_port_id); + + m_io->tx(m); + + +} + +/************************************** * Port manager * *************************************/ @@ -663,26 +703,37 @@ RXPortManager::RXPortManager() { clear_all_features(); m_io = NULL; m_cpu_dp_u = NULL; + m_port_id = UINT8_MAX; } void -RXPortManager::create(CPortLatencyHWBase *io, +RXPortManager::create(const TRexPortAttr *port_attr, + CPortLatencyHWBase *io, CRFC2544Info *rfc2544, CRxCoreErrCntrs *err_cntrs, CCpuUtlDp *cpu_util, - uint8_t crc_bytes_num, - const TRexPortAttr *port_attr) { + uint8_t crc_bytes_num) { + + m_port_id = port_attr->get_port_id(); m_io = io; m_cpu_dp_u = cpu_util; m_num_crc_fix_bytes = crc_bytes_num; + /* if IPv4 is configured - add it to the grat service */ + uint32_t src_ipv4 = port_attr->get_src_ipv4(); + if (src_ipv4) { + m_src_addr.insert(COneIPv4Info(src_ipv4, 0, port_attr->get_src_mac(), m_port_id)); + } + /* init features */ m_latency.create(rfc2544, err_cntrs); - m_server.create(port_attr, io); + m_server.create(m_port_id, io, &m_src_addr); + m_grat_arp.create(m_port_id, io, &m_src_addr); /* by default, server feature is always on */ set_feature(SERVER); + set_feature(GRAT_ARP); } void RXPortManager::handle_pkt(const rte_mbuf_t *m) { @@ -706,7 +757,6 @@ void RXPortManager::handle_pkt(const rte_mbuf_t *m) { } } - int RXPortManager::process_all_pending_pkts(bool flush_rx) { rte_mbuf_t *rx_pkts[64]; @@ -747,8 +797,13 @@ RXPortManager::tick() { if (is_feature_set(RECORDER)) { m_recorder.flush_to_disk(); } + + if (is_feature_set(GRAT_ARP)) { + m_grat_arp.send_next_grat_arp(); + } } + Json::Value RXPortManager::to_json() const { Json::Value output = Json::objectValue; @@ -777,3 +832,4 @@ RXPortManager::to_json() const { return output; } + diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.h b/src/stateless/rx/trex_stateless_rx_port_mngr.h index 12b601ea..e72b0ff0 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.h +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.h @@ -264,7 +264,7 @@ class RXServer { public: RXServer(); - void create(const TRexPortAttr *port_attr, CPortLatencyHWBase *io); + void create(uint8_t port_id, CPortLatencyHWBase *io, const CManyIPInfo *src_addr); void handle_pkt(const rte_mbuf_t *m); private: @@ -272,9 +272,36 @@ private: void handle_arp(RXPktParser &parser); rte_mbuf_t *duplicate_mbuf(const rte_mbuf_t *m); - const TRexPortAttr *m_port_attr; CPortLatencyHWBase *m_io; uint8_t m_port_id; + const CManyIPInfo *m_src_addr; +}; + +/************************************** + * Gratidious ARP + * + *************************************/ +class RXGratARP { +public: + RXGratARP() { + m_io = NULL; + m_port_id = UINT8_MAX; + m_src_addr = NULL; + } + + void create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr); + + + /** + * the main 'tick' of the service + * + */ + void send_next_grat_arp(); + +private: + CPortLatencyHWBase *m_io; + CManyIPInfo *m_src_addr; + uint8_t m_port_id; }; /************************ manager ***************************/ @@ -291,22 +318,25 @@ public: LATENCY = 0x1, RECORDER = 0x2, QUEUE = 0x4, - SERVER = 0x8 + SERVER = 0x8, + GRAT_ARP = 0x10, }; RXPortManager(); - void create(CPortLatencyHWBase *io, + void create(const TRexPortAttr *port_attr, + CPortLatencyHWBase *io, CRFC2544Info *rfc2544, CRxCoreErrCntrs *err_cntrs, CCpuUtlDp *cpu_util, - uint8_t crc_bytes_num, - const TRexPortAttr *port_attr); + uint8_t crc_bytes_num); + void clear_stats() { m_latency.reset_stats(); } + void get_latency_stats(rx_per_flow_t *rx_stats, int min, int max, @@ -390,6 +420,15 @@ public: */ void tick(); + /** + * updates the source addresses registered with the port + * + */ + void update_src_addr(const CManyIPInfo &new_src_addr) { + /* deep copy */ + m_src_addr = new_src_addr; + } + bool has_features_set() { return (m_features != NO_FEATURES); } @@ -423,17 +462,19 @@ private: } uint32_t m_features; - + uint8_t m_port_id; RXLatency m_latency; RXPacketRecorder m_recorder; RXQueue m_queue; RXServer m_server; + RXGratARP m_grat_arp; // compensate for the fact that hardware send us packets without Ethernet CRC, and we report with it uint8_t m_num_crc_fix_bytes; CCpuUtlDp *m_cpu_dp_u; CPortLatencyHWBase *m_io; + CManyIPInfo m_src_addr; }; |