summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWenxian Li <wenxianl@cisco.com>2015-09-08 18:41:17 -0400
committerWenxian Li <wenxianl@cisco.com>2015-09-08 18:41:17 -0400
commit60e901aabaeab7d205da65030849056c05c8b73e (patch)
tree20883ed8ae63c326f3c042992e8dbe668656568e /src
parent9a524989d331f04abecd3faa72d98157a8651739 (diff)
parent463cb7c212e927a732fb5b702a288a06550c5eb8 (diff)
Merge remote-tracking branch
Conflicts: linux/b linux/ws_main.py linux_dpdk/ws_main.py src/bp_sim.h
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bp_gtest.cpp37
-rwxr-xr-xsrc/bp_sim.cpp32
-rwxr-xr-xsrc/bp_sim.h1
-rw-r--r--src/gtest/rpc_test.cpp242
-rwxr-xr-xsrc/main_dpdk.cpp62
-rwxr-xr-xsrc/pal/linux_dpdk/dpdk180/rte_config.h3
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp59
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp223
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_test.cpp81
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h77
-rw-r--r--src/rpc-server/trex_rpc_cmd.cpp258
-rw-r--r--src/rpc-server/trex_rpc_cmd_api.h179
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp70
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.h79
-rw-r--r--src/rpc-server/trex_rpc_exception_api.h42
-rw-r--r--src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp202
-rw-r--r--src/rpc-server/trex_rpc_jsonrpc_v2_parser.h94
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.cpp146
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.h51
-rw-r--r--src/rpc-server/trex_rpc_server.cpp153
-rw-r--r--src/rpc-server/trex_rpc_server_api.h165
-rw-r--r--src/rpc-server/trex_rpc_server_mock.cpp75
-rwxr-xr-xsrc/rx_check.cpp14
-rwxr-xr-xsrc/rx_check_header.h3
-rw-r--r--src/stateless/trex_stateless.cpp63
-rw-r--r--src/stateless/trex_stateless_api.h96
-rw-r--r--src/stateless/trex_stream.cpp93
-rw-r--r--src/stateless/trex_stream_api.h169
-rwxr-xr-xsrc/timer_wheel_pq.cpp7
-rwxr-xr-xsrc/zmq/include/zmq.h416
-rwxr-xr-xsrc/zmq/include/zmq_utils.h105
-rwxr-xr-xsrc/zmq/libzmq.abin7932556 -> 0 bytes
-rwxr-xr-xsrc/zmq/libzmq.la41
-rwxr-xr-xsrc/zmq/libzmq.lai41
-rwxr-xr-xsrc/zmq/libzmq.sobin3150071 -> 0 bytes
-rwxr-xr-xsrc/zmq/libzmq.so.3bin3150071 -> 0 bytes
-rwxr-xr-xsrc/zmq/libzmq.so.3.1.0bin3150071 -> 0 bytes
37 files changed, 2733 insertions, 646 deletions
diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp
index 94037759..a529d637 100755
--- a/src/bp_gtest.cpp
+++ b/src/bp_gtest.cpp
@@ -1464,6 +1464,8 @@ TEST_F(rx_check, rx_check_normal) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1492,6 +1494,8 @@ TEST_F(rx_check, rx_check_drop) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1528,8 +1532,10 @@ TEST_F(rx_check, rx_check_ooo) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
- rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
- rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.clean();
+
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
rxh.m_magic=RX_CHECK_MAGIC;
rxh.m_aging_sec=10;
@@ -1569,8 +1575,9 @@ TEST_F(rx_check, rx_check_ooo_1) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
- rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
- rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.clean();
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
rxh.set_dir(0);
rxh.set_both_dir(0);
@@ -1606,8 +1613,9 @@ TEST_F(rx_check, rx_check_ooo_2) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
- rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
- rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.clean();
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
rxh.m_magic=RX_CHECK_MAGIC;
rxh.m_aging_sec=10;
@@ -1644,6 +1652,7 @@ TEST_F(rx_check, rx_check_normal_two_dir) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
+ rxh.clean();
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1673,6 +1682,7 @@ TEST_F(rx_check, rx_check_normal_two_dir_fails) {
for (i=0; i<10; i++) {
CRx_check_header rxh;
+ rxh.clean();
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1699,6 +1709,8 @@ TEST_F(rx_check, rx_check_normal_two_dir_ok) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1733,6 +1745,8 @@ TEST_F(rx_check, rx_check_normal_one_pkt_one_dir) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1759,6 +1773,8 @@ TEST_F(rx_check, rx_check_normal_one_pkt_one_dir_0) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1784,6 +1800,8 @@ TEST_F(rx_check, rx_check_normal_one_pkt_two_dir_0) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1816,6 +1834,8 @@ TEST_F(rx_check, rx_check_normal_one_pkt_two_dir_err1) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1859,6 +1879,8 @@ TEST_F(rx_check, rx_check_normal_two_dir_oo) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_time_stamp=0;
@@ -1903,6 +1925,8 @@ TEST_F(rx_check, rx_check_normal_aging) {
int i;
CRx_check_header rxh;
+ rxh.clean();
+
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_magic=RX_CHECK_MAGIC;
@@ -1937,6 +1961,7 @@ TEST_F(rx_check, rx_check_normal_no_aging) {
int i;
CRx_check_header rxh;
+ rxh.clean();
rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
rxh.m_magic=RX_CHECK_MAGIC;
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 48b4a158..47047831 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -1294,7 +1294,9 @@ bool CPacketIndication::ConvertPacketToIpv6InPlace(CCapPktRaw * pkt,
void CPacketIndication::ProcessPacket(CPacketParser *parser,
CCapPktRaw * pkt){
_ProcessPacket(parser,pkt);
- UpdateOffsets(); /* update fast offsets */
+ if ( m_desc.IsValidPkt() ){
+ UpdateOffsets(); /* update fast offsets */
+ }
}
@@ -2119,7 +2121,13 @@ int CCapFileFlowInfo::load_cap_file(std::string cap_file,uint16_t _id,uint8_t pl
}
}
+ }else{
+ printf("ERROR packet %d is not supported, should be IP(0x0800)/TCP/UDP format try to convert it using Wireshark !\n",cnt);
+ exit(-1);
}
+ }else{
+ printf("ERROR packet %d is not supported, should be IP(0x0800)/TCP/UDP format try to convert it using Wireshark !\n",cnt);
+ exit(-1);
}
}
@@ -4449,6 +4457,7 @@ int CErfIF::send_node(CGenNode * node){
CFlowPktInfo * lp=node->m_pkt_info;
rte_mbuf_t * m=lp->generate_new_mbuf(node);
+
fill_pkt(m_raw,m);
CPktNsecTimeStamp t_c(node->m_time);
m_raw->time_nsec = t_c.m_time_nsec;
@@ -4630,6 +4639,7 @@ void CCPortLatency::reset(){
m_tx_pkt_err=0;
m_tx_pkt_ok =0;
m_pkt_ok=0;
+ m_rx_check=0;
m_no_magic=0;
m_unsup_prot=0;
m_no_id=0;
@@ -5441,10 +5451,11 @@ void on_node_last(uint8_t plugin_id,CGenNode * node){
}
rte_mbuf_t * on_node_generate_mbuf(uint8_t plugin_id,CGenNode * node,CFlowPktInfo * pkt_info){
- if (CPluginCallback::callback) {
- CPluginCallback::callback->on_node_generate_mbuf(plugin_id,node,pkt_info);
- }
-
+ rte_mbuf_t * m;
+ assert(CPluginCallback::callback);
+ m=CPluginCallback::callback->on_node_generate_mbuf(plugin_id,node,pkt_info);
+ assert(m);
+ return(m);
}
@@ -6280,22 +6291,25 @@ rte_mbuf_t * CPluginCallbackSimple::rtsp_plugin(uint8_t plugin_id,CGenNode *
/* replace the tuples */
rte_mbuf_t * CPluginCallbackSimple::on_node_generate_mbuf(uint8_t plugin_id,CGenNode * node,CFlowPktInfo * pkt_info){
+
+ rte_mbuf_t * m=NULL;
switch (plugin_id) {
case mpRTSP:
- rtsp_plugin(plugin_id,node,pkt_info);
+ m=rtsp_plugin(plugin_id,node,pkt_info);
break;
case mpSIP_VOICE:
- sip_voice_plugin(plugin_id,node,pkt_info);
+ m=sip_voice_plugin(plugin_id,node,pkt_info);
break;
case mpDYN_PYLOAD:
- dyn_pyload_plugin(plugin_id,node,pkt_info);
+ m=dyn_pyload_plugin(plugin_id,node,pkt_info);
break;
case mpAVL_HTTP_BROWSIN:
- http_plugin(plugin_id,node,pkt_info);
+ m=http_plugin(plugin_id,node,pkt_info);
break;
default:
assert(0);
}
+ return (m);
}
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 6fb638e0..804c936a 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -1249,6 +1249,7 @@ struct CFlowYamlInfo {
m_server_addr=0;
m_client_pool_idx = 0;
m_server_pool_idx = 0;
+ m_cap_mode=false;
}
std::string m_name;
diff --git a/src/gtest/rpc_test.cpp b/src/gtest/rpc_test.cpp
new file mode 100644
index 00000000..a3df2a67
--- /dev/null
+++ b/src/gtest/rpc_test.cpp
@@ -0,0 +1,242 @@
+/*
+ Itay Marom
+
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <common/gtest.h>
+#include <trex_rpc_server_api.h>
+#include <zmq.h>
+#include <json/json.h>
+#include <sstream>
+
+using namespace std;
+
+class RpcTest : public testing::Test {
+
+ virtual void SetUp() {
+ TrexRpcServerConfig cfg = TrexRpcServerConfig(TrexRpcServerConfig::RPC_PROT_TCP, 5050);
+
+ m_rpc = new TrexRpcServer(cfg);
+ m_rpc->start();
+
+ m_context = zmq_ctx_new ();
+ m_socket = zmq_socket (m_context, ZMQ_REQ);
+ zmq_connect (m_socket, "tcp://localhost:5050");
+ }
+
+ virtual void TearDown() {
+ m_rpc->stop();
+
+ delete m_rpc;
+ zmq_close(m_socket);
+ zmq_term(m_context);
+ }
+
+public:
+ string send_msg(const string &msg) {
+ char buffer[512];
+
+ zmq_send (m_socket, msg.c_str(), msg.size(), 0);
+ int len = zmq_recv(m_socket, buffer, sizeof(buffer), 0);
+
+ return string(buffer, len);
+ }
+
+ TrexRpcServer *m_rpc;
+ void *m_context;
+ void *m_socket;
+};
+
+TEST_F(RpcTest, basic_rpc_test) {
+ Json::Value request;
+ Json::Value response;
+ Json::Reader reader;
+
+ string req_str;
+ string resp_str;
+
+ // check bad JSON format
+ req_str = "bad format message";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], Json::Value::null);
+ EXPECT_EQ(response["error"]["code"], -32700);
+
+ // check bad version
+ req_str = "{\"jsonrpc\": \"1.5\", \"method\": \"foobar\", \"id\": \"1\"}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], "1");
+ EXPECT_EQ(response["error"]["code"], -32600);
+
+ // no method name present
+ req_str = "{\"jsonrpc\": \"2.0\", \"id\": 482}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], 482);
+ EXPECT_EQ(response["error"]["code"], -32600);
+
+ /* method does not exist */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"jfgldjlfds\", \"id\": 482}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], 482);
+ EXPECT_EQ(response["error"]["code"], -32601);
+
+ /* error but as notification */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"jfgldjlfds\"}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_TRUE(response == Json::Value::null);
+
+
+}
+
+TEST_F(RpcTest, test_add_command) {
+ Json::Value request;
+ Json::Value response;
+ Json::Reader reader;
+
+ string req_str;
+ string resp_str;
+
+ /* simple add - missing paramters */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"id\": 488}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], 488);
+ EXPECT_EQ(response["error"]["code"], -32602);
+
+ /* simple add that works */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 17, \"y\": -13} , \"id\": \"itay\"}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], "itay");
+ EXPECT_EQ(response["result"], 4);
+
+ /* add with bad paratemers types */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": \"blah\", \"y\": -13} , \"id\": 17}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], 17);
+ EXPECT_EQ(response["error"]["code"], -32602);
+
+ /* add with invalid count of parameters */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"y\": -13} , \"id\": 17}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], 17);
+ EXPECT_EQ(response["error"]["code"], -32602);
+
+
+ /* big numbers */
+ req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 4827371, \"y\": -39181273} , \"id\": \"itay\"}";
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], "itay");
+ EXPECT_EQ(response["result"], -34353902);
+
+}
+
+TEST_F(RpcTest, batch_rpc_test) {
+ Json::Value request;
+ Json::Value response;
+ Json::Reader reader;
+
+ string req_str;
+ string resp_str;
+
+ req_str = "[ \
+ {\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 22, \"y\": 17}, \"id\": \"1\"}, \
+ {\"jsonrpc\": \"2.0\", \"method\": \"test_sub\", \"params\": {\"x\": 22, \"y\": 17}, \"id\": \"2\"}, \
+ {\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 22, \"y\": \"itay\"}, \"id\": \"2\"}, \
+ {\"foo\": \"boo\"}, \
+ {\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_sheker\", \"params\": {\"name\": \"myself\"}, \"id\": 5}, \
+ {\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 22, \"y\": 17} } \
+ ]";
+
+ resp_str = send_msg(req_str);
+
+ EXPECT_TRUE(reader.parse(resp_str, response, false));
+ EXPECT_TRUE(response.isArray());
+
+ // message 1
+ EXPECT_TRUE(response[0]["jsonrpc"] == "2.0");
+ EXPECT_TRUE(response[0]["id"] == "1");
+ EXPECT_TRUE(response[0]["result"] == 39);
+
+ // message 2
+ EXPECT_TRUE(response[1]["jsonrpc"] == "2.0");
+ EXPECT_TRUE(response[1]["id"] == "2");
+ EXPECT_TRUE(response[1]["result"] == 5);
+
+ // message 3
+ EXPECT_TRUE(response[2]["jsonrpc"] == "2.0");
+ EXPECT_TRUE(response[2]["id"] == "2");
+ EXPECT_TRUE(response[2]["error"]["code"] == -32602);
+
+ // message 4
+ EXPECT_TRUE(response[3] == Json::Value::null);
+
+ // message 5
+ EXPECT_TRUE(response[4]["jsonrpc"] == "2.0");
+ EXPECT_TRUE(response[4]["id"] == 5);
+ EXPECT_TRUE(response[4]["error"]["code"] == -32601);
+
+ // message 6 - no ID but a valid command
+ EXPECT_TRUE(response[5] == Json::Value::null);
+
+ return;
+}
+
+TEST_F(RpcTest, add_stream) {
+ Json::Value request;
+ Json::Value response;
+ Json::Reader reader;
+
+ string req_str;
+ string resp_str;
+
+ req_str = "{'stream':{'port_id':7,'stream_id':12,'enable':True,'start':True,'Is':10.0,'packet':[0,1,2,3,4],"
+ "'vm_data':[{'Name':'ip_cnt','Size':4,'big_edian':True,'type':'inc','core_mask':'split','init_val':'10.0.0.7','min':'10.0.0.1','max':'10.0.0.10',}],"
+ "'vm_program':[{'op_core':['read_to_reg_mem','write_reg_offet','write_rand_offset'],'read_name':'nameofopecodetoread','pkt_offset':20}],"
+ "'mode':{'type':'continues','pps':1000},'next_stream':17,'next_stream_loop':100,'rx_stats':{'enable':True,'rx_stream_id':71,'seq_enable':True,'latency':True}}}";
+
+ resp_str = send_msg(req_str);
+}
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 1e6c8b20..820fb3fa 100755
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -55,6 +55,7 @@ limitations under the License.
#include <common/arg/SimpleGlob.h>
#include <common/arg/SimpleOpt.h>
#include <common/basic_utils.h>
+#include <../linux_dpdk/version.h>
extern "C" {
#include <dpdk_lib18/librte_pmd_ixgbe/ixgbe/ixgbe_type.h>
@@ -70,8 +71,6 @@ extern "C" {
#include "utl_term_io.h"
#include "msg_manager.h"
#include "platform_cfg.h"
-
-#define VERSION "1.73"
#define RX_CHECK_MIX_SAMPLE_RATE 8
@@ -637,9 +636,31 @@ static int usage(){
printf("\n");
printf("\n");
- printf(" Copyright (C) 2012 by hhaim Cisco-System POC for Israel dev-test \n");
- printf(" version : %s \n",VERSION);
-
+ printf(" Copyright (c) 2015-2015 Cisco Systems, Inc. \n");
+ printf(" \n");
+ printf(" Licensed under the Apache License, Version 2.0 (the 'License') \n");
+ printf(" you may not use this file except in compliance with the License. \n");
+ printf(" You may obtain a copy of the License at \n");
+ printf(" \n");
+ printf(" http://www.apache.org/licenses/LICENSE-2.0 \n");
+ printf(" \n");
+ printf(" Unless required by applicable law or agreed to in writing, software \n");
+ printf(" distributed under the License is distributed on an \"AS IS\" BASIS, \n");
+ printf(" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n");
+ printf(" See the License for the specific language governing permissions and \n");
+ printf(" limitations under the License. \n");
+ printf(" \n");
+ printf(" Open Source Components / Libraries \n");
+ printf(" DPDK (BSD) \n");
+ printf(" YAML-CPP (BSD) \n");
+ printf(" \n");
+ printf(" Open Source Binaries \n");
+ printf(" ZMQ (LGPL v3plus) \n");
+ printf(" \n");
+ printf(" Version : %s \n",VERSION_BUILD_NUM);
+ printf(" User : %s \n",VERSION_USER);
+ printf(" Date : %s , %s \n",get_build_date(),get_build_time());
+ printf(" Uuid : %s \n",VERSION_UIID);
return (0);
}
@@ -4370,7 +4391,7 @@ int main_test(int argc , char * argv[]){
int ret;
unsigned lcore_id;
- printf("Starting T-Rex %s please wait ... \n",VERSION);
+ printf("Starting TRex %s please wait ... \n",VERSION_BUILD_NUM);
CGlobalInfo::m_options.preview.clean();
@@ -4551,7 +4572,6 @@ void CTRexExtendedDriverBase1G::update_global_config_fdir(port_cfg_t * cfg){
cfg->update_global_config_fdir_10g_1g();
}
-
int CTRexExtendedDriverBase1G::configure_rx_filter_rules(CPhyEthIF * _if){
uint16_t hops = get_rx_check_hops();
@@ -4563,15 +4583,15 @@ int CTRexExtendedDriverBase1G::configure_rx_filter_rules(CPhyEthIF * _if){
int i;
// IPv4: bytes being compared are {TTL, Protocol}
uint16_t ff_rules_v4[4]={
- 0xFF06 - v4_hops,
- 0xFE11 - v4_hops,
- 0xFF11 - v4_hops,
- 0xFE06 - v4_hops,
+ (uint16_t)(0xFF06 - v4_hops),
+ (uint16_t)(0xFE11 - v4_hops),
+ (uint16_t)(0xFF11 - v4_hops),
+ (uint16_t)(0xFE06 - v4_hops),
} ;
// IPv6: bytes being compared are {NextHdr, HopLimit}
uint16_t ff_rules_v6[2]={
- 0x3CFF - hops,
- 0x3CFE - hops,
+ (uint16_t)(0x3CFF - hops),
+ (uint16_t)(0x3CFE - hops),
} ;
uint16_t *ff_rules;
uint16_t num_rules;
@@ -4709,17 +4729,17 @@ int CTRexExtendedDriverBase10G::configure_rx_filter_rules(CPhyEthIF * _if){
// IPv4: bytes being compared are {TTL, Protocol}
uint16_t ff_rules_v4[4]={
- 0xFF11 - v4_hops,
- 0xFE11 - v4_hops,
- 0xFF06 - v4_hops,
- 0xFE06 - v4_hops,
+ (uint16_t)(0xFF11 - v4_hops),
+ (uint16_t)(0xFE11 - v4_hops),
+ (uint16_t)(0xFF06 - v4_hops),
+ (uint16_t)(0xFE06 - v4_hops),
} ;
// IPv6: bytes being compared are {NextHdr, HopLimit}
uint16_t ff_rules_v6[4]={
- 0x3CFF - hops,
- 0x3CFE - hops,
- 0x3CFF - hops,
- 0x3CFE - hops,
+ (uint16_t)(0x3CFF - hops),
+ (uint16_t)(0x3CFE - hops),
+ (uint16_t)(0x3CFF - hops),
+ (uint16_t)(0x3CFE - hops),
} ;
const rte_l4type ff_rules_type[4]={
RTE_FDIR_L4TYPE_UDP,
diff --git a/src/pal/linux_dpdk/dpdk180/rte_config.h b/src/pal/linux_dpdk/dpdk180/rte_config.h
index 68dd7a7b..0603ed06 100755
--- a/src/pal/linux_dpdk/dpdk180/rte_config.h
+++ b/src/pal/linux_dpdk/dpdk180/rte_config.h
@@ -1,5 +1,8 @@
#ifndef __RTE_CONFIG_H
#define __RTE_CONFIG_H
+
+#define typeof __typeof__
+
#undef RTE_EXEC_ENV
#define RTE_EXEC_ENV "linuxapp"
#undef RTE_EXEC_ENV_LINUXAPP
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
new file mode 100644
index 00000000..6b765aca
--- /dev/null
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -0,0 +1,59 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include "trex_rpc_cmds.h"
+#include <trex_rpc_server_api.h>
+
+#ifndef TREX_RPC_MOCK_SERVER
+ #include <../linux_dpdk/version.h>
+#endif
+
+using namespace std;
+
+/**
+ * get status
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &result) {
+
+ Json::Value &section = result["result"];
+
+ #ifndef TREX_RPC_MOCK_SERVER
+
+ section["general"]["version"] = VERSION_BUILD_NUM;
+ section["general"]["build_date"] = get_build_date();
+ section["general"]["build_time"] = get_build_time();
+ section["general"]["version_user"] = VERSION_USER;
+ section["general"]["uptime"] = TrexRpcServer::get_server_uptime();
+
+ #else
+
+ section["general"]["version"] = "v0.0";
+ section["general"]["build_date"] = __DATE__;
+ section["general"]["build_time"] = __TIME__;
+ section["general"]["version_user"] = "MOCK";
+ section["general"]["uptime"] = TrexRpcServer::get_server_uptime();
+
+ #endif
+
+ return (TREX_RPC_CMD_OK);
+}
+
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
new file mode 100644
index 00000000..d1dffc44
--- /dev/null
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -0,0 +1,223 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include "trex_rpc_cmds.h"
+#include <trex_rpc_server_api.h>
+#include <trex_stream_api.h>
+#include <trex_stateless_api.h>
+
+#include <iostream>
+
+using namespace std;
+
+/***************************
+ * add new stream
+ *
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
+
+ const Json::Value &section = parse_object(params, "stream", result);
+
+ /* get the type of the stream */
+ const Json::Value &mode = parse_object(section, "mode", result);
+ string type = parse_string(mode, "type", result);
+
+ /* allocate a new stream based on the type */
+ TrexStream *stream = allocate_new_stream(section, result);
+
+ /* some fields */
+ stream->m_enabled = parse_bool(section, "enabled", result);
+ stream->m_self_start = parse_bool(section, "self_start", result);
+
+ /* inter stream gap */
+ stream->m_isg_usec = parse_double(section, "Is", result);
+
+ stream->m_next_stream_id = parse_int(section, "next_stream_id", result);
+
+ const Json::Value &pkt = parse_array(section, "packet", result);
+
+ /* fetch the packet from the message */
+
+ stream->m_pkt_len = pkt.size();
+ stream->m_pkt = new uint8_t[pkt.size()];
+ if (!stream->m_pkt) {
+ generate_internal_err(result, "unable to allocate memory");
+ }
+
+ /* parse the packet */
+ for (int i = 0; i < pkt.size(); i++) {
+ stream->m_pkt[i] = parse_byte(pkt, i, result);
+ }
+
+ /* parse RX info */
+ const Json::Value &rx = parse_object(section, "rx_stats", result);
+
+ stream->m_rx_check.m_enable = parse_bool(rx, "enabled", result);
+
+ /* if it is enabled - we need more fields */
+ if (stream->m_rx_check.m_enable) {
+ stream->m_rx_check.m_stream_id = parse_int(rx, "stream_id", result);
+ stream->m_rx_check.m_seq_enabled = parse_bool(rx, "seq_enabled", result);
+ stream->m_rx_check.m_latency = parse_bool(rx, "latency", result);
+ }
+
+ /* make sure this is a valid stream to add */
+ validate_stream(stream, result);
+
+ TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(stream->m_port_id);
+ port->get_stream_table()->add_stream(stream);
+
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
+}
+
+
+
+TrexStream *
+TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, Json::Value &result) {
+
+ uint8_t port_id = parse_int(section, "port_id", result);
+ uint32_t stream_id = parse_int(section, "stream_id", result);
+
+ TrexStream *stream;
+
+ const Json::Value &mode = parse_object(section, "mode", result);
+ std::string type = parse_string(mode, "type", result);
+
+ if (type == "continuous") {
+
+ uint32_t pps = parse_int(mode, "pps", result);
+ stream = new TrexStreamContinuous(port_id, stream_id, pps);
+
+ } else if (type == "single_burst") {
+
+ uint32_t total_pkts = parse_int(mode, "total_pkts", result);
+ uint32_t pps = parse_int(mode, "pps", result);
+
+ stream = new TrexStreamBurst(port_id, stream_id, total_pkts, pps);
+
+ } else if (type == "multi_burst") {
+
+ uint32_t pps = parse_int(mode, "pps", result);
+ double ibg_usec = parse_double(mode, "ibg", result);
+ uint32_t num_bursts = parse_int(mode, "number_of_bursts", result);
+ uint32_t pkts_per_burst = parse_int(mode, "pkts_per_burst", result);
+
+ stream = new TrexStreamMultiBurst(port_id, stream_id, pkts_per_burst, pps, num_bursts, ibg_usec);
+
+
+ } else {
+ generate_parse_err(result, "bad stream type provided: '" + type + "'");
+ }
+
+ /* make sure we were able to allocate the memory */
+ if (!stream) {
+ generate_internal_err(result, "unable to allocate memory");
+ }
+
+ return (stream);
+
+}
+
+void
+TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &result) {
+
+ /* check packet size */
+ if ( (stream->m_pkt_len < TrexStream::MIN_PKT_SIZE_BYTES) || (stream->m_pkt_len > TrexStream::MAX_PKT_SIZE_BYTES) ) {
+ std::stringstream ss;
+ ss << "bad packet size provided: should be between " << TrexStream::MIN_PKT_SIZE_BYTES << " and " << TrexStream::MAX_PKT_SIZE_BYTES;
+ delete stream;
+ generate_execute_err(result, ss.str());
+ }
+
+ /* port id should be between 0 and count - 1 */
+ if (stream->m_port_id >= get_trex_stateless()->get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+ delete stream;
+ generate_execute_err(result, ss.str());
+ }
+
+ /* add the stream to the port's stream table */
+ TrexStatelessPort * port = get_trex_stateless()->get_port_by_id(stream->m_port_id);
+
+ /* does such a stream exists ? */
+ if (port->get_stream_table()->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());
+ }
+
+}
+
+/***************************
+ * remove stream
+ *
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
+ uint8_t port_id = parse_byte(params, "port_id", result);
+ uint32_t stream_id = parse_int(params, "stream_id", result);
+
+
+ if (port_id >= get_trex_stateless()->get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+ generate_execute_err(result, ss.str());
+ }
+
+ TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(port_id);
+ TrexStream *stream = port->get_stream_table()->get_stream_by_id(stream_id);
+
+ if (!stream) {
+ std::stringstream ss;
+ ss << "stream " << stream_id << " does not exists";
+ generate_execute_err(result, ss.str());
+ }
+
+ port->get_stream_table()->remove_stream(stream);
+
+ result["result"] = "ACK";
+}
+
+/***************************
+ * remove all streams
+ * for a port
+ *
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdRemoveAllStreams::_run(const Json::Value &params, Json::Value &result) {
+ uint8_t port_id = parse_byte(params, "port_id", result);
+
+ if (port_id >= get_trex_stateless()->get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+ generate_execute_err(result, ss.str());
+ }
+
+ TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(port_id);
+ port->get_stream_table()->remove_and_delete_all_streams();
+
+ result["result"] = "ACK";
+}
+
diff --git a/src/rpc-server/commands/trex_rpc_cmd_test.cpp b/src/rpc-server/commands/trex_rpc_cmd_test.cpp
new file mode 100644
index 00000000..3153317e
--- /dev/null
+++ b/src/rpc-server/commands/trex_rpc_cmd_test.cpp
@@ -0,0 +1,81 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include "trex_rpc_cmds.h"
+#include <iostream>
+#include <sstream>
+#include <trex_rpc_cmds_table.h>
+
+using namespace std;
+
+/**
+ * add command
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdTestAdd::_run(const Json::Value &params, Json::Value &result) {
+
+ result["result"] = parse_int(params, "x", result) + parse_int(params, "y", result);
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * sub command
+ *
+ * @author imarom (16-Aug-15)
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdTestSub::_run(const Json::Value &params, Json::Value &result) {
+
+ result["result"] = parse_int(params, "x", result) - parse_int(params, "y", result);
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * ping command
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdPing::_run(const Json::Value &params, Json::Value &result) {
+
+ result["result"] = "ACK";
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * query command
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetReg::_run(const Json::Value &params, Json::Value &result) {
+ vector<string> cmds;
+
+ TrexRpcCommandsTable::get_instance().query(cmds);
+
+ Json::Value test = Json::arrayValue;
+ for (auto cmd : cmds) {
+ test.append(cmd);
+ }
+
+ result["result"] = test;
+
+ return (TREX_RPC_CMD_OK);
+}
+
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
new file mode 100644
index 00000000..64551fac
--- /dev/null
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -0,0 +1,77 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_CMD_H__
+#define __TREX_RPC_CMD_H__
+
+#include <trex_rpc_cmd_api.h>
+#include <json/json.h>
+
+class TrexStream;
+
+/* all the RPC commands decl. goes here */
+
+/******************* test section ************/
+
+/**
+ * syntactic sugar for creating a simple command
+ */
+
+#define TREX_RPC_CMD_DEFINE_EXTENED(class_name, cmd_name, param_count, ext) \
+ class class_name : public TrexRpcCommand { \
+ public: \
+ class_name () : TrexRpcCommand(cmd_name, param_count) {} \
+ protected: \
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result); \
+ ext \
+ }
+
+#define TREX_RPC_CMD_DEFINE(class_name, cmd_name, param_count) TREX_RPC_CMD_DEFINE_EXTENED(class_name, cmd_name, param_count, ;)
+
+/**
+ * test cmds
+ */
+TREX_RPC_CMD_DEFINE(TrexRpcCmdTestAdd, "test_add", 2);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdTestSub, "test_sub", 2);
+
+/**
+ * general cmds
+ */
+TREX_RPC_CMD_DEFINE(TrexRpcCmdPing, "ping", 0);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetReg, "get_reg_cmds", 0);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStatus, "get_status", 0);
+
+/**
+ * stream cmds
+ */
+TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveAllStreams, "remove_all_streams", 1);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream, "remove_stream", 2);
+
+TREX_RPC_CMD_DEFINE_EXTENED(TrexRpcCmdAddStream, "add_stream", 1,
+
+/* extended part */
+TrexStream * allocate_new_stream(const Json::Value &section, Json::Value &result);
+void validate_stream(const TrexStream *stream, Json::Value &result);
+
+);
+
+
+#endif /* __TREX_RPC_CMD_H__ */
diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp
new file mode 100644
index 00000000..6988cba7
--- /dev/null
+++ b/src/rpc-server/trex_rpc_cmd.cpp
@@ -0,0 +1,258 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_rpc_cmd_api.h>
+
+trex_rpc_cmd_rc_e
+TrexRpcCommand::run(const Json::Value &params, Json::Value &result) {
+ trex_rpc_cmd_rc_e rc;
+
+ /* the internal run can throw a parser error / other error */
+ try {
+ check_param_count(params, m_param_count, result);
+ rc = _run(params, result);
+ } catch (TrexRpcCommandException &e) {
+ return e.get_rc();
+ }
+
+ return (rc);
+}
+
+void
+TrexRpcCommand::check_param_count(const Json::Value &params, int expected, Json::Value &result) {
+
+ if (params.size() != expected) {
+ std::stringstream ss;
+ ss << "method expects '" << expected << "' paramteres, '" << params.size() << "' provided";
+ generate_parse_err(result, ss.str());
+ }
+}
+
+const char *
+TrexRpcCommand::type_to_str(field_type_e type) {
+ switch (type) {
+ case FIELD_TYPE_BYTE:
+ return "byte";
+ case FIELD_TYPE_BOOL:
+ return "bool";
+ case FIELD_TYPE_INT:
+ return "int";
+ case FIELD_TYPE_DOUBLE:
+ return "double";
+ case FIELD_TYPE_OBJ:
+ return "object";
+ case FIELD_TYPE_STR:
+ return "string";
+ case FIELD_TYPE_ARRAY:
+ return "array";
+
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const char *
+TrexRpcCommand::json_type_to_name(const Json::Value &value) {
+
+ switch(value.type()) {
+ case Json::nullValue:
+ return "null";
+ case Json::intValue:
+ return "int";
+ case Json::uintValue:
+ return "uint";
+ case Json::realValue:
+ return "real";
+ case Json::stringValue:
+ return "string";
+ case Json::booleanValue:
+ return "boolean";
+ case Json::arrayValue:
+ return "array";
+ case Json::objectValue:
+ return "object";
+
+ default:
+ return "UNKNOWN";
+ }
+
+}
+
+uint8_t
+TrexRpcCommand::parse_byte(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_BYTE, result);
+ return parent[name].asUInt();
+}
+
+uint8_t
+TrexRpcCommand::parse_byte(const Json::Value &parent, int index, Json::Value &result) {
+ check_field_type(parent, index, FIELD_TYPE_BYTE, result);
+ return parent[index].asUInt();
+}
+
+int
+TrexRpcCommand::parse_int(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_INT, result);
+ return parent[name].asInt();
+}
+
+bool
+TrexRpcCommand::parse_bool(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_BOOL, result);
+ return parent[name].asBool();
+}
+
+double
+TrexRpcCommand::parse_double(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_DOUBLE, result);
+ return parent[name].asDouble();
+}
+
+const std::string
+TrexRpcCommand::parse_string(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_STR, result);
+ return parent[name].asString();
+}
+
+const Json::Value &
+TrexRpcCommand::parse_object(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_OBJ, result);
+ return parent[name];
+}
+
+const Json::Value &
+TrexRpcCommand::parse_array(const Json::Value &parent, const std::string &name, Json::Value &result) {
+ check_field_type(parent, name, FIELD_TYPE_ARRAY, result);
+ return parent[name];
+}
+
+/**
+ * for index element (array)
+ */
+void
+TrexRpcCommand::check_field_type(const Json::Value &parent, int index, field_type_e type, Json::Value &result) {
+
+ /* should never get here without parent being array */
+ if (!parent.isArray()) {
+ throw TrexRpcException("internal parsing error");
+ }
+
+ const Json::Value &field = parent[index];
+
+ std::stringstream ss;
+ ss << "array element: " << (index + 1) << " ";
+ check_field_type_common(field, ss.str(), type, result);
+}
+
+void
+TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result) {
+ /* should never get here without parent being object */
+ if (!parent.isObject()) {
+ throw TrexRpcException("internal parsing error");
+ }
+
+ const Json::Value &field = parent[name];
+ check_field_type_common(field, name, type, result);
+}
+void
+TrexRpcCommand::check_field_type_common(const Json::Value &field, const std::string &name, field_type_e type, Json::Value &result) {
+ std::stringstream ss;
+
+ /* first check if field exists */
+ if (field == Json::Value::null) {
+ ss << "field '" << name << "' is missing";
+ generate_parse_err(result, ss.str());
+ }
+
+ bool rc = true;
+
+ switch (type) {
+ case FIELD_TYPE_BYTE:
+ if ( (!field.isUInt()) || (field.asInt() > 0xFF)) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_BOOL:
+ if (!field.isBool()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_INT:
+ if (!field.isInt()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_DOUBLE:
+ if (!field.isDouble()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_OBJ:
+ if (!field.isObject()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_STR:
+ if (!field.isString()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_ARRAY:
+ if (!field.isArray()) {
+ rc = false;
+ }
+ break;
+
+ default:
+ throw TrexRpcException("unhandled type");
+ break;
+
+ }
+ if (!rc) {
+ ss << "error at offset: " << field.getOffsetStart() << " - '" << name << "' is '" << json_type_to_name(field) << "', expecting '" << type_to_str(type) << "'";
+ generate_parse_err(result, ss.str());
+ }
+
+}
+
+void
+TrexRpcCommand::generate_parse_err(Json::Value &result, const std::string &msg) {
+ result["specific_err"] = msg;
+ throw (TrexRpcCommandException(TREX_RPC_CMD_PARSE_ERR));
+}
+
+void
+TrexRpcCommand::generate_internal_err(Json::Value &result, const std::string &msg) {
+ result["specific_err"] = msg;
+ throw (TrexRpcCommandException(TREX_RPC_CMD_INTERNAL_ERR));
+}
+
+void
+TrexRpcCommand::generate_execute_err(Json::Value &result, const std::string &msg) {
+ result["specific_err"] = msg;
+ throw (TrexRpcCommandException(TREX_RPC_CMD_EXECUTE_ERR));
+}
+
diff --git a/src/rpc-server/trex_rpc_cmd_api.h b/src/rpc-server/trex_rpc_cmd_api.h
new file mode 100644
index 00000000..da895809
--- /dev/null
+++ b/src/rpc-server/trex_rpc_cmd_api.h
@@ -0,0 +1,179 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_CMD_API_H__
+#define __TREX_RPC_CMD_API_H__
+
+#include <string>
+#include <vector>
+#include <json/json.h>
+#include <trex_rpc_exception_api.h>
+
+/**
+ * describe different types of rc for run()
+ */
+typedef enum trex_rpc_cmd_rc_ {
+ TREX_RPC_CMD_OK,
+ TREX_RPC_CMD_PARSE_ERR,
+ TREX_RPC_CMD_EXECUTE_ERR,
+ TREX_RPC_CMD_INTERNAL_ERR
+} trex_rpc_cmd_rc_e;
+
+/**
+ * simple exception for RPC command processing
+ *
+ * @author imarom (23-Aug-15)
+ */
+class TrexRpcCommandException : TrexRpcException {
+public:
+ TrexRpcCommandException(trex_rpc_cmd_rc_e rc) : m_rc(rc) {
+
+ }
+
+ trex_rpc_cmd_rc_e get_rc() {
+ return m_rc;
+
+ }
+
+protected:
+ trex_rpc_cmd_rc_e m_rc;
+};
+
+/**
+ * interface for RPC command
+ *
+ * @author imarom (13-Aug-15)
+ */
+class TrexRpcCommand {
+public:
+
+ /**
+ * method name and params
+ */
+ TrexRpcCommand(const std::string &method_name, int param_count) : m_name(method_name), m_param_count(param_count) {
+
+ }
+
+ /**
+ * entry point for executing RPC command
+ *
+ */
+ trex_rpc_cmd_rc_e run(const Json::Value &params, Json::Value &result);
+
+ const std::string &get_name() {
+ return m_name;
+ }
+
+ virtual ~TrexRpcCommand() {}
+
+protected:
+
+ /**
+ * different types of fields
+ */
+ enum field_type_e {
+ FIELD_TYPE_BYTE,
+ FIELD_TYPE_INT,
+ FIELD_TYPE_DOUBLE,
+ FIELD_TYPE_BOOL,
+ FIELD_TYPE_STR,
+ FIELD_TYPE_OBJ,
+ FIELD_TYPE_ARRAY
+ };
+
+ /**
+ * implemented by the dervied class
+ *
+ */
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result) = 0;
+
+ /**
+ * check param count
+ */
+ void check_param_count(const Json::Value &params, int expected, Json::Value &result);
+
+ /**
+ * parse functions
+ *
+ */
+ uint8_t parse_byte(const Json::Value &parent, const std::string &name, Json::Value &result);
+ int parse_int(const Json::Value &parent, const std::string &name, Json::Value &result);
+ double parse_double(const Json::Value &parent, const std::string &name, Json::Value &result);
+ bool parse_bool(const Json::Value &parent, const std::string &name, Json::Value &result);
+ const std::string parse_string(const Json::Value &parent, const std::string &name, Json::Value &result);
+ const Json::Value & parse_object(const Json::Value &parent, const std::string &name, Json::Value &result);
+ const Json::Value & parse_array(const Json::Value &parent, const std::string &name, Json::Value &result);
+
+ uint8_t parse_byte(const Json::Value &parent, int index, Json::Value &result);
+ int parse_int(const Json::Value &parent, int index, Json::Value &result);
+ double parse_double(const Json::Value &parent, int index, Json::Value &result);
+ bool parse_bool(const Json::Value &parent, int index, Json::Value &result);
+ const std::string parse_string(const Json::Value &parent, int index, Json::Value &result);
+ const Json::Value & parse_object(const Json::Value &parent, int index, Json::Value &result);
+ const Json::Value & parse_array(const Json::Value &parent, int index, Json::Value &result);
+
+ /**
+ * check field type
+ *
+ */
+ void check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result);
+ void check_field_type(const Json::Value &parent, int index, field_type_e type, Json::Value &result);
+ void check_field_type_common(const Json::Value &field, const std::string &name, field_type_e type, Json::Value &result);
+
+ /**
+ * error generating functions
+ *
+ */
+ void generate_parse_err(Json::Value &result, const std::string &msg);
+
+
+ /**
+ * method execute error
+ *
+ */
+ void generate_execute_err(Json::Value &result, const std::string &msg);
+
+ /**
+ * internal error
+ *
+ */
+ void generate_internal_err(Json::Value &result, const std::string &msg);
+
+
+ /**
+ * translate enum to string
+ *
+ */
+ const char * type_to_str(field_type_e type);
+
+ /**
+ * translate JSON values to string
+ *
+ */
+ const char * json_type_to_name(const Json::Value &value);
+
+ /* RPC command name */
+ std::string m_name;
+ int m_param_count;
+};
+
+#endif /* __TREX_RPC_CMD_API_H__ */
+
diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp
new file mode 100644
index 00000000..7d5d49ae
--- /dev/null
+++ b/src/rpc-server/trex_rpc_cmds_table.cpp
@@ -0,0 +1,70 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_rpc_cmds_table.h>
+#include <iostream>
+
+#include "commands/trex_rpc_cmds.h"
+
+using namespace std;
+
+/************* table related methods ***********/
+TrexRpcCommandsTable::TrexRpcCommandsTable() {
+ /* add the test command (for gtest) */
+ register_command(new TrexRpcCmdTestAdd());
+ register_command(new TrexRpcCmdTestSub());
+ register_command(new TrexRpcCmdPing());
+ register_command(new TrexRpcCmdGetReg());
+ register_command(new TrexRpcCmdGetStatus());
+
+ /* stream commands */
+ register_command(new TrexRpcCmdAddStream());
+ register_command(new TrexRpcCmdRemoveStream());
+ register_command(new TrexRpcCmdRemoveAllStreams());
+}
+
+TrexRpcCommandsTable::~TrexRpcCommandsTable() {
+ for (auto cmd : m_rpc_cmd_table) {
+ delete cmd.second;
+ }
+}
+
+TrexRpcCommand * TrexRpcCommandsTable::lookup(const string &method_name) {
+ auto search = m_rpc_cmd_table.find(method_name);
+
+ if (search != m_rpc_cmd_table.end()) {
+ return search->second;
+ } else {
+ return NULL;
+ }
+}
+
+
+void TrexRpcCommandsTable::register_command(TrexRpcCommand *command) {
+
+ m_rpc_cmd_table[command->get_name()] = command;
+}
+
+void TrexRpcCommandsTable::query(vector<string> &cmds) {
+ for (auto cmd : m_rpc_cmd_table) {
+ cmds.push_back(cmd.first);
+ }
+}
+
diff --git a/src/rpc-server/trex_rpc_cmds_table.h b/src/rpc-server/trex_rpc_cmds_table.h
new file mode 100644
index 00000000..a41944f1
--- /dev/null
+++ b/src/rpc-server/trex_rpc_cmds_table.h
@@ -0,0 +1,79 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_CMDS_TABLE_H__
+#define __TREX_RPC_CMDS_TABLE_H__
+
+#include <unordered_map>
+#include <string>
+#include <vector>
+#include <json/json.h>
+
+class TrexRpcCommand;
+
+/**
+ * holds all the commands registered
+ *
+ * @author imarom (13-Aug-15)
+ */
+class TrexRpcCommandsTable {
+
+public:
+
+ static TrexRpcCommandsTable& get_instance() {
+ static TrexRpcCommandsTable instance;
+ return instance;
+ }
+
+ /**
+ * register a new command
+ *
+ */
+ void register_command(TrexRpcCommand *command);
+
+ /**
+ * lookup for a command
+ *
+ */
+ TrexRpcCommand * lookup(const std::string &method_name);
+
+ /**
+ * query all commands registered
+ *
+ */
+ void query(std::vector<std::string> &cmds);
+
+private:
+ TrexRpcCommandsTable();
+ ~TrexRpcCommandsTable();
+
+ /* c++ 2011 style singleton */
+ TrexRpcCommandsTable(TrexRpcCommandsTable const&) = delete;
+ void operator=(TrexRpcCommandsTable const&) = delete;
+
+ /**
+ * holds all the registered RPC commands
+ *
+ */
+ std::unordered_map<std::string, TrexRpcCommand *> m_rpc_cmd_table;
+};
+
+#endif /* __TREX_RPC_CMDS_TABLE_H__ */
diff --git a/src/rpc-server/trex_rpc_exception_api.h b/src/rpc-server/trex_rpc_exception_api.h
new file mode 100644
index 00000000..e349b980
--- /dev/null
+++ b/src/rpc-server/trex_rpc_exception_api.h
@@ -0,0 +1,42 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_EXCEPTION_API_H__
+#define __TREX_RPC_EXCEPTION_API_H__
+
+#include <string>
+#include <stdexcept>
+
+/**
+ * generic exception for RPC errors
+ *
+ */
+class TrexRpcException : public std::runtime_error
+{
+public:
+ TrexRpcException() : std::runtime_error("") {
+
+ }
+ TrexRpcException(const std::string &what) : std::runtime_error(what) {
+ }
+};
+
+#endif /* __TREX_RPC_EXCEPTION_API_H__ */
diff --git a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp
new file mode 100644
index 00000000..3831bb37
--- /dev/null
+++ b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp
@@ -0,0 +1,202 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <trex_rpc_exception_api.h>
+#include <trex_rpc_jsonrpc_v2_parser.h>
+#include <trex_rpc_cmd_api.h>
+#include <trex_rpc_cmds_table.h>
+
+#include <json/json.h>
+
+#include <iostream>
+
+/**
+ * error as described in the RFC
+ * http://www.jsonrpc.org/specification
+ */
+enum {
+ JSONRPC_V2_ERR_PARSE = -32700,
+ JSONRPC_V2_ERR_INVALID_REQ = -32600,
+ JSONRPC_V2_ERR_METHOD_NOT_FOUND = -32601,
+ JSONRPC_V2_ERR_INVALID_PARAMS = -32602,
+ JSONRPC_V2_ERR_INTERNAL_ERROR = -32603,
+
+ /* specific server errors */
+ JSONRPC_V2_ERR_EXECUTE_ERROR = -32000,
+};
+
+
+/*************** JSON RPC parsed object base type ************/
+
+TrexJsonRpcV2ParsedObject::TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force = false) : m_msg_id(msg_id) {
+ /* if we have msg_id or a force was issued - write resposne */
+ m_respond = (msg_id != Json::Value::null) || force;
+}
+
+void TrexJsonRpcV2ParsedObject::execute(Json::Value &response) {
+
+ /* common fields */
+ if (m_respond) {
+ response["jsonrpc"] = "2.0";
+ response["id"] = m_msg_id;
+ _execute(response);
+ } else {
+ Json::Value dummy;
+ _execute(dummy);
+ }
+}
+
+/****************** valid method return value **************/
+class JsonRpcMethod : public TrexJsonRpcV2ParsedObject {
+public:
+ JsonRpcMethod(const Json::Value &msg_id, TrexRpcCommand *cmd, const Json::Value &params) : TrexJsonRpcV2ParsedObject(msg_id), m_cmd(cmd), m_params(params) {
+
+ }
+
+ virtual void _execute(Json::Value &response) {
+ Json::Value result;
+
+ trex_rpc_cmd_rc_e rc = m_cmd->run(m_params, result);
+
+ switch (rc) {
+ case TREX_RPC_CMD_OK:
+ response["result"] = result["result"];
+ break;
+
+ case TREX_RPC_CMD_PARSE_ERR:
+ response["error"]["code"] = JSONRPC_V2_ERR_INVALID_PARAMS;
+ response["error"]["message"] = "Bad paramters for method";
+ response["error"]["specific_err"] = result["specific_err"];
+ break;
+
+ case TREX_RPC_CMD_EXECUTE_ERR:
+ response["error"]["code"] = JSONRPC_V2_ERR_EXECUTE_ERROR;
+ response["error"]["message"] = "Failed To Execute Method";
+ response["error"]["specific_err"] = result["specific_err"];
+ break;
+
+ case TREX_RPC_CMD_INTERNAL_ERR:
+ response["error"]["code"] = JSONRPC_V2_ERR_INTERNAL_ERROR;
+ response["error"]["message"] = "Internal Server Error";
+ response["error"]["specific_err"] = result["specific_err"];
+ break;
+ }
+
+ }
+
+private:
+ TrexRpcCommand *m_cmd;
+ Json::Value m_params;
+};
+
+/******************* RPC error **************/
+
+/**
+ * describes the parser error
+ *
+ */
+class JsonRpcError : public TrexJsonRpcV2ParsedObject {
+public:
+
+ JsonRpcError(const Json::Value &msg_id, int code, const std::string &msg, bool force = false) : TrexJsonRpcV2ParsedObject(msg_id, force), m_code(code), m_msg(msg) {
+
+ }
+
+ virtual void _execute(Json::Value &response) {
+ response["error"]["code"] = m_code;
+ response["error"]["message"] = m_msg;
+ }
+
+private:
+ int m_code;
+ std::string m_msg;
+};
+
+
+/************** JSON RPC V2 parser implementation *************/
+
+TrexJsonRpcV2Parser::TrexJsonRpcV2Parser(const std::string &msg) : m_msg(msg) {
+
+}
+
+/**
+ * parse a batch of commands
+ *
+ * @author imarom (17-Aug-15)
+ *
+ * @param commands
+ */
+void TrexJsonRpcV2Parser::parse(std::vector<TrexJsonRpcV2ParsedObject *> &commands) {
+
+ Json::Reader reader;
+ Json::Value request;
+
+ /* basic JSON parsing */
+ bool rc = reader.parse(m_msg, request, false);
+ if (!rc) {
+ commands.push_back(new JsonRpcError(Json::Value::null, JSONRPC_V2_ERR_PARSE, "Bad JSON Format", true));
+ return;
+ }
+
+ /* request can be an array of requests */
+ if (request.isArray()) {
+ /* handle each command */
+ for (auto single_request : request) {
+ parse_single_request(single_request, commands);
+ }
+ } else {
+ /* handle single command */
+ parse_single_request(request, commands);
+ }
+
+
+}
+
+
+void TrexJsonRpcV2Parser::parse_single_request(Json::Value &request,
+ std::vector<TrexJsonRpcV2ParsedObject *> &commands) {
+
+ Json::Value msg_id = request["id"];
+
+ /* check version */
+ if (request["jsonrpc"] != "2.0") {
+ commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_INVALID_REQ, "Invalid JSONRPC Version"));
+ return;
+ }
+
+ /* check method name */
+ std::string method_name = request["method"].asString();
+ if (method_name == "") {
+ commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_INVALID_REQ, "Missing Method Name"));
+ return;
+ }
+
+ /* lookup the method in the DB */
+ TrexRpcCommand * rpc_cmd = TrexRpcCommandsTable::get_instance().lookup(method_name);
+ if (!rpc_cmd) {
+ commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_METHOD_NOT_FOUND, "Method not registered"));
+ return;
+ }
+
+ /* create a method object */
+ commands.push_back(new JsonRpcMethod(msg_id, rpc_cmd, request["params"]));
+}
+
diff --git a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h
new file mode 100644
index 00000000..3367ad6a
--- /dev/null
+++ b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h
@@ -0,0 +1,94 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_JSONRPC_V2_PARSER_H__
+#define __TREX_RPC_JSONRPC_V2_PARSER_H__
+
+#include <string>
+#include <vector>
+#include <json/json.h>
+
+/**
+ * JSON RPC V2 parsed object
+ *
+ * @author imarom (12-Aug-15)
+ */
+class TrexJsonRpcV2ParsedObject {
+public:
+
+ TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force);
+ virtual ~TrexJsonRpcV2ParsedObject() {}
+
+ /**
+ * main function to execute the command
+ *
+ */
+ void execute(Json::Value &response);
+
+protected:
+
+ /**
+ * instance private implementation
+ */
+ virtual void _execute(Json::Value &response) = 0;
+
+ Json::Value m_msg_id;
+ bool m_respond;
+};
+
+/**
+ * JSON RPC V2 parser
+ *
+ * @author imarom (12-Aug-15)
+ */
+class TrexJsonRpcV2Parser {
+
+public:
+
+ /**
+ * creates a JSON-RPC object from a string
+ *
+ * @author imarom (12-Aug-15)
+ *
+ * @param msg
+ */
+ TrexJsonRpcV2Parser(const std::string &msg);
+
+ /**
+ * parses the string to a executable commands vector
+ *
+ * @author imarom (12-Aug-15)
+ */
+ void parse(std::vector<TrexJsonRpcV2ParsedObject *> &commands);
+
+private:
+
+ /**
+ * handle a single request
+ *
+ */
+ void parse_single_request(Json::Value &request, std::vector<TrexJsonRpcV2ParsedObject *> &commands);
+
+ std::string m_msg;
+};
+
+#endif /* __TREX_RPC_JSONRPC_V2_PARSER_H__ */
+
diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp
new file mode 100644
index 00000000..7484758d
--- /dev/null
+++ b/src/rpc-server/trex_rpc_req_resp_server.cpp
@@ -0,0 +1,146 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <trex_rpc_server_api.h>
+#include <trex_rpc_req_resp_server.h>
+#include <trex_rpc_jsonrpc_v2_parser.h>
+
+#include <unistd.h>
+#include <sstream>
+#include <iostream>
+
+#include <zmq.h>
+#include <json/json.h>
+
+/**
+ * ZMQ based request-response server
+ *
+ */
+TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg, "req resp") {
+ /* ZMQ is not thread safe - this should be outside */
+ m_context = zmq_ctx_new();
+}
+
+/**
+ * main entry point for the server
+ * this function will be created on a different thread
+ *
+ * @author imarom (17-Aug-15)
+ */
+void TrexRpcServerReqRes::_rpc_thread_cb() {
+ std::stringstream ss;
+
+ /* create a socket based on the configuration */
+
+ m_socket = zmq_socket (m_context, ZMQ_REP);
+
+ switch (m_cfg.get_protocol()) {
+ case TrexRpcServerConfig::RPC_PROT_TCP:
+ ss << "tcp://*:";
+ break;
+ default:
+ throw TrexRpcException("unknown protocol for RPC");
+ }
+
+ ss << m_cfg.get_port();
+
+ /* bind the scoket */
+ int rc = zmq_bind (m_socket, ss.str().c_str());
+ if (rc != 0) {
+ throw TrexRpcException("Unable to start ZMQ server at: " + ss.str());
+ }
+
+ /* server main loop */
+ while (m_is_running) {
+ int msg_size = zmq_recv (m_socket, m_msg_buffer, sizeof(m_msg_buffer), 0);
+
+ /* msg_size of -1 is an error - decode it */
+ if (msg_size == -1) {
+ /* normal shutdown and zmq_term was called */
+ if (errno == ETERM) {
+ break;
+ } else {
+ throw TrexRpcException("Unhandled error of zmq_recv");
+ }
+ }
+
+ /* transform it to a string */
+ std::string request((const char *)m_msg_buffer, msg_size);
+
+ verbose_msg("Server Received: " + request);
+
+ handle_request(request);
+ }
+
+ /* must be done from the same thread */
+ zmq_close(m_socket);
+}
+
+/**
+ * stops the ZMQ based RPC server
+ *
+ */
+void TrexRpcServerReqRes::_stop_rpc_thread() {
+ /* by calling zmq_term we signal the blocked thread to exit */
+ zmq_term(m_context);
+
+}
+
+/**
+ * handles a request given to the server
+ * respondes to the request
+ */
+void TrexRpcServerReqRes::handle_request(const std::string &request) {
+ std::vector<TrexJsonRpcV2ParsedObject *> commands;
+ Json::FastWriter writer;
+ Json::Value response;
+
+ /* first parse the request using JSON RPC V2 parser */
+ TrexJsonRpcV2Parser rpc_request(request);
+ rpc_request.parse(commands);
+
+ int index = 0;
+
+ /* for every command parsed - launch it */
+ for (auto command : commands) {
+ Json::Value single_response;
+
+ command->execute(single_response);
+ delete command;
+
+ response[index++] = single_response;
+
+ }
+
+ /* write the JSON to string and sever on ZMQ */
+ std::string response_str;
+
+ if (response.size() == 1) {
+ response_str = writer.write(response[0]);
+ } else {
+ response_str = writer.write(response);
+ }
+
+ verbose_msg("Server Replied: " + response_str);
+
+ zmq_send(m_socket, response_str.c_str(), response_str.size(), 0);
+
+}
diff --git a/src/rpc-server/trex_rpc_req_resp_server.h b/src/rpc-server/trex_rpc_req_resp_server.h
new file mode 100644
index 00000000..f12d0540
--- /dev/null
+++ b/src/rpc-server/trex_rpc_req_resp_server.h
@@ -0,0 +1,51 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_REQ_RESP_API_H__
+#define __TREX_RPC_REQ_RESP_API_H__
+
+#include <trex_rpc_server_api.h>
+
+/**
+ * request-response RPC server
+ *
+ * @author imarom (11-Aug-15)
+ */
+class TrexRpcServerReqRes : public TrexRpcServerInterface {
+public:
+
+ TrexRpcServerReqRes(const TrexRpcServerConfig &cfg);
+
+protected:
+ void _rpc_thread_cb();
+ void _stop_rpc_thread();
+
+private:
+ void handle_request(const std::string &request);
+
+ static const int RPC_MAX_MSG_SIZE = 2048;
+ void *m_context;
+ void *m_socket;
+ uint8_t m_msg_buffer[RPC_MAX_MSG_SIZE];
+};
+
+
+#endif /* __TREX_RPC_REQ_RESP_API_H__ */
diff --git a/src/rpc-server/trex_rpc_server.cpp b/src/rpc-server/trex_rpc_server.cpp
new file mode 100644
index 00000000..366bfc5b
--- /dev/null
+++ b/src/rpc-server/trex_rpc_server.cpp
@@ -0,0 +1,153 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <trex_rpc_server_api.h>
+#include <trex_rpc_req_resp_server.h>
+#include <unistd.h>
+#include <zmq.h>
+#include <sstream>
+#include <iostream>
+
+/************** RPC server interface ***************/
+
+TrexRpcServerInterface::TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name) : m_cfg(cfg), m_name(name) {
+ m_is_running = false;
+ m_is_verbose = false;
+}
+
+TrexRpcServerInterface::~TrexRpcServerInterface() {
+ if (m_is_running) {
+ stop();
+ }
+}
+
+void TrexRpcServerInterface::verbose_msg(const std::string &msg) {
+ if (!m_is_verbose) {
+ return;
+ }
+
+ std::cout << "[verbose][" << m_name << "] " << msg << "\n";
+}
+
+/**
+ * starts a RPC specific server
+ *
+ * @author imarom (17-Aug-15)
+ */
+void TrexRpcServerInterface::start() {
+ m_is_running = true;
+
+ verbose_msg("Starting RPC Server");
+
+ m_thread = new std::thread(&TrexRpcServerInterface::_rpc_thread_cb, this);
+ if (!m_thread) {
+ throw TrexRpcException("unable to create RPC thread");
+ }
+}
+
+void TrexRpcServerInterface::stop() {
+ m_is_running = false;
+
+ verbose_msg("Attempting To Stop RPC Server");
+
+ /* call the dynamic type class stop */
+ _stop_rpc_thread();
+
+ /* hold until thread has joined */
+ m_thread->join();
+
+ verbose_msg("Server Stopped");
+
+ delete m_thread;
+}
+
+void TrexRpcServerInterface::set_verbose(bool verbose) {
+ m_is_verbose = verbose;
+}
+
+bool TrexRpcServerInterface::is_verbose() {
+ return m_is_verbose;
+}
+
+bool TrexRpcServerInterface::is_running() {
+ return m_is_running;
+}
+
+
+/************** RPC server *************/
+
+static const std::string
+get_current_date_time() {
+ time_t now = time(0);
+ struct tm tstruct;
+ char buf[80];
+ tstruct = *localtime(&now);
+ strftime(buf, sizeof(buf), "%b %d %Y @ %X", &tstruct);
+
+ return buf;
+}
+
+const std::string TrexRpcServer::s_server_uptime = get_current_date_time();
+
+TrexRpcServer::TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg) {
+
+ /* add the request response server */
+ m_servers.push_back(new TrexRpcServerReqRes(req_resp_cfg));
+}
+
+TrexRpcServer::~TrexRpcServer() {
+
+ /* make sure they are all stopped */
+ stop();
+
+ for (auto server : m_servers) {
+ delete server;
+ }
+}
+
+/**
+ * start the server array
+ *
+ */
+void TrexRpcServer::start() {
+ for (auto server : m_servers) {
+ server->start();
+ }
+}
+
+/**
+ * stop the server array
+ *
+ */
+void TrexRpcServer::stop() {
+ for (auto server : m_servers) {
+ if (server->is_running()) {
+ server->stop();
+ }
+ }
+}
+
+void TrexRpcServer::set_verbose(bool verbose) {
+ for (auto server : m_servers) {
+ server->set_verbose(verbose);
+ }
+}
+
diff --git a/src/rpc-server/trex_rpc_server_api.h b/src/rpc-server/trex_rpc_server_api.h
new file mode 100644
index 00000000..6bb81c73
--- /dev/null
+++ b/src/rpc-server/trex_rpc_server_api.h
@@ -0,0 +1,165 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef __TREX_RPC_SERVER_API_H__
+#define __TREX_RPC_SERVER_API_H__
+
+#include <stdint.h>
+#include <vector>
+#include <thread>
+#include <string>
+#include <stdexcept>
+#include <trex_rpc_exception_api.h>
+
+class TrexRpcServerInterface;
+
+/**
+ * defines a configuration of generic RPC server
+ *
+ * @author imarom (17-Aug-15)
+ */
+class TrexRpcServerConfig {
+public:
+
+ enum rpc_prot_e {
+ RPC_PROT_TCP
+ };
+
+ TrexRpcServerConfig(rpc_prot_e protocol, uint16_t port) : m_protocol(protocol), m_port(port) {
+
+ }
+
+ uint16_t get_port() {
+ return m_port;
+ }
+
+ rpc_prot_e get_protocol() {
+ return m_protocol;
+ }
+
+private:
+ rpc_prot_e m_protocol;
+ uint16_t m_port;
+};
+
+/**
+ * generic type RPC server instance
+ *
+ * @author imarom (12-Aug-15)
+ */
+class TrexRpcServerInterface {
+public:
+
+ TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name);
+ virtual ~TrexRpcServerInterface();
+
+ /**
+ * starts the server
+ *
+ */
+ void start();
+
+ /**
+ * stops the server
+ *
+ */
+ void stop();
+
+ /**
+ * set verbose on or off
+ *
+ */
+ void set_verbose(bool verbose);
+
+ /**
+ * return TRUE if server is active
+ *
+ */
+ bool is_running();
+
+ /**
+ * is the server verbose or not
+ *
+ */
+ bool is_verbose();
+
+protected:
+ /**
+ * instances implement this
+ *
+ */
+ virtual void _rpc_thread_cb() = 0;
+ virtual void _stop_rpc_thread() = 0;
+
+ /**
+ * prints a verbosed message (if enabled)
+ *
+ */
+ void verbose_msg(const std::string &msg);
+
+ TrexRpcServerConfig m_cfg;
+ bool m_is_running;
+ bool m_is_verbose;
+ std::thread *m_thread;
+ std::string m_name;
+};
+
+/**
+ * TREX RPC server
+ * may contain serveral types of RPC servers
+ * (request response, async and etc.)
+ *
+ * @author imarom (12-Aug-15)
+ */
+class TrexRpcServer {
+public:
+
+ /* currently only request response server config is required */
+ TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg);
+ ~TrexRpcServer();
+
+ /**
+ * starts the RPC server
+ *
+ * @author imarom (19-Aug-15)
+ */
+ void start();
+
+ /**
+ * stops the RPC server
+ *
+ * @author imarom (19-Aug-15)
+ */
+ void stop();
+
+ void set_verbose(bool verbose);
+
+ static const std::string &get_server_uptime() {
+ return s_server_uptime;
+ }
+
+private:
+ std::vector<TrexRpcServerInterface *> m_servers;
+ bool m_verbose;
+ static const std::string s_server_uptime;
+};
+
+#endif /* __TREX_RPC_SERVER_API_H__ */
diff --git a/src/rpc-server/trex_rpc_server_mock.cpp b/src/rpc-server/trex_rpc_server_mock.cpp
new file mode 100644
index 00000000..98d1f35d
--- /dev/null
+++ b/src/rpc-server/trex_rpc_server_mock.cpp
@@ -0,0 +1,75 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <trex_rpc_server_api.h>
+#include <iostream>
+#include <unistd.h>
+
+using namespace std;
+
+/**
+ * on simulation this is not rebuild every version
+ * (improved stub)
+ *
+ */
+extern "C" const char * get_build_date(void){
+ return (__DATE__);
+}
+
+extern "C" const char * get_build_time(void){
+ return (__TIME__ );
+}
+
+int gtest_main(int argc, char **argv);
+
+int main(int argc, char *argv[]) {
+
+ // gtest ?
+ if (argc > 1) {
+ if (string(argv[1]) != "--ut") {
+ cout << "\n[Usage] " << argv[0] << ": " << " [--ut]\n\n";
+ exit(-1);
+ }
+ return gtest_main(argc, argv);
+ }
+
+ cout << "\n-= Starting RPC Server Mock =-\n\n";
+ cout << "Listening on tcp://localhost:5050 [ZMQ]\n\n";
+
+ TrexRpcServerConfig rpc_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050);
+ TrexRpcServer rpc(rpc_cfg);
+
+ /* init the RPC server */
+ rpc.start();
+
+ cout << "Setting Server To Full Verbose\n\n";
+ rpc.set_verbose(true);
+
+ cout << "Server Started\n\n";
+
+ while (true) {
+ sleep(1);
+ }
+
+ rpc.stop();
+
+
+}
diff --git a/src/rx_check.cpp b/src/rx_check.cpp
index 67ce89e1..3a67ca23 100755
--- a/src/rx_check.cpp
+++ b/src/rx_check.cpp
@@ -243,6 +243,11 @@ bool RxCheckManager::Create(){
m_hist.Create();
m_cur_time=0.00000001;
m_on_drain=false;
+
+ int i;
+ for (i=0; i<MAX_TEMPLATES_STATS;i++ ) {
+ m_template_info[i].reset();
+ }
return (true);
}
@@ -277,11 +282,6 @@ void RxCheckManager::handle_packet(CRx_check_header * rxh){
lf=m_ft.lookup(rxh->m_flow_id);
m_stats.m_lookup++;
- if ((m_stats.m_lookup & 0xff)==0) {
- /* handle aging from time to time */
-
- tw_handle() ;
- }
bool any_err=false;
if ( rxh->is_fif_dir() ) {
@@ -393,6 +393,10 @@ void RxCheckManager::handle_packet(CRx_check_header * rxh){
on_flow_end(lf);
}
+ if ((m_stats.m_lookup & 0xff)==0) {
+ /* handle aging from time to time */
+ tw_handle() ;
+ }
}
void RxCheckManager::update_template_err(uint8_t template_id){
diff --git a/src/rx_check_header.h b/src/rx_check_header.h
index 3ac5dd1f..54af2451 100755
--- a/src/rx_check_header.h
+++ b/src/rx_check_header.h
@@ -85,6 +85,9 @@ public:
int get_dir(void){
return (btGetMaskBit8(m_flags,0,0) ? 1:0);
}
+ void clean(){
+ memset(this,0,sizeof(CRx_check_header));
+ }
/* need to mark if we expect to see both sides of the flow, this is know offline */
void set_both_dir(int both){
diff --git a/src/stateless/trex_stateless.cpp b/src/stateless/trex_stateless.cpp
new file mode 100644
index 00000000..05931983
--- /dev/null
+++ b/src/stateless/trex_stateless.cpp
@@ -0,0 +1,63 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_stateless_api.h>
+
+/***********************************************************
+ * Trex stateless object
+ *
+ **********************************************************/
+TrexStateless::TrexStateless(uint8_t port_count) : m_port_count(port_count) {
+
+ m_ports = new TrexStatelessPort*[port_count];
+
+ for (int i = 0; i < m_port_count; i++) {
+ m_ports[i] = new TrexStatelessPort(i);
+ }
+}
+
+TrexStateless::~TrexStateless() {
+ for (int i = 0; i < m_port_count; i++) {
+ delete m_ports[i];
+ }
+
+ delete m_ports;
+}
+
+TrexStatelessPort * TrexStateless::get_port_by_id(uint8_t port_id) {
+ if (port_id >= m_port_count) {
+ throw TrexException("index out of range");
+ }
+
+ return m_ports[port_id];
+
+}
+
+uint8_t TrexStateless::get_port_count() {
+ return m_port_count;
+}
+
+/******** HACK - REMOVE ME ***********/
+TrexStateless * get_trex_stateless() {
+ static TrexStateless trex_stateless(8);
+ return &trex_stateless;
+
+}
+
diff --git a/src/stateless/trex_stateless_api.h b/src/stateless/trex_stateless_api.h
new file mode 100644
index 00000000..6406a946
--- /dev/null
+++ b/src/stateless/trex_stateless_api.h
@@ -0,0 +1,96 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#ifndef __TREX_STATELESS_API_H__
+#define __TREX_STATELESS_API_H__
+
+#include <stdint.h>
+#include <string>
+#include <stdexcept>
+
+#include <trex_stream_api.h>
+
+/**
+ * generic exception for errors
+ * TODO: move this to a better place
+ */
+class TrexException : public std::runtime_error
+{
+public:
+ TrexException() : std::runtime_error("") {
+
+ }
+ TrexException(const std::string &what) : std::runtime_error(what) {
+ }
+};
+
+/**
+ * describes a stateless port
+ *
+ * @author imarom (31-Aug-15)
+ */
+class TrexStatelessPort {
+public:
+
+ TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) {
+ }
+
+ /**
+ * access the stream table
+ *
+ */
+ TrexStreamTable *get_stream_table() {
+ return &m_stream_table;
+ }
+
+private:
+ TrexStreamTable m_stream_table;
+ uint8_t m_port_id;
+};
+
+/**
+ * defines the T-Rex stateless operation mode
+ *
+ */
+class TrexStateless {
+public:
+ /**
+ * create a T-Rex stateless object
+ *
+ * @author imarom (31-Aug-15)
+ *
+ * @param port_count
+ */
+ TrexStateless(uint8_t port_count);
+ ~TrexStateless();
+
+ TrexStatelessPort *get_port_by_id(uint8_t port_id);
+ uint8_t get_port_count();
+
+protected:
+ TrexStatelessPort **m_ports;
+ uint8_t m_port_count;
+};
+
+/****** HACK *******/
+TrexStateless *get_trex_stateless();
+
+#endif /* __TREX_STATELESS_API_H__ */
+
diff --git a/src/stateless/trex_stream.cpp b/src/stateless/trex_stream.cpp
new file mode 100644
index 00000000..1465b1ba
--- /dev/null
+++ b/src/stateless/trex_stream.cpp
@@ -0,0 +1,93 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_stream_api.h>
+#include <cstddef>
+
+/**************************************
+ * stream
+ *************************************/
+TrexStream::TrexStream(uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) {
+
+ /* default values */
+ m_isg_usec = 0;
+ m_next_stream_id = -1;
+ m_enabled = false;
+ m_self_start = false;
+
+ m_pkt = NULL;
+ m_pkt_len = 0;
+
+ m_rx_check.m_enable = false;
+
+}
+
+TrexStream::~TrexStream() {
+ if (m_pkt) {
+ delete [] m_pkt;
+ }
+}
+
+/**************************************
+ * stream table
+ *************************************/
+TrexStreamTable::TrexStreamTable() {
+
+}
+
+TrexStreamTable::~TrexStreamTable() {
+ for (auto stream : m_stream_table) {
+ delete stream.second;
+ }
+}
+
+void TrexStreamTable::add_stream(TrexStream *stream) {
+ TrexStream *old_stream = get_stream_by_id(stream->m_stream_id);
+ if (old_stream) {
+ remove_stream(old_stream);
+ delete old_stream;
+ }
+
+ m_stream_table[stream->m_stream_id] = stream;
+}
+
+void TrexStreamTable::remove_stream(TrexStream *stream) {
+ m_stream_table.erase(stream->m_stream_id);
+}
+
+
+void TrexStreamTable::remove_and_delete_all_streams() {
+
+ for (auto stream : m_stream_table) {
+ delete stream.second;
+ }
+
+ m_stream_table.clear();
+}
+
+TrexStream * TrexStreamTable::get_stream_by_id(uint32_t stream_id) {
+ auto search = m_stream_table.find(stream_id);
+
+ if (search != m_stream_table.end()) {
+ return search->second;
+ } else {
+ return NULL;
+ }
+}
diff --git a/src/stateless/trex_stream_api.h b/src/stateless/trex_stream_api.h
new file mode 100644
index 00000000..f57b7aae
--- /dev/null
+++ b/src/stateless/trex_stream_api.h
@@ -0,0 +1,169 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#ifndef __TREX_STREAM_API_H__
+#define __TREX_STREAM_API_H__
+
+#include <unordered_map>
+#include <stdint.h>
+
+class TrexRpcCmdAddStream;
+
+/**
+ * Stateless Stream
+ *
+ */
+class TrexStream {
+ /* provide the RPC parser a way to access private fields */
+ friend class TrexRpcCmdAddStream;
+ friend class TrexStreamTable;
+
+public:
+ TrexStream(uint8_t port_id, uint32_t stream_id);
+ virtual ~TrexStream() = 0;
+
+ /* defines the min max per packet supported */
+ static const uint32_t MIN_PKT_SIZE_BYTES = 1;
+ static const uint32_t MAX_PKT_SIZE_BYTES = 9000;
+
+private:
+ /* basic */
+ uint8_t m_port_id;
+ uint32_t m_stream_id;
+
+
+ /* config fields */
+ double m_isg_usec;
+ uint32_t m_next_stream_id;
+
+ /* indicators */
+ bool m_enabled;
+ bool m_self_start;
+
+ /* pkt */
+ uint8_t *m_pkt;
+ uint16_t m_pkt_len;
+
+ /* VM */
+
+ /* RX check */
+ struct {
+ bool m_enable;
+ bool m_seq_enabled;
+ bool m_latency;
+ uint32_t m_stream_id;
+
+ } m_rx_check;
+
+};
+
+/**
+ * continuous stream
+ *
+ */
+class TrexStreamContinuous : public TrexStream {
+public:
+ TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, uint32_t pps) : TrexStream(port_id, stream_id), m_pps(pps) {
+ }
+protected:
+ uint32_t m_pps;
+};
+
+/**
+ * single burst
+ *
+ */
+class TrexStreamBurst : public TrexStream {
+public:
+ TrexStreamBurst(uint8_t port_id, uint32_t stream_id, uint32_t total_pkts, uint32_t pps) :
+ TrexStream(port_id, stream_id),
+ m_total_pkts(total_pkts),
+ m_pps(pps) {
+ }
+
+protected:
+ uint32_t m_total_pkts;
+ uint32_t m_pps;
+};
+
+/**
+ * multi burst
+ *
+ */
+class TrexStreamMultiBurst : public TrexStreamBurst {
+public:
+ TrexStreamMultiBurst(uint8_t port_id,
+ uint32_t stream_id,
+ uint32_t pkts_per_burst,
+ uint32_t pps,
+ uint32_t num_bursts,
+ double ibg_usec) : TrexStreamBurst(port_id, stream_id, pkts_per_burst, pps), m_num_bursts(num_bursts), m_ibg_usec(ibg_usec) {
+
+ }
+protected:
+ uint32_t m_num_bursts;
+ double m_ibg_usec;
+
+};
+
+/**
+ * holds all the streams
+ *
+ */
+class TrexStreamTable {
+public:
+
+ TrexStreamTable();
+ ~TrexStreamTable();
+
+ /**
+ * add a stream
+ * if a previous one exists, the old one will be deleted
+ */
+ void add_stream(TrexStream *stream);
+
+ /**
+ * remove a stream
+ */
+ void remove_stream(TrexStream *stream);
+
+ /**
+ * remove all streams on the table
+ * memory will be deleted
+ */
+ void remove_and_delete_all_streams();
+
+ /**
+ * fetch a stream if exists
+ * o.w NULL
+ *
+ */
+ TrexStream * get_stream_by_id(uint32_t stream_id);
+
+private:
+ /**
+ * holds all the stream in a hash table by stream id
+ *
+ */
+ std::unordered_map<int, TrexStream *> m_stream_table;
+};
+
+#endif /* __TREX_STREAM_API_H__ */
+
diff --git a/src/timer_wheel_pq.cpp b/src/timer_wheel_pq.cpp
index 172d061e..bb480abd 100755
--- a/src/timer_wheel_pq.cpp
+++ b/src/timer_wheel_pq.cpp
@@ -169,11 +169,14 @@ bool CTimerWheel::handle(){
assert(timer->m_flow);
CFlowTimerHandle * flow =timer->m_flow;
m_st_handle++;
+
+ timer->m_flow=0;/* stop the timer */
+ flow->m_timer=0;
+
if ( flow->m_callback ){
flow->m_callback(flow);
}
- timer->m_flow=0;/* stop the timer */
- flow->m_timer=0;
+
m_pq.pop();
m_st_free++;
delete timer;
diff --git a/src/zmq/include/zmq.h b/src/zmq/include/zmq.h
deleted file mode 100755
index f7b10db6..00000000
--- a/src/zmq/include/zmq.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
-
- This file is part of 0MQ.
-
- 0MQ is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- 0MQ is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- *************************************************************************
- NOTE to contributors. This file comprises the principal public contract
- for ZeroMQ API users (along with zmq_utils.h). Any change to this file
- supplied in a stable release SHOULD not break existing applications.
- In practice this means that the value of constants must not change, and
- that old values may not be reused for new constants.
- *************************************************************************
-*/
-
-#ifndef __ZMQ_H_INCLUDED__
-#define __ZMQ_H_INCLUDED__
-
-/* Version macros for compile-time API version detection */
-#define ZMQ_VERSION_MAJOR 4
-#define ZMQ_VERSION_MINOR 0
-#define ZMQ_VERSION_PATCH 3
-
-#define ZMQ_MAKE_VERSION(major, minor, patch) \
- ((major) * 10000 + (minor) * 100 + (patch))
-#define ZMQ_VERSION \
- ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined _WIN32_WCE
-#include <errno.h>
-#endif
-#include <stddef.h>
-#include <stdio.h>
-#if defined _WIN32
-#include <winsock2.h>
-#endif
-
-/* Handle DSO symbol visibility */
-#if defined _WIN32
-# if defined ZMQ_STATIC
-# define ZMQ_EXPORT
-# elif defined DLL_EXPORT
-# define ZMQ_EXPORT __declspec(dllexport)
-# else
-# define ZMQ_EXPORT __declspec(dllimport)
-# endif
-#else
-# if defined __SUNPRO_C || defined __SUNPRO_CC
-# define ZMQ_EXPORT __global
-# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
-# define ZMQ_EXPORT __attribute__ ((visibility("default")))
-# else
-# define ZMQ_EXPORT
-# endif
-#endif
-
-/* Define integer types needed for event interface */
-#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS
-# include <inttypes.h>
-#elif defined _MSC_VER && _MSC_VER < 1600
-# ifndef int32_t
-typedef __int32 int32_t;
-# endif
-# ifndef uint16_t
-typedef unsigned __int16 uint16_t;
-# endif
-# ifndef uint8_t
-typedef unsigned __int8 uint8_t;
-# endif
-#else
-# include <stdint.h>
-#endif
-
-
-/******************************************************************************/
-/* 0MQ errors. */
-/******************************************************************************/
-
-/* A number random enough not to collide with different errno ranges on */
-/* different OSes. The assumption is that error_t is at least 32-bit type. */
-#define ZMQ_HAUSNUMERO 156384712
-
-/* On Windows platform some of the standard POSIX errnos are not defined. */
-#ifndef ENOTSUP
-#define ENOTSUP (ZMQ_HAUSNUMERO + 1)
-#endif
-#ifndef EPROTONOSUPPORT
-#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2)
-#endif
-#ifndef ENOBUFS
-#define ENOBUFS (ZMQ_HAUSNUMERO + 3)
-#endif
-#ifndef ENETDOWN
-#define ENETDOWN (ZMQ_HAUSNUMERO + 4)
-#endif
-#ifndef EADDRINUSE
-#define EADDRINUSE (ZMQ_HAUSNUMERO + 5)
-#endif
-#ifndef EADDRNOTAVAIL
-#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6)
-#endif
-#ifndef ECONNREFUSED
-#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7)
-#endif
-#ifndef EINPROGRESS
-#define EINPROGRESS (ZMQ_HAUSNUMERO + 8)
-#endif
-#ifndef ENOTSOCK
-#define ENOTSOCK (ZMQ_HAUSNUMERO + 9)
-#endif
-#ifndef EMSGSIZE
-#define EMSGSIZE (ZMQ_HAUSNUMERO + 10)
-#endif
-#ifndef EAFNOSUPPORT
-#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11)
-#endif
-#ifndef ENETUNREACH
-#define ENETUNREACH (ZMQ_HAUSNUMERO + 12)
-#endif
-#ifndef ECONNABORTED
-#define ECONNABORTED (ZMQ_HAUSNUMERO + 13)
-#endif
-#ifndef ECONNRESET
-#define ECONNRESET (ZMQ_HAUSNUMERO + 14)
-#endif
-#ifndef ENOTCONN
-#define ENOTCONN (ZMQ_HAUSNUMERO + 15)
-#endif
-#ifndef ETIMEDOUT
-#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16)
-#endif
-#ifndef EHOSTUNREACH
-#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17)
-#endif
-#ifndef ENETRESET
-#define ENETRESET (ZMQ_HAUSNUMERO + 18)
-#endif
-
-/* Native 0MQ error codes. */
-#define EFSM (ZMQ_HAUSNUMERO + 51)
-#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52)
-#define ETERM (ZMQ_HAUSNUMERO + 53)
-#define EMTHREAD (ZMQ_HAUSNUMERO + 54)
-
-/* Run-time API version detection */
-ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
-
-/* This function retrieves the errno as it is known to 0MQ library. The goal */
-/* of this function is to make the code 100% portable, including where 0MQ */
-/* compiled with certain CRT library (on Windows) is linked to an */
-/* application that uses different CRT library. */
-ZMQ_EXPORT int zmq_errno (void);
-
-/* Resolves system errors and 0MQ errors to human-readable string. */
-ZMQ_EXPORT const char *zmq_strerror (int errnum);
-
-/******************************************************************************/
-/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */
-/******************************************************************************/
-
-/* New API */
-/* Context options */
-#define ZMQ_IO_THREADS 1
-#define ZMQ_MAX_SOCKETS 2
-
-/* Default for new contexts */
-#define ZMQ_IO_THREADS_DFLT 1
-#define ZMQ_MAX_SOCKETS_DFLT 1023
-
-ZMQ_EXPORT void *zmq_ctx_new (void);
-ZMQ_EXPORT int zmq_ctx_term (void *context);
-ZMQ_EXPORT int zmq_ctx_shutdown (void *ctx_);
-ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval);
-ZMQ_EXPORT int zmq_ctx_get (void *context, int option);
-
-/* Old (legacy) API */
-ZMQ_EXPORT void *zmq_init (int io_threads);
-ZMQ_EXPORT int zmq_term (void *context);
-ZMQ_EXPORT int zmq_ctx_destroy (void *context);
-
-
-/******************************************************************************/
-/* 0MQ message definition. */
-/******************************************************************************/
-
-typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t;
-
-typedef void (zmq_free_fn) (void *data, void *hint);
-
-ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg);
-ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size);
-ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data,
- size_t size, zmq_free_fn *ffn, void *hint);
-ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags);
-ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags);
-ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg);
-ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src);
-ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src);
-ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg);
-ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg);
-ZMQ_EXPORT int zmq_msg_more (zmq_msg_t *msg);
-ZMQ_EXPORT int zmq_msg_get (zmq_msg_t *msg, int option);
-ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
-
-
-/******************************************************************************/
-/* 0MQ socket definition. */
-/******************************************************************************/
-
-/* Socket types. */
-#define ZMQ_PAIR 0
-#define ZMQ_PUB 1
-#define ZMQ_SUB 2
-#define ZMQ_REQ 3
-#define ZMQ_REP 4
-#define ZMQ_DEALER 5
-#define ZMQ_ROUTER 6
-#define ZMQ_PULL 7
-#define ZMQ_PUSH 8
-#define ZMQ_XPUB 9
-#define ZMQ_XSUB 10
-#define ZMQ_STREAM 11
-
-/* Deprecated aliases */
-#define ZMQ_XREQ ZMQ_DEALER
-#define ZMQ_XREP ZMQ_ROUTER
-
-/* Socket options. */
-#define ZMQ_AFFINITY 4
-#define ZMQ_IDENTITY 5
-#define ZMQ_SUBSCRIBE 6
-#define ZMQ_UNSUBSCRIBE 7
-#define ZMQ_RATE 8
-#define ZMQ_RECOVERY_IVL 9
-#define ZMQ_SNDBUF 11
-#define ZMQ_RCVBUF 12
-#define ZMQ_RCVMORE 13
-#define ZMQ_FD 14
-#define ZMQ_EVENTS 15
-#define ZMQ_TYPE 16
-#define ZMQ_LINGER 17
-#define ZMQ_RECONNECT_IVL 18
-#define ZMQ_BACKLOG 19
-#define ZMQ_RECONNECT_IVL_MAX 21
-#define ZMQ_MAXMSGSIZE 22
-#define ZMQ_SNDHWM 23
-#define ZMQ_RCVHWM 24
-#define ZMQ_MULTICAST_HOPS 25
-#define ZMQ_RCVTIMEO 27
-#define ZMQ_SNDTIMEO 28
-#define ZMQ_LAST_ENDPOINT 32
-#define ZMQ_ROUTER_MANDATORY 33
-#define ZMQ_TCP_KEEPALIVE 34
-#define ZMQ_TCP_KEEPALIVE_CNT 35
-#define ZMQ_TCP_KEEPALIVE_IDLE 36
-#define ZMQ_TCP_KEEPALIVE_INTVL 37
-#define ZMQ_TCP_ACCEPT_FILTER 38
-#define ZMQ_IMMEDIATE 39
-#define ZMQ_XPUB_VERBOSE 40
-#define ZMQ_ROUTER_RAW 41
-#define ZMQ_IPV6 42
-#define ZMQ_MECHANISM 43
-#define ZMQ_PLAIN_SERVER 44
-#define ZMQ_PLAIN_USERNAME 45
-#define ZMQ_PLAIN_PASSWORD 46
-#define ZMQ_CURVE_SERVER 47
-#define ZMQ_CURVE_PUBLICKEY 48
-#define ZMQ_CURVE_SECRETKEY 49
-#define ZMQ_CURVE_SERVERKEY 50
-#define ZMQ_PROBE_ROUTER 51
-#define ZMQ_REQ_CORRELATE 52
-#define ZMQ_REQ_RELAXED 53
-#define ZMQ_CONFLATE 54
-#define ZMQ_ZAP_DOMAIN 55
-
-/* Message options */
-#define ZMQ_MORE 1
-
-/* Send/recv options. */
-#define ZMQ_DONTWAIT 1
-#define ZMQ_SNDMORE 2
-
-/* Security mechanisms */
-#define ZMQ_NULL 0
-#define ZMQ_PLAIN 1
-#define ZMQ_CURVE 2
-
-/* Deprecated options and aliases */
-#define ZMQ_IPV4ONLY 31
-#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE
-#define ZMQ_NOBLOCK ZMQ_DONTWAIT
-#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY
-#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY
-
-/******************************************************************************/
-/* 0MQ socket events and monitoring */
-/******************************************************************************/
-
-/* Socket transport events (tcp and ipc only) */
-#define ZMQ_EVENT_CONNECTED 1
-#define ZMQ_EVENT_CONNECT_DELAYED 2
-#define ZMQ_EVENT_CONNECT_RETRIED 4
-
-#define ZMQ_EVENT_LISTENING 8
-#define ZMQ_EVENT_BIND_FAILED 16
-
-#define ZMQ_EVENT_ACCEPTED 32
-#define ZMQ_EVENT_ACCEPT_FAILED 64
-
-#define ZMQ_EVENT_CLOSED 128
-#define ZMQ_EVENT_CLOSE_FAILED 256
-#define ZMQ_EVENT_DISCONNECTED 512
-#define ZMQ_EVENT_MONITOR_STOPPED 1024
-
-#define ZMQ_EVENT_ALL ( ZMQ_EVENT_CONNECTED | ZMQ_EVENT_CONNECT_DELAYED | \
- ZMQ_EVENT_CONNECT_RETRIED | ZMQ_EVENT_LISTENING | \
- ZMQ_EVENT_BIND_FAILED | ZMQ_EVENT_ACCEPTED | \
- ZMQ_EVENT_ACCEPT_FAILED | ZMQ_EVENT_CLOSED | \
- ZMQ_EVENT_CLOSE_FAILED | ZMQ_EVENT_DISCONNECTED | \
- ZMQ_EVENT_MONITOR_STOPPED)
-
-/* Socket event data */
-typedef struct {
- uint16_t event; // id of the event as bitfield
- int32_t value ; // value is either error code, fd or reconnect interval
-} zmq_event_t;
-
-ZMQ_EXPORT void *zmq_socket (void *, int type);
-ZMQ_EXPORT int zmq_close (void *s);
-ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval,
- size_t optvallen);
-ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval,
- size_t *optvallen);
-ZMQ_EXPORT int zmq_bind (void *s, const char *addr);
-ZMQ_EXPORT int zmq_connect (void *s, const char *addr);
-ZMQ_EXPORT int zmq_unbind (void *s, const char *addr);
-ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr);
-ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags);
-ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags);
-ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags);
-ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events);
-
-ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags);
-ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags);
-
-/* Experimental */
-struct iovec;
-
-ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags);
-ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags);
-
-/******************************************************************************/
-/* I/O multiplexing. */
-/******************************************************************************/
-
-#define ZMQ_POLLIN 1
-#define ZMQ_POLLOUT 2
-#define ZMQ_POLLERR 4
-
-typedef struct
-{
- void *socket;
-#if defined _WIN32
- SOCKET fd;
-#else
- int fd;
-#endif
- short events;
- short revents;
-} zmq_pollitem_t;
-
-#define ZMQ_POLLITEMS_DFLT 16
-
-ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
-
-/* Built-in message proxy (3-way) */
-
-ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture);
-
-/* Encode a binary key as printable text using ZMQ RFC 32 */
-ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);
-
-/* Encode a binary key from printable text per ZMQ RFC 32 */
-ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
-
-/* Deprecated aliases */
-#define ZMQ_STREAMER 1
-#define ZMQ_FORWARDER 2
-#define ZMQ_QUEUE 3
-/* Deprecated method */
-ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend);
-
-#undef ZMQ_EXPORT
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/zmq/include/zmq_utils.h b/src/zmq/include/zmq_utils.h
deleted file mode 100755
index 9b14aa72..00000000
--- a/src/zmq/include/zmq_utils.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
-
- This file is part of 0MQ.
-
- 0MQ is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- 0MQ is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __ZMQ_UTILS_H_INCLUDED__
-#define __ZMQ_UTILS_H_INCLUDED__
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* Define integer types needed for event interface */
-#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS
-# include <inttypes.h>
-#elif defined _MSC_VER && _MSC_VER < 1600
-# ifndef int32_t
-typedef __int32 int32_t;
-# endif
-# ifndef uint16_t
-typedef unsigned __int16 uint16_t;
-# endif
-#else
-# include <stdint.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Handle DSO symbol visibility */
-#if defined _WIN32
-# if defined ZMQ_STATIC
-# define ZMQ_EXPORT
-# elif defined DLL_EXPORT
-# define ZMQ_EXPORT __declspec(dllexport)
-# else
-# define ZMQ_EXPORT __declspec(dllimport)
-# endif
-#else
-# if defined __SUNPRO_C || defined __SUNPRO_CC
-# define ZMQ_EXPORT __global
-# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
-# define ZMQ_EXPORT __attribute__ ((visibility("default")))
-# else
-# define ZMQ_EXPORT
-# endif
-#endif
-
-/* These functions are documented by man pages */
-
-/* Encode data with Z85 encoding. Returns encoded data */
-ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);
-
-/* Decode data with Z85 encoding. Returns decoded data */
-ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
-
-/* Generate z85-encoded public and private keypair with libsodium. */
-/* Returns 0 on success. */
-ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key);
-
-typedef void (zmq_thread_fn) (void*);
-
-/* These functions are not documented by man pages */
-
-/* Helper functions are used by perf tests so that they don't have to care */
-/* about minutiae of time-related functions on different OS platforms. */
-
-/* Starts the stopwatch. Returns the handle to the watch. */
-ZMQ_EXPORT void *zmq_stopwatch_start (void);
-
-/* Stops the stopwatch. Returns the number of microseconds elapsed since */
-/* the stopwatch was started. */
-ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_);
-
-/* Sleeps for specified number of seconds. */
-ZMQ_EXPORT void zmq_sleep (int seconds_);
-
-/* Start a thread. Returns a handle to the thread. */
-ZMQ_EXPORT void *zmq_threadstart (zmq_thread_fn* func, void* arg);
-
-/* Wait for thread to complete then free up resources. */
-ZMQ_EXPORT void zmq_threadclose (void* thread);
-
-#undef ZMQ_EXPORT
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/zmq/libzmq.a b/src/zmq/libzmq.a
deleted file mode 100755
index 8c994993..00000000
--- a/src/zmq/libzmq.a
+++ /dev/null
Binary files differ
diff --git a/src/zmq/libzmq.la b/src/zmq/libzmq.la
deleted file mode 100755
index 2e5f984d..00000000
--- a/src/zmq/libzmq.la
+++ /dev/null
@@ -1,41 +0,0 @@
-# libzmq.la - a libtool library file
-# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.3ubuntu1
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='libzmq.so.3'
-
-# Names of this library.
-library_names='libzmq.so.3.1.0 libzmq.so.3 libzmq.so'
-
-# The name of the static archive.
-old_library='libzmq.a'
-
-# Linker flags that can not go in dependency_libs.
-inherited_linker_flags=''
-
-# Libraries that this one depends upon.
-dependency_libs=' -lrt -lpthread'
-
-# Names of additional weak libraries provided by this library
-weak_library_names=''
-
-# Version information for libzmq.
-current=4
-age=1
-revision=0
-
-# Is this an already installed library?
-installed=no
-
-# Should we warn about portability when linking against -modules?
-shouldnotlink=no
-
-# Files to dlopen/dlpreopen
-dlopen=''
-dlpreopen=''
-
-# Directory that this library needs to be installed in:
-libdir='/usr/local/lib'
diff --git a/src/zmq/libzmq.lai b/src/zmq/libzmq.lai
deleted file mode 100755
index 126d3d5e..00000000
--- a/src/zmq/libzmq.lai
+++ /dev/null
@@ -1,41 +0,0 @@
-# libzmq.la - a libtool library file
-# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.3ubuntu1
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='libzmq.so.3'
-
-# Names of this library.
-library_names='libzmq.so.3.1.0 libzmq.so.3 libzmq.so'
-
-# The name of the static archive.
-old_library='libzmq.a'
-
-# Linker flags that can not go in dependency_libs.
-inherited_linker_flags=''
-
-# Libraries that this one depends upon.
-dependency_libs=' -lrt -lpthread'
-
-# Names of additional weak libraries provided by this library
-weak_library_names=''
-
-# Version information for libzmq.
-current=4
-age=1
-revision=0
-
-# Is this an already installed library?
-installed=yes
-
-# Should we warn about portability when linking against -modules?
-shouldnotlink=no
-
-# Files to dlopen/dlpreopen
-dlopen=''
-dlpreopen=''
-
-# Directory that this library needs to be installed in:
-libdir='/usr/local/lib'
diff --git a/src/zmq/libzmq.so b/src/zmq/libzmq.so
deleted file mode 100755
index 16980c27..00000000
--- a/src/zmq/libzmq.so
+++ /dev/null
Binary files differ
diff --git a/src/zmq/libzmq.so.3 b/src/zmq/libzmq.so.3
deleted file mode 100755
index 16980c27..00000000
--- a/src/zmq/libzmq.so.3
+++ /dev/null
Binary files differ
diff --git a/src/zmq/libzmq.so.3.1.0 b/src/zmq/libzmq.so.3.1.0
deleted file mode 100755
index 16980c27..00000000
--- a/src/zmq/libzmq.so.3.1.0
+++ /dev/null
Binary files differ