summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp48
-rw-r--r--src/rpc-server/trex_rpc_cmd_api.h2
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp135
-rw-r--r--src/stateless/cp/trex_stateless_port.h82
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 &params, 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 &params, 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 &params, const std::string &name, std::initializer_list<T> choices, Json::Value &result) {
+ template<typename T> T parse_choice(const Json::Value &params, 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__ */