Use external, dynamically loaded modules to generate the streams that
get added to the client.
The module API is compatible with TRex's STL [1] to ease prototyping.
[1]
https://trex-tgn.cisco.com/trex/doc/trex_stateless.html
Signed-off-by: Adrian Moreno <amorenoz(a)redhat.com>
---
lnst/External/TRex/TRexLib.py | 37 +++++++++++++++-----------------
lnst/External/TRex/UDPSimple.py | 38 +++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 20 deletions(-)
create mode 100644 lnst/External/TRex/UDPSimple.py
diff --git a/lnst/External/TRex/TRexLib.py b/lnst/External/TRex/TRexLib.py
index 68e6289..39b56f9 100644
--- a/lnst/External/TRex/TRexLib.py
+++ b/lnst/External/TRex/TRexLib.py
@@ -1,3 +1,4 @@
+import importlib
import os
import sys
import time
@@ -11,7 +12,8 @@ TREX_CLI_DEFAULT_PARAMS = {
"warmup_time": 5,
"server_hostname": "localhost",
"trex_stl_path": 'trex_client/interactive',
- "msg_size": 64
+ "msg_size": 64,
+ "module": "UDPSimple"
}
class TRexCli:
@@ -28,6 +30,7 @@ class TRexCli:
- warmup_time (int): Time to wait before starting to take measurements. Default:
5
- server_hostname (str): Host where the server is running.
- msg_size (int): Message size
+ - module(str): The python module to call for stream creation. Default
(UDPSimple)
"""
trex_stl_path = 'trex_client/interactive'
@@ -69,31 +72,25 @@ class TRexCli:
self.results["msg"] = "Failed to reset ports"
return False
- for i, (src, dst) in enumerate(self.params.flows):
- L2 = trex_api.Ether(
- src=str(src["mac_addr"]),
- dst=str(dst["mac_addr"]))
- L3 = trex_api.IP(
- src=str(src["ip_addr"]),
- dst=str(dst["ip_addr"]))
- L4 = trex_api.UDP()
- base_pkt = L2/L3/L4
-
- pad = max(0, self.params.msg_size - len(base_pkt)) * 'x'
- packet = base_pkt/pad
+ module = importlib.import_module('.'.join(["lnst",
"External", "TRex", self.params.module]))
+ stream_generator = module.register()
- trex_packet = trex_api.STLPktBuilder(pkt=packet)
+ for i, (src, dst) in enumerate(self.params.flows):
+ port = self.params.ports[i]
+ modkwargs = {}
+ modkwargs["port_id"] = port
+ modkwargs["msg_size"] = self.params.msg_size
+ modkwargs["src_ip"] = src["ip_addr"]
+ modkwargs["dst_ip"] = dst["ip_addr"]
+ modkwargs["src_mac"] = src["mac_addr"]
+ modkwargs["dst_mac"] = dst["mac_addr"]
- trex_stream = trex_api.STLStream(
- packet=trex_packet,
- mode=trex_api.STLTXCont(percentage=100))
+ trex_streams = stream_generator.get_streams(direction=(port%2), **modkwargs)
- port = self.params.ports[i]
- client.add_streams(trex_stream, ports=[port])
+ client.add_streams(trex_streams, ports=[port])
client.set_port_attr(ports=self.params.ports, promiscuous=True)
-
measurements = []
client.start(ports=self.params.ports)
diff --git a/lnst/External/TRex/UDPSimple.py b/lnst/External/TRex/UDPSimple.py
new file mode 100644
index 0000000..dfa89de
--- /dev/null
+++ b/lnst/External/TRex/UDPSimple.py
@@ -0,0 +1,38 @@
+from trex_stl_lib.api import *
+
+
+class UDPSimple(object):
+ """
+ Generate a simple continuous UDP stream
+ Port MAC and IP addresses are used
+ Extra arguments in kwargs:
+ msg_size: the size of the packet to use (default 64)
+ port_id: The port the stream will be added to
+ """
+
+ def create_stream (self, **kwargs):
+ # Use port's configured mac and ip addresses
+ L2 = Ether()
+ L3 = IP()
+ L4 = UDP()
+
+ size = kwargs.get("msg_size", 64)
+
+ base_pkt = L2/L3/L4
+
+ pad = max(0, size - len(base_pkt)) * 'x'
+ packet = base_pkt/pad
+ trex_packet = STLPktBuilder(pkt=packet)
+
+ return STLStream(
+ packet=trex_packet,
+ mode=STLTXCont(percentage=100))
+
+ def get_streams (self, direction = 0, **kwargs):
+ # create 1 stream
+ return [ self.create_stream(**kwargs) ]
+
+# dynamic load - used for trex console or simulator
+def register():
+ return UDPSimple()
+
--
2.26.2