diff options
author | 2015-12-23 09:48:38 -0500 | |
---|---|---|
committer | 2015-12-23 09:59:43 -0500 | |
commit | fb46a1735d7f723ddc791221563e365ad54ef5e0 (patch) | |
tree | 28c258c4f8cf327f3967b272fa5de1c98c8ca06e /src | |
parent | 0bde21ac82ff025939f73bbd1e4783345917e49a (diff) |
connected control plane to split
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 26 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 20 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 35 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 93 | ||||
-rw-r--r-- | src/stateless/cp/trex_vm_splitter.cpp | 6 |
5 files changed, 121 insertions, 59 deletions
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index dff2b4b0..dc1313f1 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -2659,12 +2659,12 @@ public: assert(m_stream); - StreamVmInstruction *split_instr = new StreamVmInstructionFlowMan("var1", - 8, - op, - init, - start, - end); + StreamVmInstructionVar *split_instr = new StreamVmInstructionFlowMan("var1", + 8, + op, + init, + start, + end); StreamVm &vm = m_stream->m_vm; @@ -2686,13 +2686,13 @@ public: assert(m_stream); - StreamVmInstruction *split_instr = new StreamVmInstructionFlowClient("var1", - client_min_value, - client_max_value, - port_min, - port_max, - 0, - 0); + StreamVmInstructionVar *split_instr = new StreamVmInstructionFlowClient("var1", + client_min_value, + client_max_value, + port_min, + port_max, + 0, + 0); StreamVm &vm = m_stream->m_vm; diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index e0186493..51db0b20 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -82,7 +82,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { stream->m_pkt.meta = parse_string(pkt, "meta", result); /* parse VM */ - const Json::Value &vm = parse_array(section ,"vm", result); + const Json::Value &vm = parse_object(section ,"vm", result); parse_vm(vm, stream, result); /* parse RX info */ @@ -248,9 +248,12 @@ TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, Trex void TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result) { + + const Json::Value &instructions = parse_array(vm ,"instructions", result); + /* array of VM instructions on vm */ - for (int i = 0; i < vm.size(); i++) { - const Json::Value & inst = parse_object(vm, i, result); + for (int i = 0; i < instructions.size(); i++) { + const Json::Value & inst = parse_object(instructions, i, result); auto vm_types = {"fix_checksum_ipv4", "flow_var", "write_flow_var","tuple_flow_var"}; std::string vm_type = parse_choice(inst, "type", vm_types, result); @@ -272,6 +275,17 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V throw TrexRpcException("internal error"); } } + + const std::string &var_name = parse_string(vm, "split_by_var", result); + if (var_name != "") { + StreamVmInstructionVar *instr = stream->m_vm.lookup_var_by_name(var_name); + if (!instr) { + std::stringstream ss; + ss << "VM: request to split by variable '" << var_name << "' but does not exists"; + generate_parse_err(result, ss.str()); + } + stream->m_vm.set_split_instruction(instr); + } } void diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index cbd2ce7c..cccbfe88 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -600,12 +600,7 @@ void StreamVm::build_bss() { * */ void -StreamVm::set_split_instruction(StreamVmInstruction *instr) { - if (!instr->is_splitable()) { - throw TrexException("non splitable instruction"); - return; - } - +StreamVm::set_split_instruction(StreamVmInstructionVar *instr) { m_split_instr = instr; } @@ -631,7 +626,9 @@ StreamVm::copy_instructions(StreamVm &other) const { /* for the split instruction - find the right one */ if (instr == m_split_instr) { - other.m_split_instr = new_instr; + /* dynamic cast must succeed here */ + other.m_split_instr = dynamic_cast<StreamVmInstructionVar *>(new_instr); + assert(other.m_split_instr); } } @@ -677,6 +674,30 @@ StreamVm::~StreamVm() { free_bss(); } +/** +* return a pointer to a flow var / client var +* by name if exists, otherwise NULL +* +*/ +StreamVmInstructionVar * +StreamVm::lookup_var_by_name(const std::string &var_name) { + for (StreamVmInstruction *inst : m_inst_list) { + + /* try to cast up to a variable */ + StreamVmInstructionVar *var = dynamic_cast<StreamVmInstructionVar *>(inst); + if (!var) { + continue; + } + + if (var->get_var_name() == var_name) { + return var; + } + + } + + return NULL; +} + void StreamVm::Dump(FILE *fd){ fprintf(fd," instructions \n"); diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index ce905655..f327267e 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -579,9 +579,7 @@ public: virtual StreamVmInstruction * clone() = 0; - /** - * by default an instruction is not a splitable field - */ + /* by default an instruction is not splitable */ virtual bool is_splitable() const { return false; } @@ -591,6 +589,39 @@ private: }; /** + * abstract class that defines a flow var + * + * @author imarom (23-Dec-15) + */ +class StreamVmInstructionVar : public StreamVmInstruction { + +public: + + StreamVmInstructionVar(const std::string &var_name) : m_var_name(var_name) { + + } + + const std::string & get_var_name() { + return m_var_name; + } + + virtual bool is_splitable() const { + return true; + } + + /** + * what is the split range for this var + * + */ + virtual uint64_t get_splitable_range() const = 0; + +public: + + /* flow var name */ + const std::string m_var_name; +}; + +/** * fix checksum for ipv4 * */ @@ -619,7 +650,7 @@ public: * * @author imarom (07-Sep-15) */ -class StreamVmInstructionFlowMan : public StreamVmInstruction { +class StreamVmInstructionFlowMan : public StreamVmInstructionVar { public: @@ -627,14 +658,10 @@ public: return ( StreamVmInstruction::itFLOW_MAN); } - uint64_t get_range() const { + virtual uint64_t get_splitable_range() const { return (m_max_value - m_min_value + 1); } - virtual bool is_splitable() const { - return true; - } - /** * different types of operations on the object */ @@ -672,14 +699,13 @@ public: 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) { + uint64_t max_value) : StreamVmInstructionVar(var_name) { + m_op = op; + m_size_bytes = size; + m_init_value = init_value; + m_min_value = min_value; + m_max_value = max_value; } virtual void Dump(FILE *fd); @@ -702,10 +728,6 @@ private: public: - - /* flow var name */ - std::string m_var_name; - /* flow var size */ uint8_t m_size_bytes; @@ -725,7 +747,7 @@ public: * * @author hhaim */ -class StreamVmInstructionFlowClient : public StreamVmInstruction { +class StreamVmInstructionFlowClient : public StreamVmInstructionVar { public: enum client_flags_e { @@ -737,9 +759,6 @@ public: return ( StreamVmInstruction::itFLOW_CLIENT); } - virtual bool is_splitable() const { - return true; - } StreamVmInstructionFlowClient(const std::string &var_name, uint32_t client_min_value, @@ -748,8 +767,8 @@ public: uint16_t port_max, uint32_t limit_num_flows, /* zero means don't limit */ uint16_t flags - ) { - m_var_name = var_name; + ) : StreamVmInstructionVar(var_name) { + m_client_min = client_min_value; m_client_max = client_max_value; @@ -774,6 +793,10 @@ public: return (m_port_max - m_port_min + 1); } + virtual uint64_t get_splitable_range() const { + return get_ip_range(); + } + bool is_unlimited_flows(){ return ( (m_flags & StreamVmInstructionFlowClient::CLIENT_F_UNLIMITED_FLOWS ) == StreamVmInstructionFlowClient::CLIENT_F_UNLIMITED_FLOWS ); @@ -791,10 +814,6 @@ public: public: - - /* flow var name */ - std::string m_var_name; - uint32_t m_client_min; // min ip uint32_t m_client_max; // max ip uint16_t m_port_min; // start port @@ -1014,9 +1033,9 @@ public: } - void set_split_instruction(StreamVmInstruction *instr); + void set_split_instruction(StreamVmInstructionVar *instr); - StreamVmInstruction * get_split_instruction() { + StreamVmInstructionVar * get_split_instruction() { return m_split_instr; } @@ -1098,6 +1117,14 @@ public: /* raise exception */ void err(const std::string &err); + + /** + * return a pointer to a flow var / client var + * by name if exists, otherwise NULL + * + */ + StreamVmInstructionVar * lookup_var_by_name(const std::string &var_name); + private: /* lookup for varible offset, */ @@ -1138,7 +1165,7 @@ private: StreamDPVmInstructions m_instructions; - StreamVmInstruction *m_split_instr; + StreamVmInstructionVar *m_split_instr; }; diff --git a/src/stateless/cp/trex_vm_splitter.cpp b/src/stateless/cp/trex_vm_splitter.cpp index 56776f7e..9465718f 100644 --- a/src/stateless/cp/trex_vm_splitter.cpp +++ b/src/stateless/cp/trex_vm_splitter.cpp @@ -61,7 +61,7 @@ TrexVmSplitter::split(TrexStream *stream, std::vector<TrexStream *> core_streams bool TrexVmSplitter::split_internal() { - const StreamVmInstruction *split_instr = m_stream->m_vm.get_split_instruction(); + const StreamVmInstructionVar *split_instr = m_stream->m_vm.get_split_instruction(); /* if no split instruction was specified - fall back*/ if (split_instr == NULL) { @@ -97,7 +97,7 @@ TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) { } /* if the range is too small - it is unsplitable */ - if (instr->get_range() < m_dp_core_count) { + if (instr->get_splitable_range() < m_dp_core_count) { return false; } @@ -105,7 +105,7 @@ TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) { duplicate_vm(); /* calculate range splitting */ - uint64_t range = instr->get_range(); + uint64_t range = instr->get_splitable_range(); uint64_t range_part = range / m_dp_core_count; uint64_t leftover = range % m_dp_core_count; |