summaryrefslogtreecommitdiffstats
path: root/nfvbench/traffic_gen/traffic_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'nfvbench/traffic_gen/traffic_utils.py')
-rw-r--r--nfvbench/traffic_gen/traffic_utils.py160
1 files changed, 160 insertions, 0 deletions
diff --git a/nfvbench/traffic_gen/traffic_utils.py b/nfvbench/traffic_gen/traffic_utils.py
new file mode 100644
index 0000000..e5dc463
--- /dev/null
+++ b/nfvbench/traffic_gen/traffic_utils.py
@@ -0,0 +1,160 @@
+# Copyright 2016 Cisco Systems, Inc. All rights reserved.
+#
+# 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.
+
+
+import bitmath
+from traffic_base import AbstractTrafficGenerator
+
+
+def convert_rates(l2frame_size, rate, intf_speed):
+ avg_packet_size = get_average_packet_size(l2frame_size)
+ if 'rate_pps' in rate:
+ initial_rate_type = 'rate_pps'
+ pps = rate['rate_pps']
+ bps = pps_to_bps(pps, avg_packet_size)
+ load = bps_to_load(bps, intf_speed)
+ elif 'rate_bps' in rate:
+ initial_rate_type = 'rate_bps'
+ bps = rate['rate_bps']
+ load = bps_to_load(bps, intf_speed)
+ pps = bps_to_pps(bps, avg_packet_size)
+ elif 'rate_percent' in rate:
+ initial_rate_type = 'rate_percent'
+ load = rate['rate_percent']
+ bps = load_to_bps(load, intf_speed)
+ pps = bps_to_pps(bps, avg_packet_size)
+ else:
+ raise Exception('Traffic config needs to have a rate type key')
+
+ return {
+ 'initial_rate_type': initial_rate_type,
+ 'rate_pps': pps,
+ 'rate_percent': load,
+ 'rate_bps': bps
+ }
+
+
+def get_average_packet_size(l2frame_size):
+ if l2frame_size.upper() == 'IMIX':
+ return AbstractTrafficGenerator.imix_avg_l2_size
+ else:
+ return float(l2frame_size)
+
+
+def load_to_bps(load_percentage, intf_speed):
+ return float(load_percentage) / 100.0 * intf_speed
+
+
+def bps_to_load(bps, intf_speed):
+ return float(bps) / intf_speed * 100.0
+
+
+def bps_to_pps(bps, avg_packet_size):
+ return float(bps) / (avg_packet_size + 20.0) / 8
+
+
+def pps_to_bps(pps, avg_packet_size):
+ return float(pps) * (avg_packet_size + 20.0) * 8
+
+
+def weighted_avg(weight, count):
+ if sum(weight):
+ return sum(map(lambda x: x[0] * x[1], zip(weight, count))) / sum(weight)
+ else:
+ return float('nan')
+
+multiplier_map = {
+ 'K': 1000,
+ 'M': 1000000,
+ 'G': 1000000000
+}
+
+def parse_rate_str(rate_str):
+ if rate_str.endswith('pps'):
+ rate_pps = rate_str[:-3]
+ if not rate_pps:
+ raise Exception('%s is missing a numeric value' % rate_str)
+ try:
+ multiplier = multiplier_map[rate_pps[-1].upper()]
+ rate_pps = rate_pps[:-1]
+ except KeyError:
+ multiplier = 1
+ rate_pps = int(rate_pps.strip()) * multiplier
+ if rate_pps <= 0:
+ raise Exception('%s is out of valid range' % rate_str)
+ return {'rate_pps': str(rate_pps)}
+ elif rate_str.endswith('ps'):
+ rate = rate_str.replace('ps', '').strip()
+ bit_rate = bitmath.parse_string(rate).bits
+ if bit_rate <= 0:
+ raise Exception('%s is out of valid range' % rate_str)
+ return {'rate_bps': str(int(bit_rate))}
+ elif rate_str.endswith('%'):
+ rate_percent = float(rate_str.replace('%', '').strip())
+ if rate_percent <= 0 or rate_percent > 100.0:
+ raise Exception('%s is out of valid range (must be 1-100%%)' % rate_str)
+ return {'rate_percent': str(rate_percent)}
+ else:
+ raise Exception('Unknown rate string format %s' % rate_str)
+
+
+def divide_rate(rate, divisor):
+ if 'rate_pps' in rate:
+ key = 'rate_pps'
+ value = int(rate[key])
+ elif 'rate_bps' in rate:
+ key = 'rate_bps'
+ value = int(rate[key])
+ else:
+ key = 'rate_percent'
+ value = float(rate[key])
+ value /= divisor
+ rate = dict(rate)
+ rate[key] = str(value) if value else str(1)
+ return rate
+
+
+def to_rate_str(rate):
+ if 'rate_pps' in rate:
+ pps = rate['rate_pps']
+ return '{}pps'.format(pps)
+ elif 'rate_bps' in rate:
+ bps = rate['rate_bps']
+ return '{}bps'.format(bps)
+ elif 'rate_percent' in rate:
+ load = rate['rate_percent']
+ return '{}%'.format(load)
+ else:
+ assert False
+
+
+def nan_replace(d):
+ """Replaces every occurence of 'N/A' with float nan."""
+ for k, v in d.iteritems():
+ if isinstance(v, dict):
+ nan_replace(v)
+ elif v == 'N/A':
+ d[k] = float('nan')
+
+
+def mac_to_int(mac):
+ """Converts MAC address to integer representation."""
+ return int(mac.translate(None, ":.- "), 16)
+
+
+def int_to_mac(i):
+ """Converts integer representation of MAC address to hex string."""
+ mac = format(i, 'x').zfill(12)
+ blocks = [mac[x:x + 2] for x in xrange(0, len(mac), 2)]
+ return ':'.join(blocks)