+ # get an instance of traffic client
+ self.traffic_client = TrafficClient(config, notifier)
+
+ if self.config.no_traffic:
+ LOG.info('Dry run: traffic generation is disabled')
+ else:
+ # Start the traffic generator server
+ self.traffic_client.start_traffic_generator()
+
+ # get an instance of a chain manager
+ self.chain_manager = ChainManager(self)
+
+ # at this point all resources are setup/discovered
+ # we need to program the traffic dest MAC and VLANs
+ gen_config = self.traffic_client.generator_config
+ if config.vlan_tagging:
+ # VLAN is discovered from the networks
+ gen_config.set_vlans(0, self.chain_manager.get_chain_vlans(0))
+ gen_config.set_vlans(1, self.chain_manager.get_chain_vlans(1))
+
+ # the only case we do not need to set the dest MAC is in the case of
+ # l2-loopback (because the traffic gen will default to use the peer MAC)
+ # or EXT+ARP+VLAN (because dest MAC will be discovered by TRex ARP)
+ # Note that in the case of EXT+ARP+VxLAN, the dest MACs need to be loaded
+ # because ARP only operates on the dest VTEP IP not on the VM dest MAC
+ if not config.l2_loopback and \
+ (config.service_chain != ChainType.EXT or config.no_arp or config.vxlan):
+ gen_config.set_dest_macs(0, self.chain_manager.get_dest_macs(0))
+ gen_config.set_dest_macs(1, self.chain_manager.get_dest_macs(1))
+
+ if config.vxlan:
+ # VXLAN is discovered from the networks
+ vtep_vlan = gen_config.gen_config.vtep_vlan
+ src_vteps = gen_config.gen_config.src_vteps
+ dst_vtep = gen_config.gen_config.dst_vtep
+ gen_config.set_vxlans(0, self.chain_manager.get_chain_vxlans(0))
+ gen_config.set_vxlans(1, self.chain_manager.get_chain_vxlans(1))
+ gen_config.set_vtep_vlan(0, vtep_vlan)
+ gen_config.set_vtep_vlan(1, vtep_vlan)
+ # Configuring source an remote VTEPs on TREx interfaces
+ gen_config.set_vxlan_endpoints(0, src_vteps[0], dst_vtep)
+ gen_config.set_vxlan_endpoints(1, src_vteps[1], dst_vtep)
+ self.config['vxlan_gen_config'] = gen_config
+
+ if config.mpls:
+ # MPLS VPN is discovered from the networks
+ src_vteps = gen_config.gen_config.src_vteps
+ vtep_gateway_ips = gen_config.gen_config.vtep_gateway_ips
+ gen_config.set_mpls_inner_labels(0, self.chain_manager.get_chain_mpls_inner_labels(0))
+ gen_config.set_mpls_inner_labels(1, self.chain_manager.get_chain_mpls_inner_labels(1))
+ outer_mpls_labels_left = self.config.internal_networks.left.mpls_transport_labels
+ outer_mpls_labels_right = self.config.internal_networks.right.mpls_transport_labels
+ if outer_mpls_labels_left or outer_mpls_labels_right:
+ gen_config.set_mpls_outer_labels(0, outer_mpls_labels_left)
+ gen_config.set_mpls_outer_labels(1, outer_mpls_labels_right)
+ # Configuring source an remote VTEPs on TREx interfaces
+ gen_config.set_mpls_peers(0, src_vteps[0], vtep_gateway_ips[0])
+ gen_config.set_mpls_peers(1, src_vteps[1], vtep_gateway_ips[1])
+ self.config['mpls_gen_config'] = gen_config
+
+ # get an instance of the stats manager
+ self.stats_manager = StatsManager(self)
+ LOG.info('ChainRunner initialized')
+
+ def __setup_traffic(self):
+ self.traffic_client.setup()
+ if not self.config.no_traffic:
+ # ARP is needed for EXT chain or VxLAN overlay or MPLS unless disabled explicitly
+ if (self.config.service_chain == ChainType.EXT or self.config.mpls or
+ self.config.vxlan or self.config.l3_router or self.config.loop_vm_arp)\
+ and not self.config.no_arp:
+ self.traffic_client.ensure_arp_successful()
+ self.traffic_client.ensure_end_to_end()
+
+ def __get_result_per_frame_size(self, frame_size, bidirectional):
+ traffic_result = {
+ frame_size: {}
+ }
+ result = {}
+ if not self.config.no_traffic:
+ self.traffic_client.set_traffic(frame_size, bidirectional)