summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-12-13 18:15:22 +0200
committerimarom <imarom@cisco.com>2016-12-13 18:15:22 +0200
commit0fdd81a94d62592b0ec9888022d793f670c8476f (patch)
treeec52cd0f090793e26f67bc017d402b737acd71b5 /src/stateless
parent0c45815234abbb79b147b8093eb19e274ee65f52 (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.cpp59
-rw-r--r--src/stateless/cp/trex_stateless_port.h11
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp13
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h31
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp27
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h10
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.cpp78
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.h54
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;
};