diff --git a/scripts/automation/trex_control_plane/interactive/trex/examples/stl/stl_ndr_bench_tool.py b/scripts/automation/trex_control_plane/interactive/trex/examples/stl/stl_ndr_bench_tool.py index 26493129d6..507ec5b7a8 100755 --- a/scripts/automation/trex_control_plane/interactive/trex/examples/stl/stl_ndr_bench_tool.py +++ b/scripts/automation/trex_control_plane/interactive/trex/examples/stl/stl_ndr_bench_tool.py @@ -67,13 +67,13 @@ def ndr_benchmark_test(server='127.0.0.1', pdr=0.1, iteration_duration=20.00, nd # transmitting ports for port_id in dir_0: - streams = STLProfile.load_py(profile, direction=0, port_id=port_id, **profile_tunables).get_streams() + streams = STLProfile.load_py(profile, client=c, direction=0, port_id=port_id, **profile_tunables).get_streams() c.add_streams(streams, ports=dir_0) # if traffic is bi-directional -> add streams to second direction as well. if bi_dir: for port_id in dir_1: - streams = STLProfile.load_py(profile, direction=1, port_id=port_id, **profile_tunables).get_streams() + streams = STLProfile.load_py(profile, client=c, direction=1, port_id=port_id, **profile_tunables).get_streams() c.add_streams(streams, ports=dir_1) config = ndr.NdrBenchConfig(**configs) diff --git a/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_client.py b/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_client.py index 60a351a652..c218838568 100644 --- a/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_client.py @@ -2964,6 +2964,7 @@ def start_line (self, line): profile_name = str(profile) port_id = int(profile) profile = STLProfile.load(opts.file[0], + client = self, direction = port_id % 2, port_id = port_id, **tunable_dict) diff --git a/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_streams.py b/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_streams.py index 999bdfd4da..f8a131920c 100644 --- a/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/interactive/trex/stl/trex_stl_streams.py @@ -1139,7 +1139,7 @@ def get_module_tunables(module): return output @staticmethod - def load_py (python_file, direction = 0, port_id = 0, **kwargs): + def load_py (python_file, client = None, direction = 0, port_id = 0, **kwargs): """ Load from Python profile """ # in case load_py is not being called from stl_client, there is need to convert @@ -1172,6 +1172,7 @@ def load_py (python_file, direction = 0, port_id = 0, **kwargs): try: streams = module.register().get_streams(direction = direction, port_id = port_id, + client = client, **kwargs) except SystemExit: # called ".. -t --help", return None @@ -1385,7 +1386,7 @@ def __pkts_to_streams (pkts, loop_count, vm, packet_hook, start_delay_usec = 0, return profile @staticmethod - def load (filename, direction = 0, port_id = 0, **kwargs): + def load (filename, client = None, direction = 0, port_id = 0, **kwargs): """ Load a profile by its type. Supported types are: * py * json @@ -1402,7 +1403,7 @@ def load (filename, direction = 0, port_id = 0, **kwargs): suffix = x[1] if (len(x) == 2) else None if suffix == 'py': - profile = STLProfile.load_py(filename, direction, port_id, **kwargs) + profile = STLProfile.load_py(filename, client, direction, port_id, **kwargs) elif suffix == 'json': profile = STLProfile.load_json(filename) diff --git a/scripts/stl/l3.py b/scripts/stl/l3.py new file mode 100644 index 0000000000..f2c5846ced --- /dev/null +++ b/scripts/stl/l3.py @@ -0,0 +1,87 @@ +import argparse +import ipaddress + +from trex.common.services.trex_service import Service +from trex.common.services.trex_service_arp import ServiceARP +from trex.common.services.trex_service_IPv6ND import ServiceIPv6ND +from trex_stl_lib.api import * + + +class L3Profile(object): + + def get_streams(self, direction=0, port_id=0, client=None, tunables=(), **kwargs): + if client is None: + raise ValueError("client is None, cannot resolve gateways mac addresses") + parser = argparse.ArgumentParser() + parser.add_argument( + "--left-ip", + type=ipaddress.ip_address, + default=ipaddress.ip_address("172.16.0.1"), + ) + parser.add_argument( + "--left-gw", + type=ipaddress.ip_address, + default=ipaddress.ip_address("172.16.0.254"), + ) + parser.add_argument( + "--right-ip", + type=ipaddress.ip_address, + default=ipaddress.ip_address("172.16.1.1"), + ) + parser.add_argument( + "--right-gw", + type=ipaddress.ip_address, + default=ipaddress.ip_address("172.16.1.254"), + ) + parser.add_argument("--size", type=int, default=60) + args = parser.parse_args(tunables) + + if direction == 0: + src_ip = args.left_ip + gw_ip = args.left_gw + dst_ip = args.right_ip + else: + src_ip = args.right_ip + gw_ip = args.right_gw + dst_ip = args.left_ip + + try: + client.set_service_mode(ports=[port_id], enabled=True) + ctx = client.create_service_ctx(port=port_id) + if dst_ip.version == 4: + resolv = ServiceARP( + ctx, + dst_ip=str(gw_ip), + src_ip=str(src_ip), + verbose_level=Service.INFO, + ) + else: + resolv = ServiceIPv6ND( + ctx, + dst_ip=str(gw_ip), + src_ip=str(src_ip), + verbose_level=Service.INFO, + ) + ctx.run(resolv) + record = resolv.get_record() + if not record: + raise ValueError(f"gateway IP {gw_ip} not resolved") + + gw_mac = record.dst_mac + finally: + client.set_service_mode(ports=[port_id], enabled=False) + + base_pkt = Ether(dst=gw_mac) + if dst_ip.version == 4: + base_pkt /= IP(src=str(src_ip), dst=str(dst_ip)) + else: + base_pkt /= IPv6(src=str(src_ip), dst=str(dst_ip)) + base_pkt /= UDP() + pad = max(0, args.size - len(base_pkt)) * b"x" + pkt = STLPktBuilder(pkt=base_pkt / pad) + + return [STLStream(packet=pkt, mode=STLTXCont())] + + +def register(): + return L3Profile()