summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-01-24 11:35:41 -0500
committerimarom <imarom@cisco.com>2016-01-24 11:35:41 -0500
commitb87ac8e2af727598b3120510b221244c9c499e56 (patch)
tree425d9cb46b9fa49eb13a0e2773a3e68591182c6c
parent7294d7f162e19e0ccd3a37eafbafe22cf63df6a4 (diff)
added support for L1 B/W check
both start/update now enforce this and it can be bypassed by providing 'force'
-rw-r--r--scripts/automation/trex_control_plane/client/trex_port.py16
-rwxr-xr-xscripts/automation/trex_control_plane/client/trex_stateless_client.py21
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp13
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h4
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp39
-rw-r--r--src/stateless/cp/trex_stateless_port.h8
6 files changed, 65 insertions, 36 deletions
diff --git a/scripts/automation/trex_control_plane/client/trex_port.py b/scripts/automation/trex_control_plane/client/trex_port.py
index d32d2a01..dcb03da3 100644
--- a/scripts/automation/trex_control_plane/client/trex_port.py
+++ b/scripts/automation/trex_control_plane/client/trex_port.py
@@ -249,7 +249,7 @@ class Port(object):
return self.streams
# start traffic
- def start (self, mul, duration):
+ def start (self, mul, duration, force):
if not self.is_acquired():
return self.err("port is not owned")
@@ -263,10 +263,11 @@ class Port(object):
if self.state == self.STATE_TX:
return self.err("Unable to start traffic - port is already transmitting")
- params = {"handler": self.handler,
- "port_id": self.port_id,
- "mul": mul,
- "duration": duration}
+ params = {"handler": self.handler,
+ "port_id": self.port_id,
+ "mul": mul,
+ "duration": duration,
+ "force": force}
rc = self.transmit("start_traffic", params)
if rc.bad():
@@ -344,7 +345,7 @@ class Port(object):
return self.ok()
- def update (self, mul):
+ def update (self, mul, force):
if not self.is_acquired():
return self.err("port is not owned")
@@ -354,7 +355,8 @@ class Port(object):
params = {"handler": self.handler,
"port_id": self.port_id,
- "mul": mul}
+ "mul": mul,
+ "force": force}
rc = self.transmit("update_traffic", params)
if rc.bad():
diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_client.py b/scripts/automation/trex_control_plane/client/trex_stateless_client.py
index c59da7b4..32618a05 100755
--- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py
+++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py
@@ -605,14 +605,14 @@ class STLClient(object):
return self.ports[port_id].get_stream_id_list()
- def __start_traffic (self, multiplier, duration, port_id_list = None):
+ def __start_traffic (self, multiplier, duration, port_id_list = None, force = False):
port_id_list = self.__ports(port_id_list)
rc = RC()
for port_id in port_id_list:
- rc.add(self.ports[port_id].start(multiplier, duration))
+ rc.add(self.ports[port_id].start(multiplier, duration, force))
return rc
@@ -655,7 +655,7 @@ class STLClient(object):
rc = RC()
for port_id in port_id_list:
- rc.add(self.ports[port_id].update(mult))
+ rc.add(self.ports[port_id].update(mult, force))
return rc
@@ -786,7 +786,7 @@ class STLClient(object):
if not dry:
self.logger.pre_cmd("Starting traffic on port(s) {0}:".format(port_id_list))
- rc = self.__start_traffic(mult, duration, port_id_list)
+ rc = self.__start_traffic(mult, duration, port_id_list, force)
self.logger.post_cmd(rc)
return rc
@@ -815,10 +815,10 @@ class STLClient(object):
return RC_OK()
#update cmd
- def __update (self, port_id_list, mult):
+ def __update (self, port_id_list, mult, force):
self.logger.pre_cmd("Updating traffic on port(s) {0}:".format(port_id_list))
- rc = self.__update_traffic(mult, port_id_list)
+ rc = self.__update_traffic(mult, port_id_list, force)
self.logger.post_cmd(rc)
return rc
@@ -1365,7 +1365,7 @@ class STLClient(object):
# update traffic
@__api_check(True)
- def update (self, ports = None, mult = "1", total = False):
+ def update (self, ports = None, mult = "1", total = False, force = False):
# by default the user means all the active ports
if ports == None:
@@ -1389,7 +1389,7 @@ class STLClient(object):
# call low level functions
- rc = self.__update(ports, mult_obj)
+ rc = self.__update(ports, mult_obj, force)
if not rc:
raise STLError(rc)
@@ -1638,7 +1638,8 @@ class STLClient(object):
self.update_line.__doc__,
parsing_opts.PORT_LIST_WITH_ALL,
parsing_opts.MULTIPLIER,
- parsing_opts.TOTAL)
+ parsing_opts.TOTAL,
+ parsing_opts.FORCE)
opts = parser.parse_args(line.split())
if opts is None:
@@ -1651,7 +1652,7 @@ class STLClient(object):
self.logger.log(format_text("No ports in valid state to update\n", 'bold'))
return
- self.update(ports, opts.mult, opts.total)
+ self.update(ports, opts.mult, opts.total, opts.force)
# true means print time
return True
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index b6585a88..821479f5 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -450,6 +450,7 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
double duration = parse_double(params, "duration", result);
+ bool force = parse_bool(params, "force", result);
/* multiplier */
const Json::Value &mul_obj = parse_object(params, "mul", result);
@@ -457,7 +458,7 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
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);
-
+
if (op != "abs") {
generate_parse_err(result, "start message can only specify absolute speed rate");
}
@@ -465,9 +466,9 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
TrexPortMultiplier mul(type, op, value);
try {
- port->start_traffic(mul, duration);
+ port->start_traffic(mul, duration, force);
- } catch (const TrexRpcException &ex) {
+ } catch (const TrexException &ex) {
generate_execute_err(result, ex.what());
}
@@ -585,6 +586,8 @@ TrexRpcCmdUpdateTraffic::_run(const Json::Value &params, Json::Value &result) {
uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+ bool force = parse_bool(params, "force", result);
+
/* multiplier */
const Json::Value &mul_obj = parse_object(params, "mul", result);
@@ -597,8 +600,8 @@ TrexRpcCmdUpdateTraffic::_run(const Json::Value &params, Json::Value &result) {
try {
- port->update_traffic(mul);
- } catch (const TrexRpcException &ex) {
+ port->update_traffic(mul, force);
+ } catch (const TrexException &ex) {
generate_execute_err(result, ex.what());
}
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 081398d1..48a38780 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -110,12 +110,12 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStream, "get_stream", 3, false);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 3, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 4, true);
TREX_RPC_CMD_DEFINE(TrexRpcCmdStopTraffic, "stop_traffic", 1, true);
TREX_RPC_CMD_DEFINE(TrexRpcCmdPauseTraffic, "pause_traffic", 1, true);
TREX_RPC_CMD_DEFINE(TrexRpcCmdResumeTraffic, "resume_traffic", 1, true);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdUpdateTraffic, "update_traffic", 2, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdUpdateTraffic, "update_traffic", 3, true);
TREX_RPC_CMD_DEFINE(TrexRpcCmdValidate, "validate", 2, false);
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index f14cc84c..d47802ec 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -132,7 +132,7 @@ TrexStatelessPort::release(void) {
*
*/
void
-TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration) {
+TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, bool force) {
/* command allowed only on state stream */
verify_state(PORT_STATE_STREAMS);
@@ -143,7 +143,8 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration)
/* on start - we can only provide absolute values */
assert(mul.m_op == TrexPortMultiplier::OP_ABS);
- double factor = calculate_effective_factor(mul);
+ /* caclulate the effective factor for DP */
+ double factor = calculate_effective_factor(mul, force);
/* fetch all the streams from the table */
vector<TrexStream *> streams;
@@ -274,14 +275,14 @@ TrexStatelessPort::resume_traffic(void) {
}
void
-TrexStatelessPort::update_traffic(const TrexPortMultiplier &mul) {
+TrexStatelessPort::update_traffic(const TrexPortMultiplier &mul, bool force) {
double factor;
verify_state(PORT_STATE_TX | PORT_STATE_PAUSE);
/* generate a message to all the relevant DP cores to start transmitting */
- double new_factor = calculate_effective_factor(mul);
+ double new_factor = calculate_effective_factor(mul, force);
switch (mul.m_op) {
case TrexPortMultiplier::OP_ABS:
@@ -446,20 +447,42 @@ TrexStatelessPort::get_port_speed_bps() const {
}
}
+static inline double
+bps_to_gbps(double bps) {
+ return (bps / (1000.0 * 1000 * 1000));
+}
+
double
-TrexStatelessPort::calculate_effective_factor(const TrexPortMultiplier &mul) {
+TrexStatelessPort::calculate_effective_factor(const TrexPortMultiplier &mul, bool force) {
- /* for a simple factor request */
- if (mul.m_type == TrexPortMultiplier::MUL_FACTOR) {
- return (mul.m_value);
+ double factor = calculate_effective_factor_internal(mul);
+
+ /* did we exceeded the max L1 line rate ? */
+ double expected_l1_rate = factor * m_graph_obj->get_max_bps_l1();
+
+ /* if not force and exceeded - throw exception */
+ if ( (!force) && (expected_l1_rate > get_port_speed_bps()) ) {
+ stringstream ss;
+ ss << "Expected L1 B/W: '" << bps_to_gbps(expected_l1_rate) << " Gbps' exceeds port line rate: '" << bps_to_gbps(get_port_speed_bps()) << " Gbps'";
+ throw TrexException(ss.str());
}
+ return factor;
+}
+
+double
+TrexStatelessPort::calculate_effective_factor_internal(const TrexPortMultiplier &mul) {
+
/* we now need the graph - generate it if we don't have it (happens once) */
if (!m_graph_obj) {
generate_streams_graph();
}
switch (mul.m_type) {
+
+ case TrexPortMultiplier::MUL_FACTOR:
+ return (mul.m_value);
+
case TrexPortMultiplier::MUL_BPS:
return (mul.m_value / m_graph_obj->get_max_bps_l2());
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index c3785b0c..64cf73a4 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -162,7 +162,7 @@ public:
* start traffic
* throws TrexException in case of an error
*/
- void start_traffic(const TrexPortMultiplier &mul, double duration);
+ void start_traffic(const TrexPortMultiplier &mul, double duration, bool force = false);
/**
* stop traffic
@@ -186,7 +186,7 @@ public:
* update current traffic on port
*
*/
- void update_traffic(const TrexPortMultiplier &mul);
+ void update_traffic(const TrexPortMultiplier &mul, bool force);
/**
* get the port state
@@ -351,8 +351,8 @@ private:
* calculate effective M per core
*
*/
- double calculate_effective_factor(const TrexPortMultiplier &mul);
-
+ double calculate_effective_factor(const TrexPortMultiplier &mul, bool force = false);
+ double calculate_effective_factor_internal(const TrexPortMultiplier &mul);
/**