summaryrefslogtreecommitdiffstats
path: root/nfvbench
diff options
context:
space:
mode:
Diffstat (limited to 'nfvbench')
-rw-r--r--nfvbench/chain_runner.py12
-rw-r--r--nfvbench/nfvbench.py17
-rw-r--r--nfvbench/stats_manager.py4
-rw-r--r--nfvbench/summarizer.py6
-rw-r--r--nfvbench/traffic_gen/traffic_base.py14
-rw-r--r--nfvbench/traffic_gen/traffic_utils.py16
-rw-r--r--nfvbench/traffic_gen/trex.py37
7 files changed, 53 insertions, 53 deletions
diff --git a/nfvbench/chain_runner.py b/nfvbench/chain_runner.py
index c120501..876fec2 100644
--- a/nfvbench/chain_runner.py
+++ b/nfvbench/chain_runner.py
@@ -90,13 +90,13 @@ class ChainRunner(object):
self.traffic_client.ensure_arp_successful()
self.traffic_client.ensure_end_to_end()
- def __get_result_per_frame_size(self, frame_size, actual_frame_size, bidirectional):
+ 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(actual_frame_size, bidirectional)
+ self.traffic_client.set_traffic(frame_size, bidirectional)
if self.config.single_run:
result = self.stats_manager.run_fixed_rate()
@@ -105,9 +105,6 @@ class ChainRunner(object):
for dr in ['pdr', 'ndr']:
if dr in results:
- if frame_size != actual_frame_size:
- results[dr]['l2frame_size'] = frame_size
- results[dr]['actual_l2frame_size'] = actual_frame_size
traffic_result[frame_size][dr] = results[dr]
if 'warning' in results[dr]['stats'] and results[dr]['stats']['warning']:
traffic_result['warning'] = results[dr]['stats']['warning']
@@ -117,8 +114,6 @@ class ChainRunner(object):
result['run_config'] = self.traffic_client.get_run_config(result)
required = result['run_config']['direction-total']['orig']['rate_pps']
actual = result['stats']['total_tx_rate']
- if frame_size != actual_frame_size:
- result['actual_l2frame_size'] = actual_frame_size
warning = self.traffic_client.compare_tx_rates(required, actual)
if warning is not None:
result['run_config']['warning'] = warning
@@ -128,9 +123,8 @@ class ChainRunner(object):
def __get_chain_result(self):
result = OrderedDict()
- for fs, actual_fs in zip(self.config.frame_sizes, self.config.actual_frame_sizes):
+ for fs in self.config.frame_sizes:
result.update(self.__get_result_per_frame_size(fs,
- actual_fs,
self.config.traffic.bidirectional))
chain_result = {
'flow_count': self.config.flow_count,
diff --git a/nfvbench/nfvbench.py b/nfvbench/nfvbench.py
index 933d6fa..0d6da7f 100644
--- a/nfvbench/nfvbench.py
+++ b/nfvbench/nfvbench.py
@@ -90,18 +90,19 @@ class NFVBench(object):
self.factory,
self.notifier)
new_frame_sizes = []
- min_packet_size = "68" if self.config.vlan_tagging else "64"
+ # make sure that the min frame size is 64
+ min_packet_size = 64
for frame_size in self.config.frame_sizes:
try:
- if int(frame_size) < int(min_packet_size):
- new_frame_sizes.append(min_packet_size)
- LOG.info("Adjusting frame size %s Bytes to minimum size %s Bytes due to " +
- "traffic generator restriction", frame_size, min_packet_size)
- else:
+ if int(frame_size) < min_packet_size:
+ frame_size = str(min_packet_size)
+ LOG.info("Adjusting frame size %s bytes to minimum size %s bytes",
+ frame_size, min_packet_size)
+ if frame_size not in new_frame_sizes:
new_frame_sizes.append(frame_size)
except ValueError:
- new_frame_sizes.append(frame_size)
- self.config.actual_frame_sizes = tuple(new_frame_sizes)
+ new_frame_sizes.append(frame_size.upper())
+ self.config.frame_sizes = new_frame_sizes
result = {
"date": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
"nfvbench_version": __version__,
diff --git a/nfvbench/stats_manager.py b/nfvbench/stats_manager.py
index a1fb497..98ac413 100644
--- a/nfvbench/stats_manager.py
+++ b/nfvbench/stats_manager.py
@@ -73,9 +73,9 @@ class StatsManager(object):
def _update_interface_stats(self, diff=False):
"""Update interface stats for both the traffic generator and the worker."""
- self.traffic_client.update_interface_stats(diff=True)
+ self.traffic_client.update_interface_stats(diff)
if self.worker:
- self.worker.update_interface_stats(diff=True)
+ self.worker.update_interface_stats(diff)
def run_fixed_rate(self):
"""Run a fixed rate and analyze results."""
diff --git a/nfvbench/summarizer.py b/nfvbench/summarizer.py
index 0d84ab2..f03d3bc 100644
--- a/nfvbench/summarizer.py
+++ b/nfvbench/summarizer.py
@@ -350,12 +350,6 @@ class NFVBenchSummarizer(Summarizer):
def __chain_analysis_summarize(self, frame_size, analysis):
self._put()
self._put('L2 frame size:', frame_size)
- if 'actual_l2frame_size' in analysis:
- self._put('Actual l2 frame size:', analysis['actual_l2frame_size'])
- elif self.config['ndr_run'] and 'actual_l2frame_size' in analysis['ndr']:
- self._put('Actual l2 frame size:', analysis['ndr']['actual_l2frame_size'])
- elif self.config['pdr_run'] and 'actual_l2frame_size' in analysis['pdr']:
- self._put('Actual l2 frame size:', analysis['pdr']['actual_l2frame_size'])
if self.config['ndr_run']:
self._put('NDR search duration:', Formatter.float(0)(analysis['ndr']['time_taken_sec']),
'seconds')
diff --git a/nfvbench/traffic_gen/traffic_base.py b/nfvbench/traffic_gen/traffic_base.py
index 459af0f..0360591 100644
--- a/nfvbench/traffic_gen/traffic_base.py
+++ b/nfvbench/traffic_gen/traffic_base.py
@@ -18,6 +18,7 @@ import sys
from nfvbench.log import LOG
import traffic_utils
+
class Latency(object):
"""A class to hold latency data."""
@@ -50,14 +51,11 @@ class TrafficGeneratorException(Exception):
class AbstractTrafficGenerator(object):
+
def __init__(self, traffic_client):
self.traffic_client = traffic_client
self.generator_config = traffic_client.generator_config
self.config = traffic_client.config
- self.imix_l2_sizes = [64, 594, 1518]
- self.imix_ratios = [7, 4, 1]
- self.imix_avg_l2_size = 0
- self.adjust_imix_min_size(64)
@abc.abstractmethod
def get_version(self):
@@ -134,11 +132,3 @@ class AbstractTrafficGenerator(object):
return: a list of speed in Gbps indexed by the port#
"""
pass
-
- def adjust_imix_min_size(self, min_size):
- # assume the min size is always the first entry
- self.imix_l2_sizes[0] = min_size
- self.imix_avg_l2_size = sum(
- [1.0 * imix[0] * imix[1] for imix in zip(self.imix_l2_sizes, self.imix_ratios)]) / sum(
- self.imix_ratios)
- traffic_utils.imix_avg_l2_size = self.imix_avg_l2_size
diff --git a/nfvbench/traffic_gen/traffic_utils.py b/nfvbench/traffic_gen/traffic_utils.py
index c3428a4..f856267 100644
--- a/nfvbench/traffic_gen/traffic_utils.py
+++ b/nfvbench/traffic_gen/traffic_utils.py
@@ -16,13 +16,18 @@
import bitmath
from nfvbench.utils import multiplier_map
-imix_avg_l2_size = None
+# IMIX frame size including the 4-byte FCS field
+IMIX_L2_SIZES = [64, 594, 1518]
+IMIX_RATIOS = [7, 4, 1]
+# weighted average l2 frame size includng the 4-byte FCS
+IMIX_AVG_L2_FRAME_SIZE = sum(
+ [1.0 * imix[0] * imix[1] for imix in zip(IMIX_L2_SIZES, IMIX_RATIOS)]) / sum(IMIX_RATIOS)
def convert_rates(l2frame_size, rate, intf_speed):
"""Convert a given rate unit into the other rate units.
- l2frame_size: size of the L2 frame in bytes or 'IMIX'
+ l2frame_size: size of the L2 frame in bytes (includes 32-bit FCS) or 'IMIX'
rate: a dict that has at least one of the following key:
'rate_pps', 'rate_bps', 'rate_percent'
with the corresponding input value
@@ -59,8 +64,13 @@ def convert_rates(l2frame_size, rate, intf_speed):
def get_average_packet_size(l2frame_size):
+ """Retrieve the average L2 frame size
+
+ l2frame_size: an L2 frame size in bytes (including FCS) or 'IMIX'
+ return: average l2 frame size inlcuding the 32-bit FCS
+ """
if l2frame_size.upper() == 'IMIX':
- return imix_avg_l2_size
+ return IMIX_AVG_L2_FRAME_SIZE
return float(l2frame_size)
diff --git a/nfvbench/traffic_gen/trex.py b/nfvbench/traffic_gen/trex.py
index 6aec57d..6bb0c34 100644
--- a/nfvbench/traffic_gen/trex.py
+++ b/nfvbench/traffic_gen/trex.py
@@ -27,6 +27,9 @@ from nfvbench.utils import TimeoutError
from traffic_base import AbstractTrafficGenerator
from traffic_base import TrafficGeneratorException
import traffic_utils as utils
+from traffic_utils import IMIX_AVG_L2_FRAME_SIZE
+from traffic_utils import IMIX_L2_SIZES
+from traffic_utils import IMIX_RATIOS
# pylint: disable=import-error
from trex_stl_lib.api import CTRexVmInsFixHwCs
@@ -245,15 +248,17 @@ class TRex(AbstractTrafficGenerator):
results['avg_delay_usec'] = int(average / self.chain_count)
def _create_pkt(self, stream_cfg, l2frame_size):
+ """Create a packet of given size.
+
+ l2frame_size: size of the L2 frame in bytes (including the 32-bit FCS)
+ """
+ # Trex will add the FCS field, so we need to remove 4 bytes from the l2 frame size
+ frame_size = int(l2frame_size) - 4
+
pkt_base = Ether(src=stream_cfg['mac_src'], dst=stream_cfg['mac_dst'])
if stream_cfg['vlan_tag'] is not None:
- # 50 = 14 (Ethernet II) + 4 (Vlan tag) + 4 (CRC Checksum) + 20 (IPv4) + 8 (UDP)
pkt_base /= Dot1Q(vlan=stream_cfg['vlan_tag'])
- l2payload_size = int(l2frame_size) - 50
- else:
- # 46 = 14 (Ethernet II) + 4 (CRC Checksum) + 20 (IPv4) + 8 (UDP)
- l2payload_size = int(l2frame_size) - 46
- payload = 'x' * l2payload_size
+
udp_args = {}
if stream_cfg['udp_src_port']:
udp_args['sport'] = int(stream_cfg['udp_src_port'])
@@ -301,8 +306,9 @@ class TRex(AbstractTrafficGenerator):
l4_offset="UDP",
l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP)
]
+ pad = max(0, frame_size - len(pkt_base)) * 'x'
- return STLPktBuilder(pkt=pkt_base / payload, vm=STLScVmRaw(vm_param))
+ return STLPktBuilder(pkt=pkt_base / pad, vm=STLScVmRaw(vm_param))
def generate_streams(self, port, chain_id, stream_cfg, l2frame, latency=True):
"""Create a list of streams corresponding to a given chain and stream config.
@@ -310,15 +316,13 @@ class TRex(AbstractTrafficGenerator):
port: port where the streams originate (0 or 1)
chain_id: the chain to which the streams are associated to
stream_cfg: stream configuration
- l2frame: L2 frame size
+ l2frame: L2 frame size (including 4-byte FCS) or 'IMIX'
latency: if True also create a latency stream
"""
streams = []
pg_id, lat_pg_id = self.get_pg_id(port, chain_id)
if l2frame == 'IMIX':
- min_size = 64 if stream_cfg['vlan_tag'] is None else 68
- self.adjust_imix_min_size(min_size)
- for ratio, l2_frame_size in zip(self.imix_ratios, self.imix_l2_sizes):
+ for ratio, l2_frame_size in zip(IMIX_RATIOS, IMIX_L2_SIZES):
pkt = self._create_pkt(stream_cfg, l2_frame_size)
streams.append(STLStream(packet=pkt,
flow_stats=STLFlowStats(pg_id=pg_id),
@@ -326,13 +330,20 @@ class TRex(AbstractTrafficGenerator):
if latency:
# for IMIX, the latency packets have the average IMIX packet size
- pkt = self._create_pkt(stream_cfg, self.imix_avg_l2_size)
+ pkt = self._create_pkt(stream_cfg, IMIX_AVG_L2_FRAME_SIZE)
else:
- pkt = self._create_pkt(stream_cfg, l2frame)
+ l2frame_size = int(l2frame)
+ pkt = self._create_pkt(stream_cfg, l2frame_size)
streams.append(STLStream(packet=pkt,
flow_stats=STLFlowStats(pg_id=pg_id),
mode=STLTXCont()))
+ # for the latency stream, the minimum payload is 16 bytes even in case of vlan tagging
+ # without vlan, the min l2 frame size is 64
+ # with vlan it is 68
+ # This only applies to the latency stream
+ if latency and stream_cfg['vlan_tag'] and l2frame_size < 68:
+ pkt = self._create_pkt(stream_cfg, 68)
if latency:
streams.append(STLStream(packet=pkt,