def generate_packets(self): """ generate packets from trex TG """ base_pkt = self.base_pkt size = self.fsize - 4 pad = max(0, size - len(base_pkt)) * 'x' self.packets = [STLPktBuilder(pkt=base_pkt / pad, vm=vm) for vm in self.vms]
def get_pkt_type(self): """ Get packet description. Example: IP:UDP """ if self.packet_desc is None: self.packet_desc = STLPktBuilder.pkt_layers_desc_from_buffer( self.get_pkt()) return self.packet_desc
def create_stream(self): return STLStream( packet=STLPktBuilder( pkt=Ether()/IP(src="16.0.0.1", dst="48.0.0.1")/UDP(dport=12, sport=1025)/(10*'x')), mode=STLTXCont())
def generate_loaded_streams_sum(self, sync=True): if self.state == self.STATE_DOWN: return {} if sync: self.sync_streams() data = OrderedDict() for id in sorted(map(int, self.streams.keys())): obj = self.streams[str(id)] obj['pkt_len'] = len(obj['pkt']) + 4 if obj['dummy']: obj['pkt_type'] = 'Dummy' obj['pkt_len'] = '-' if 'pkt_type' not in obj: # lazy build scapy repr. obj['pkt_type'] = STLPktBuilder.pkt_layers_desc_from_buffer( obj['pkt']) data[id] = OrderedDict([('id', id), ('packet_type', obj['pkt_type']), ('L2 len', obj['pkt_len']), ('mode', obj['mode']), ('rate', obj['rate']), ('next_stream', obj['next_id'] if obj['next_id'] != '-1' else 'None') ]) return {"streams": data}
def stl_send_3_pkts(client, ports=None): base_pkt = STLPktBuilder(pkt=Ether() / IP()) stream = STLStream(packet=base_pkt, mode=STLTXSingleBurst(pps=100000, total_pkts=3)) client.reset(ports) client.add_streams(stream, ports) client.start(ports, mult="5%") client.wait_on_traffic(ports) client.remove_all_streams(ports)
def _create_stream(self, src_ip, dst_ip): base_frame = \ Pkt.Ether() / Pkt.IP(src=src_ip, dst=dst_ip) / Pkt.UDP(dport=12, sport=1025) frame_size = self.params["traffic_profile"]["frame_size"] pad_size = max(0, frame_size - len(base_frame)) frame = base_frame / ("x" * max(0, pad_size)) frame_rate = self.params["traffic_profile"]["frame_rate"] return STLStream(packet=STLPktBuilder(pkt=frame), mode=STLTXCont(pps=frame_rate))
def _create_single_packet(self, size=64): size = size - 4 ether_packet = self.ether_packet ip_packet = self.ip6_packet if self.ip6_packet else self.ip_packet udp_packet = self.udp_packet if self.qinq: qinq_packet = self.qinq_packet base_pkt = ether_packet / qinq_packet / ip_packet / udp_packet else: base_pkt = ether_packet / ip_packet / udp_packet pad = max(0, size - len(base_pkt)) * 'x' packet = STLPktBuilder(pkt=base_pkt / pad, vm=self.trex_vm) return packet
def __parse_packet(self, packet_dict): packet_type = set(packet_dict).intersection(['binary', 'pcap']) if len(packet_type) != 1: raise STLError( "Packet section must contain either 'binary' or 'pcap'") if 'binary' in packet_type: try: pkt_str = base64.b64decode(packet_dict['binary']) except TypeError: raise STLError("'binary' field is not a valid packet format") builder = STLPktBuilder(pkt_buffer=pkt_str) elif 'pcap' in packet_type: pcap = os.path.join(self.yaml_path, packet_dict['pcap']) if not os.path.exists(pcap): raise STLError("'pcap' - cannot find '{0}'".format(pcap)) builder = STLPktBuilder(pkt=pcap) return builder
def __init__( self, name=None, packet=None, mode=STLTXCont(pps=1), enabled=True, self_start=True, isg=0.0, flow_stats=None, next=None, stream_id=None, action_count=0, random_seed=0, mac_src_override_by_pkt=None, mac_dst_override_mode=None, # see STLStreamDstMAC_xx dummy_stream=False): """ Stream object :parameters: name : string Name of the stream. Required if this stream is dependent on another stream, and another stream needs to refer to this stream by name. packet : STLPktBuilder see :class: `trex_stl_lib.trex_stl_packet_builder_scapy.STLPktBuilder` Template packet and field engine program. Example: packet = STLPktBuilder(pkt = base_pkt/pad) mode : :class:`trex_stl_lib.trex_stl_streams.STLTXCont` or : class:`trex_stl_lib.trex_stl_streams.STLTXSingleBurst` or : class:`trex_stl_lib.trex_stl_streams.STLTXMultiBurst` enabled : bool Indicates whether the stream is enabled. self_start : bool If False, another stream activates it. isg : float Inter-stream gap in usec. Time to wait until the stream sends the first packet. flow_stats : :class:`trex_stl_lib.trex_stl_streams.STLFlowStats` Per stream statistic object. See: STLFlowStats next : string Name of the stream to activate. stream_id : For use by HLTAPI. action_count : uint16_t If there is a next stream, number of loops before stopping. Default: 0(unlimited). random_seed: uint16_t If given, the seed for this stream will be this value. Useful if you need a deterministic random value. mac_src_override_by_pkt : bool Template packet sets src MAC. mac_dst_override_mode=None : STLStreamDstMAC_xx Template packet sets dst MAC. dummy_stream : bool For delay purposes, will not be sent. """ # type checking validate_type('mode', mode, STLTXMode) validate_type('packet', packet, (type(None), CTrexPktBuilderInterface)) validate_type('flow_stats', flow_stats, (type(None), STLFlowStatsInterface)) validate_type('enabled', enabled, bool) validate_type('self_start', self_start, bool) validate_type('isg', isg, (int, float)) validate_type('stream_id', stream_id, (type(None), int)) validate_type('random_seed', random_seed, int) validate_type('dummy_stream', dummy_stream, bool) if (type(mode) == STLTXCont) and (next is not None): raise STLError("Continuous stream cannot have a next stream ID") # tag for the stream and next - can be anything self.name = name self.next = next # save for easy construct code from stream object self.mac_src_override_by_pkt = mac_src_override_by_pkt self.mac_dst_override_mode = mac_dst_override_mode self.id = stream_id self.fields = {} int_mac_src_override_by_pkt = 0 int_mac_dst_override_mode = 0 if mac_src_override_by_pkt is None: int_mac_src_override_by_pkt = 0 if packet: if packet.is_default_src_mac() is False: int_mac_src_override_by_pkt = 1 else: int_mac_src_override_by_pkt = int(mac_src_override_by_pkt) if mac_dst_override_mode is None: int_mac_dst_override_mode = 0 if packet: if packet.is_default_dst_mac() is False: int_mac_dst_override_mode = STLStreamDstMAC_PKT else: int_mac_dst_override_mode = int(mac_dst_override_mode) self.is_default_mac = not (int_mac_src_override_by_pkt or int_mac_dst_override_mode) self.fields['flags'] = (int_mac_src_override_by_pkt & 1) + \ ((int_mac_dst_override_mode & 3) << 1) + (int(dummy_stream) << 3) self.fields['action_count'] = action_count # basic fields self.fields['enabled'] = enabled self.fields['self_start'] = self_start self.fields['isg'] = isg if random_seed != 0: self.fields['random_seed'] = random_seed # optional # mode self.fields['mode'] = mode.to_json() self.mode_desc = str(mode) # packet self.fields['packet'] = {} self.fields['vm'] = {} if not packet: packet = STLPktBuilder(pkt=Ether() / IP()) if dummy_stream: self.packet_desc = 'Dummy' self.scapy_pkt_builder = packet # packet builder packet.compile() # packet and VM self.fields['packet'] = packet.dump_pkt() self.fields['vm'] = packet.get_vm_data() self.pkt = base64.b64decode(self.fields['packet']['binary']) # this is heavy, calculate lazy self.packet_desc = None if not flow_stats: self.fields['flow_stats'] = STLFlowStats.defaults() else: self.fields['flow_stats'] = flow_stats.to_json()
def __pkts_to_streams(pkts, loop_count, vm, packet_hook, start_delay_usec=0, end_delay_usec=0): streams = [] if packet_hook: pkts = [(packet_hook(cap), meta) for (cap, meta) in pkts] last_ts = 0 for i, (cap, ts) in enumerate(pkts, start=1): isg = ts - last_ts last_ts = ts # handle last packet if i == len(pkts): if end_delay_usec: next = 'delay_stream' action_count = 0 streams.append( STLStream(name='delay_stream', mode=STLTXSingleBurst(total_pkts=1, percentage=100), self_start=False, isg=end_delay_usec, action_count=loop_count, dummy_stream=True, next=1)) else: next = 1 action_count = loop_count else: next = i + 1 action_count = 0 if i == 1: streams.append( STLStream( name=1, packet=STLPktBuilder(pkt_buffer=cap, vm=vm), mode=STLTXSingleBurst(total_pkts=1, percentage=100), self_start=True, isg=isg + start_delay_usec, # usec action_count=action_count, next=next)) else: streams.append( STLStream( name=i, packet=STLPktBuilder(pkt_buffer=cap, vm=vm), mode=STLTXSingleBurst(total_pkts=1, percentage=100), self_start=False, isg=isg, # usec action_count=action_count, next=next)) profile = STLProfile(streams) profile.meta = {'type': 'pcap'} return profile
def stl_map_ports(client, ports=None): # by default use all ports if ports is None: ports = client.get_all_ports() client.acquire(ports, force=True, sync_streams=False) unresolved_ports = list_difference(ports, client.get_resolved_ports()) if unresolved_ports: raise STLError( "Port(s) {0} have unresolved destination addresses".format( unresolved_ports)) stl_send_3_pkts(client, ports) PKTS_SENT = 5 pgid_per_port = {} active_pgids_tmp = client.get_active_pgids() active_pgids = [] for key in list(active_pgids_tmp.keys()): active_pgids += active_pgids_tmp[key] base_pkt = Ether() / IP() / UDP() / ('x' * 18) test_pgid = 10000000 # add latency packet per checked port for port in ports: for i in range(3): while test_pgid in active_pgids: test_pgid += 1 stream = STLStream(packet=STLPktBuilder(pkt=base_pkt), flow_stats=STLFlowLatencyStats(pg_id=test_pgid), mode=STLTXSingleBurst(pps=1e4, total_pkts=PKTS_SENT)) try: client.add_streams(stream, [port]) except STLError: continue pgid_per_port[port] = test_pgid test_pgid += 1 break if len(pgid_per_port) != len(ports): raise STLError('Could not add flow stats streams per port.') # inject client.clear_stats(ports, clear_global=False, clear_flow_stats=True, clear_latency_stats=False, clear_xstats=False) client.start(ports, mult="5%") client.wait_on_traffic(ports) stats = client.get_pgid_stats(list(pgid_per_port.values()))['flow_stats'] # cleanup client.reset(ports) table = {'map': {}, 'bi': [], 'unknown': []} # actual mapping for tx_port in ports: table['map'][tx_port] = None for rx_port in ports: if stats[pgid_per_port[tx_port]]['rx_pkts'][ rx_port] * 2 > PKTS_SENT: table['map'][tx_port] = rx_port unmapped = list(ports) while len(unmapped) > 0: port_a = unmapped.pop(0) port_b = table['map'][port_a] # if unknown - add to the unknown list if port_b is None: table['unknown'].append(port_a) # self-loop, due to bug? elif port_a == port_b: continue # bi-directional ports elif (table['map'][port_b] == port_a): unmapped.remove(port_b) table['bi'].append((port_a, port_b)) return table