summaryrefslogtreecommitdiffstats
path: root/VNFs/DPPD-PROX/helper-scripts/rapid/rapid_generator_machine.py
diff options
context:
space:
mode:
Diffstat (limited to 'VNFs/DPPD-PROX/helper-scripts/rapid/rapid_generator_machine.py')
-rw-r--r--VNFs/DPPD-PROX/helper-scripts/rapid/rapid_generator_machine.py181
1 files changed, 181 insertions, 0 deletions
diff --git a/VNFs/DPPD-PROX/helper-scripts/rapid/rapid_generator_machine.py b/VNFs/DPPD-PROX/helper-scripts/rapid/rapid_generator_machine.py
new file mode 100644
index 00000000..e52b17db
--- /dev/null
+++ b/VNFs/DPPD-PROX/helper-scripts/rapid/rapid_generator_machine.py
@@ -0,0 +1,181 @@
+#!/usr/bin/python
+
+##
+## Copyright (c) 2020 Intel Corporation
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+
+from rapid_log import RapidLog
+from rapid_machine import RapidMachine
+from math import ceil, log2
+
+
+class RandomPortBits(object):
+ """
+ Class to generate PROX bitmaps for random bit generation
+ in source & dst UPD ports to emulate mutiple flows
+ """
+ @staticmethod
+ def get_bitmap(flow_number):
+ number_of_random_bits = ceil(log2(flow_number))
+ if number_of_random_bits > 30:
+ raise Exception("Not able to support that many flows")
+ # throw exeption since we need the first bit to be 1
+ # Otherwise, the randomization could results in all 0's
+ # and that might be an invalid UDP port and result in
+ # packets being discarded
+ src_number_of_random_bits = number_of_random_bits // 2
+ dst_number_of_random_bits = (number_of_random_bits -
+ src_number_of_random_bits)
+ src_port_bitmap = '1000000000000000'.replace ('0','X',
+ src_number_of_random_bits)
+ dst_port_bitmap = '1000000000000000'.replace ('0','X',
+ dst_number_of_random_bits)
+ return [src_port_bitmap, dst_port_bitmap, 1 << number_of_random_bits]
+
+class RapidGeneratorMachine(RapidMachine):
+ """
+ Class to deal with a generator PROX instance (VM, bare metal, container)
+ """
+ def __init__(self, key, user, password, vim, rundir, resultsdir,
+ machine_params, configonly, ipv6):
+ mac_address_size = 6
+ ethertype_size = 2
+ FCS_size = 4
+ if ipv6:
+ ip_header_size = 40
+ self.ip_length_offset = 18
+ # In IPV6, the IP size is the size of the IP content
+ self.frame_size_minus_ip_size = (2 * mac_address_size +
+ ethertype_size + ip_header_size + FCS_size)
+ else:
+ ip_header_size = 20
+ self.ip_length_offset = 16
+ # In IPV4, the IP size is the size of the IP header + IP content
+ self.frame_size_minus_ip_size = (2 * mac_address_size +
+ ethertype_size + FCS_size)
+ self.frame_size_minus_udp_header_and_content = (2 * mac_address_size +
+ ethertype_size + ip_header_size + FCS_size )
+ udp_header_start_offset = (2 * mac_address_size + ethertype_size +
+ ip_header_size)
+ self.udp_source_port_offset = udp_header_start_offset
+ self.udp_dest_port_offset = udp_header_start_offset + 2
+ self.udp_length_offset = udp_header_start_offset + 4
+ self.ipv6 = ipv6
+ if 'bucket_size_exp' in machine_params.keys():
+ self.bucket_size_exp = machine_params['bucket_size_exp']
+ else:
+ self.bucket_size_exp = 11
+ super().__init__(key, user, password, vim, rundir, resultsdir,
+ machine_params, configonly)
+
+ def get_cores(self):
+ return (self.machine_params['gencores'] +
+ self.machine_params['latcores'])
+
+ def remap_all_cpus(self):
+ """Convert relative cpu ids for different parameters (gencores, latcores)
+ """
+ super().remap_all_cpus()
+
+ if self.cpu_mapping is None:
+ return
+
+ if 'gencores' in self.machine_params.keys():
+ cpus_remapped = super().remap_cpus(self.machine_params['gencores'])
+ RapidLog.debug('{} ({}): gencores {} remapped to {}'.format(self.name, self.ip, self.machine_params['gencores'], cpus_remapped))
+ self.machine_params['gencores'] = cpus_remapped
+
+ if 'latcores' in self.machine_params.keys():
+ cpus_remapped = super().remap_cpus(self.machine_params['latcores'])
+ RapidLog.debug('{} ({}): latcores {} remapped to {}'.format(self.name, self.ip, self.machine_params['latcores'], cpus_remapped))
+ self.machine_params['latcores'] = cpus_remapped
+
+ def generate_lua(self):
+ appendix = 'gencores="%s"\n'% ','.join(map(str,
+ self.machine_params['gencores']))
+ appendix = appendix + 'latcores="%s"\n'% ','.join(map(str,
+ self.machine_params['latcores']))
+ appendix = (appendix +
+ 'bucket_size_exp="{}"\n'.format(self.bucket_size_exp))
+ if 'heartbeat' in self.machine_params.keys():
+ appendix = (appendix +
+ 'heartbeat="%s"\n'% self.machine_params['heartbeat'])
+ else:
+ appendix = appendix + 'heartbeat="60"\n'
+ super().generate_lua(appendix)
+
+ def start_prox(self):
+ # Start the generator with the -e option so that the cores don't
+ # start automatically
+ super().start_prox('-e')
+
+ def set_generator_speed(self, speed):
+ # The assumption is that we only use task 0 for generating
+ # We should check the gen.cfg file to make sure there is only task=0
+ speed_per_gen_core = speed / len(self.machine_params['gencores'])
+ self.socket.speed(speed_per_gen_core, self.machine_params['gencores'])
+
+ def set_udp_packet_size(self, imix_frame_sizes):
+ # We should check the gen.cfg to make sure we only send UDP packets
+ # If only 1 packet size, still using the 'old' way of setting the
+ # packet sizes in PROX. Otherwise, using the 'new' way which
+ # automatically sets IP and UDP sizes. We should switch to the new way
+ # eventually for all cases.
+ if len(imix_frame_sizes) == 1:
+ # Frame size = PROX pkt size + 4 bytes CRC
+ # The set_size function takes the PROX packet size as a parameter
+ self.socket.set_size(self.machine_params['gencores'], 0,
+ imix_frame_sizes[0] - 4)
+ # Writing length in the ip header
+ self.socket.set_value(self.machine_params['gencores'], 0,
+ self.ip_length_offset, imix_frame_sizes[0] -
+ self.frame_size_minus_ip_size, 2)
+ # Writing length in the udp header
+ self.socket.set_value(self.machine_params['gencores'], 0,
+ self.udp_length_offset, imix_frame_sizes[0] -
+ self.frame_size_minus_udp_header_and_content, 2)
+ else:
+ if self.ipv6:
+ RapidLog.critical('IMIX not supported for IPV6')
+ prox_sizes = [frame_size - 4 for frame_size in imix_frame_sizes]
+ self.socket.set_imix(self.machine_params['gencores'], 0,
+ prox_sizes)
+
+ def set_flows(self, number_of_flows):
+ source_port, destination_port, actualflows = RandomPortBits.get_bitmap(
+ number_of_flows)
+ self.socket.set_random(self.machine_params['gencores'],0,
+ self.udp_source_port_offset, source_port,2)
+ self.socket.set_random(self.machine_params['gencores'],0,
+ self.udp_dest_port_offset, destination_port,2)
+ return actualflows
+
+ def start_gen_cores(self):
+ self.socket.start(self.machine_params['gencores'])
+
+ def stop_gen_cores(self):
+ self.socket.stop(self.machine_params['gencores'])
+
+ def start_latency_cores(self):
+ self.socket.start(self.machine_params['latcores'])
+
+ def stop_latency_cores(self):
+ self.socket.stop(self.machine_params['latcores'])
+
+ def lat_stats(self):
+ # Checking all tasks in the cfg file. In this way, we can have more
+ # latency tasks on the same core
+ return (self.socket.lat_stats(self.machine_params['latcores'],
+ self.all_tasks_for_this_cfg))