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
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) rx_port_attr = clt.get_port_attr(rx_port) assert tx_port_attr["src_ipv4"] == "192.168.17.1" assert rx_port_attr["src_ipv4"] == "192.168.18.1" clt.reset(ports=all_ports) clt.add_streams([st], ports=[tx_port]) print(f"Inject {TOTAL_PKTS} packets on port {all_ports[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
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)
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