summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]nfvbench/cfg.default.yaml11
-rw-r--r--nfvbench/nfvbench.py19
-rwxr-xr-x[-rw-r--r--]nfvbench/traffic_client.py20
-rw-r--r--test/test_nfvbench.py17
4 files changed, 57 insertions, 10 deletions
diff --git a/nfvbench/cfg.default.yaml b/nfvbench/cfg.default.yaml
index 07d48f3..e1c05c3 100644..100755
--- a/nfvbench/cfg.default.yaml
+++ b/nfvbench/cfg.default.yaml
@@ -156,6 +156,15 @@ traffic_generator:
# `gateway_ip_addrs_step`: step for generating router gateway sequences. default is 0.0.0.1
# `udp_src_port`: the source port for sending UDP traffic, default is picked by TRex (53)
# `udp_dst_port`: the destination port for sending UDP traffic, default is picked by TRex (53)
+ # `mac_addrs_left` & `mac_addrs_right`: Lists of MAC addresses corresponding to the number of chains
+ # specified for `service_chain_count`.
+ # - If both lists are empty the far end MAC of the traffic generator will be used for left and right
+ # - The MAC addresses will only be used when `service_chain` is EXT and `no_arp` is true.
+ # - The length of each list must match the number of chains being used.
+ # - The index of each list must correspond to the chain index to ensure proper pairing.
+ # - Below is an example of using two chains:
+ # - mac_addrs_left: ['00:00:00:00:01:00', '00:00:00:00:02:00']
+ # - mac_addrs_right: ['00:00:00:00:01:01', '00:00:00:00:02:01']
ip_addrs: ['10.0.0.0/8', '20.0.0.0/8']
ip_addrs_step: 0.0.0.1
tg_gateway_ip_addrs: ['1.1.0.100', '2.2.0.100']
@@ -164,6 +173,8 @@ traffic_generator:
gateway_ip_addrs_step: 0.0.0.1
udp_src_port:
udp_dst_port:
+ mac_addrs_left:
+ mac_addrs_right:
# Traffic Generator Profiles
# In case you have multiple testbeds or traffic generators,
diff --git a/nfvbench/nfvbench.py b/nfvbench/nfvbench.py
index 8c88248..18bdc70 100644
--- a/nfvbench/nfvbench.py
+++ b/nfvbench/nfvbench.py
@@ -164,6 +164,25 @@ class NFVBench(object):
self.config.duration_sec = float(self.config.duration_sec)
self.config.interval_sec = float(self.config.interval_sec)
+ # Check length of mac_addrs_left/right for serivce_chain EXT with no_arp
+ if self.config.service_chain == ChainType.EXT and self.config.no_arp:
+ if not (self.config.generator_config.mac_addrs_left is None and
+ self.config.generator_config.mac_addrs_right is None):
+ if (self.config.generator_config.mac_addrs_left is None or
+ self.config.generator_config.mac_addrs_right is None):
+ raise Exception("mac_addrs_left and mac_addrs_right must either "
+ "both be None or have a number of entries matching "
+ "service_chain_count")
+ if not (len(self.config.generator_config.mac_addrs_left) ==
+ self.config.service_chain_count and
+ len(self.config.generator_config.mac_addrs_right) ==
+ self.config.service_chain_count):
+ raise Exception("length of mac_addrs_left ({a}) and/or mac_addrs_right ({b}) "
+ "does not match service_chain_count ({c})"
+ .format(a=len(self.config.generator_config.mac_addrs_left),
+ b=len(self.config.generator_config.mac_addrs_right),
+ c=self.config.service_chain_count))
+
# Get traffic generator profile config
if not self.config.generator_profile:
self.config.generator_profile = self.config.traffic_generator.default_profile
diff --git a/nfvbench/traffic_client.py b/nfvbench/traffic_client.py
index 8959cab..57141be 100644..100755
--- a/nfvbench/traffic_client.py
+++ b/nfvbench/traffic_client.py
@@ -13,6 +13,7 @@
# under the License.
from datetime import datetime
+import re
import socket
import struct
import time
@@ -122,7 +123,7 @@ class Device(object):
def __init__(self, port, pci, switch_port=None, vtep_vlan=None, ip=None, tg_gateway_ip=None,
gateway_ip=None, ip_addrs_step=None, tg_gateway_ip_addrs_step=None,
gateway_ip_addrs_step=None, udp_src_port=None, udp_dst_port=None,
- chain_count=1, flow_count=1, vlan_tagging=False):
+ dst_mac=None, chain_count=1, flow_count=1, vlan_tagging=False):
self.chain_count = chain_count
self.flow_count = flow_count
self.dst = None
@@ -133,6 +134,7 @@ class Device(object):
self.vlan_tagging = vlan_tagging
self.pci = pci
self.mac = None
+ self.dst_mac = dst_mac
self.vm_mac_list = None
subnet = IPNetwork(ip)
self.ip = subnet.ip.format()
@@ -189,10 +191,16 @@ class Device(object):
for chain_idx in xrange(self.chain_count):
src_ip_first, src_ip_last = self.ip_block.reserve_ip_range(cur_chain_flow_count)
dst_ip_first, dst_ip_last = self.dst.ip_block.reserve_ip_range(cur_chain_flow_count)
+
+ dst_mac = self.dst_mac[chain_idx] if self.dst_mac is not None else self.dst.mac
+ if not re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", dst_mac.lower()):
+ raise TrafficClientException("Invalid MAC address '{mac}' specified in "
+ "mac_addrs_left/right".format(mac=dst_mac))
+
configs.append({
'count': cur_chain_flow_count,
'mac_src': self.mac,
- 'mac_dst': self.dst.mac if service_chain == ChainType.EXT else self.vm_mac_list[
+ 'mac_dst': dst_mac if service_chain == ChainType.EXT else self.vm_mac_list[
chain_idx],
'ip_src_addr': src_ip_first,
'ip_src_addr_max': src_ip_last,
@@ -270,6 +278,8 @@ class RunningTrafficProfile(object):
self.src_device = None
self.dst_device = None
self.vm_mac_list = None
+ self.mac_addrs_left = generator_config.mac_addrs_left
+ self.mac_addrs_right = generator_config.mac_addrs_right
self.__prep_interfaces(generator_config)
def to_json(self):
@@ -305,7 +315,8 @@ class RunningTrafficProfile(object):
'tg_gateway_ip_addrs_step': self.tg_gateway_ip_addrs_step,
'udp_src_port': generator_config.udp_src_port,
'udp_dst_port': generator_config.udp_dst_port,
- 'vlan_tagging': self.vlan_tagging
+ 'vlan_tagging': self.vlan_tagging,
+ 'dst_mac': generator_config.mac_addrs_left
}
dst_config = {
'chain_count': self.service_chain_count,
@@ -318,7 +329,8 @@ class RunningTrafficProfile(object):
'tg_gateway_ip_addrs_step': self.tg_gateway_ip_addrs_step,
'udp_src_port': generator_config.udp_src_port,
'udp_dst_port': generator_config.udp_dst_port,
- 'vlan_tagging': self.vlan_tagging
+ 'vlan_tagging': self.vlan_tagging,
+ 'dst_mac': generator_config.mac_addrs_right
}
self.src_device = Device(**dict(src_config, **generator_config.interfaces[0]))
diff --git a/test/test_nfvbench.py b/test/test_nfvbench.py
index 113ecfd..16784d8 100644
--- a/test/test_nfvbench.py
+++ b/test/test_nfvbench.py
@@ -465,11 +465,12 @@ def check_config(configs, cc, fc, src_ip, dst_ip, step_ip):
assert cfc == fc
-def create_device(fc, cc, ip, gip, tggip, step_ip):
+def create_device(fc, cc, ip, gip, tggip, step_ip, mac):
return Device(0, 0, flow_count=fc, chain_count=cc, ip=ip, gateway_ip=gip, tg_gateway_ip=tggip,
ip_addrs_step=step_ip,
tg_gateway_ip_addrs_step=step_ip,
- gateway_ip_addrs_step=step_ip)
+ gateway_ip_addrs_step=step_ip,
+ dst_mac=mac)
def check_device_flow_config(step_ip):
@@ -479,8 +480,9 @@ def check_device_flow_config(step_ip):
ip1 = '20.0.0.0'
tggip = '50.0.0.0'
gip = '60.0.0.0'
- dev0 = create_device(fc, cc, ip0, gip, tggip, step_ip)
- dev1 = create_device(fc, cc, ip1, gip, tggip, step_ip)
+ mac = ['00:11:22:33:44:55'] * cc
+ dev0 = create_device(fc, cc, ip0, gip, tggip, step_ip, mac)
+ dev1 = create_device(fc, cc, ip1, gip, tggip, step_ip, mac)
dev0.set_destination(dev1)
configs = dev0.get_stream_configs(ChainType.EXT)
check_config(configs, cc, fc, ip0, ip1, step_ip)
@@ -495,8 +497,9 @@ def test_device_ip_range():
def ip_range_overlaps(ip0, ip1, flows):
tggip = '50.0.0.0'
gip = '60.0.0.0'
- dev0 = create_device(flows, 10, ip0, gip, tggip, '0.0.0.1')
- dev1 = create_device(flows, 10, ip1, gip, tggip, '0.0.0.1')
+ mac = ['00:11:22:33:44:55'] * 10
+ dev0 = create_device(flows, 10, ip0, gip, tggip, '0.0.0.1', mac)
+ dev1 = create_device(flows, 10, ip1, gip, tggip, '0.0.0.1', mac)
dev0.set_destination(dev1)
return dev0.ip_range_overlaps()
@@ -609,6 +612,8 @@ def get_dummy_tg_config(chain_type, rate):
'tg_gateway_ip_addrs_step': '0.0.0.1',
'gateway_ip_addrs': ['1.1.0.2', '2.2.0.2'],
'gateway_ip_addrs_step': '0.0.0.1',
+ 'mac_addrs_left': None,
+ 'mac_addrs_right': None,
'udp_src_port': None,
'udp_dst_port': None},
'service_chain': chain_type,