[NFVBENCH-58] Add option to specify dest MAC with EXT CHAIN when ARP is 57/50057/12
authorMichael Pedersen <michael.soelvkaer@gmail.com>
Wed, 20 Dec 2017 21:38:22 +0000 (14:38 -0700)
committerMichael Pedersen <michaelx.pedersen@intel.com>
Wed, 17 Jan 2018 23:09:32 +0000 (16:09 -0700)
disabled

Change-Id: Ia605d7314d8047e84c5e17088ed5ce588a50e256
Signed-off-by: Michael Pedersen <michael.soelvkaer@gmail.com>
nfvbench/cfg.default.yaml [changed mode: 0644->0755]
nfvbench/nfvbench.py
nfvbench/traffic_client.py [changed mode: 0644->0755]
test/test_nfvbench.py

old mode 100644 (file)
new mode 100755 (executable)
index 07d48f3..e1c05c3
@@ -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,
index 8c88248..18bdc70 100644 (file)
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index 8959cab..57141be
@@ -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]))
index 113ecfd..16784d8 100644 (file)
@@ -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,