summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/trex_stateless.cpp72
-rw-r--r--src/stateless/trex_stateless_api.h62
-rw-r--r--src/stateless/trex_stream.cpp20
-rw-r--r--src/stateless/trex_stream_api.h36
-rw-r--r--src/stateless/trex_stream_vm.cpp54
-rw-r--r--src/stateless/trex_stream_vm.h171
6 files changed, 385 insertions, 30 deletions
diff --git a/src/stateless/trex_stateless.cpp b/src/stateless/trex_stateless.cpp
index 05931983..2ab0c5d9 100644
--- a/src/stateless/trex_stateless.cpp
+++ b/src/stateless/trex_stateless.cpp
@@ -24,13 +24,30 @@ limitations under the License.
* Trex stateless object
*
**********************************************************/
-TrexStateless::TrexStateless(uint8_t port_count) : m_port_count(port_count) {
+TrexStateless::TrexStateless() {
+ m_is_configured = false;
+}
- m_ports = new TrexStatelessPort*[port_count];
+/**
+ * one time configuration of the stateless object
+ *
+ */
+void TrexStateless::configure(uint8_t port_count) {
- for (int i = 0; i < m_port_count; i++) {
- m_ports[i] = new TrexStatelessPort(i);
+ TrexStateless& instance = get_instance_internal();
+
+ if (instance.m_is_configured) {
+ throw TrexException("re-configuration of stateless object is not allowed");
+ }
+
+ instance.m_port_count = port_count;
+ instance.m_ports = new TrexStatelessPort*[port_count];
+
+ for (int i = 0; i < instance.m_port_count; i++) {
+ instance.m_ports[i] = new TrexStatelessPort(i);
}
+
+ instance.m_is_configured = true;
}
TrexStateless::~TrexStateless() {
@@ -38,7 +55,7 @@ TrexStateless::~TrexStateless() {
delete m_ports[i];
}
- delete m_ports;
+ delete [] m_ports;
}
TrexStatelessPort * TrexStateless::get_port_by_id(uint8_t port_id) {
@@ -54,10 +71,47 @@ uint8_t TrexStateless::get_port_count() {
return m_port_count;
}
-/******** HACK - REMOVE ME ***********/
-TrexStateless * get_trex_stateless() {
- static TrexStateless trex_stateless(8);
- return &trex_stateless;
+/***************************
+ * trex stateless port
+ *
+ **************************/
+TrexStatelessPort::TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) {
+ m_started = false;
+}
+
+
+/**
+ * starts the traffic on the port
+ *
+ */
+TrexStatelessPort::traffic_rc_e
+TrexStatelessPort::start_traffic(void) {
+ if (m_started) {
+ return (TRAFFIC_ERR_ALREADY_STARTED);
+ }
+
+ if (get_stream_table()->size() == 0) {
+ return (TRAFFIC_ERR_NO_STREAMS);
+ }
+
+ m_started = true;
+
+ return (TRAFFIC_OK);
+}
+
+void
+TrexStatelessPort::stop_traffic(void) {
+ if (m_started) {
+ m_started = false;
+ }
+}
+/**
+* access the stream table
+*
+*/
+TrexStreamTable * TrexStatelessPort::get_stream_table() {
+ return &m_stream_table;
}
+
diff --git a/src/stateless/trex_stateless_api.h b/src/stateless/trex_stateless_api.h
index 6406a946..358ab339 100644
--- a/src/stateless/trex_stateless_api.h
+++ b/src/stateless/trex_stateless_api.h
@@ -49,20 +49,32 @@ public:
class TrexStatelessPort {
public:
- TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) {
- }
+ /**
+ * describess error codes for starting traffic
+ */
+ enum traffic_rc_e {
+ TRAFFIC_OK,
+ TRAFFIC_ERR_ALREADY_STARTED,
+ TRAFFIC_ERR_NO_STREAMS,
+ TRAFFIC_ERR_FAILED_TO_COMPILE_STREAMS
+ };
+
+ TrexStatelessPort(uint8_t port_id);
+
+ traffic_rc_e start_traffic(void);
+
+ void stop_traffic(void);
/**
* access the stream table
*
*/
- TrexStreamTable *get_stream_table() {
- return &m_stream_table;
- }
+ TrexStreamTable *get_stream_table();
private:
TrexStreamTable m_stream_table;
uint8_t m_port_id;
+ bool m_started;
};
/**
@@ -71,26 +83,48 @@ private:
*/
class TrexStateless {
public:
+
/**
- * create a T-Rex stateless object
- *
- * @author imarom (31-Aug-15)
+ * configure the stateless object singelton
+ * reconfiguration is not allowed
+ * an exception will be thrown
+ */
+ static void configure(uint8_t port_count);
+
+ /**
+ * singleton public get instance
*
- * @param port_count
*/
- TrexStateless(uint8_t port_count);
- ~TrexStateless();
+ static TrexStateless& get_instance() {
+ TrexStateless& instance = get_instance_internal();
+
+ if (!instance.m_is_configured) {
+ throw TrexException("object is not configured");
+ }
+
+ return instance;
+ }
TrexStatelessPort *get_port_by_id(uint8_t port_id);
uint8_t get_port_count();
protected:
+ TrexStateless();
+ ~TrexStateless();
+
+ static TrexStateless& get_instance_internal () {
+ static TrexStateless instance;
+ return instance;
+ }
+
+ /* c++ 2011 style singleton */
+ TrexStateless(TrexStateless const&) = delete;
+ void operator=(TrexStateless const&) = delete;
+
+ bool m_is_configured;
TrexStatelessPort **m_ports;
uint8_t m_port_count;
};
-/****** HACK *******/
-TrexStateless *get_trex_stateless();
-
#endif /* __TREX_STATELESS_API_H__ */
diff --git a/src/stateless/trex_stream.cpp b/src/stateless/trex_stream.cpp
index 1465b1ba..2b5b2424 100644
--- a/src/stateless/trex_stream.cpp
+++ b/src/stateless/trex_stream.cpp
@@ -32,16 +32,16 @@ TrexStream::TrexStream(uint8_t port_id, uint32_t stream_id) : m_port_id(port_id)
m_enabled = false;
m_self_start = false;
- m_pkt = NULL;
- m_pkt_len = 0;
+ m_pkt.binary = NULL;
+ m_pkt.len = 0;
m_rx_check.m_enable = false;
}
TrexStream::~TrexStream() {
- if (m_pkt) {
- delete [] m_pkt;
+ if (m_pkt.binary) {
+ delete [] m_pkt.binary;
}
}
@@ -91,3 +91,15 @@ TrexStream * TrexStreamTable::get_stream_by_id(uint32_t stream_id) {
return NULL;
}
}
+
+void TrexStreamTable::get_stream_list(std::vector<uint32_t> &stream_list) {
+ stream_list.clear();
+
+ for (auto stream : m_stream_table) {
+ stream_list.push_back(stream.first);
+ }
+}
+
+int TrexStreamTable::size() {
+ return m_stream_table.size();
+}
diff --git a/src/stateless/trex_stream_api.h b/src/stateless/trex_stream_api.h
index f57b7aae..26999751 100644
--- a/src/stateless/trex_stream_api.h
+++ b/src/stateless/trex_stream_api.h
@@ -22,7 +22,11 @@ limitations under the License.
#define __TREX_STREAM_API_H__
#include <unordered_map>
+#include <vector>
#include <stdint.h>
+#include <string>
+
+#include <trex_stream_vm.h>
class TrexRpcCmdAddStream;
@@ -33,6 +37,7 @@ class TrexRpcCmdAddStream;
class TrexStream {
/* provide the RPC parser a way to access private fields */
friend class TrexRpcCmdAddStream;
+ friend class TrexRpcCmdGetStream;
friend class TrexStreamTable;
public:
@@ -51,17 +56,21 @@ private:
/* config fields */
double m_isg_usec;
- uint32_t m_next_stream_id;
+ int m_next_stream_id;
/* indicators */
bool m_enabled;
bool m_self_start;
/* pkt */
- uint8_t *m_pkt;
- uint16_t m_pkt_len;
+ struct {
+ uint8_t *binary;
+ uint16_t len;
+ std::string meta;
+ } m_pkt;
/* VM */
+ StreamVm m_vm;
/* RX check */
struct {
@@ -72,6 +81,7 @@ private:
} m_rx_check;
+
};
/**
@@ -82,6 +92,11 @@ class TrexStreamContinuous : public TrexStream {
public:
TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, uint32_t pps) : TrexStream(port_id, stream_id), m_pps(pps) {
}
+
+ uint32_t get_pps() {
+ return m_pps;
+ }
+
protected:
uint32_t m_pps;
};
@@ -157,6 +172,21 @@ public:
*/
TrexStream * get_stream_by_id(uint32_t stream_id);
+ /**
+ * populate a list with all the stream IDs
+ *
+ * @author imarom (06-Sep-15)
+ *
+ * @param stream_list
+ */
+ void get_stream_list(std::vector<uint32_t> &stream_list);
+
+ /**
+ * get the table size
+ *
+ */
+ int size();
+
private:
/**
* holds all the stream in a hash table by stream id
diff --git a/src/stateless/trex_stream_vm.cpp b/src/stateless/trex_stream_vm.cpp
new file mode 100644
index 00000000..2e760ae9
--- /dev/null
+++ b/src/stateless/trex_stream_vm.cpp
@@ -0,0 +1,54 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_stream_vm.h>
+
+/***************************
+ * StreamVmInstruction
+ *
+ **************************/
+StreamVmInstruction::~StreamVmInstruction() {
+
+}
+
+/***************************
+ * StreamVm
+ *
+ **************************/
+void StreamVm::add_instruction(StreamVmInstruction *inst) {
+ m_inst_list.push_back(inst);
+}
+
+const std::vector<StreamVmInstruction *> &
+StreamVm::get_instruction_list() {
+ return m_inst_list;
+}
+
+bool StreamVm::compile() {
+ /* implement me */
+ return (false);
+}
+
+StreamVm::~StreamVm() {
+ for (auto inst : m_inst_list) {
+ delete inst;
+ }
+}
+
diff --git a/src/stateless/trex_stream_vm.h b/src/stateless/trex_stream_vm.h
new file mode 100644
index 00000000..56edbcaf
--- /dev/null
+++ b/src/stateless/trex_stream_vm.h
@@ -0,0 +1,171 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#ifndef __TREX_STREAM_VM_API_H__
+#define __TREX_STREAM_VM_API_H__
+
+#include <string>
+#include <stdint.h>
+#include <vector>
+
+/**
+ * interface for stream VM instruction
+ *
+ */
+class StreamVmInstruction {
+public:
+
+ virtual ~StreamVmInstruction();
+
+private:
+ static const std::string m_name;
+};
+
+/**
+ * fix checksum for ipv4
+ *
+ */
+class StreamVmInstructionFixChecksumIpv4 : public StreamVmInstruction {
+public:
+ StreamVmInstructionFixChecksumIpv4(uint16_t offset) : m_pkt_offset(offset) {
+
+ }
+
+private:
+ uint16_t m_pkt_offset;
+};
+
+/**
+ * flow manipulation instruction
+ *
+ * @author imarom (07-Sep-15)
+ */
+class StreamVmInstructionFlowMan : public StreamVmInstruction {
+
+public:
+
+ /**
+ * different types of operations on the object
+ */
+ enum flow_var_op_e {
+ FLOW_VAR_OP_INC,
+ FLOW_VAR_OP_DEC,
+ FLOW_VAR_OP_RANDOM
+ };
+
+ StreamVmInstructionFlowMan(const std::string &var_name,
+ uint8_t size,
+ flow_var_op_e op,
+ uint64_t init_value,
+ uint64_t min_value,
+ uint64_t max_value) :
+ m_var_name(var_name),
+ m_size_bytes(size),
+ m_op(op),
+ m_init_value(init_value),
+ m_min_value(min_value),
+ m_max_value(max_value) {
+
+ }
+
+private:
+
+
+ /* flow var name */
+ std::string m_var_name;
+
+ /* flow var size */
+ uint8_t m_size_bytes;
+
+ /* type of op */
+ flow_var_op_e m_op;
+
+ /* range */
+ uint64_t m_init_value;
+ uint64_t m_min_value;
+ uint64_t m_max_value;
+
+
+};
+
+/**
+ * write flow var to packet
+ *
+ */
+class StreamVmInstructionWriteToPkt : public StreamVmInstruction {
+public:
+
+ StreamVmInstructionWriteToPkt(const std::string &flow_var_name,
+ uint16_t pkt_offset,
+ int32_t add_value = 0,
+ bool is_big_endian = true) :
+
+ m_flow_var_name(flow_var_name),
+ m_pkt_offset(pkt_offset),
+ m_add_value(add_value),
+ m_is_big_endian(is_big_endian) {}
+private:
+
+ /* flow var name to write */
+ std::string m_flow_var_name;
+
+ /* where to write */
+ uint16_t m_pkt_offset;
+
+ /* add/dec value from field when writing */
+ int32_t m_add_value;
+
+ /* writing endian */
+ bool m_is_big_endian;
+};
+
+/**
+ * describes a VM program
+ *
+ */
+class StreamVm {
+public:
+
+ /**
+ * add new instruction to the VM
+ *
+ */
+ void add_instruction(StreamVmInstruction *inst);
+
+ /**
+ * get const access to the instruction list
+ *
+ */
+ const std::vector<StreamVmInstruction *> & get_instruction_list();
+
+ /**
+ * compile the VM
+ * return true of success, o.w false
+ *
+ */
+ bool compile();
+
+ ~StreamVm();
+
+private:
+ std::vector<StreamVmInstruction *> m_inst_list;
+};
+
+#endif /* __TREX_STREAM_VM_API_H__ */