summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-11-06 17:20:17 +0200
committerimarom <imarom@cisco.com>2016-11-06 17:20:17 +0200
commita1ade6fd8e044b9866a8644db3519305539cfc61 (patch)
tree08b4d0e2db80c4d1e5cb759512c5e3631c19fd95 /scripts
parent234779fd32e747f4ac918f3c39e59618dde0f2d7 (diff)
RX features - RX sniffer
Signed-off-by: imarom <imarom@cisco.com>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/automation/trex_control_plane/stl/console/trex_console.py7
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py108
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py37
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py2
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py28
5 files changed, 156 insertions, 26 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py
index b23b5f1f..92c04a7f 100755
--- a/scripts/automation/trex_control_plane/stl/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py
@@ -327,6 +327,13 @@ class TRexConsole(TRexGeneralCmd):
def help_portattr (self):
self.do_portattr("-h")
+ def do_set_rx_sniffer (self, line):
+ '''Sets a port sniffer on RX channel as PCAP recorder'''
+ self.stateless_client.set_rx_sniffer_line(line)
+
+ def help_sniffer (self):
+ self.do_set_rx_sniffer("-h")
+
@verify_connected
def do_map (self, line):
'''Maps ports topology\n'''
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 907e405a..b9143896 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
@@ -24,6 +24,8 @@ import re
import random
import json
import traceback
+import os.path
+
############################ logger #############################
############################ #############################
@@ -322,26 +324,28 @@ class EventsHandler(object):
# port attr changed
elif (event_type == 8):
+ return
- port_id = int(data['port_id'])
-
- if data['attr'] == self.client.ports[port_id].attr:
- return # false alarm
-
- old_info = self.client.ports[port_id].get_formatted_info()
- self.__async_event_port_attr_changed(port_id, data['attr'])
-
- new_info = self.client.ports[port_id].get_formatted_info()
- ev = "port {0} attributes changed".format(port_id)
- for key, old_val in old_info.items():
- new_val = new_info[key]
- if old_val != new_val:
- ev += '\n {key}: {old} -> {new}'.format(
- key = key,
- old = old_val.lower() if type(old_val) is str else old_val,
- new = new_val.lower() if type(new_val) is str else new_val)
- show_event = True
+ # port_id = int(data['port_id'])
+ #
+ # if data['attr'] == self.client.ports[port_id].attr:
+ # return # false alarm
+ #
+ # old_info = self.client.ports[port_id].get_formatted_info()
+ # self.__async_event_port_attr_changed(port_id, data['attr'])
+ #
+ # new_info = self.client.ports[port_id].get_formatted_info()
+ # ev = "port {0} attributes changed".format(port_id)
+ # for key, old_val in old_info.items():
+ # new_val = new_info[key]
+ # if old_val != new_val:
+ # ev += '\n {key}: {old} -> {new}'.format(
+ # key = key,
+ # old = old_val.lower() if type(old_val) is str else old_val,
+ # new = new_val.lower() if type(new_val) is str else new_val)
+ # show_event = True
+
# server stopped
elif (event_type == 100):
ev = "Server has stopped"
@@ -814,6 +818,17 @@ class STLClient(object):
return rc
+ def __set_rx_sniffer (self, port_id_list, base_filename, limit):
+ port_id_list = self.__ports(port_id_list)
+ rc = RC()
+
+ for port_id in port_id_list:
+ head, tail = os.path.splitext(base_filename)
+ filename = "{0}-{1}{2}".format(head, port_id, tail)
+ rc.add(self.ports[port_id].set_rx_sniffer(filename, limit))
+
+ return rc
+
# connect to server
def __connect(self):
@@ -2685,6 +2700,39 @@ class STLClient(object):
if not rc:
raise STLError(rc)
+
+
+ @__api_check(True)
+ def set_rx_sniffer (self, ports = None, base_filename = 'rx_capture', limit = 1000):
+ """
+ Sets RX sniffer for port(s) written to a PCAP file
+
+ :parameters:
+ ports - for which ports to apply a unique sniffer (each port gets a unique file)
+ base_filename - filename will be appended with '-<port_number>'
+ limit - limit how many packets will be written
+ :raises:
+ + :exe:'STLError'
+
+ """
+ ports = ports if ports is not None else self.get_acquired_ports()
+ ports = self._validate_port_list(ports)
+
+ # check arguments
+ validate_type('base_filename', base_filename, basestring)
+ validate_type('limit', limit, (int))
+
+
+ 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)
+
+
+ if not rc:
+ raise STLError(rc)
+
+
+
def clear_events (self):
"""
Clear all events
@@ -3281,7 +3329,29 @@ class STLClient(object):
return self.set_port_attr(opts.ports, opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.rx_filter_mode)
-
+
+ @__console
+ def set_rx_sniffer_line (self, line):
+ '''Sets a port sniffer on RX channel in form of a PCAP file'''
+
+ parser = parsing_opts.gen_parser(self,
+ "set_rx_sniffer",
+ self.set_rx_sniffer_line.__doc__,
+ parsing_opts.PORT_LIST_WITH_ALL,
+ parsing_opts.OUTPUT_FILENAME,
+ parsing_opts.LIMIT,
+ parsing_opts.ALL_FILES)
+
+ opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True)
+ if not opts:
+ return opts
+
+ if parsing_opts.ALL_FILES:
+ self.set_port_attr(ports = opts.ports, rx_filter_mode = 'all')
+
+ self.set_rx_sniffer(opts.ports, opts.output_filename, opts.limit)
+
+
@__console
def show_profile_line (self, line):
'''Shows profile information'''
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 59793495..571a6e16 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
@@ -252,6 +252,10 @@ class Port(object):
# attributes
self.attr = rc.data()['attr']
+
+ # rx info
+ self.rx_info = rc.data()['rx_info']
+
return self.ok()
@@ -484,18 +488,15 @@ class Port(object):
return self.ok()
- #
+
@writeable
- def start_rx_capture (self, pcap_filename, limit):
-
- prefix, suffix = pcap_filename.split('.')
- filename = "{0}-{1}.{2}".format(prefix, self.port_id, suffix)
+ def set_rx_sniffer (self, pcap_filename, limit):
params = {"handler": self.handler,
"port_id": self.port_id,
"type": "capture",
"enabled": True,
- "pcap_filename": filename,
+ "pcap_filename": pcap_filename,
"limit": limit}
rc = self.transmit("set_rx_feature", params)
@@ -679,6 +680,10 @@ class Port(object):
# generate formatted (console friendly) port info
def get_formatted_info (self):
+
+ # sync the attributes
+ self.sync()
+
info = dict(self.info)
info['status'] = self.get_port_state_name()
@@ -726,7 +731,22 @@ class Port(object):
else:
info['speed'] = 'N/A'
- info['rx_filter_mode'] = self.attr.get('rx_filter_mode', 'N/A')
+
+ # RX info
+ if 'rx_filter_mode' in self.attr:
+ info['rx_filter_mode'] = 'Hardware Match' if self.attr['rx_filter_mode'] == 'hw' else 'Fetch All'
+ else:
+ info['rx_filter_mode'] = 'N/A'
+
+ if 'sniffer' in self.rx_info:
+ sniffer = self.rx_info['sniffer']
+ if sniffer['is_active']:
+ info['rx_sniffer'] = '{0}\n[{1} / {2}]'.format(sniffer['pcap_filename'], sniffer['count'], sniffer['limit'])
+ else:
+ info['rx_sniffer'] = 'off'
+ else:
+ info['rx_sniffer'] = 'N/A'
+
return info
@@ -759,6 +779,9 @@ class Port(object):
"flow ctrl" : info['fc'],
"RX Filter Mode": info['rx_filter_mode'],
+ "RX Queueing": 'off',
+ "RX sniffer": info['rx_sniffer'],
+
}
def clear_stats(self):
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
index 7e47eb61..5e71b7f2 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
@@ -678,6 +678,8 @@ class CTRexInfoGenerator(object):
("NUMA Node", []),
("----", []),
("RX Filter Mode", []),
+ ("RX Queueing", []),
+ ("RX sniffer", []),
]
)
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
index 0d316c9e..715a741e 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
@@ -45,6 +45,10 @@ FLOW_CTRL = 28
SUPPORTED = 29
RX_FILTER_MODE = 30
+OUTPUT_FILENAME = 31
+ALL_FILES = 32
+LIMIT = 33
+
GLOBAL_STATS = 50
PORT_STATS = 51
PORT_STATUS = 52
@@ -310,6 +314,29 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'choices': ['hw', 'all']}),
+ OUTPUT_FILENAME: ArgumentPack(['-o', '--output'],
+ {'help': 'Output PCAP filename',
+ 'dest': 'output_filename',
+ 'default': None,
+ 'required': True,
+ 'type': str}),
+
+
+
+ ALL_FILES: ArgumentPack(['--all'],
+ {'help': 'change RX port filter to fetch all packets',
+ 'dest': 'all',
+ 'default': False,
+ 'action': "store_true"}),
+
+
+ LIMIT: ArgumentPack(['-l', '--limit'],
+ {'help': 'Limit the packet count to be written to the file',
+ 'dest': 'limit',
+ 'default': 1000,
+ 'type': int}),
+
+
SUPPORTED: ArgumentPack(['--supp'],
{'help': 'Show which attributes are supported by current NICs',
'default': None,
@@ -459,6 +486,7 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
ALL_PORTS],
{'required': False}),
+
STREAM_FROM_PATH_OR_FILE: ArgumentGroup(MUTEX, [FILE_PATH,
FILE_FROM_DB],
{'required': True}),