Exemplo n.º 1
0
def get_streams(pps, duration, ip_tot_len, ip_src, ip_dst):
    udp_data_len = ip_tot_len - IPv4_HDR_LEN - UDP_HDR_LEN
    if udp_data_len < 16:
        raise RuntimeError("The minimal payload size is 16 bytes.")
    print(f"UDP payload size: {udp_data_len}")
    udp_payload = "Z" * udp_data_len
    pkt = STLPktBuilder(pkt=Ether() / IP(src=ip_src, dst=ip_dst) /
                        UDP(dport=8888, sport=9999, chksum=0) / udp_payload)
    streams = [
        STLStream(
            name="s0",
            packet=pkt,
            flow_stats=STLFlowLatencyStats(pg_id=0),
            mode=STLTXSingleBurst(pps=pps, total_pkts=int(duration * pps)),
        )
    ]
    return streams
Exemplo n.º 2
0
    def configure_traffic_stream(self, traffic_flows, nr_of_flows, packet_size,
                                 **kwargs):

        flow_percentage = float(kwargs.pop("percentage", 1000000)) / 10000
        trex_dst_mac = kwargs.pop("traffic_dst_mac", '00:00:02:00:00:00')
        trex_src_mac = kwargs.pop("traffic_src_mac", '00:00:01:00:00:00')
        l2_macs = kwargs.pop("l2_macs", 1)

        #
        # The packet size passed here assumes it includes the checksum, however
        # the TRex packet size does not. Adjust the size to correct this.
        #
        packet_size -= 4

        if traffic_flows == TrafficFlowType.none or \
           self.__traffic_flows != TrafficFlowType.none:
            #
            # We need either a cleanup, or a cleanup before we configure
            # a new traffic flow type
            #
            self._delete_traffic_stream_config()

        if traffic_flows == TrafficFlowType.l2_mac or \
           traffic_flows == TrafficFlowType.l3_ipv4 or \
           traffic_flows == TrafficFlowType.nfv_mobile:

            #
            # Max flows due to IPv4 address limit, and addresses used for tests
            #
            if nr_of_flows > 0x00ffffff:
                raise ValueError(
                    "To many flows requested, max {} supported!".format(
                        0x00ffffff))

            L2 = Ether(src=trex_src_mac, dst=trex_dst_mac)
            L3 = IP(src="1.0.0.0", dst="2.0.0.0")
            L4 = UDP(chksum=0)

            if (len(L2 / L3 / L4) + 4) > packet_size:  # +4 for Ethernet CRC
                raise ValueError("Packet size ({} bytes) too small for"
                                 "requested packet ({} bytes)!".format(
                                     packet_size,
                                     len(L2 / L3 / L4) + 4))

            if traffic_flows == TrafficFlowType.l2_mac:
                src_base = self._mac_2_int(trex_src_mac) & 0xff000000
                dst_base = self._mac_2_int(trex_dst_mac) & 0xff000000
                vm = [
                    # Source MAC address
                    STLVmFlowVar(name="src",
                                 min_value=src_base,
                                 max_value=src_base + nr_of_flows - 1,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="src", pkt_offset=8),

                    # Destination MAC address
                    STLVmFlowVar(name="dst",
                                 min_value=dst_base,
                                 max_value=dst_base + nr_of_flows - 1,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="dst", pkt_offset=2)
                ]

            elif traffic_flows == TrafficFlowType.l3_ipv4:

                src_end = str(
                    netaddr.IPAddress(
                        int(netaddr.IPAddress('1.0.0.0')) + nr_of_flows - 1))
                dst_end = str(
                    netaddr.IPAddress(
                        int(netaddr.IPAddress('2.0.0.0')) + nr_of_flows - 1))

                vm = [
                    # Source IPv4 address
                    STLVmFlowVar(name="src",
                                 min_value="1.0.0.0",
                                 max_value=src_end,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="src", pkt_offset="IP.src"),

                    # Destination IPv4 address
                    STLVmFlowVar(name="dst",
                                 min_value="2.0.0.0",
                                 max_value=dst_end,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="dst", pkt_offset="IP.dst"),

                    # Checksum
                    STLVmFixIpv4(offset="IP")
                ]
            elif traffic_flows == TrafficFlowType.nfv_mobile:

                src_end = str(
                    netaddr.IPAddress(
                        int(netaddr.IPAddress('1.0.0.0')) + nr_of_flows - 1))
                dst_end = str(
                    netaddr.IPAddress(
                        int(netaddr.IPAddress('2.0.0.0')) + nr_of_flows - 1))

                vm = [
                    # Source MAC address
                    STLVmFlowVar(name="srcm",
                                 min_value=0x01000001,
                                 max_value=0x01000001 + l2_macs - 1,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="srcm", pkt_offset=8),

                    # Destination MAC address
                    STLVmFlowVar(name="dstm",
                                 min_value=0x02000000,
                                 max_value=0x02000000 + l2_macs - 1,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="dstm", pkt_offset=2),

                    # Source IPv4 address
                    STLVmFlowVar(name="src",
                                 min_value="1.0.0.0",
                                 max_value=src_end,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="src", pkt_offset="IP.src"),

                    # Destination IPv4 address
                    STLVmFlowVar(name="dst",
                                 min_value="2.0.0.0",
                                 max_value=dst_end,
                                 size=4,
                                 op="inc"),
                    STLVmWrFlowVar(fv_name="dst", pkt_offset="IP.dst"),

                    # Checksum
                    STLVmFixIpv4(offset="IP")
                ]

            else:
                raise ValueError(
                    "Unsupported traffic type for T-Rex tester!!!")

            if traffic_flows == TrafficFlowType.nfv_mobile:
                stream_percentage = flow_percentage / 2
            else:
                stream_percentage = flow_percentage

            headers = L2 / L3 / L4
            padding = max(0, (packet_size - len(headers))) * 'e'
            packet = headers / padding

            trex_packet = STLPktBuilder(pkt=packet, vm=vm)

            trex_stream = STLStream(
                packet=trex_packet,
                mode=STLTXCont(percentage=stream_percentage))

            self.__trex_client.add_streams(trex_stream,
                                           ports=[self.__trex_port])

            #
            # For nfv_mobile we still need to setup the alternating streams.
            #
            if traffic_flows == TrafficFlowType.nfv_mobile:
                alternate_flows = kwargs.pop("alternate_flows", 200000)
                stream_percentage = flow_percentage / 2

                self.__active_alternate_stream = 0
                #
                # Keep the flows the same as for the Xena version, so the
                # traffic scripts using this do not have to differentiate
                # between traffic generator types.
                #
                # The Xena uses streams and every stream can generate 64K
                # flows. To Find the flow start we need the number of base
                # flows rounded of the next 64K (stream) and use the next one.
                #
                # For the individual iterations of the flow set they also
                # need to start at a 64K boundary.
                #
                start_stream_id = self._div_round_up(nr_of_flows, 0x10000) + 1
                for alternate_flow_sets in range(0, 3):
                    flow_start = start_stream_id * 0x10000

                    src_start = str(
                        netaddr.IPAddress(
                            int(netaddr.IPAddress('1.0.0.0')) + flow_start))
                    src_end = str(
                        netaddr.IPAddress(
                            int(netaddr.IPAddress('1.0.0.0')) + flow_start +
                            alternate_flows - 1))
                    dst_start = str(
                        netaddr.IPAddress(
                            int(netaddr.IPAddress('2.0.0.0')) + flow_start))
                    dst_end = str(
                        netaddr.IPAddress(
                            int(netaddr.IPAddress('2.0.0.0')) + flow_start +
                            alternate_flows - 1))

                    vm = [
                        # Source MAC address
                        STLVmFlowVar(name="srcm",
                                     min_value=0x01000001,
                                     max_value=0x01000001 + l2_macs - 1,
                                     size=4,
                                     op="inc"),
                        STLVmWrFlowVar(fv_name="srcm", pkt_offset=8),

                        # Destination MAC address
                        STLVmFlowVar(name="dstm",
                                     min_value=0x02000000,
                                     max_value=0x02000000 + l2_macs - 1,
                                     size=4,
                                     op="inc"),
                        STLVmWrFlowVar(fv_name="dstm", pkt_offset=2),

                        # Source IPv4 address
                        STLVmFlowVar(name="src",
                                     min_value=src_start,
                                     max_value=src_end,
                                     size=4,
                                     op="inc"),
                        STLVmWrFlowVar(fv_name="src", pkt_offset="IP.src"),

                        # Destination IPv4 address
                        STLVmFlowVar(name="dst",
                                     min_value=dst_start,
                                     max_value=dst_end,
                                     size=4,
                                     op="inc"),
                        STLVmWrFlowVar(fv_name="dst", pkt_offset="IP.dst"),

                        # Checksum
                        STLVmFixIpv4(offset="IP")
                    ]
                    trex_packet = STLPktBuilder(pkt=packet, vm=vm)

                    stream = STLStream(
                        packet=trex_packet,
                        mode=STLTXCont(percentage=stream_percentage),
                        start_paused=False
                        if alternate_flow_sets == 0 else True)

                    self.__alternate_stream_sets.append(
                        self.__trex_client.add_streams(
                            stream, ports=[self.__trex_port]))

                    start_stream_id += self._div_round_up(
                        alternate_flows, 0x10000)

            self.__traffic_flows = traffic_flows
            return True
        elif traffic_flows == TrafficFlowType.none:
            self.__traffic_flows = traffic_flows
            return True
        else:
            raise ValueError(
                "Unsupported traffic flow passed for T-Rex tester!")

        self.__traffic_flows = TrafficFlowType.none
        return False
Exemplo n.º 3
0
        f"The average latency: {avg} usecs, total max: {total_max} usecs, jitter: {jitter} usecs"
    )
    print(hist)

    return True


if __name__ == "__main__":
    # Create a client for stateless tests.
    clt = STLClient()
    passed = True

    try:
        udp_payload = "A" * 50
        pkt = STLPktBuilder(
            pkt=Ether() / IP(src="192.168.17.1", dst="192.168.17.2") /
            UDP(dport=8888, sport=9999, chksum=0) / udp_payload)
        st = STLStream(
            name="udp_single_burst",
            packet=pkt,
            # Packet group id
            flow_stats=STLFlowLatencyStats(pg_id=PG_ID),
            mode=STLTXSingleBurst(total_pkts=TOTAL_PKTS, pps=PPS),
        )

        clt.connect()
        all_ports = clt.get_all_ports()
        print("All ports: {}".format(",".join(map(str, all_ports))))
        tx_port, rx_port = all_ports
        print(f"TX port: {tx_port}, RX port: {rx_port}")
        tx_port_attr = clt.get_port_attr(tx_port)
Exemplo n.º 4
0
    TOTAL_PKTS = args.total_pkts
    PPS = args.pps
    MONITOR_DUR = args.monitor_dur

    print(f"Total TX packets: {TOTAL_PKTS}, PPS: {PPS},Monitor duration: {MONITOR_DUR}")

    # Create a client for stateless tests.
    clt = STLClient()
    passed = True

    try:
        udp_payload = "A" * 1400
        if args.eth_src_spoofing:
            pkt = STLPktBuilder(
                pkt=Ether(SPOOFED_ETH_SRC)
                / IP(src=args.ip_src, dst=args.ip_dst)
                / UDP(dport=8888, sport=9999, chksum=0)
                / udp_payload
            )
        else:
            pkt = STLPktBuilder(
                pkt=Ether()
                / IP(src=args.ip_src, dst=args.ip_dst)
                / UDP(dport=8888, sport=9999, chksum=0)
                / udp_payload
            )
        st = STLStream(
            name="udp_single_burst",
            packet=pkt,
            # Packet group id
            flow_stats=STLFlowLatencyStats(pg_id=PG_ID),
            mode=STLTXSingleBurst(total_pkts=TOTAL_PKTS, pps=PPS),
Exemplo n.º 5
0
    def _create_pkt(self, stream_cfg, l2frame_size):
        """Create a packet of given size.

        l2frame_size: size of the L2 frame in bytes (including the 32-bit FCS)
        """
        # Trex will add the FCS field, so we need to remove 4 bytes from the l2 frame size
        frame_size = int(l2frame_size) - 4
        vm_param = []
        if stream_cfg['vxlan'] is True:
            self._bind_vxlan()
            encap_level = '1'
            pkt_base = Ether(src=stream_cfg['vtep_src_mac'], dst=stream_cfg['vtep_dst_mac'])
            if stream_cfg['vtep_vlan'] is not None:
                pkt_base /= Dot1Q(vlan=stream_cfg['vtep_vlan'])
            pkt_base /= IP(src=stream_cfg['vtep_src_ip'], dst=stream_cfg['vtep_dst_ip'])
            pkt_base /= UDP(sport=random.randint(1337, 32767), dport=4789)
            pkt_base /= VXLAN(vni=stream_cfg['net_vni'])
            pkt_base /= Ether(src=stream_cfg['mac_src'], dst=stream_cfg['mac_dst'])
            # need to randomize the outer header UDP src port based on flow
            vxlan_udp_src_fv = STLVmFlowVar(
                name="vxlan_udp_src",
                min_value=1337,
                max_value=32767,
                size=2,
                op="random")
            vm_param = [vxlan_udp_src_fv,
                        STLVmWrFlowVar(fv_name="vxlan_udp_src", pkt_offset="UDP.sport")]
        else:
            encap_level = '0'
            pkt_base = Ether(src=stream_cfg['mac_src'], dst=stream_cfg['mac_dst'])

        if stream_cfg['vlan_tag'] is not None:
            pkt_base /= Dot1Q(vlan=stream_cfg['vlan_tag'])

        udp_args = {}
        if stream_cfg['udp_src_port']:
            udp_args['sport'] = int(stream_cfg['udp_src_port'])
        if stream_cfg['udp_dst_port']:
            udp_args['dport'] = int(stream_cfg['udp_dst_port'])
        pkt_base /= IP() / UDP(**udp_args)

        if stream_cfg['ip_addrs_step'] == 'random':
            src_fv = STLVmFlowVarRepeatableRandom(
                name="ip_src",
                min_value=stream_cfg['ip_src_addr'],
                max_value=stream_cfg['ip_src_addr_max'],
                size=4,
                seed=random.randint(0, 32767),
                limit=stream_cfg['ip_src_count'])
            dst_fv = STLVmFlowVarRepeatableRandom(
                name="ip_dst",
                min_value=stream_cfg['ip_dst_addr'],
                max_value=stream_cfg['ip_dst_addr_max'],
                size=4,
                seed=random.randint(0, 32767),
                limit=stream_cfg['ip_dst_count'])
        else:
            src_fv = STLVmFlowVar(
                name="ip_src",
                min_value=stream_cfg['ip_src_addr'],
                max_value=stream_cfg['ip_src_addr'],
                size=4,
                op="inc",
                step=stream_cfg['ip_addrs_step'])
            dst_fv = STLVmFlowVar(
                name="ip_dst",
                min_value=stream_cfg['ip_dst_addr'],
                max_value=stream_cfg['ip_dst_addr_max'],
                size=4,
                op="inc",
                step=stream_cfg['ip_addrs_step'])

        vm_param.extend([
            src_fv,
            STLVmWrFlowVar(fv_name="ip_src", pkt_offset="IP:{}.src".format(encap_level)),
            dst_fv,
            STLVmWrFlowVar(fv_name="ip_dst", pkt_offset="IP:{}.dst".format(encap_level))
        ])

        for encap in range(int(encap_level), -1, -1):
            # Fixing the checksums for all encap levels
            vm_param.append(STLVmFixChecksumHw(l3_offset="IP:{}".format(encap),
                                               l4_offset="UDP:{}".format(encap),
                                               l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP))
        pad = max(0, frame_size - len(pkt_base)) * 'x'

        return STLPktBuilder(pkt=pkt_base / pad, vm=STLScVmRaw(vm_param))
Exemplo n.º 6
0
def get_streams(
    pps: float, burst_num: int, model: str, src_num, tot_pkts_burst, l3_data, test: bool
) -> list:
    """
    Utilize the single burst stream profile in STL to build the model-based traffic.
    The ONLY focus here is the inter-arrival times of bursts.
    """

    if src_num > 1:
        raise RuntimeError("Currently not implemented!")
    pps = pps * 10 ** 6
    pprint.pp(pps)
    if pps < LATENCY_FLOW_PPS:
        raise RuntimeError(
            f"The minimal PPS {LATENCY_FLOW_PPS} is required for accuracy."
        )

    # Limit the search symbol table to current module.
    func_params = globals().get(f"create_stream_params_{model}", None)
    if not func_params:
        raise RuntimeError(f"Unknown model: {model}!")
    stream_params, flow_duration = func_params(pps, burst_num, src_num, tot_pkts_burst)
    if test:
        print("* Stream parameters: ")
        pprint.pp(stream_params)
        print(f"* Flow duration: {flow_duration} seconds.")

    streams = list()
    for index, param in enumerate(stream_params):
        self_start = False
        next_name = f"s{index+1}"

        if index == 0:
            self_start = True
        elif index == len(stream_params) - 1:
            next_name = None

        udp_payload_len = param["ip_tot_len"] - IPv4_HDR_LEN - UDP_HDR_LEN
        if udp_payload_len < 16:
            raise RuntimeError("The minimal payload size is 16 bytes.")
        udp_payload = "Z" * udp_payload_len
        # UDP checksum is disabled.
        pkt = STLPktBuilder(
            pkt=Ether()
            / IP(src=l3_data["ip_src"], dst=l3_data["ip_dst"])
            / UDP(dport=8888, sport=9999, chksum=0)
            / udp_payload
        )
        streams.append(
            STLStream(
                name=f"s{index}",
                isg=param["isg"] * 10 ** 6,  # TRex interprets them as µs
                packet=pkt,
                flow_stats=STLFlowLatencyStats(pg_id=index),
                mode=STLTXSingleBurst(
                    pps=param["pps"], total_pkts=param["tot_pkts_burst"]
                ),
                next=next_name,
                self_start=self_start,
            )
        )

    return (streams, flow_duration)
Exemplo n.º 7
0
def create_streams_with_second_flow(stream_params: dict,
                                    second_stream_params: dict, ip_src: str,
                                    ip_dst: str) -> list:
    """Create a list of STLStream objects with the second flow."""

    spoofed_eth_srcs = ["0c:42:a1:51:41:d8", "ab:ab:ab:ab:ab:02"]
    udp_payload_size = IP_TOT_LEN - IPv4_HDR_LEN - UDP_HDR_LEN
    if udp_payload_size < 16:
        raise RuntimeError("The minimal payload size is 16 bytes.")
    print(f"UDP payload size: {udp_payload_size}")
    udp_payload = ["Z" * udp_payload_size, "Z" * (udp_payload_size - 1)]
    # UDP checksum is disabled.

    pkts = list()
    pkts.append(
        STLPktBuilder(pkt=Ether(src=spoofed_eth_srcs[0]) /
                      IP(src=ip_src, dst=ip_dst) /
                      UDP(dport=8888, sport=9999, chksum=0) / udp_payload[0]))
    pkts.append(
        STLPktBuilder(pkt=Ether(src=spoofed_eth_srcs[0]) /
                      IP(src=ip_src, dst=ip_dst) /
                      UDP(dport=8888, sport=9999, chksum=0) / udp_payload[1]))

    streams = list()
    pg_id = 0
    for prefix, params in enumerate([stream_params, second_stream_params]):
        print("Prefix: ", prefix)
        for index, stp in enumerate(params):
            next_st_name = None
            next_st_w_name = None
            self_start = False
            if index != len(params) - 1:
                next_st_name = f"s{prefix+1}{index+1}"
                next_st_w_name = f"sw{prefix+1}{index+1}"
            if index == 0:
                self_start = True

            # Add extra workload stream.
            workload_stream_pps = stp["pps"] - LATENCY_FLOW_PPS
            streams.append(
                STLStream(
                    name=f"sw{prefix+1}{index}",
                    isg=stp["isg"],
                    packet=pkts[prefix],
                    mode=STLTXSingleBurst(
                        pps=workload_stream_pps,
                        total_pkts=int(workload_stream_pps * stp["on_time"]),
                    ),
                    next=next_st_w_name,
                    self_start=self_start,
                ))

            # Add latency monitoring flow with a fixed PPS.
            streams.append(
                STLStream(
                    name=f"s{prefix+1}{index}",
                    isg=stp["isg"],
                    packet=pkts[prefix],
                    flow_stats=STLFlowLatencyStats(pg_id=pg_id),  # index),
                    mode=STLTXSingleBurst(
                        pps=LATENCY_FLOW_PPS,
                        total_pkts=int(LATENCY_FLOW_PPS * stp["on_time"]),
                    ),
                    next=next_st_name,
                    self_start=self_start,
                ))
            pg_id += 1

    return streams
Exemplo n.º 8
0
def create_streams(stream_params: dict, ip_src: str, ip_dst: str) -> list:
    """Create a list of STLStream objects."""

    udp_payload_size = IP_TOT_LEN - IPv4_HDR_LEN - UDP_HDR_LEN
    if udp_payload_size < 16:
        raise RuntimeError("The minimal payload size is 16 bytes.")
    print(f"UDP payload size: {udp_payload_size}")
    udp_payload = "Z" * udp_payload_size
    # UDP checksum is disabled.
    pkt = STLPktBuilder(pkt=Ether() / IP(src=ip_src, dst=ip_dst) /
                        UDP(dport=8888, sport=9999, chksum=0) / udp_payload)

    streams = list()

    # Ref: https://trex-tgn.cisco.com/trex/doc/trex_stateless.html#_tutorial_per_stream_latency_jitter_packet_errors

    # Latency streams are handled fully by software and do not support at full
    # line rate like normal streams. Typically, it is sufficient to have a
    # low-rate latency stream alongside with the real workload stream.
    # In order to have a latency resolution of 1usec, it is not necessary to
    # send a latency stream at a speed higher than 1 MPPS. It is suggested not
    # make the total rate of latency streams higher than 5 MPPS.

    for index, stp in enumerate(stream_params):
        next_st_name = None
        next_st_w_name = None
        self_start = False
        if index != len(stream_params) - 1:
            next_st_name = f"s{index+1}"
            next_st_w_name = f"sw{index+1}"
        if index == 0:
            self_start = True

        # Add extra workload stream.
        workload_stream_pps = stp["pps"] - LATENCY_FLOW_PPS
        streams.append(
            STLStream(
                name=f"sw{index}",
                isg=stp["isg"],
                packet=pkt,
                mode=STLTXSingleBurst(
                    pps=workload_stream_pps,
                    total_pkts=int(workload_stream_pps * stp["on_time"]),
                ),
                next=next_st_w_name,
                self_start=self_start,
            ))

        # Add latency monitoring flow with a fixed PPS.
        streams.append(
            STLStream(
                name=f"s{index}",
                isg=stp["isg"],
                packet=pkt,
                flow_stats=STLFlowLatencyStats(pg_id=index),
                mode=STLTXSingleBurst(
                    pps=LATENCY_FLOW_PPS,
                    total_pkts=int(LATENCY_FLOW_PPS * stp["on_time"]),
                ),
                next=next_st_name,
                self_start=self_start,
            ))

    return streams