The TRex RPC Server =================== :author: Itay Marom :email: <imarom@cisco.com> :revnumber: 1.70-0.0 :quotes.++: :numbered: :web_server_url: http://trex-tgn.cisco.com/trex :local_web_server_url: csi-wiki-01:8181/trex == RPC Support On TRex TRex implements a RPC protocol in order to config, view and in general execute remote calls on TRex In this document we will provide information on how a client can implement the protocol used to communicate with TRex In general, we will describe the following: * *Transport Layer* - The transport layer used to communicate with TRex server * *RPC Reprensentation Protocol* - The format in which remote procedures are carried === Transport Layer TRex server transport layer is implemented using ZMQ. The default configuration is TCP on port 5555, however this is configurable. {zwsp} + The communication model is based on the request-reply ZMQ model: http://zguide.zeromq.org/page:all#Ask-and-Ye-Shall-Receive {zwsp} + for more on ZMQ and implementation please refer to: {zwsp} + http://zeromq.org/intro:read-the-manual === RPC Reprensentation Protocol The RPC reprensentation protocol is JSON RPC v2.0. Every request and response will be encoded in a JSON RPC v2.0 format. {zwsp} + For more info on JSON RPC v2.0 spec please refer to: {zwsp} + http://www.jsonrpc.org/specification {zwsp} + Later on in the document we will describe all the supported commands. === TRex RPC Mock Server Before we get into the commands, it's worth mentioning that TRex has a mock RPC server designed to allow playing around with the server in order to understand the response and perform adjustments to the request. TRex also provides a Python based console that can connect to the server (mock or real) and send various commands to the server. ==== Building The Mock Server Building the mock server is performed like this: [source,bash] ---- trex-core/linux> ./b configure trex-core/linux> ./b --target=mock-rpc-server-64-debug ---- ==== Running The Mock Server Launching the mock server is performed like this: [source,bash] ---- trex-core/scripts> ./mock-rpc-server-64-debug -= Starting RPC Server Mock =- Listening on tcp://localhost:5050 [ZMQ] Setting Server To Full Verbose Server Started ---- ==== Using The TRex Console To Interact When the mock server is up, you can already send commands to the server. {zwsp} + {zwsp} + Let's demonstrate the operation with the Python based TRex console: {zwsp} + [source,bash] ---- trex-core/scripts> ./trex-console Connecting To RPC Server On tcp://localhost:5050 [SUCCESS] -=TRex Console V1.0=- Type 'help' or '?' for supported actions TRex > ---- As we will see later on, a basic RPC command supported by the server is 'ping'. {zwsp} + Let's issue a ping command to the server and see what happens on both sides: {zwsp} + {zwsp} + On the 'client' side: [source,bash] ---- TRex > verbose on verbose set to on TRex > ping -> Pinging RPC server [verbose] Sending Request To Server: { "id": "l0tog11a", "jsonrpc": "2.0", "method": "ping", "params": {} } [verbose] Server Response: { "id": "l0tog11a", "jsonrpc": "2.0", "result": "ACK" } [SUCCESS] ---- On the 'server' side: [source,bash] ---- trex-core/scripts> ./mock-rpc-server-64-debug -= Starting RPC Server Mock =- Listening on tcp://localhost:5050 [ZMQ] Setting Server To Full Verbose Server Started [verbose][req resp] Server Received: { "id" : "maa5a3g1", "jsonrpc" : "2.0", "method" : "ping", "params" : {} } [verbose][req resp] Server Replied: { "id" : "maa5a3g1", "jsonrpc" : "2.0", "result" : "ACK" } ---- == RPC Commands The following RPC commands are supported === Ping * *Name* - 'ping' * *Description* - Pings the TRex server * *Paramters* - None * *Result* - "ACK" On Sucess Example: [source,bash] ---- 'Request': { "jsonrpc": "2.0", "id": 1, "method": "ping", "params": null } 'Response': { "jsonrpc" : "2.0", "id" : 1, "result" : "ACK" } ---- === Get Registered Commands * *Name* - 'get_reg_cmds' * *Description* - Queries the server for all the registered commands * *Paramters* - None * *Result* - A list of all the supported commands by the server Example: [source,bash] ---- 'Request': { "jsonrpc": "2.0", "id": 1, "method": "get_reg_cmds", "params": null } 'Response': { "jsonrpc": "2.0", "id": 1, "result": [ "remove_all_streams", "remove_stream", "add_stream", "get_reg_cmds", "ping", "test_sub", "get_status", "test_add" ] } ---- === Get Status * *Name* - 'get_status' * *Description* - Queries the server for general information e.g.: user owning the device, number of ports configured * *Paramters* - None * *Result* - An object of all the supported commands by the server. +++<u>Result Details:</u>+++ 'general.version' - TRex version. 'general.build_date' - build date. 'general.build_time' - build time. 'general.built_by' - who built this version 'general.uptime' - uptime of the server 'general.owner' - user currently owning the device or 'none' if no one has taken ownership. {zwsp} + 'ports.count' - number of ports available on the server. === Add Stream * *Name* - 'add_stream' * *Description* - Adds a stream to a port * *Paramters* ** *port_id* - port id associated with this stream ** *stream_id* - stream id associated with the stream object ** *stream* - object of type xref:stream_obj['stream'] * *Result* - ACK in case of success ==== Object type 'stream' anchor:stream_obj[] Add_stream gets a single parameter of type object. The format of that object is as follows: .Object type 'stream' [options="header",cols="1,1,3"] |================= | Field | Type | Description | enabled | boolean | is this stream enabled | self_start | boolean | is this stream triggered by starting injection or triggered by another stream | isg | double | ['usec'] inter stream gap - delay time in usec until the stream is started | next_stream | int | next stream to start after this stream. -1 means stop after this stream | packet | object | object of type xref:packet_obj['packet'] | mode | object | object of type xref:mode_obj['mode'] | vm | object | object of type xref:vm_obj['vm'] | rx_stats | object | object of type xref:rx_stats_obj['rx_stats'] |================= ===== Object type 'packet' anchor:packet_obj[] packet contains binary and meta data .Object type 'packet' [options="header",cols="1,1,3"] |================= | Field | Type | Description | binary | byte array | binary dump of the packet to be used in the stream as array of bytes | meta | string | meta data object. opaque to the RPC server. will be passed on queries |================= ===== Object type 'mode' anchor:mode_obj[] mode object can be 'one' of the following objects: .Object type 'mode - continuous' [options="header",cols="1,1,3"] |================= | Field | Type | Description | type | string | ''continuous'' | pps | int | rate in packets per second |================= .Object type 'mode - single_burst' [options="header",cols="1,1,3"] |================= | Field | Type | Description | type | string | ''single_burst'' | pps | int | rate in packets per second | total pkts | int | total packets in the burst |================= .Object type 'mode - multi_burst' [options="header",cols="1,1,3"] |================= | Field | Type | Description | type | string | ''multi_burst'' | pps | int | rate in packets per second | pkts_per_burst | int | packets in a single burst | ibg | double | ['usec'] inter burst gap. delay between bursts in usec | count | int | number of bursts. ''0'' means loop forever, ''1'' will fall back to single burst |================= ===== Object type 'vm' anchor:vm_obj[] Describes the VM instructions to be used with this stream .Object type 'vm' [options="header",cols="1,1,3"] |================= | Field | Type | Description |================= ===== Object type 'rx_stats' anchor:rx_stats_obj[] Describes rx stats for the stream .Object type 'rx_stats' [options="header",cols="1,1,3"] |================= | Field | Type | Description | enabled | boolean | is rx_stats enabled for this stream | rx_stream_id | int | | seq_enabled | boolean | should write 32 bit sequence | latency_enabled | boolean | should write 32 bit latency |================= [source,bash] ---- 'Request': { "id": 1, "jsonrpc": "2.0", "method": "add_stream", "params": { "port_id": 1, "stream_id": 502 "stream": { "enabled": true, "isg": 4.3, "mode": { "pps": 3, "total_pkts": 5000, "type": "single_burst" }, "next_stream_id": -1, "packet": { "binary": [ 4, 1, 255 ], "meta": "" }, "rx_stats": { "enabled": false }, "self_start": true, } } } 'Response': { "id": 1, "jsonrpc": "2.0", "result": "ACK" } ---- === Remove Stream * *Name* - 'remove_stream' * *Description* - Removes a stream from a port * *Paramters* ** *port_id* - port assosicated with the stream. ** *stream_id* - stream to remove * *Result* - ACK in case of success [source,bash] ---- 'Request': { "id": 1 "jsonrpc": "2.0", "method": "remove_stream", "params": { "port_id": 1, "stream_id": 502 } } 'Response': { "id": 1 "jsonrpc": "2.0", "result": "ACK" } ---- === Get Stream ID List * *Name* - 'get_stream_list' * *Description* - fetch all the assoicated streams for a port * *Paramters* ** *port_id* - port to query for registered streams * *Result* - array of 'stream_id' [source,bash] ---- 'Request': { "id": 1, "jsonrpc": "2.0", "method": "get_stream_list", "params": { "port_id": 1 } } 'Response': { "id": 1, "jsonrpc": "2.0", "result": [ 502, 18 ] } ----