summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xscripts/automation/trex_control_plane/stl/console/trex_console.py2
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py63
-rwxr-xr-xsrc/bp_sim.cpp5
-rwxr-xr-xsrc/main.cpp9
-rwxr-xr-xsrc/msg_manager.cpp15
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp40
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h21
-rw-r--r--src/sim/trex_sim.h61
-rw-r--r--src/sim/trex_sim_stateless.cpp69
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp12
-rw-r--r--src/stateless/cp/trex_stateless_port.h7
-rw-r--r--src/stateless/cp/trex_stream.cpp35
-rw-r--r--src/stateless/cp/trex_stream.h174
13 files changed, 318 insertions, 195 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py
index 9e9dcf62..0beb10df 100755
--- a/scripts/automation/trex_control_plane/stl/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py
@@ -532,7 +532,7 @@ class TRexConsole(TRexGeneralCmd):
info = self.stateless_client.get_connection_info()
exe = './trex-console --top -t -q -s {0} -p {1} --async_port {2}'.format(info['server'], info['sync_port'], info['async_port'])
- cmd = ['xterm', '-geometry', '111x42', '-sl', '0', '-title', 'trex_tui', '-e', exe]
+ cmd = ['xterm', '-geometry', '111x47', '-sl', '0', '-title', 'trex_tui', '-e', exe]
self.terminal = subprocess.Popen(cmd)
return
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
index e5578564..34c7a857 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
@@ -117,8 +117,10 @@ class CTRexInfoGenerator(object):
per_field_stats = OrderedDict([("owner", []),
("state", []),
("--", []),
- ("Tx bps", []),
+ ("Tx bps L2", []),
+ ("Tx bps L1", []),
("Tx pps", []),
+ ("Line Util.", []),
("---", []),
("Rx bps", []),
@@ -313,7 +315,15 @@ class CTRexStats(object):
# must be implemented by designated classes (such as port/ global stats)
raise NotImplementedError()
+ def generate_extended_values (self, snapshot):
+ raise NotImplementedError()
+
+
def update(self, snapshot):
+
+ # some extended generated values (from base values)
+ self.generate_extended_values(snapshot)
+
# update
self.latest_stats = snapshot
@@ -326,6 +336,8 @@ class CTRexStats(object):
if (not self.reference_stats) or (diff_time > 3):
self.reference_stats = self.latest_stats
+
+
self.last_update_ts = time.time()
@@ -439,6 +451,20 @@ class CGlobalStats(CTRexStats):
return stats
+ def generate_extended_values (self, snapshot):
+ # L1 bps
+ bps = snapshot.get("m_tx_bps")
+ pps = snapshot.get("m_tx_pps")
+
+ if pps > 0:
+ avg_pkt_size = bps / (pps * 8.0)
+ bps_L1 = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size )
+ else:
+ bps_L1 = 0.0
+
+ snapshot['m_tx_bps_L1'] = bps_L1
+
+
def generate_stats(self):
return OrderedDict([("connection", "{host}, Port {port}".format(host=self.connection_info.get("server"),
port=self.connection_info.get("sync_port"))),
@@ -450,8 +476,11 @@ class CGlobalStats(CTRexStats):
(" ", ""),
- ("total_tx", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
- self.get_trend_gui("m_tx_bps"))),
+ ("total_tx_L2", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
+ self.get_trend_gui("m_tx_bps"))),
+
+ ("total_tx_L1", u"{0} {1}".format( self.get("m_tx_bps_L1", format=True, suffix="b/sec"),
+ self.get_trend_gui("m_tx_bps_L1"))),
("total_rx", u"{0} {1}".format( self.get("m_rx_bps", format=True, suffix="b/sec"),
self.get_trend_gui("m_rx_bps"))),
@@ -532,6 +561,21 @@ class CPortStats(CTRexStats):
return stats
+ def generate_extended_values (self, snapshot):
+ # L1 bps
+ bps = snapshot.get("m_total_tx_bps")
+ pps = snapshot.get("m_total_tx_pps")
+
+ if pps > 0:
+ avg_pkt_size = bps / (pps * 8.0)
+ bps_L1 = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size )
+ else:
+ bps_L1 = 0.0
+
+ snapshot['m_total_tx_bps_L1'] = bps_L1
+ snapshot['m_percentage'] = (bps_L1 / self._port_obj.get_speed_bps()) * 100
+
+
def generate_stats(self):
state = self._port_obj.get_port_state_name() if self._port_obj else ""
@@ -542,6 +586,7 @@ class CPortStats(CTRexStats):
else:
state = format_text(state, 'bold')
+
return {"owner": self._port_obj.user if self._port_obj else "",
"state": "{0}".format(state),
@@ -550,8 +595,16 @@ class CPortStats(CTRexStats):
"----": " ",
"-----": " ",
- "Tx bps": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False),
- self.get("m_total_tx_bps", format = True, suffix = "bps")),
+ "Tx bps L1": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps_L1", show_value = False),
+ self.get("m_total_tx_bps_L1", format = True, suffix = "bps")),
+
+ "Tx bps L2": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False),
+ self.get("m_total_tx_bps", format = True, suffix = "bps")),
+
+ "Line Util.": u"{0} {1}".format(self.get_trend_gui("m_percentage", show_value = False),
+ format_text(
+ self.get("m_percentage", format = True, suffix = "%") if self._port_obj else "",
+ 'bold')),
"Rx bps": u"{0} {1}".format(self.get_trend_gui("m_total_rx_bps", show_value = False),
self.get("m_total_rx_bps", format = True, suffix = "bps")),
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index a1851b55..88e2c3ad 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -4137,7 +4137,10 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name,
void CFlowGenList::Delete(){
clean_p_thread_info();
Clean();
- delete CPluginCallback::callback;
+ if (CPluginCallback::callback) {
+ delete CPluginCallback::callback;
+ CPluginCallback::callback = NULL;
+ }
}
diff --git a/src/main.cpp b/src/main.cpp
index 6ee3a03d..6a6b5721 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -82,6 +82,8 @@ static CSimpleOpt::SOption parser_options[] =
SO_END_OF_OPTIONS
};
+static TrexStateless *m_sim_statelss_obj;
+
static int usage(){
printf(" Usage: bp_sim [OPTION] -f cfg.yaml -o outfile.erf \n");
@@ -247,6 +249,13 @@ void set_default_mac_addr(){
}
}
+TrexStateless * get_stateless_obj() {
+ return m_sim_statelss_obj;
+}
+
+void set_stateless_obj(TrexStateless *obj) {
+ m_sim_statelss_obj = obj;
+}
int main(int argc , char * argv[]){
diff --git a/src/msg_manager.cpp b/src/msg_manager.cpp
index 5fe44771..9ade1bfc 100755
--- a/src/msg_manager.cpp
+++ b/src/msg_manager.cpp
@@ -52,8 +52,6 @@ bool CMessagingManager::Create(uint8_t num_dp_threads,std::string a_name){
}
void CMessagingManager::Delete(){
- assert(m_cp_to_dp);
- assert(m_dp_to_cp);
int i;
for (i=0; i<m_num_dp_threads; i++) {
CNodeRing * lp;
@@ -63,8 +61,16 @@ void CMessagingManager::Delete(){
lp->Delete();
}
- delete []m_dp_to_cp;
- delete []m_cp_to_dp;
+ if (m_dp_to_cp) {
+ delete [] m_dp_to_cp;
+ m_dp_to_cp = NULL;
+ }
+
+ if (m_cp_to_dp) {
+ delete [] m_cp_to_dp;
+ m_cp_to_dp = NULL;
+ }
+
}
CNodeRing * CMessagingManager::getRingCpToDp(uint8_t thread_id){
@@ -83,6 +89,7 @@ void CMsgIns::Free(){
if (m_ins) {
m_ins->Delete();
delete m_ins;
+ m_ins = NULL;
}
}
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 74985883..0918ff0e 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -49,7 +49,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
string type = parse_string(mode, "type", result);
/* allocate a new stream based on the type */
- std::unique_ptr<TrexStream> stream( allocate_new_stream(section, port_id, stream_id, result) );
+ std::unique_ptr<TrexStream> stream = allocate_new_stream(section, port_id, stream_id, result);
/* save this for future queries */
stream->store_stream_json(section);
@@ -98,7 +98,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
/* parse VM */
const Json::Value &vm = parse_object(section ,"vm", result);
- parse_vm(vm, stream.get(), result);
+ parse_vm(vm, stream, result);
/* parse RX info */
const Json::Value &rx = parse_object(section, "rx_stats", result);
@@ -113,7 +113,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
}
/* make sure this is a valid stream to add */
- validate_stream(stream.get(), result);
+ validate_stream(stream, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
@@ -131,10 +131,10 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
-TrexStream *
+std::unique_ptr<TrexStream>
TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result) {
- TrexStream *stream = NULL;
+ std::unique_ptr<TrexStream> stream;
const Json::Value &mode = parse_object(section, "mode", result);
std::string type = parse_string(mode, "type", result);
@@ -142,13 +142,13 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
if (type == "continuous") {
- stream = new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id);
+ stream.reset(new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id));
} else if (type == "single_burst") {
uint32_t total_pkts = parse_int(mode, "total_pkts", result);
- stream = new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id);
+ stream.reset(new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id));
stream->set_single_burst(total_pkts);
@@ -158,7 +158,7 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
uint32_t num_bursts = parse_int(mode, "count", result);
uint32_t pkts_per_burst = parse_int(mode, "pkts_per_burst", result);
- stream = new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id );
+ stream.reset(new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id ));
stream->set_multi_burst(pkts_per_burst,num_bursts,ibg_usec);
@@ -175,9 +175,14 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
}
void
-TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
- double value = parse_double(rate, "value", result);
+ double value = parse_double(rate, "value", result);
+ if (value <= 0) {
+ std::stringstream ss;
+ ss << "rate value must be a positive number - got: '" << value << "'";
+ generate_parse_err(result, ss.str());
+ }
auto rate_types = {"pps", "bps_L1", "bps_L2", "percentage"};
std::string rate_type = parse_choice(rate, "type", rate_types, result);
@@ -198,7 +203,7 @@ TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, TrexStream *stream, Jso
}
void
-TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result);
stream->m_vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(pkt_offset));
@@ -206,7 +211,7 @@ TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream
void
-TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result){
+TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result){
std::string flow_var_name = parse_string(inst, "name", result);
@@ -215,7 +220,7 @@ TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexS
void
-TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result){
+TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result){
std::string flow_var_name = parse_string(inst, "name", result);
@@ -239,7 +244,7 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, Trex
void
-TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
std::string flow_var_name = parse_string(inst, "name", result);
auto sizes = {1, 2, 4, 8};
@@ -326,7 +331,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst,
void
-TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
std::string flow_var_name = parse_string(inst, "name", result);
uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result);
int add_value = parse_int(inst, "add_value", result);
@@ -339,7 +344,7 @@ 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) {
+TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
const Json::Value &instructions = parse_array(vm ,"instructions", result);
@@ -386,7 +391,7 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V
}
void
-TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &result) {
/* add the stream to the port's stream table */
TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
@@ -395,7 +400,6 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
if (port->get_stream_by_id(stream->m_stream_id)) {
std::stringstream ss;
ss << "stream " << stream->m_stream_id << " already exists";
- delete stream;
generate_execute_err(result, ss.str());
}
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 3da1e4fa..d90d880e 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -24,6 +24,7 @@ limitations under the License.
#include <trex_rpc_cmd_api.h>
#include <json/json.h>
+#include <memory>
class TrexStream;
@@ -91,16 +92,16 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream, "remove_stream", 2, tru
TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdAddStream, "add_stream", 3, true,
/* extended part */
-TrexStream * allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
-void validate_stream(const TrexStream *stream, Json::Value &result);
-void parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_rate(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
+std::unique_ptr<TrexStream> allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
+void validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_rate(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
);
diff --git a/src/sim/trex_sim.h b/src/sim/trex_sim.h
index 8feb7bc0..99bfb28e 100644
--- a/src/sim/trex_sim.h
+++ b/src/sim/trex_sim.h
@@ -25,6 +25,7 @@ limitations under the License.
#include <os_time.h>
#include <bp_sim.h>
#include <json/json.h>
+#include <trex_stateless.h>
int gtest_main(int argc, char **argv);
@@ -32,12 +33,49 @@ class TrexStateless;
class TrexPublisher;
class DpToCpHandler;
+void set_stateless_obj(TrexStateless *obj);
static inline bool
in_range(int x, int low, int high) {
return ( (x >= low) && (x <= high) );
}
+/*************** hook for platform API **************/
+class SimPlatformApi : public TrexPlatformApi {
+public:
+ SimPlatformApi(int dp_core_count) {
+ m_dp_core_count = dp_core_count;
+ }
+
+ virtual uint8_t get_dp_core_count() const {
+ return m_dp_core_count;
+ }
+
+ virtual void get_global_stats(TrexPlatformGlobalStats &stats) const {
+ }
+
+ virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const {
+ driver_name = "TEST";
+ speed = TrexPlatformApi::SPEED_10G;
+ }
+
+ virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
+ }
+
+ virtual void port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
+ for (int i = 0; i < m_dp_core_count; i++) {
+ cores_id_list.push_back(std::make_pair(i, 0));
+ }
+ }
+
+ virtual void publish_async_data_now(uint32_t key) const {
+
+ }
+
+private:
+ int m_dp_core_count;
+};
+
/**
* interface for a sim target
*
@@ -67,12 +105,27 @@ public:
*
* @author imarom (28-Dec-15)
*/
-class SimGtest : public SimInterface {
+class SimGtest : SimInterface {
public:
int run(int argc, char **argv) {
+ TrexStatelessCfg cfg;
+
+ cfg.m_port_count = 1;
+ cfg.m_rpc_req_resp_cfg = NULL;
+ cfg.m_rpc_async_cfg = NULL;
+ cfg.m_rpc_server_verbose = false;
+ cfg.m_platform_api = new SimPlatformApi(1);;
+ cfg.m_publisher = NULL;
+
+ set_stateless_obj(new TrexStateless(cfg));
assert( CMsgIns::Ins()->Create(4) );
- return gtest_main(argc, argv);
+ int rc = gtest_main(argc, argv);
+
+ delete get_stateless_obj();
+ set_stateless_obj(NULL);
+
+ return rc;
}
};
@@ -112,9 +165,6 @@ public:
int limit,
bool is_dry_run);
- TrexStateless * get_stateless_obj() {
- return m_trex_stateless;
- }
void set_verbose(bool enable) {
m_verbose = enable;
@@ -149,7 +199,6 @@ private:
return m_verbose;
}
- TrexStateless *m_trex_stateless;
DpToCpHandler *m_dp_to_cp_handler;
TrexPublisher *m_publisher;
CFlowGenList m_fl;
diff --git a/src/sim/trex_sim_stateless.cpp b/src/sim/trex_sim_stateless.cpp
index 897d1fec..a8316034 100644
--- a/src/sim/trex_sim_stateless.cpp
+++ b/src/sim/trex_sim_stateless.cpp
@@ -54,10 +54,6 @@ static string format_num(double num, const string &suffix = "") {
return "NaN";
}
-TrexStateless * get_stateless_obj() {
- return SimStateless::get_instance().get_stateless_obj();
-}
-
class SimRunException : public std::runtime_error
{
@@ -69,41 +65,6 @@ public:
}
};
-/*************** hook for platform API **************/
-class SimPlatformApi : public TrexPlatformApi {
-public:
- SimPlatformApi(int dp_core_count) {
- m_dp_core_count = dp_core_count;
- }
-
- virtual uint8_t get_dp_core_count() const {
- return m_dp_core_count;
- }
-
- virtual void get_global_stats(TrexPlatformGlobalStats &stats) const {
- }
-
- virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const {
- driver_name = "TEST";
- speed = TrexPlatformApi::SPEED_10G;
- }
-
- virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
- }
-
- virtual void port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
- for (int i = 0; i < m_dp_core_count; i++) {
- cores_id_list.push_back(std::make_pair(i, 0));
- }
- }
-
- virtual void publish_async_data_now(uint32_t key) const {
-
- }
-
-private:
- int m_dp_core_count;
-};
/**
* handler for DP to CP messages
@@ -146,7 +107,6 @@ public:
************************/
SimStateless::SimStateless() {
- m_trex_stateless = NULL;
m_publisher = NULL;
m_dp_to_cp_handler = NULL;
m_verbose = false;
@@ -198,9 +158,10 @@ SimStateless::run(const string &json_filename,
SimStateless::~SimStateless() {
- if (m_trex_stateless) {
- delete m_trex_stateless;
- m_trex_stateless = NULL;
+
+ if (get_stateless_obj()) {
+ delete get_stateless_obj();
+ set_stateless_obj(NULL);
}
if (m_publisher) {
@@ -231,11 +192,11 @@ SimStateless::prepare_control_plane() {
cfg.m_platform_api = new SimPlatformApi(m_dp_core_count);
cfg.m_publisher = m_publisher;
- m_trex_stateless = new TrexStateless(cfg);
+ set_stateless_obj(new TrexStateless(cfg));
- m_trex_stateless->launch_control_plane();
+ get_stateless_obj()->launch_control_plane();
- for (auto &port : m_trex_stateless->get_port_list()) {
+ for (auto &port : get_stateless_obj()->get_port_list()) {
port->acquire("test", 0, true);
}
@@ -274,7 +235,7 @@ SimStateless::execute_json(const std::string &json_filename) {
buffer << test.rdbuf();
try {
- rep = m_trex_stateless->get_rpc_server()->test_inject_request(buffer.str());
+ rep = get_stateless_obj()->get_rpc_server()->test_inject_request(buffer.str());
} catch (TrexRpcException &e) {
throw SimRunException(e.what());
}
@@ -321,8 +282,10 @@ static inline bool is_debug() {
void
SimStateless::show_intro(const std::string &out_filename) {
- uint64_t bps = 0;
- uint64_t pps = 0;
+ double pps;
+ double bps_L1;
+ double bps_L2;
+ double percentage;
std::cout << "\nGeneral info:\n";
std::cout << "------------\n\n";
@@ -356,10 +319,12 @@ SimStateless::show_intro(const std::string &out_filename) {
std::cout << "stream count: " << port->get_stream_count() << "\n";
- port->get_port_effective_rate(bps, pps);
+ port->get_port_effective_rate(pps, bps_L1, bps_L2, percentage);
- std::cout << "max BPS: " << format_num(bps, "bps") << "\n";
- std::cout << "max PPS: " << format_num(pps, "pps") << "\n";
+ std::cout << "max PPS : " << format_num(pps, "pps") << "\n";
+ std::cout << "max BPS L1 : " << format_num(bps_L1, "bps") << "\n";
+ std::cout << "max BPS L2 : " << format_num(bps_L2, "bps") << "\n";
+ std::cout << "line util. : " << format_num(percentage, "%") << "\n";
std::cout << "\n\nStarting simulation...\n";
}
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 8ee46d29..75f77cf7 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -631,7 +631,10 @@ TrexStatelessPort::validate(void) {
void
-TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) {
+TrexStatelessPort::get_port_effective_rate(double &pps,
+ double &bps_L1,
+ double &bps_L2,
+ double &percentage) {
if (get_stream_count() == 0) {
return;
@@ -641,8 +644,11 @@ TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) {
generate_streams_graph();
}
- bps = m_graph_obj->get_max_bps_l2() * m_factor;
- pps = m_graph_obj->get_max_pps() * m_factor;
+ pps = m_graph_obj->get_max_pps() * m_factor;
+ bps_L1 = m_graph_obj->get_max_bps_l1() * m_factor;
+ bps_L2 = m_graph_obj->get_max_bps_l2() * m_factor;
+ percentage = (bps_L1 / get_port_speed_bps()) * 100.0;
+
}
/************* Trex Port Owner **************/
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index b0b0ddf3..a101cef0 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -316,10 +316,11 @@ public:
*
* @author imarom (07-Jan-16)
*
- * @param bps
- * @param pps
*/
- void get_port_effective_rate(uint64_t &bps, uint64_t &pps);
+ void get_port_effective_rate(double &pps,
+ double &bps_L1,
+ double &bps_L2,
+ double &percentage);
private:
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index f4a8e800..357a2885 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -106,16 +106,16 @@ void TrexStream::Dump(FILE *fd){
fprintf(fd," rate :\n\n");
- fprintf(fd," pps : %f\n", get_rate().get_pps());
- fprintf(fd," bps L1 : %f\n", get_rate().get_bps_L1());
- fprintf(fd," bps L2 : %f\n", get_rate().get_bps_L2());
- fprintf(fd," percentage : %f\n", get_rate().get_percentage());
+ fprintf(fd," pps : %f\n", m_rate.get_pps());
+ fprintf(fd," bps L1 : %f\n", m_rate.get_bps_L1());
+ fprintf(fd," bps L2 : %f\n", m_rate.get_bps_L2());
+ fprintf(fd," percentage : %f\n", m_rate.get_percentage());
}
TrexStream::TrexStream(uint8_t type,
- uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) {
+ uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) , m_rate(*this) {
/* default values */
m_type = type;
@@ -160,18 +160,6 @@ TrexStream::get_stream_json() {
return m_stream_json;
}
-TrexStreamRate &
-TrexStream::get_rate() {
-
- /* lazy calculation of the rate */
- if (!m_rate.is_calculated()) {
- TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_port_id);
- double pkt_size = get_pkt_size();
- m_rate.calculate(pkt_size, port->get_port_speed_bps());
- }
-
- return m_rate;
-}
/**************************************
* stream table
@@ -253,3 +241,16 @@ int TrexStreamTable::size() {
}
+/**************************************
+ * TrexStreamRate
+ *************************************/
+uint64_t
+TrexStreamRate::get_line_speed_bps() {
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_stream.m_port_id);
+ return port->get_port_speed_bps();
+}
+
+double
+TrexStreamRate::get_pkt_size() {
+ return m_stream.get_pkt_size();
+}
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index f4739569..66f05b16 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -103,6 +103,8 @@ public:
}
};
+class TrexStream;
+
/**
* describes a stream rate
*
@@ -121,9 +123,21 @@ public:
RATE_PERCENTAGE
};
- TrexStreamRate() {
- m_base_rate_type = RATE_INVALID;
- m_is_calculated = false;
+ TrexStreamRate(TrexStream &stream) : m_stream(stream) {
+ m_pps = 0;
+ m_bps_L1 = 0;
+ m_bps_L2 = 0;
+ m_percentage = 0;
+ }
+
+
+ TrexStreamRate& operator=(const TrexStreamRate& other) {
+ m_pps = other.m_pps;
+ m_bps_L1 = other.m_bps_L1;
+ m_bps_L2 = other.m_bps_L2;
+ m_percentage = other.m_percentage;
+
+ return (*this);
}
/**
@@ -132,121 +146,133 @@ public:
*
*/
void set_base_rate(rate_type_e type, double value) {
- m_base_rate_type = type;
- m_value = value;
- m_is_calculated = false;
- }
-
+ m_pps = 0;
+ m_bps_L1 = 0;
+ m_bps_L2 = 0;
+ m_percentage = 0;
- /**
- * calculates all the rates from the base rate
- *
- */
- void calculate(uint16_t pkt_size, uint64_t line_bps) {
+ assert(value > 0);
- switch (m_base_rate_type) {
-
+ switch (type) {
case RATE_PPS:
- calculate_from_pps(m_value, pkt_size, line_bps);
+ m_pps = value;
break;
-
case RATE_BPS_L1:
- calculate_from_bps_L1(m_value, pkt_size, line_bps);
+ m_bps_L1 = value;
break;
-
case RATE_BPS_L2:
- calculate_from_bps_L2(m_value, pkt_size, line_bps);
+ m_bps_L2 = value;
break;
-
case RATE_PERCENTAGE:
- calculate_from_percentage(m_value, pkt_size, line_bps);
+ m_percentage = value;
break;
default:
assert(0);
+
}
-
- m_is_calculated = true;
- }
-
-
- bool is_calculated() const {
- return m_is_calculated;
- }
-
-
- /* update the rate by a factor */
- void update_factor(double factor) {
- assert(m_is_calculated);
-
- m_pps *= factor;
- m_bps_L1 *= factor;
- m_bps_L2 *= factor;
- m_percentage *= factor;
}
double get_pps() {
- assert(m_is_calculated);
+ if (m_pps == 0) {
+ calculate();
+ }
return (m_pps);
}
double get_bps_L1() {
- assert(m_is_calculated);
+ if (m_bps_L1 == 0) {
+ calculate();
+ }
return (m_bps_L1);
}
double get_bps_L2() {
- assert(m_is_calculated);
+ if (m_bps_L2 == 0) {
+ calculate();
+ }
return m_bps_L2;
}
double get_percentage() {
- assert(m_is_calculated);
+ if (m_percentage == 0) {
+ calculate();
+ }
return m_percentage;
}
+
+
+ /* update the rate by a factor */
+ void update_factor(double factor) {
+ /* if all are non zero - it works, if only one (base) is also works */
+ m_pps *= factor;
+ m_bps_L1 *= factor;
+ m_bps_L2 *= factor;
+ m_percentage *= factor;
+ }
+
+
+
private:
- void calculate_from_pps(double pps, uint16_t pkt_size, uint64_t line_bps) {
- m_pps = pps;
- m_bps_L1 = m_pps * (pkt_size + 24) * 8;
- m_bps_L2 = m_pps * (pkt_size + 4) * 8;
- m_percentage = (m_bps_L1 / line_bps) * 100.0;
+ /**
+ * calculates all the rates from the base rate
+ *
+ */
+ void calculate() {
+
+ if (m_pps != 0) {
+ calculate_from_pps();
+ } else if (m_bps_L1 != 0) {
+ calculate_from_bps_L1();
+ } else if (m_bps_L2 != 0) {
+ calculate_from_bps_L2();
+ } else if (m_percentage != 0) {
+ calculate_from_percentage();
+ } else {
+ assert(0);
+ }
}
- void calculate_from_bps_L1(double bps_L1, uint16_t pkt_size, uint64_t line_bps) {
- m_bps_L1 = bps_L1;
- m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) );
- m_pps = m_bps_L2 / (8 * (pkt_size + 4));
- m_percentage = (m_bps_L1 / line_bps) * 100.0;
+ uint64_t get_line_speed_bps();
+ double get_pkt_size();
+
+ void calculate_from_pps() {
+ m_bps_L1 = m_pps * (get_pkt_size() + 24) * 8;
+ m_bps_L2 = m_pps * (get_pkt_size() + 4) * 8;
+ m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
}
- void calculate_from_bps_L2(double bps_L2, uint16_t pkt_size, uint64_t line_bps) {
- m_bps_L2 = bps_L2;
- m_bps_L1 = m_bps_L2 * ( (pkt_size + 24.0) / (pkt_size + 4.0));
- m_pps = m_bps_L2 / (8 * (pkt_size + 4));
- m_percentage = (m_bps_L1 / line_bps) * 100.0;
+ void calculate_from_bps_L1() {
+ m_bps_L2 = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) );
+ m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4));
+ m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
}
- void calculate_from_percentage(double percentage, uint16_t pkt_size, uint64_t line_bps) {
- m_percentage = percentage;
- m_bps_L1 = (m_percentage / 100.0) * line_bps;
- m_bps_L2 = m_bps_L1 * ( (pkt_size + 4.0) / (pkt_size + 24.0) );
- m_pps = m_bps_L2 / (8 * (pkt_size + 4));
+ void calculate_from_bps_L2() {
+ m_bps_L1 = m_bps_L2 * ( (get_pkt_size() + 24.0) / (get_pkt_size() + 4.0));
+ m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4));
+ m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
}
- rate_type_e m_base_rate_type;
- double m_value;
+ void calculate_from_percentage() {
+ m_bps_L1 = (m_percentage / 100.0) * get_line_speed_bps();
+ m_bps_L2 = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) );
+ m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4));
+
+ }
- bool m_is_calculated;
double m_pps;
double m_bps_L1;
double m_bps_L2;
double m_percentage;
+ /* reference to the owner class */
+ TrexStream &m_stream;
};
/**
@@ -254,6 +280,7 @@ private:
*
*/
class TrexStream {
+friend class TrexStreamRate;
public:
enum STREAM_TYPE {
@@ -298,19 +325,19 @@ public:
double get_pps() {
- return get_rate().get_pps();
+ return m_rate.get_pps();
}
double get_bps_L1() {
- return get_rate().get_bps_L1();
+ return m_rate.get_bps_L1();
}
double get_bps_L2() {
- return get_rate().get_bps_L2();
+ return m_rate.get_bps_L2();
}
double get_bw_percentage() {
- return get_rate().get_percentage();
+ return m_rate.get_percentage();
}
void set_rate(TrexStreamRate::rate_type_e type, double value) {
@@ -318,7 +345,7 @@ public:
}
void update_rate_factor(double factor) {
- get_rate().update_factor(factor);
+ m_rate.update_factor(factor);
}
void set_type(uint8_t type){
@@ -502,9 +529,6 @@ private:
}
- /* get (and calculate if need) the rate of the stream */
- TrexStreamRate & get_rate();
-
/* no access to this without a lazy build method */
TrexStreamRate m_rate;
};