summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-12-12 19:26:24 +0200
committerimarom <imarom@cisco.com>2016-12-12 19:26:24 +0200
commit0c45815234abbb79b147b8093eb19e274ee65f52 (patch)
treea604b3865f201e1fe841bca3a10e8f86e3248186 /src/stateless
parentaf9f439b2bf768f9168cecac2488b4c718ab783f (diff)
grat ARP
Signed-off-by: imarom <imarom@cisco.com>
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp13
-rw-r--r--src/stateless/cp/trex_stateless_port.h6
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp5
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h17
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp16
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h2
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.cpp86
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.h55
8 files changed, 172 insertions, 28 deletions
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 7edf1a31..057f6521 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -987,6 +987,19 @@ TrexStatelessPort::get_rx_queue_pkts() {
return reply.wait_for_reply();
}
+
+void
+TrexStatelessPort::set_src_ipv4(uint32_t ipv4) {
+
+ getPortAttrObj()->set_src_ipv4(ipv4);
+
+ CManyIPInfo src_addr;
+ src_addr.insert(COneIPv4Info(ipv4, 0, getPortAttrObj()->get_src_mac(), m_port_id));
+
+ TrexStatelessRxUpdateSrcAddr *msg = new TrexStatelessRxUpdateSrcAddr(m_port_id, src_addr);
+ 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 74ab17f1..3ae74f5a 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -400,6 +400,12 @@ public:
const RXPacketBuffer *get_rx_queue_pkts();
/**
+ * sets an IPv4 source address
+ *
+ */
+ void set_src_ipv4(uint32_t ipv4);
+
+ /**
* generate a JSON describing the status
* of the RX features
*
diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp
index 17acb21e..dc656e67 100644
--- a/src/stateless/messaging/trex_stateless_messaging.cpp
+++ b/src/stateless/messaging/trex_stateless_messaging.cpp
@@ -316,3 +316,8 @@ TrexStatelessRxFeaturesToJson::handle(CRxCoreStateless *rx_core) {
return true;
}
+bool
+TrexStatelessRxUpdateSrcAddr::handle(CRxCoreStateless *rx_core) {
+ rx_core->get_rx_port_mngr(m_port_id).update_src_addr(m_src_addr);
+ return true;
+}
diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h
index 79a6bf08..5f00c244 100644
--- a/src/stateless/messaging/trex_stateless_messaging.h
+++ b/src/stateless/messaging/trex_stateless_messaging.h
@@ -27,6 +27,7 @@ limitations under the License.
#include "trex_exception.h"
#include "trex_stateless_rx_defs.h"
#include "os_time.h"
+#include "utl_ip.h"
class TrexStatelessDpCore;
class CRxCoreStateless;
@@ -568,6 +569,22 @@ private:
};
+class TrexStatelessRxUpdateSrcAddr : public TrexStatelessCpToRxMsgBase {
+public:
+ TrexStatelessRxUpdateSrcAddr(uint8_t port_id,
+ const CManyIPInfo &src_addr) {
+
+ m_port_id = port_id;
+ m_src_addr = src_addr;
+ }
+
+ virtual bool handle(CRxCoreStateless *rx_core);
+
+private:
+ uint8_t m_port_id;
+ CManyIPInfo m_src_addr;
+};
+
/**
* a request from RX core to dump to Json the RX features
*/
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;
};