import traceback
from itertools import count
+# pylint: disable=import-error
+from scapy.contrib.mpls import MPLS # flake8: noqa
+# pylint: enable=import-error
from nfvbench.log import LOG
from nfvbench.traffic_server import TRexTrafficServer
from nfvbench.utils import cast_integer
from nfvbench.utils import timeout
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.common.services.trex_service_arp import ServiceARP
from trex.stl.api import UDP
from trex.stl.api import XByteField
-
# pylint: enable=import-error
+from .traffic_base import AbstractTrafficGenerator
+from .traffic_base import TrafficGeneratorException
+from . 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
+
class VXLAN(Packet):
"""VxLAN class."""
op="random")
vm_param = [vxlan_udp_src_fv,
STLVmWrFlowVar(fv_name="vxlan_udp_src", pkt_offset="UDP.sport")]
+ elif stream_cfg['mpls'] is True:
+ encap_level = '0'
+ pkt_base = Ether(src=stream_cfg['vtep_src_mac'], dst=stream_cfg['vtep_dst_mac'])
+ if stream_cfg['vtep_vlan'] is not None:
+ pkt_base /= Dot1Q(vlan=stream_cfg['vtep_vlan'])
+ if stream_cfg['mpls_outer_label'] is not None:
+ pkt_base /= MPLS(label=stream_cfg['mpls_outer_label'], cos=1, s=0, ttl=255)
+ if stream_cfg['mpls_inner_label'] is not None:
+ pkt_base /= MPLS(label=stream_cfg['mpls_inner_label'], cos=1, s=1, ttl=255)
+ # Flow stats and MPLS labels randomization TBD
+ pkt_base /= Ether(src=stream_cfg['mac_src'], dst=stream_cfg['mac_dst'])
else:
encap_level = '0'
pkt_base = Ether(src=stream_cfg['mac_src'], dst=stream_cfg['mac_dst'])
udp_args = {}
if stream_cfg['udp_src_port']:
udp_args['sport'] = int(stream_cfg['udp_src_port'])
+ udp_args['sport_step'] = int(stream_cfg['udp_port_step'])
+ udp_args['sport_max'] = int(stream_cfg['udp_src_port_max'])
if stream_cfg['udp_dst_port']:
udp_args['dport'] = int(stream_cfg['udp_dst_port'])
- pkt_base /= IP() / UDP(**udp_args)
+ udp_args['dport_step'] = int(stream_cfg['udp_port_step'])
+ udp_args['dport_max'] = int(stream_cfg['udp_dst_port_max'])
+ pkt_base /= IP(src=stream_cfg['ip_src_addr'], dst=stream_cfg['ip_dst_addr']) / \
+ UDP(dport=udp_args['dport'], sport=udp_args['sport'])
+ if stream_cfg['ip_src_static'] is True:
+ src_max_ip_value = stream_cfg['ip_src_addr']
+ else:
+ src_max_ip_value = stream_cfg['ip_src_addr_max']
if stream_cfg['ip_addrs_step'] == 'random':
- src_fv = STLVmFlowVarRepeatableRandom(
+ src_fv_ip = STLVmFlowVarRepeatableRandom(
name="ip_src",
min_value=stream_cfg['ip_src_addr'],
- max_value=stream_cfg['ip_src_addr_max'],
+ max_value=src_max_ip_value,
size=4,
seed=random.randint(0, 32767),
limit=stream_cfg['ip_src_count'])
- dst_fv = STLVmFlowVarRepeatableRandom(
+ dst_fv_ip = STLVmFlowVarRepeatableRandom(
name="ip_dst",
min_value=stream_cfg['ip_dst_addr'],
max_value=stream_cfg['ip_dst_addr_max'],
seed=random.randint(0, 32767),
limit=stream_cfg['ip_dst_count'])
else:
- src_fv = STLVmFlowVar(
+ src_fv_ip = STLVmFlowVar(
name="ip_src",
min_value=stream_cfg['ip_src_addr'],
- max_value=stream_cfg['ip_src_addr'],
+ max_value=src_max_ip_value,
size=4,
op="inc",
step=stream_cfg['ip_addrs_step'])
- dst_fv = STLVmFlowVar(
+ dst_fv_ip = STLVmFlowVar(
name="ip_dst",
min_value=stream_cfg['ip_dst_addr'],
max_value=stream_cfg['ip_dst_addr_max'],
op="inc",
step=stream_cfg['ip_addrs_step'])
- vm_param.extend([
- src_fv,
+ if stream_cfg['udp_port_step'] == 'random':
+ src_fv_port = STLVmFlowVarRepeatableRandom(
+ name="p_src",
+ min_value=udp_args['sport'],
+ max_value=udp_args['sport_max'],
+ size=2,
+ seed=random.randint(0, 32767),
+ limit=udp_args['udp_src_count'])
+ dst_fv_port = STLVmFlowVarRepeatableRandom(
+ name="p_dst",
+ min_value=udp_args['dport'],
+ max_value=udp_args['dport_max'],
+ size=2,
+ seed=random.randint(0, 32767),
+ limit=stream_cfg['udp_dst_count'])
+ else:
+ src_fv_port = STLVmFlowVar(
+ name="p_src",
+ min_value=udp_args['sport'],
+ max_value=udp_args['sport_max'],
+ size=2,
+ op="inc",
+ step=udp_args['sport_step'])
+ dst_fv_port = STLVmFlowVar(
+ name="p_dst",
+ min_value=udp_args['dport'],
+ max_value=udp_args['dport_max'],
+ size=2,
+ op="inc",
+ step=udp_args['dport_step'])
+ vm_param = [
+ src_fv_ip,
STLVmWrFlowVar(fv_name="ip_src", pkt_offset="IP:{}.src".format(encap_level)),
- dst_fv,
- STLVmWrFlowVar(fv_name="ip_dst", pkt_offset="IP:{}.dst".format(encap_level))
- ])
-
- for encap in range(int(encap_level), -1, -1):
- # Fixing the checksums for all encap levels
- vm_param.append(STLVmFixChecksumHw(l3_offset="IP:{}".format(encap),
- l4_offset="UDP:{}".format(encap),
- l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP))
+ src_fv_port,
+ STLVmWrFlowVar(fv_name="p_src", pkt_offset="UDP:{}.sport".format(encap_level)),
+ dst_fv_ip,
+ STLVmWrFlowVar(fv_name="ip_dst", pkt_offset="IP:{}.dst".format(encap_level)),
+ dst_fv_port,
+ STLVmWrFlowVar(fv_name="p_dst", pkt_offset="UDP:{}.dport".format(encap_level)),
+ STLVmFixChecksumHw(l3_offset="IP:{}".format(encap_level),
+ l4_offset="UDP:{}".format(encap_level),
+ l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP)
+ ]
pad = max(0, frame_size - len(pkt_base)) * 'x'
return STLPktBuilder(pkt=pkt_base / pad,
"""
streams = []
pg_id, lat_pg_id = self.get_pg_id(port, chain_id)
+ if self.config.no_flow_stats:
+ LOG.info("Traffic flow statistics are disabled.")
if l2frame == 'IMIX':
for ratio, l2_frame_size in zip(IMIX_RATIOS, IMIX_L2_SIZES):
pkt = self._create_pkt(stream_cfg, l2_frame_size)
- if e2e:
+ if e2e or stream_cfg['mpls']:
streams.append(STLStream(packet=pkt,
mode=STLTXCont(pps=ratio)))
else:
if stream_cfg['vxlan'] is True:
streams.append(STLStream(packet=pkt,
flow_stats=STLFlowStats(pg_id=pg_id,
- vxlan=True),
+ vxlan=True)
+ if not self.config.no_flow_stats else None,
mode=STLTXCont(pps=ratio)))
else:
streams.append(STLStream(packet=pkt,
- flow_stats=STLFlowStats(pg_id=pg_id),
+ flow_stats=STLFlowStats(pg_id=pg_id)
+ if not self.config.no_flow_stats else None,
mode=STLTXCont(pps=ratio)))
if latency:
else:
l2frame_size = int(l2frame)
pkt = self._create_pkt(stream_cfg, l2frame_size)
- if e2e:
+ if e2e or stream_cfg['mpls']:
streams.append(STLStream(packet=pkt,
+ # Flow stats is disabled for MPLS now
+ # flow_stats=STLFlowStats(pg_id=pg_id),
mode=STLTXCont()))
else:
if stream_cfg['vxlan'] is True:
streams.append(STLStream(packet=pkt,
flow_stats=STLFlowStats(pg_id=pg_id,
- vxlan=True),
+ vxlan=True)
+ if not self.config.no_flow_stats else None,
mode=STLTXCont()))
else:
streams.append(STLStream(packet=pkt,
- flow_stats=STLFlowStats(pg_id=pg_id),
+ flow_stats=STLFlowStats(pg_id=pg_id)
+ if not self.config.no_flow_stats else None,
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
pkt = self._create_pkt(stream_cfg, 68)
if latency:
+ if self.config.no_latency_stats:
+ LOG.info("Latency flow statistics are disabled.")
if stream_cfg['vxlan'] is True:
streams.append(STLStream(packet=pkt,
flow_stats=STLFlowLatencyStats(pg_id=lat_pg_id,
- vxlan=True),
+ vxlan=True)
+ if not self.config.no_latency_stats else None,
mode=STLTXCont(pps=self.LATENCY_PPS)))
else:
streams.append(STLStream(packet=pkt,
- flow_stats=STLFlowLatencyStats(pg_id=lat_pg_id),
+ flow_stats=STLFlowLatencyStats(pg_id=lat_pg_id)
+ if not self.config.no_latency_stats else None,
mode=STLTXCont(pps=self.LATENCY_PPS)))
return streams
def __connect_after_start(self):
# after start, Trex may take a bit of time to initialize
# so we need to retry a few times
- for it in xrange(self.config.generic_retry_count):
+ for it in range(self.config.generic_retry_count):
try:
time.sleep(1)
self.client.connect()
except Exception as ex:
if it == (self.config.generic_retry_count - 1):
raise
- LOG.info("Retrying connection to TRex (%s)...", ex.message)
+ LOG.info("Retrying connection to TRex (%s)...", ex.msg)
def connect(self):
"""Connect to the TRex server."""
if os.path.isfile(logpath):
# Wait for TRex to finish writing error message
last_size = 0
- for _ in xrange(self.config.generic_retry_count):
+ for _ in range(self.config.generic_retry_count):
size = os.path.getsize(logpath)
if size == last_size:
# probably not writing anymore
LOG.info("Restarting TRex ...")
self.__stop_server()
# Wait for server stopped
- for _ in xrange(self.config.generic_retry_count):
+ for _ in range(self.config.generic_retry_count):
time.sleep(1)
if not self.client.is_connected():
LOG.info("TRex is stopped...")
self.client.release(ports=ports)
self.client.server_shutdown()
except STLError as e:
- LOG.warn('Unable to stop TRex. Error: %s', e)
+ LOG.warning('Unable to stop TRex. Error: %s', e)
else:
LOG.info('Using remote TRex. Unable to stop TRex')
dst_macs = [None] * chain_count
dst_macs_count = 0
# the index in the list is the chain id
- if self.config.vxlan:
+ if self.config.vxlan or self.config.mpls:
arps = [
ServiceARP(ctx,
src_ip=device.vtep_src_ip,
arp_dest_macs[port] = dst_macs
LOG.info('ARP resolved successfully for port %s', port)
break
- else:
- retry = attempt + 1
- LOG.info('Retrying ARP for: %s (retry %d/%d)',
- unresolved, retry, self.config.generic_retry_count)
- if retry < self.config.generic_retry_count:
- time.sleep(self.config.generic_poll_sec)
+
+ retry = attempt + 1
+ LOG.info('Retrying ARP for: %s (retry %d/%d)',
+ unresolved, retry, self.config.generic_retry_count)
+ if retry < self.config.generic_retry_count:
+ time.sleep(self.config.generic_poll_sec)
else:
LOG.error('ARP timed out for port %s (resolved %d out of %d)',
port,
bpf_filter = "ether dst %s or ether dst %s" % (src_mac_list[0], src_mac_list[1])
# ports must be set in service in order to enable capture
self.client.set_service_mode(ports=self.port_handle)
- self.capture_id = self.client.start_capture(rx_ports=self.port_handle,
- bpf_filter=bpf_filter)
+ self.capture_id = self.client.start_capture \
+ (rx_ports=self.port_handle, bpf_filter=bpf_filter)
def fetch_capture_packets(self):
"""Fetch capture packets in capture mode."""