4 ## Copyright (c) 2010-2020 Intel Corporation
6 ## Licensed under the Apache License, Version 2.0 (the "License");
7 ## you may not use this file except in compliance with the License.
8 ## You may obtain a copy of the License at
10 ## http://www.apache.org/licenses/LICENSE-2.0
12 ## Unless required by applicable law or agreed to in writing, software
13 ## distributed under the License is distributed on an "AS IS" BASIS,
14 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ## See the License for the specific language governing permissions and
16 ## limitations under the License.
19 from rapid_log import RapidLog
20 from prox_ctrl import prox_ctrl
21 from rapid_machine import RapidMachine
22 from math import ceil, log2
25 class RandomPortBits(object):
27 Class to generate PROX bitmaps for random bit generation
28 in source & dst UPD ports to emulate mutiple flows
31 def get_bitmap(flow_number):
32 number_of_random_bits = ceil(log2(flow_number))
33 if number_of_random_bits > 30:
34 raise Exception("Not able to support that many flows")
35 # throw exeption since we need the first bit to be 1
36 # Otherwise, the randomization could results in all 0's
37 # and that might be an invalid UDP port and result in
38 # packets begin discarded
39 src_number_of_random_bits = number_of_random_bits // 2
40 dst_number_of_random_bits = number_of_random_bits - src_number_of_random_bits
41 src_port_bitmap = '1000000000000000'.replace ('0','X',src_number_of_random_bits)
42 dst_port_bitmap = '1000000000000000'.replace ('0','X',dst_number_of_random_bits)
43 return [src_port_bitmap, dst_port_bitmap]
45 class RapidGeneratorMachine(RapidMachine):
47 Class to deal with rapid configuration files
50 return (self.machine_params['gencores'] + self.machine_params['latcores'])
52 def generate_lua(self, vim):
53 appendix = 'gencores="%s"\n'% ','.join(map(str, self.machine_params['gencores']))
54 appendix = appendix + 'latcores="%s"\n'% ','.join(map(str, self.machine_params['latcores']))
55 if 'gw_vm' in self.machine_params.keys():
56 for index, gw_ip in enumerate(self.machine_params['gw_ips'], start = 1):
57 appendix = appendix + 'gw_ip{}="{}"\n'.format(index, gw_ip)
58 appendix = appendix + 'gw_hex_ip{}="{}"\n'.format(index, self.ip2hex(gw_ip))
59 if 'bucket_size_exp' in self.machine_params.keys():
60 self.bucket_size_exp = self.machine_params['bucket_size_exp']
62 self.bucket_size_exp = 11
63 appendix = appendix + 'bucket_size_exp="{}"\n'.format(self.bucket_size_exp)
64 if 'heartbeat' in self.machine_params.keys():
65 appendix = appendix + 'heartbeat="%s"\n'% self.machine_params['heartbeat']
67 appendix = appendix + 'heartbeat="60"\n'
68 super().generate_lua(vim, appendix)
71 # Start the generator with the -e option so that the cores don't
73 super().start_prox('-e')
75 def set_generator_speed(self, speed):
76 # The assumption is that we only use task 0 for generating
77 # We should check the gen.cfg file to make sure there is only task=0
78 speed_per_gen_core = speed / len(self.machine_params['gencores'])
79 self.socket.speed(speed_per_gen_core, self.machine_params['gencores'])
81 def set_udp_packet_size(self, imix_frame_sizes):
82 # We should check the gen.cfg to make sure we only send UDP packets
83 # If only 1 packet size, still using the 'old' way of setting the
84 # packet sizes in PROX. Otherwise, using the 'new' way which
85 # automatically sets IP and UDP sizes. We should switch to the new way
86 # eventually for all cases.
87 if len(imix_frame_sizes) == 1:
88 # Frame size = PROX pkt size + 4 bytes CRC
89 # The set_size function takes the PROX packet size as a parameter
90 self.socket.set_size(self.machine_params['gencores'], 0,
91 imix_frame_sizes[0] - 4)
92 # 18 is the difference between the frame size and IP size =
93 # size of (MAC addresses, ethertype and FCS)
94 self.socket.set_value(self.machine_params['gencores'], 0, 16,
95 imix_frame_sizes[0] - 18, 2)
96 # 38 is the difference between the frame size and UDP size =
97 # 18 + size of IP header (=20)
98 self.socket.set_value(self.machine_params['gencores'], 0, 38,
99 imix_frame_sizes[0] - 38, 2)
101 prox_sizes = [frame_size - 4 for frame_size in imix_frame_sizes]
102 self.socket.set_imix(self.machine_params['gencores'], 0,
105 def set_flows(self, number_of_flows):
106 source_port,destination_port = RandomPortBits.get_bitmap(
108 self.socket.set_random(self.machine_params['gencores'],0,34,
110 self.socket.set_random(self.machine_params['gencores'],0,36,
113 def start_gen_cores(self):
114 self.socket.start(self.machine_params['gencores'])
116 def stop_gen_cores(self):
117 self.socket.stop(self.machine_params['gencores'])
119 def start_latency_cores(self):
120 self.socket.start(self.machine_params['latcores'])
122 def stop_latency_cores(self):
123 self.socket.stop(self.machine_params['latcores'])
126 # Checking all tasks in the cfg file. In this way, we can have more
127 # latency tasks on the same core
128 return (self.socket.lat_stats(self.machine_params['latcores'],
129 self.all_tasks_for_this_cfg))