From d09b123992f990a6c219dd47707cc703fe9055b5 Mon Sep 17 00:00:00 2001 From: imarom Date: Tue, 8 Nov 2016 19:29:05 +0200 Subject: RX queue - ARP request working Signed-off-by: imarom --- .../stl/trex_stl_lib/trex_stl_client.py | 90 +++++++++++++++++----- .../stl/trex_stl_lib/trex_stl_port.py | 28 ++++--- src/rpc-server/commands/trex_rpc_cmd_general.cpp | 4 +- src/rpc-server/commands/trex_rpc_cmds.h | 2 +- src/rpc-server/trex_rpc_cmds_table.cpp | 2 +- src/stateless/cp/trex_stateless_port.cpp | 4 +- src/stateless/cp/trex_stateless_port.h | 4 +- .../messaging/trex_stateless_messaging.cpp | 10 +-- src/stateless/messaging/trex_stateless_messaging.h | 6 +- src/stateless/rx/trex_stateless_rx_core.h | 2 +- 10 files changed, 105 insertions(+), 47 deletions(-) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index 583917ea..b607ce23 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -1771,6 +1771,38 @@ class STLClient(object): if not rc: raise STLError(rc) + def test (self): + + self.reset(ports = [0, 1]) + + self.set_rx_queue(ports = [0], size = 1000, rxf = 'all') + + #base_pkt = Ether()/ARP()/('x'*50) + base_pkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(psrc = '1.1.1.2',pdst = '1.1.1.1', hwsrc = 'a0:36:9f:20:e6:ce') + #base_pkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ICMP() + + print('Sending ARP request on port 0:\n') + base_pkt.show2() + + # send some traffic + x = STLStream( packet = STLPktBuilder(pkt = base_pkt), mode = STLTXSingleBurst(total_pkts = 1) ) + + self.add_streams(streams = [x], ports = [0]) + self.start(ports = [0], mult = '100%') + self.wait_on_traffic(ports = [0]) + time.sleep(1) + + pkts = self.get_rx_queue_pkts(ports = [0]) + + print('got back on port 0:\n') + for pkt in pkts[0]: + Ether(pkt).show2() + + self.remove_rx_queue(ports = [1]) + self.set_port_attr(ports = [1], rxf = 'hw') + #for pkt in pkts[1]: + # Ether(pkt).show2() + @__api_check(True) def ping(self): @@ -1785,12 +1817,8 @@ class STLClient(object): + :exc:`STLError` """ - rc = self.set_port_attr(ports = [0, 1], rx_filter_mode = 'all') - rc = self.set_rx_queue(ports = [0, 1], size = 1000) - if not rc: - raise STLError(rc) - - + self.test() + self.logger.pre_cmd("Pinging the server on '{0}' port '{1}': ".format(self.connection_info['server'], self.connection_info['sync_port'])) rc = self._transmit("ping", api_class = None) @@ -1911,8 +1939,8 @@ class STLClient(object): self.clear_stats(ports) self.set_port_attr(ports, promiscuous = False, - link_up = True, - rx_filter_mode = 'hw') + #link_up = True, + rxf = 'hw') self.remove_rx_sniffer(ports) self.remove_rx_queue(ports) @@ -2692,7 +2720,7 @@ class STLClient(object): link_up = None, led_on = None, flow_ctrl = None, - rx_filter_mode = None): + rxf = None): """ Set port attributes @@ -2701,7 +2729,7 @@ class STLClient(object): link_up - True or False led_on - True or False flow_ctrl - 0: disable all, 1: enable tx side, 2: enable rx side, 3: full enable - rx_filter_mode - 'hw' for hardware rules matching packets only or 'all' all packets + rxf - 'hw' for hardware rules matching packets only or 'all' all packets :raises: + :exe:'STLError' @@ -2715,7 +2743,7 @@ class STLClient(object): validate_type('link_up', link_up, (bool, type(None))) validate_type('led_on', led_on, (bool, type(None))) validate_type('flow_ctrl', flow_ctrl, (int, type(None))) - validate_choice('rx_filter_mode', rx_filter_mode, ['hw', 'all']) + validate_choice('rxf', rxf, ['hw', 'all']) # build attributes attr_dict = {} @@ -2727,8 +2755,8 @@ class STLClient(object): attr_dict['led_status'] = {'on': led_on} if flow_ctrl is not None: attr_dict['flow_ctrl_mode'] = {'mode': flow_ctrl} - if rx_filter_mode is not None: - attr_dict['rx_filter_mode'] = {'mode': rx_filter_mode} + if rxf is not None: + attr_dict['rx_filter_mode'] = {'mode': rxf} # no attributes to set if not attr_dict: @@ -2744,7 +2772,7 @@ class STLClient(object): @__api_check(True) - def set_rx_sniffer (self, ports = None, base_filename = 'rx_capture', limit = 1000): + def set_rx_sniffer (self, ports = None, base_filename = 'rx_capture', limit = 1000, rxf = None): """ Sets RX sniffer for port(s) written to a PCAP file @@ -2752,6 +2780,7 @@ class STLClient(object): ports - for which ports to apply a unique sniffer (each port gets a unique file) base_filename - filename will be appended with '-' limit - limit how many packets will be written + rxf - RX filter mode to use: 'hw' or 'all' :raises: + :exe:'STLError' @@ -2765,6 +2794,10 @@ class STLClient(object): if limit <= 0: raise STLError("'limit' must be a positive value") + # change RX filter mode if asked + if rxf: + self.set_port_attr(ports, rxf = rxf) + self.logger.pre_cmd("Setting RX sniffers on port(s) {0}:".format(ports)) rc = self.__set_rx_sniffer(ports, base_filename, limit) self.logger.post_cmd(rc) @@ -2796,7 +2829,7 @@ class STLClient(object): @__api_check(True) - def set_rx_queue (self, ports = None, size = 1000): + def set_rx_queue (self, ports = None, size = 1000, rxf = None): """ Sets RX queue for port(s) The queue is cyclic and will hold last 'size' packets @@ -2804,6 +2837,7 @@ class STLClient(object): :parameters: ports - for which ports to apply a unique sniffer (each port gets a unique file) size - size of the queue + rxf - which RX filter to use on those ports: 'hw' or 'all' :raises: + :exe:'STLError' @@ -2816,6 +2850,10 @@ class STLClient(object): if size <= 0: raise STLError("'size' must be a positive value") + # change RX filter mode if asked + if rxf: + self.set_port_attr(ports, rxf = rxf) + self.logger.pre_cmd("Setting RX queue on port(s) {0}:".format(ports)) rc = self.__set_rx_queue(ports, size) self.logger.post_cmd(rc) @@ -2847,6 +2885,23 @@ class STLClient(object): + @__api_check(True) + def get_rx_queue_pkts (self, ports = None): + """ + Returns any packets queued on the RX side by the server + return value is a dictonary per port + + """ + ports = ports if ports is not None else self.get_acquired_ports() + ports = self._validate_port_list(ports) + + result = {} + for port in ports: + result[port] = self.ports[port].get_rx_queue_pkts() + + return result + + def clear_events (self): """ Clear all events @@ -3460,10 +3515,9 @@ class STLClient(object): if not opts: return opts - if parsing_opts.ALL_FILES: - self.set_port_attr(ports = opts.ports, rx_filter_mode = 'all') + rxf = 'all' if opts.all else None - self.set_rx_sniffer(opts.ports, opts.output_filename, opts.limit) + self.set_rx_sniffer(opts.ports, opts.output_filename, opts.limit, rxf) @__console diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py index 94745d15..96c5e832 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py @@ -546,7 +546,24 @@ class Port(object): return self.ok() + @owned + def get_rx_queue_pkts (self): + params = {"handler": self.handler, + "port_id": self.port_id} + + rc = self.transmit("get_rx_queue_pkts", params) + if rc.bad(): + return self.err(rc.err()) + pkts = rc.data()['pkts'] + + # decode the packets + for i in range(len(pkts)): + pkts[i] = base64.b64decode(pkts[i]) + + return pkts + + @owned def pause (self): @@ -640,17 +657,6 @@ class Port(object): return self.ok() - @owned - def get_rx_sw_pkts (self): - params = {"handler": self.handler, - "port_id": self.port_id} - - rc = self.transmit("get_rx_sw_pkts", params) - if rc.bad(): - return self.err(rc.err()) - - return self.ok() - @writeable def push_remote (self, pcap_filename, ipg_usec, speedup, count, duration, is_dual, slave_handler): diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index 3653de1a..b63c2faa 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -765,14 +765,14 @@ TrexRpcCmdSetRxFeature::parse_server_msg(const Json::Value &msg, TrexStatelessPo trex_rpc_cmd_rc_e -TrexRpcCmdGetRxSwPkts::_run(const Json::Value ¶ms, Json::Value &result) { +TrexRpcCmdGetRxQueuePkts::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_port(params, result); TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); try { - RxPacketBuffer *pkt_buffer = port->get_rx_sw_pkts(); + RxPacketBuffer *pkt_buffer = port->get_rx_queue_pkts(); result["result"]["pkts"] = pkt_buffer->to_json(); } catch (const TrexException &ex) { diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index 26de717f..b8a5d323 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -158,7 +158,7 @@ TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdSetRxFeature, "set_rx_feature", 3, false, ); -TREX_RPC_CMD_DEFINE(TrexRpcCmdGetRxSwPkts, "get_rx_sw_pkts", 2, false, APIClass::API_CLASS_TYPE_CORE); +TREX_RPC_CMD_DEFINE(TrexRpcCmdGetRxQueuePkts, "get_rx_queue_pkts", 2, false, APIClass::API_CLASS_TYPE_CORE); #endif /* __TREX_RPC_CMD_H__ */ diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp index 45e32d4a..f006a4cd 100644 --- a/src/rpc-server/trex_rpc_cmds_table.cpp +++ b/src/rpc-server/trex_rpc_cmds_table.cpp @@ -73,7 +73,7 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() { register_command(new TrexRpcCmdShutdown()); register_command(new TrexRpcCmdSetRxFeature()); - register_command(new TrexRpcCmdGetRxSwPkts()); + register_command(new TrexRpcCmdGetRxQueuePkts()); } diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 691185cd..ff83087c 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -978,12 +978,12 @@ TrexStatelessPort::stop_rx_queue() { RxPacketBuffer * -TrexStatelessPort::get_rx_sw_pkts() { +TrexStatelessPort::get_rx_queue_pkts() { /* ask RX core for the pkt queue */ TrexStatelessMsgReply msg_reply; - TrexStatelessCpToRxMsgBase *msg = new TrexStatelessRxSwGetPkts(m_port_id, msg_reply); + TrexStatelessCpToRxMsgBase *msg = new TrexStatelessRxQueueGetPkts(m_port_id, msg_reply); send_message_to_rx(msg); RxPacketBuffer *pkt_buffer = msg_reply.wait_for_reply(); diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 36f17659..d71ba932 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -408,10 +408,10 @@ public: } /** - * fetch the RX software packets from the queue + * fetch the RX queue packets from the queue * */ - RxPacketBuffer *get_rx_sw_pkts(); + RxPacketBuffer *get_rx_queue_pkts(); private: diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp index 95168c4d..c2182f3c 100644 --- a/src/stateless/messaging/trex_stateless_messaging.cpp +++ b/src/stateless/messaging/trex_stateless_messaging.cpp @@ -257,11 +257,6 @@ bool TrexStatelessRxQuit::handle (CRxCoreStateless *rx_core) { } -TrexStatelessRxSwGetPkts::TrexStatelessRxSwGetPkts(uint8_t port_id, TrexStatelessMsgReply &reply) : m_reply(reply) { - m_port_id = port_id; -} - - bool TrexStatelessRxStartCapture::handle(CRxCoreStateless *rx_core) { rx_core->start_capture(m_port_id, m_pcap_filename, m_limit, m_shared_counter); @@ -291,8 +286,9 @@ TrexStatelessRxStopQueue::handle(CRxCoreStateless *rx_core) { } -bool TrexStatelessRxSwGetPkts::handle(CRxCoreStateless *rx_core) { - RxPacketBuffer *pkt_buffer = rx_core->get_rx_sw_pkt_buffer(m_port_id); + +bool TrexStatelessRxQueueGetPkts::handle(CRxCoreStateless *rx_core) { + RxPacketBuffer *pkt_buffer = rx_core->get_rx_queue_pkts(m_port_id); assert(pkt_buffer); m_reply.set(pkt_buffer); diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h index b598a6d6..52b1662e 100644 --- a/src/stateless/messaging/trex_stateless_messaging.h +++ b/src/stateless/messaging/trex_stateless_messaging.h @@ -521,10 +521,12 @@ private: -class TrexStatelessRxSwGetPkts : public TrexStatelessCpToRxMsgBase { +class TrexStatelessRxQueueGetPkts : public TrexStatelessCpToRxMsgBase { public: - TrexStatelessRxSwGetPkts(uint8_t port_id, TrexStatelessMsgReply &reply); + TrexStatelessRxQueueGetPkts(uint8_t port_id, TrexStatelessMsgReply &reply) : m_reply(reply) { + m_port_id = port_id; + } /** * virtual function to handle a message diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h index b5844583..519724d8 100644 --- a/src/stateless/rx/trex_stateless_rx_core.h +++ b/src/stateless/rx/trex_stateless_rx_core.h @@ -111,7 +111,7 @@ class CRxCoreStateless { double get_cpu_util(); void update_cpu_util(); - RxPacketBuffer *get_rx_sw_pkt_buffer(uint8_t port_id) { + RxPacketBuffer *get_rx_queue_pkts(uint8_t port_id) { return m_rx_port_mngr[port_id].get_pkt_buffer(); } -- cgit 1.2.3-korg