diff options
author | 2016-01-24 11:35:41 -0500 | |
---|---|---|
committer | 2016-01-24 11:35:41 -0500 | |
commit | b87ac8e2af727598b3120510b221244c9c499e56 (patch) | |
tree | 425d9cb46b9fa49eb13a0e2773a3e68591182c6c | |
parent | 7294d7f162e19e0ccd3a37eafbafe22cf63df6a4 (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.py | 16 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/client/trex_stateless_client.py | 21 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 13 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmds.h | 4 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 39 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 8 |
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 ¶ms, 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 ¶ms, 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 ¶ms, 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 ¶ms, 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 ¶ms, 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); /** |