summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py58
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py2
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py60
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py52
-rwxr-xr-xscripts/dpdk_nic_bind.py7
-rwxr-xr-xscripts/dpdk_setup_ports.py6
-rwxr-xr-xscripts/t-rex-649
7 files changed, 160 insertions, 34 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 82aa932d..b11ddbe3 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
@@ -560,11 +560,14 @@ class STLClient(object):
self.util_stats = trex_stl_stats.CUtilStats(self)
+ self.xstats = trex_stl_stats.CXStats(self)
+
self.stats_generator = trex_stl_stats.CTRexInfoGenerator(self.global_stats,
self.ports,
self.flow_stats,
self.latency_stats,
self.util_stats,
+ self.xstats,
self.async_client.monitor)
@@ -1785,6 +1788,25 @@ class STLClient(object):
self.logger.pre_cmd('Getting Utilization stats')
return self.util_stats.get_stats()
+ @__api_check(True)
+ def get_xstats(self, port_id):
+ print(port_id)
+ """
+ Get extended stats of port: all the counters as dict.
+
+ :parameters:
+ port_id: int
+
+ :returns:
+ Dict with names of counters as keys and values of uint64. Actual keys may vary per NIC.
+
+ :raises:
+ + :exc:`STLError`
+
+ """
+ self.logger.pre_cmd('Getting xstats')
+ return self.xstats.get_stats(port_id)
+
@__api_check(True)
def reset(self, ports = None):
@@ -2462,7 +2484,7 @@ class STLClient(object):
@__api_check(False)
- def clear_stats (self, ports = None, clear_global = True, clear_flow_stats = True, clear_latency_stats = True):
+ def clear_stats (self, ports = None, clear_global = True, clear_flow_stats = True, clear_latency_stats = True, clear_xstats = True):
"""
Clear stats on port(s)
@@ -2572,12 +2594,15 @@ class STLClient(object):
@__api_check(True)
- def set_port_attr (self, ports = None, promiscuous = None):
+ def set_port_attr (self, ports = None, promiscuous = None, link_up = None, led_on = None, flow_ctrl = None):
"""
Set port attributes
:parameters:
promiscuous - True or False
+ 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
:raises:
None
@@ -2589,11 +2614,20 @@ class STLClient(object):
# check arguments
validate_type('promiscuous', promiscuous, (bool, type(None)))
+ 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)))
# build attributes
attr_dict = {}
if promiscuous is not None:
- attr_dict['promiscuous'] = {'enabled': bool(promiscuous)}
+ attr_dict['promiscuous'] = {'enabled': promiscuous}
+ if link_up is not None:
+ attr_dict['link_status'] = {'up': link_up}
+ if led_on is not None:
+ attr_dict['led_status'] = {'on': led_on}
+ if flow_ctrl is not None:
+ attr_dict['flow_ctrl_mode'] = {'mode': flow_ctrl}
# no attributes to set
if not attr_dict:
@@ -3167,20 +3201,28 @@ class STLClient(object):
"port_attr",
self.set_port_attr_line.__doc__,
parsing_opts.PORT_LIST_WITH_ALL,
- parsing_opts.PROMISCUOUS_SWITCH)
+ parsing_opts.PROMISCUOUS,
+ parsing_opts.LINK_STATUS,
+ parsing_opts.LED_STATUS,
+ parsing_opts.FLOW_CTRL,
+ )
opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True)
if not opts:
return opts
+ opts.prom = parsing_opts.on_off_dict.get(opts.prom)
+ opts.link = parsing_opts.on_off_dict.get(opts.link)
+ opts.led = parsing_opts.on_off_dict.get(opts.led)
+ opts.flow_ctrl = parsing_opts.flow_ctrl_dict.get(opts.flow_ctrl)
+
# if no attributes - fall back to printing the status
- if opts.prom is None:
+ if not filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl]):
self.show_stats_line("--ps --port {0}".format(' '.join(str(port) for port in opts.ports)))
return
- self.set_port_attr(opts.ports, opts.prom)
- return RC_OK()
-
+ return self.set_port_attr(opts.ports, opts.prom, opts.link, opts.led, opts.flow_ctrl)
+
@__console
def show_profile_line (self, line):
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
index aa002d59..dc06f9fb 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
@@ -738,8 +738,8 @@ class STLVmFlowVarRepetableRandom(CTRexVmDescBase):
.. code-block:: python
- :caption: Example1
+ # Example1
# input , 1 byte or random with limit of 5
STLVmFlowVarRepetableRandom("var1",size=1,limit=5)
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 5d9cdcaa..eaa5e8b0 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
@@ -147,12 +147,13 @@ class CTRexInfoGenerator(object):
STLClient and the ports.
"""
- def __init__(self, global_stats_ref, ports_dict_ref, rx_stats_ref, latency_stats_ref, util_stats_ref, async_monitor):
+ def __init__(self, global_stats_ref, ports_dict_ref, rx_stats_ref, latency_stats_ref, util_stats_ref, xstats_ref, async_monitor):
self._global_stats = global_stats_ref
self._ports_dict = ports_dict_ref
self._rx_stats_ref = rx_stats_ref
self._latency_stats_ref = latency_stats_ref
self._util_stats_ref = util_stats_ref
+ self._xstats_ref = xstats_ref
self._async_monitor = async_monitor
def generate_single_statistic(self, port_id_list, statistic_type):
@@ -1003,6 +1004,7 @@ class CPortStats(CTRexStats):
def _update(self, snapshot):
+ speed = self._port_obj.get_speed_bps()
# L1 bps
tx_bps = snapshot.get("m_total_tx_bps")
@@ -1015,22 +1017,34 @@ class CPortStats(CTRexStats):
bps_rx_L1 = calc_bps_L1(rx_bps, rx_pps)
snapshot['m_total_tx_bps_L1'] = bps_tx_L1
- snapshot['m_tx_util'] = (bps_tx_L1 / self._port_obj.get_speed_bps()) * 100.0
+ if speed:
+ snapshot['m_tx_util'] = (bps_tx_L1 / speed) * 100.0
+ else:
+ snapshot['m_tx_util'] = 0
snapshot['m_total_rx_bps_L1'] = bps_rx_L1
- snapshot['m_rx_util'] = (bps_rx_L1 / self._port_obj.get_speed_bps()) * 100.0
+ if speed:
+ snapshot['m_rx_util'] = (bps_rx_L1 / speed) * 100.0
+ else:
+ snapshot['m_rx_util'] = 0
# TX line util not smoothed
diff_tx_pkts = snapshot.get('opackets', 0) - self.latest_stats.get('opackets', 0)
diff_tx_bytes = snapshot.get('obytes', 0) - self.latest_stats.get('obytes', 0)
tx_bps_L1 = calc_bps_L1(8.0 * diff_tx_bytes / ts_diff, float(diff_tx_pkts) / ts_diff)
- snapshot['tx_percentage'] = 100.0 * tx_bps_L1 / self._port_obj.get_speed_bps()
+ if speed:
+ snapshot['tx_percentage'] = 100.0 * tx_bps_L1 / speed
+ else:
+ snapshot['tx_percentage'] = 0
# RX line util not smoothed
diff_rx_pkts = snapshot.get('ipackets', 0) - self.latest_stats.get('ipackets', 0)
diff_rx_bytes = snapshot.get('ibytes', 0) - self.latest_stats.get('ibytes', 0)
rx_bps_L1 = calc_bps_L1(8.0 * diff_rx_bytes / ts_diff, float(diff_rx_pkts) / ts_diff)
- snapshot['rx_percentage'] = 100.0 * rx_bps_L1 / self._port_obj.get_speed_bps()
+ if speed:
+ snapshot['rx_percentage'] = 100.0 * rx_bps_L1 / speed
+ else:
+ snapshot['rx_percentage'] = 0
# simple...
self.latest_stats = snapshot
@@ -1417,7 +1431,7 @@ class CUtilStats(CTRexStats):
self.client = client
self.history = deque(maxlen = 1)
self.mbuf_types_list = None
- self.last_update_ts = 0
+ self.last_update_ts = -999
def get_stats(self, use_1sec_cache = False):
time_now = time.time()
@@ -1433,6 +1447,40 @@ class CUtilStats(CTRexStats):
return self.history[-1]
+class CXStats(CTRexStats):
+
+ def __init__(self, client):
+ super(CXStats, self).__init__()
+ self.client = client
+ self.history = deque(maxlen = 1)
+ self.names = {}
+ self.last_update_ts = -999
+
+ def get_stats(self, port_id, use_1sec_cache = False):
+ time_now = time.time()
+ if self.last_update_ts + 1 < time_now or not self.history or not use_1sec_cache:
+ if self.client.is_connected():
+ rc = self.client._transmit('get_port_xstats_values', params = {'port_id': port_id})
+ if not rc:
+ raise Exception(rc)
+ self.last_update_ts = time_now
+ values = rc.data().get('xstats_values', [])
+ if len(values) != len(self.names): # need to update names ("keys")
+ rc = self.client._transmit('get_port_xstats_names', params = {'port_id': port_id})
+ if not rc:
+ raise Exception(rc)
+ self.names = rc.data().get('xstats_names', [])
+ if len(values) != len(self.names):
+ raise Exception('Length of get_xstats_names: %s and get_port_xstats_values: %s' % (len(self.names), len(values)))
+ self.history.append(dict([(key, val) for key, val in zip(self.names, values)]))
+ else:
+ self.history.append({})
+
+ stats = {}
+ for key, val in self.history[-1].items():
+ stats[key] = self.history[-1][key] - self.reference_stats.get(key, 0)
+ return stats
+
if __name__ == "__main__":
pass
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 8ae86981..148f7715 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
@@ -1,5 +1,5 @@
import argparse
-from collections import namedtuple
+from collections import namedtuple, OrderedDict
from .common import list_intersect, list_difference
from .text_opts import format_text
from ..trex_stl_types import *
@@ -11,6 +11,18 @@ import os
ArgumentPack = namedtuple('ArgumentPack', ['name_or_flags', 'options'])
ArgumentGroup = namedtuple('ArgumentGroup', ['type', 'args', 'options'])
+on_off_dict = OrderedDict([
+ ('on', True),
+ ('off', False),
+])
+
+flow_ctrl_dict = OrderedDict([
+ ('none', 0), # Disable flow control
+ ('tx', 1), # Enable flowctrl on TX side (RX pause frames)
+ ('rx', 2), # Enable flowctrl on RX side (TX pause frames)
+ ('full', 3), # Enable flow control on both sides
+])
+
# list of available parsing options
MULTIPLIER = 1
@@ -32,14 +44,15 @@ IPG = 16
SPEEDUP = 17
COUNT = 18
PROMISCUOUS = 19
-NO_PROMISCUOUS = 20
-PROMISCUOUS_SWITCH = 21
+LINK_STATUS = 20
+LED_STATUS = 21
TUNABLES = 22
REMOTE_FILE = 23
LOCKED = 24
PIN_CORES = 25
CORE_MASK = 26
DUAL = 27
+FLOW_CTRL = 28
GLOBAL_STATS = 50
PORT_STATS = 51
@@ -282,10 +295,21 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'type': int}),
PROMISCUOUS: ArgumentPack(['--prom'],
- {'help': "Sets port promiscuous on",
- 'dest': "prom",
- 'default': None,
- 'action': "store_true"}),
+ {'help': "Set port promiscuous on/off",
+ 'choices': on_off_dict}),
+
+ LINK_STATUS: ArgumentPack(['--link'],
+ {'help': 'Set link status on/off',
+ 'choices': on_off_dict}),
+
+ LED_STATUS: ArgumentPack(['--led'],
+ {'help': 'Set LED status on/off',
+ 'choices': on_off_dict}),
+
+ FLOW_CTRL: ArgumentPack(['--fc'],
+ {'help': 'Set Flow Control type',
+ 'dest': 'flow_ctrl',
+ 'choices': flow_ctrl_dict}),
TUNABLES: ArgumentPack(['-t'],
{'help': "Sets tunables for a profile. Example: '-t fsize=100,pg_id=7'",
@@ -295,12 +319,6 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'action': 'merge',
'type': decode_tunables}),
- NO_PROMISCUOUS: ArgumentPack(['--no-prom', '--no_prom'],
- {'help': "Sets port promiscuous off",
- 'dest': "prom",
- 'default': None,
- 'action': "store_false"}),
-
PORT_LIST: ArgumentPack(['--port', '-p'],
{"nargs": '+',
'dest':'ports',
@@ -424,12 +442,6 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'default': None,
'help': "Core mask - only cores responding to the bit mask will be active"}),
-
- # promiscuous
- PROMISCUOUS_SWITCH: ArgumentGroup(MUTEX, [PROMISCUOUS,
- NO_PROMISCUOUS],
- {'required': False}),
-
# advanced options
PORT_LIST_WITH_ALL: ArgumentGroup(MUTEX, [PORT_LIST,
ALL_PORTS],
@@ -462,6 +474,8 @@ class _MergeAction(argparse._AppendAction):
items.extend(values)
elif type(items) is dict and type(values) is dict: # tunables are dict
items.update(values)
+ else:
+ raise Exception("Argparser 'merge' option should be used on dict or list.")
setattr(namespace, self.dest, items)
diff --git a/scripts/dpdk_nic_bind.py b/scripts/dpdk_nic_bind.py
index 44d4e82d..ed0462ec 100755
--- a/scripts/dpdk_nic_bind.py
+++ b/scripts/dpdk_nic_bind.py
@@ -629,6 +629,13 @@ def show_table():
table.add_row([id, d['NUMA'], d['Slot_str'], d.get('MAC', ''), d['Device_str'], d.get('Driver_str', ''), d['Interface'], d['Active']])
print(table.draw())
+# dumps pci address and description (user friendly device name)
+def dump_pci_description():
+ if not devices:
+ get_nic_details()
+ for d in devices.values():
+ print('%s - %s' % (d['Slot'], d['Device_str']))
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
appropriate action for each'''
diff --git a/scripts/dpdk_setup_ports.py b/scripts/dpdk_setup_ports.py
index 58d58690..2782384c 100755
--- a/scripts/dpdk_setup_ports.py
+++ b/scripts/dpdk_setup_ports.py
@@ -699,6 +699,8 @@ To see more detailed info on interfaces (table):
help=argparse.SUPPRESS
)
+ parser.add_argument('--dump-pci-description', help='suppress', dest='dump_pci_desc', action='store_true')
+
parser.add_argument("-i", "--interactive", action='store_true',
help=""" Create TRex config in interactive mode """,
)
@@ -786,6 +788,10 @@ def main ():
dpdk_nic_bind.show_table()
return
+ if map_driver.args.dump_pci_desc:
+ dpdk_nic_bind.dump_pci_description()
+ return
+
obj =CIfMap(map_driver.cfg_file);
if map_driver.args.create_interfaces is not None:
diff --git a/scripts/t-rex-64 b/scripts/t-rex-64
index 4e5c0fae..4d0d7813 100755
--- a/scripts/t-rex-64
+++ b/scripts/t-rex-64
@@ -12,6 +12,15 @@ if [ $RESULT -ne 0 ]; then
exit $RESULT
fi
+pci_desc_re='^(\S+) - (.+)$'
+source find_python.sh
+while read line
+do
+ if [[ "$line" =~ $pci_desc_re ]]; then
+ pci_name="pci$(echo ${BASH_REMATCH[1]} | tr ':' '_' | tr '.' '_')" # make alphanumeric name
+ export $pci_name="${BASH_REMATCH[2]}"
+ fi
+done <<< "$($PYTHON dpdk_setup_ports.py --dump-pci-description)"
cd $(dirname $0)
export LD_LIBRARY_PATH=$PWD