diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 48 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_cmd_api.h | 2 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 135 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 82 |
4 files changed, 190 insertions, 77 deletions
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index a5bf0d16..dea4c171 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -475,28 +475,17 @@ TrexRpcCmdStartTraffic::_run(const Json::Value ¶ms, Json::Value &result) { /* multiplier */ const Json::Value &mul_obj = parse_object(params, "mul", result); - std::string mul_type = parse_string(mul_obj, "type", result); - double mul_value = parse_double(mul_obj, "max", result); - /* now create an object for multiplier */ - TrexStatelessPort::mul_st mul; - - mul.value = mul_value; - - /* dispatch according to type of multiplier */ - if (mul_type == "raw") { - mul.type = TrexStatelessPort::MUL_FACTOR; - - } else if (mul_type == "max_bps") { - mul.type = TrexStatelessPort::MUL_MAX_BPS; + std::string type = parse_choice(mul_obj, "type", TrexPortMultiplier::g_types, result); + std::string op = parse_string(mul_obj, "op", result); + double value = parse_double(mul_obj, "value", result); - } else if (mul_type == "max_pps") { - mul.type = TrexStatelessPort::MUL_MAX_PPS; - - } else { - generate_parse_err(result, "multiplier type can be either 'raw', 'max_bps' or 'max_pps'"); + if (op != "abs") { + generate_parse_err(result, "start message can only specify absolute speed rate"); } + TrexPortMultiplier mul(type, op, value); + try { port->start_traffic(mul, duration); @@ -651,28 +640,15 @@ TrexRpcCmdUpdateTraffic::_run(const Json::Value ¶ms, Json::Value &result) { TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); /* multiplier */ - const Json::Value &mul_obj = parse_object(params, "mul", result); - std::string mul_type = parse_string(mul_obj, "type", result); - double mul_value = parse_double(mul_obj, "max", result); - - /* now create an object for multiplier */ - TrexStatelessPort::mul_st mul; - - mul.value = mul_value; - /* dispatch according to type of multiplier */ - if (mul_type == "raw") { - mul.type = TrexStatelessPort::MUL_FACTOR; + const Json::Value &mul_obj = parse_object(params, "mul", result); - } else if (mul_type == "max_bps") { - mul.type = TrexStatelessPort::MUL_MAX_BPS; + std::string type = parse_choice(mul_obj, "type", TrexPortMultiplier::g_types, result); + std::string op = parse_choice(mul_obj, "op", TrexPortMultiplier::g_ops, result); + double value = parse_double(mul_obj, "value", result); - } else if (mul_type == "max_pps") { - mul.type = TrexStatelessPort::MUL_MAX_PPS; + TrexPortMultiplier mul(type, op, value); - } else { - generate_parse_err(result, "multiplier type can be either 'raw', 'max_bps' or 'max_pps'"); - } try { port->update_traffic(mul); diff --git a/src/rpc-server/trex_rpc_cmd_api.h b/src/rpc-server/trex_rpc_cmd_api.h index 3c718eaa..e93fb775 100644 --- a/src/rpc-server/trex_rpc_cmd_api.h +++ b/src/rpc-server/trex_rpc_cmd_api.h @@ -159,7 +159,7 @@ protected: * parse a field from choices * */ - template<typename T> T parse_choice(const Json::Value ¶ms, const std::string &name, std::initializer_list<T> choices, Json::Value &result) { + template<typename T> T parse_choice(const Json::Value ¶ms, const std::string &name, const std::initializer_list<T> choices, Json::Value &result) { const Json::Value &field = params[name]; if (field == Json::Value::null) { diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 8346b61d..95bdca0b 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -104,7 +104,7 @@ TrexStatelessPort::release(void) { * */ void -TrexStatelessPort::start_traffic(const TrexStatelessPort::mul_st &mul, double duration) { +TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration) { /* command allowed only on state stream */ verify_state(PORT_STATE_STREAMS); @@ -112,7 +112,9 @@ TrexStatelessPort::start_traffic(const TrexStatelessPort::mul_st &mul, double du /* just making sure no leftovers... */ delete_streams_graph(); - /* calculate the effective M */ + /* on start - we can only provide absolute values */ + assert(mul.m_op == TrexPortMultiplier::OP_ABS); + double per_core_mul = calculate_effective_mul(mul); /* fetch all the streams from the table */ @@ -221,19 +223,41 @@ TrexStatelessPort::resume_traffic(void) { } void -TrexStatelessPort::update_traffic(const TrexStatelessPort::mul_st &mul) { +TrexStatelessPort::update_traffic(const TrexPortMultiplier &mul) { + + double factor; verify_state(PORT_STATE_TX | PORT_STATE_PAUSE); /* generate a message to all the relevant DP cores to start transmitting */ double new_per_core_m = calculate_effective_mul(mul); - double factor = new_per_core_m / m_current_per_core_m; + + switch (mul.m_op) { + case TrexPortMultiplier::OP_ABS: + factor = new_per_core_m / m_current_per_core_m; + break; + + case TrexPortMultiplier::OP_ADD: + factor = (m_current_per_core_m + new_per_core_m) / m_current_per_core_m; + break; + + case TrexPortMultiplier::OP_SUB: + factor = (m_current_per_core_m - new_per_core_m) / m_current_per_core_m; + if (factor <= 0) { + throw TrexRpcException("Update request will lower traffic to less than zero"); + } + break; + + default: + assert(0); + break; + } TrexStatelessCpToDpMsgBase *update_msg = new TrexStatelessDpUpdate(m_port_id, factor); send_message_to_dp(update_msg); - m_current_per_core_m = new_per_core_m; + m_current_per_core_m *= factor; } @@ -368,16 +392,29 @@ TrexStatelessPort::on_dp_event_occured(TrexDpPortEvent::event_e event_type) { } } -/** - * calculate an effective M based on requirments - * - */ +uint64_t +TrexStatelessPort::get_port_speed_bps() { + switch (m_speed) { + case TrexPlatformApi::SPEED_1G: + return (1LLU * 1000 * 1000 * 1000); + + case TrexPlatformApi::SPEED_10G: + return (10LLU * 1000 * 1000 * 1000); + + case TrexPlatformApi::SPEED_40G: + return (40LLU * 1000 * 1000 * 1000); + + default: + return 0; + } +} + double -TrexStatelessPort::calculate_effective_mul(const mul_st &mul) { +TrexStatelessPort::calculate_effective_mul(const TrexPortMultiplier &mul) { /* for a simple factor request - calculate the multiplier per core */ - if (mul.type == MUL_FACTOR) { - return (mul.value / m_cores_id_list.size()); + if (mul.m_type == TrexPortMultiplier::MUL_FACTOR) { + return (mul.m_value / m_cores_id_list.size()); } /* we now need the graph - generate it if we don't have it (happens once) */ @@ -385,16 +422,30 @@ TrexStatelessPort::calculate_effective_mul(const mul_st &mul) { generate_streams_graph(); } - /* now we can calculate the effective M */ - if (mul.type == MUL_MAX_BPS) { - return ( (mul.value / m_graph_obj->get_max_bps()) / m_cores_id_list.size()); - } else if (mul.type == MUL_MAX_PPS) { - return ( (mul.value / m_graph_obj->get_max_pps()) / m_cores_id_list.size()); - } else { + switch (mul.m_type) { + case TrexPortMultiplier::MUL_BPS: + return ( (mul.m_value / m_graph_obj->get_max_bps()) / m_cores_id_list.size()); + + case TrexPortMultiplier::MUL_PPS: + return ( (mul.m_value / m_graph_obj->get_max_pps()) / m_cores_id_list.size()); + + case TrexPortMultiplier::MUL_PERCENTAGE: + /* if abs percentage is from the line speed - otherwise its from the current speed */ + + if (mul.m_op == TrexPortMultiplier::OP_ABS) { + double required = (mul.m_value / 100.0) * get_port_speed_bps(); + return ( (required / m_graph_obj->get_max_bps()) / m_cores_id_list.size()); + } else { + return (m_current_per_core_m * (mul.m_value / 100.0)); + } + + default: assert(0); } + } + void TrexStatelessPort::generate_streams_graph() { @@ -419,3 +470,51 @@ TrexStatelessPort::delete_streams_graph() { } } + + +/*************************** + * port multiplier + * + **************************/ +const std::initializer_list<std::string> TrexPortMultiplier::g_types = {"raw", "bps", "pps", "percentage"}; +const std::initializer_list<std::string> TrexPortMultiplier::g_ops = {"abs", "add", "sub"}; + +TrexPortMultiplier:: +TrexPortMultiplier(const std::string &type_str, const std::string &op_str, double value) { + mul_type_e type; + mul_op_e op; + + if (type_str == "raw") { + type = MUL_FACTOR; + + } else if (type_str == "bps") { + type = MUL_BPS; + + } else if (type_str == "pps") { + type = MUL_PPS; + + } else if (type_str == "percentage") { + type = MUL_PERCENTAGE; + } else { + throw TrexException("bad type str: " + type_str); + } + + if (op_str == "abs") { + op = OP_ABS; + + } else if (op_str == "add") { + op = OP_ADD; + + } else if (op_str == "sub") { + op = OP_SUB; + + } else { + throw TrexException("bad op str: " + op_str); + } + + m_type = type; + m_op = op; + m_value = value; + +} + diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 7d20f338..45eb16e8 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -27,6 +27,7 @@ limitations under the License. class TrexStatelessCpToDpMsgBase; class TrexStreamsGraphObj; +class TrexPortMultiplier; /** * describes a stateless port @@ -59,24 +60,7 @@ public: RC_ERR_FAILED_TO_COMPILE_STREAMS }; - /** - * defines the type of multipler passed to start - */ - enum mul_type_e { - MUL_FACTOR, - MUL_MAX_BPS, - MUL_MAX_PPS - }; - - /** - * multiplier object - */ - typedef struct { - mul_type_e type; - double value; - } mul_st; - - + TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api); /** @@ -95,7 +79,7 @@ public: * start traffic * throws TrexException in case of an error */ - void start_traffic(const mul_st &mul, double duration = -1); + void start_traffic(const TrexPortMultiplier &mul, double duration = -1); /** * stop traffic @@ -119,7 +103,7 @@ public: * update current traffic on port * */ - void update_traffic(const mul_st &mul); + void update_traffic(const TrexPortMultiplier &mul); /** * get the port state @@ -227,7 +211,6 @@ public: } - private: @@ -276,7 +259,13 @@ private: * calculate effective M per core * */ - double calculate_effective_mul(const mul_st &mul); + double calculate_effective_mul(const TrexPortMultiplier &mul); + + /** + * get port speed in bits per second + * + */ + uint64_t get_port_speed_bps(); /** * generates a graph of streams graph @@ -314,4 +303,53 @@ private: const TrexStreamsGraphObj *m_graph_obj; }; + + +/** + * port multiplier object + * + */ +class TrexPortMultiplier { +public: + + + /** + * defines the type of multipler passed to start + */ + enum mul_type_e { + MUL_FACTOR, + MUL_BPS, + MUL_PPS, + MUL_PERCENTAGE + }; + + /** + * multiplier can be absolute value + * increment value or subtract value + */ + enum mul_op_e { + OP_ABS, + OP_ADD, + OP_SUB + }; + + + TrexPortMultiplier(mul_type_e type, mul_op_e op, double value) { + m_type = type; + m_op = op; + m_value = value; + } + + TrexPortMultiplier(const std::string &type_str, const std::string &op_str, double value); + + +public: + static const std::initializer_list<std::string> g_types; + static const std::initializer_list<std::string> g_ops; + + mul_type_e m_type; + mul_op_e m_op; + double m_value; +}; + #endif /* __TREX_STATELESS_PORT_H__ */ |