diff options
author | imarom <imarom@cisco.com> | 2016-12-13 18:15:22 +0200 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-12-13 18:15:22 +0200 |
commit | 0fdd81a94d62592b0ec9888022d793f670c8476f (patch) | |
tree | ec52cd0f090793e26f67bc017d402b737acd71b5 /src/stateless | |
parent | 0c45815234abbb79b147b8093eb19e274ee65f52 (diff) |
Major refactor - L2 / L3 modes for ports
Signed-off-by: imarom <imarom@cisco.com>
Diffstat (limited to 'src/stateless')
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 59 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 11 | ||||
-rw-r--r-- | src/stateless/messaging/trex_stateless_messaging.cpp | 13 | ||||
-rw-r--r-- | src/stateless/messaging/trex_stateless_messaging.h | 31 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.cpp | 27 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.h | 10 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_port_mngr.cpp | 78 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_port_mngr.h | 54 |
8 files changed, 247 insertions, 36 deletions
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 057f6521..62805dbc 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -988,18 +988,67 @@ TrexStatelessPort::get_rx_queue_pkts() { } +/** + * configures port in L2 mode + * + */ +void +TrexStatelessPort::set_l2_mode(const uint8_t *dest_mac) { + + /* no IPv4 src */ + getPortAttrObj()->set_src_ipv4(0); + + /* set destination as MAC */ + getPortAttrObj()->get_dest().set_dest(dest_mac); + + TrexStatelessRxSetL2Mode *msg = new TrexStatelessRxSetL2Mode(m_port_id); + send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg ); +} + +/** + * configures port in L3 mode - unresolved + */ +void +TrexStatelessPort::set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4) { + + /* set src IPv4 */ + getPortAttrObj()->set_src_ipv4(src_ipv4); + + /* set dest IPv4 */ + getPortAttrObj()->get_dest().set_dest(dest_ipv4); + + /* send RX core the relevant info */ + CManyIPInfo ip_info; + ip_info.insert(COneIPv4Info(src_ipv4, 0, getPortAttrObj()->get_src_mac())); + + TrexStatelessRxSetL3Mode *msg = new TrexStatelessRxSetL3Mode(m_port_id, ip_info, false); + send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg ); +} + +/** + * configures port in L3 mode - resolved + * + */ void -TrexStatelessPort::set_src_ipv4(uint32_t ipv4) { +TrexStatelessPort::set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4, const uint8_t *resolved_mac) { - getPortAttrObj()->set_src_ipv4(ipv4); + /* set src IPv4 */ + getPortAttrObj()->set_src_ipv4(src_ipv4); - CManyIPInfo src_addr; - src_addr.insert(COneIPv4Info(ipv4, 0, getPortAttrObj()->get_src_mac(), m_port_id)); + /* set dest IPv4 + resolved MAC */ + getPortAttrObj()->get_dest().set_dest(dest_ipv4, resolved_mac); - TrexStatelessRxUpdateSrcAddr *msg = new TrexStatelessRxUpdateSrcAddr(m_port_id, src_addr); + /* send RX core the relevant info */ + CManyIPInfo ip_info; + ip_info.insert(COneIPv4Info(src_ipv4, 0, getPortAttrObj()->get_src_mac())); + + bool is_grat_arp_needed = !getPortAttrObj()->is_loopback(); + + TrexStatelessRxSetL3Mode *msg = new TrexStatelessRxSetL3Mode(m_port_id, ip_info, is_grat_arp_needed); send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg ); } + Json::Value TrexStatelessPort::rx_features_to_json() { static MsgReply<Json::Value> reply; diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 3ae74f5a..317f4f70 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -400,10 +400,17 @@ public: const RXPacketBuffer *get_rx_queue_pkts(); /** - * sets an IPv4 source address + * configures port for L2 mode * */ - void set_src_ipv4(uint32_t ipv4); + void set_l2_mode(const uint8_t *dest_mac); + + /** + * configures port in L3 mode + * + */ + void set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4); + void set_l3_mode(uint32_t src_ipv4, uint32_t dest_ipv4, const uint8_t *resolved_mac); /** * generate a JSON describing the status diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp index dc656e67..2b8e93bb 100644 --- a/src/stateless/messaging/trex_stateless_messaging.cpp +++ b/src/stateless/messaging/trex_stateless_messaging.cpp @@ -317,7 +317,16 @@ TrexStatelessRxFeaturesToJson::handle(CRxCoreStateless *rx_core) { } bool -TrexStatelessRxUpdateSrcAddr::handle(CRxCoreStateless *rx_core) { - rx_core->get_rx_port_mngr(m_port_id).update_src_addr(m_src_addr); +TrexStatelessRxSetL2Mode::handle(CRxCoreStateless *rx_core) { + rx_core->get_rx_port_mngr(m_port_id).set_l2_mode(); + return true; } + +bool +TrexStatelessRxSetL3Mode::handle(CRxCoreStateless *rx_core) { + rx_core->get_rx_port_mngr(m_port_id).set_l3_mode(m_src_addr, m_is_grat_arp_needed); + + return true; +} + diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h index 5f00c244..dbdd9b56 100644 --- a/src/stateless/messaging/trex_stateless_messaging.h +++ b/src/stateless/messaging/trex_stateless_messaging.h @@ -569,13 +569,33 @@ private: }; -class TrexStatelessRxUpdateSrcAddr : public TrexStatelessCpToRxMsgBase { +/** + * updates the RX core that we are in L2 mode + */ +class TrexStatelessRxSetL2Mode : public TrexStatelessCpToRxMsgBase { public: - TrexStatelessRxUpdateSrcAddr(uint8_t port_id, - const CManyIPInfo &src_addr) { - + TrexStatelessRxSetL2Mode(uint8_t port_id) { m_port_id = port_id; - m_src_addr = src_addr; + } + + virtual bool handle(CRxCoreStateless *rx_core); + +private: + uint8_t m_port_id; +}; + +/** + * updates the RX core that we are in a L3 mode + */ +class TrexStatelessRxSetL3Mode : public TrexStatelessCpToRxMsgBase { +public: + TrexStatelessRxSetL3Mode(uint8_t port_id, + const CManyIPInfo &src_addr, + bool is_grat_arp_needed) { + + m_port_id = port_id; + m_src_addr = src_addr; + m_is_grat_arp_needed = is_grat_arp_needed; } virtual bool handle(CRxCoreStateless *rx_core); @@ -583,6 +603,7 @@ public: private: uint8_t m_port_id; CManyIPInfo m_src_addr; + bool m_is_grat_arp_needed; }; /** diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp index 31fef68f..502af9c1 100644 --- a/src/stateless/rx/trex_stateless_rx_core.cpp +++ b/src/stateless/rx/trex_stateless_rx_core.cpp @@ -185,17 +185,30 @@ void CRxCoreStateless::port_manager_tick() { } } +/** + * for each port handle the grat ARP mechansim + * + */ +void CRxCoreStateless::handle_grat_arp() { + for (int i = 0; i < m_max_ports; i++) { + m_rx_port_mngr[i].send_next_grat_arp(); + } +} + 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; - + dsec_t grat_arp_sec = now_sec() + (double)CGlobalInfo::m_options.m_arp_ref_per; + while (m_state == STATE_WORKING) { process_all_pending_pkts(); dsec_t now = now_sec(); + /* until a scheduler is added here - dirty IFs */ + if ( (now - sync_time_sec) > 0 ) { periodic_check_for_cp_messages(); } @@ -204,7 +217,12 @@ void CRxCoreStateless::handle_work_stage() { port_manager_tick(); tick_time_sec = now + 1.0; } - + + if ( (now - grat_arp_sec) > 0) { + handle_grat_arp(); + grat_arp_sec = now + (double)CGlobalInfo::m_options.m_arp_ref_per; + } + rte_pause(); } @@ -346,3 +364,8 @@ CRxCoreStateless::get_rx_port_mngr(uint8_t port_id) { return m_rx_port_mngr[port_id]; } + +void +CRxCoreStateless::get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff) { + get_rx_port_mngr(port_id).get_ignore_stats(stat, get_diff); +} diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h index 96e511b4..4eed59a1 100644 --- a/src/stateless/rx/trex_stateless_rx_core.h +++ b/src/stateless/rx/trex_stateless_rx_core.h @@ -21,6 +21,7 @@ #ifndef __TREX_STATELESS_RX_CORE_H__ #define __TREX_STATELESS_RX_CORE_H__ #include <stdint.h> + #include "stateful_rx_core.h" #include "os_time.h" #include "pal/linux/sanb_atomic.h" @@ -153,6 +154,12 @@ class CRxCoreStateless { RXPortManager &get_rx_port_mngr(uint8_t port_id); + /** + * fetch the ignored stats for a port + * + */ + void get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff); + private: void handle_cp_msg(TrexStatelessCpToRxMsgBase *msg); bool periodic_check_for_cp_messages(); @@ -166,7 +173,8 @@ class CRxCoreStateless { void handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r); void handle_work_stage(); void port_manager_tick(); - + void handle_grat_arp(); + int process_all_pending_pkts(bool flush_rx = false); void flush_all_pending_pkts() { diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp index e36f825d..4c54a132 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp @@ -661,10 +661,15 @@ RXServer::duplicate_mbuf(const rte_mbuf_t *m) { * *************************************/ 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; +RXGratARP::create(uint8_t port_id, + CPortLatencyHWBase *io, + CManyIPInfo *src_addr, + CRXCoreIgnoreStat *ign_stats) { + + m_port_id = port_id; + m_io = io; + m_src_addr = src_addr; + m_ign_stats = ign_stats; } void @@ -689,9 +694,19 @@ RXGratARP::send_next_grat_arp() { CTestPktGen::create_arp_req(p, sip, sip, src_mac, vlan, m_port_id); - m_io->tx(m); + if (m_io->tx(m) == 0) { + m_ign_stats->m_tx_arp += 1; + m_ign_stats->m_tot_bytes += 64; + } +} + +Json::Value +RXGratARP::to_json() const { + Json::Value output = Json::objectValue; + output["interval_sec"] = (double)CGlobalInfo::m_options.m_arp_ref_per; + return output; } /************************************** @@ -729,11 +744,10 @@ RXPortManager::create(const TRexPortAttr *port_attr, /* init features */ m_latency.create(rfc2544, err_cntrs); m_server.create(m_port_id, io, &m_src_addr); - m_grat_arp.create(m_port_id, io, &m_src_addr); + m_grat_arp.create(m_port_id, io, &m_src_addr, &m_ign_stats); - /* by default, server feature is always on */ + /* by default, server is always on */ set_feature(SERVER); - set_feature(GRAT_ARP); } void RXPortManager::handle_pkt(const rte_mbuf_t *m) { @@ -797,13 +811,43 @@ RXPortManager::tick() { if (is_feature_set(RECORDER)) { m_recorder.flush_to_disk(); } - +} + +void +RXPortManager::send_next_grat_arp() { if (is_feature_set(GRAT_ARP)) { m_grat_arp.send_next_grat_arp(); } } + +void +RXPortManager::set_l2_mode() { + + /* no IPv4 addresses */ + m_src_addr.clear(); + + /* stop grat arp */ + stop_grat_arp(); +} + +void +RXPortManager::set_l3_mode(const CManyIPInfo &ip_info, bool is_grat_arp_needed) { + + /* copy L3 address */ + m_src_addr = ip_info; + + if (is_grat_arp_needed) { + start_grat_arp(); + } + else { + stop_grat_arp(); + } + +} + + Json::Value RXPortManager::to_json() const { Json::Value output = Json::objectValue; @@ -829,7 +873,23 @@ RXPortManager::to_json() const { output["queue"]["is_active"] = false; } + if (is_feature_set(GRAT_ARP)) { + output["grat_arp"] = m_grat_arp.to_json(); + output["grat_arp"]["is_active"] = true; + } else { + output["grat_arp"]["is_active"] = false; + } + return output; } +void RXPortManager::get_ignore_stats(CRXCoreIgnoreStat &stat, bool get_diff) { + if (get_diff) { + stat = m_ign_stats - m_ign_stats_prev; + m_ign_stats_prev = m_ign_stats; + } else { + stat = m_ign_stats; + } +} + diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.h b/src/stateless/rx/trex_stateless_rx_port_mngr.h index e72b0ff0..8947def7 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.h +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.h @@ -284,12 +284,16 @@ private: class RXGratARP { public: RXGratARP() { - m_io = NULL; - m_port_id = UINT8_MAX; - m_src_addr = NULL; + m_io = NULL; + m_port_id = UINT8_MAX; + m_src_addr = NULL; + m_ign_stats = NULL; } - void create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr); + void create(uint8_t port_id, + CPortLatencyHWBase *io, + CManyIPInfo *src_addr, + CRXCoreIgnoreStat *ignore_stats); /** @@ -298,10 +302,13 @@ public: */ void send_next_grat_arp(); + Json::Value to_json() const; + private: + uint8_t m_port_id; CPortLatencyHWBase *m_io; CManyIPInfo *m_src_addr; - uint8_t m_port_id; + CRXCoreIgnoreStat *m_ign_stats; }; /************************ manager ***************************/ @@ -389,7 +396,13 @@ public: return m_queue.fetch(); } + void start_grat_arp() { + set_feature(GRAT_ARP); + } + void stop_grat_arp() { + unset_feature(GRAT_ARP); + } /** * fetch and process all packets @@ -421,14 +434,25 @@ public: void tick(); /** - * updates the source addresses registered with the port + * send next grat arp (if on) * + * @author imarom (12/13/2016) */ - void update_src_addr(const CManyIPInfo &new_src_addr) { - /* deep copy */ - m_src_addr = new_src_addr; - } + void send_next_grat_arp(); + + /** + * set port mode to L2 + */ + void set_l2_mode(); + /** + * set port mode to L3 + * + * @author imarom (12/13/2016) + */ + void set_l3_mode(const CManyIPInfo &ip_info, bool is_grat_arp_needed); + + bool has_features_set() { return (m_features != NO_FEATURES); } @@ -439,6 +463,12 @@ public: } /** + * returns ignored set of stats + * (grat ARP, PING response and etc.) + */ + void get_ignore_stats(CRXCoreIgnoreStat &stat, bool get_diff); + + /** * write the status to a JSON format */ Json::Value to_json() const; @@ -475,6 +505,10 @@ private: CCpuUtlDp *m_cpu_dp_u; CPortLatencyHWBase *m_io; CManyIPInfo m_src_addr; + + /* stats to ignore (ARP and etc.) */ + CRXCoreIgnoreStat m_ign_stats; + CRXCoreIgnoreStat m_ign_stats_prev; }; |