diff options
-rwxr-xr-x[-rw-r--r--] | nfvbench/cfg.default.yaml | 11 | ||||
-rw-r--r-- | nfvbench/nfvbench.py | 19 | ||||
-rwxr-xr-x[-rw-r--r--] | nfvbench/traffic_client.py | 20 | ||||
-rw-r--r-- | test/test_nfvbench.py | 17 |
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, |