pkt_gen: Add support for generating GENEVE frames
[vswitchperf.git] / vswitches / ovs_dpdk_vhost.py
index 154d535..447ce09 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2016 Intel Corporation.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 """VSPERF VSwitch implementation using DPDK and vhost ports
 """
 
 """VSPERF VSwitch implementation using DPDK and vhost ports
 """
 
+import logging
 from conf import settings
 from vswitches.vswitch import IVSwitch
 from src.ovs import VSwitchd, OFBridge
 from src.dpdk import dpdk
 
 from conf import settings
 from vswitches.vswitch import IVSwitch
 from src.ovs import VSwitchd, OFBridge
 from src.dpdk import dpdk
 
-_VSWITCHD_CONST_ARGS = ['--', '--log-file']
+_VSWITCHD_CONST_ARGS = ['--', '--pidfile', '--log-file']
 
 class OvsDpdkVhost(IVSwitch):
     """VSwitch implementation using DPDK and vhost ports
 
 class OvsDpdkVhost(IVSwitch):
     """VSwitch implementation using DPDK and vhost ports
@@ -33,11 +34,18 @@ class OvsDpdkVhost(IVSwitch):
     implementation. For generic information of the nature of the methods,
     see the interface.
     """
     implementation. For generic information of the nature of the methods,
     see the interface.
     """
+
+    _logger = logging.getLogger()
+
     def __init__(self):
         vswitchd_args = ['--dpdk']
         vswitchd_args += settings.getValue('VSWITCHD_DPDK_ARGS')
         vswitchd_args += _VSWITCHD_CONST_ARGS
 
     def __init__(self):
         vswitchd_args = ['--dpdk']
         vswitchd_args += settings.getValue('VSWITCHD_DPDK_ARGS')
         vswitchd_args += _VSWITCHD_CONST_ARGS
 
+        if settings.getValue('VNF').endswith('Cuse'):
+            self._logger.info("Inserting VHOST Cuse modules into kernel...")
+            dpdk.insert_vhost_modules()
+
         self._vswitchd = VSwitchd(vswitchd_args=vswitchd_args,
                                   expected_cmd=
                                   r'EAL: Master l*core \d+ is ready')
         self._vswitchd = VSwitchd(vswitchd_args=vswitchd_args,
                                   expected_cmd=
                                   r'EAL: Master l*core \d+ is ready')
@@ -58,12 +66,19 @@ class OvsDpdkVhost(IVSwitch):
         """
         self._vswitchd.kill()
         dpdk.cleanup()
         """
         self._vswitchd.kill()
         dpdk.cleanup()
+        dpdk.remove_vhost_modules()
 
 
-    def add_switch(self, switch_name):
+    def add_switch(self, switch_name, params=None):
         """See IVswitch for general description
         """
         bridge = OFBridge(switch_name)
         """See IVswitch for general description
         """
         bridge = OFBridge(switch_name)
-        bridge.create()
+        if params is None:
+            bridge.create(['--', 'set', 'bridge', switch_name,
+                           'datapath_type=netdev'])
+        else:
+            bridge.create(['--', 'set', 'bridge', switch_name,
+                           'datapath_type=netdev'] + params)
+
         bridge.set_db_attribute('Open_vSwitch', '.',
                                 'other_config:max-idle',
                                 settings.getValue('VSWITCH_FLOW_TIMEOUT'))
         bridge.set_db_attribute('Open_vSwitch', '.',
                                 'other_config:max-idle',
                                 settings.getValue('VSWITCH_FLOW_TIMEOUT'))
@@ -75,8 +90,6 @@ class OvsDpdkVhost(IVSwitch):
                                     'other_config:pmd-cpu-mask',
                                     settings.getValue('VSWITCH_PMD_CPU_MASK'))
 
                                     'other_config:pmd-cpu-mask',
                                     settings.getValue('VSWITCH_PMD_CPU_MASK'))
 
-        bridge.set_db_attribute('Bridge', bridge.br_name,
-                                'datapath_type', 'netdev')
         self._bridges[switch_name] = bridge
 
     def del_switch(self, switch_name):
         self._bridges[switch_name] = bridge
 
     def del_switch(self, switch_name):
@@ -93,7 +106,7 @@ class OvsDpdkVhost(IVSwitch):
         The new port is named dpdk<n> where n is an integer starting from 0.
         """
         bridge = self._bridges[switch_name]
         The new port is named dpdk<n> where n is an integer starting from 0.
         """
         bridge = self._bridges[switch_name]
-        dpdk_count = self._get_port_count(bridge, 'type=dpdk')
+        dpdk_count = self._get_port_count('type=dpdk')
         port_name = 'dpdk' + str(dpdk_count)
         params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
         of_port = bridge.add_port(port_name, params)
         port_name = 'dpdk' + str(dpdk_count)
         params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
         of_port = bridge.add_port(port_name, params)
@@ -109,13 +122,35 @@ class OvsDpdkVhost(IVSwitch):
         """
         bridge = self._bridges[switch_name]
         # Changed dpdkvhost to dpdkvhostuser to be able to run in Qemu 2.2
         """
         bridge = self._bridges[switch_name]
         # Changed dpdkvhost to dpdkvhostuser to be able to run in Qemu 2.2
-        vhost_count = self._get_port_count(bridge, 'type=dpdkvhostuser')
-        port_name = 'dpdkvhostuser' + str(vhost_count)
-        params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostuser']
+        if settings.getValue('VNF').endswith('Cuse'):
+            vhost_count = self._get_port_count('type=dpdkvhostcuse')
+            port_name = 'dpdkvhostcuse' + str(vhost_count)
+            params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostcuse']
+        else:
+            vhost_count = self._get_port_count('type=dpdkvhostuser')
+            port_name = 'dpdkvhostuser' + str(vhost_count)
+            params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostuser']
+
         of_port = bridge.add_port(port_name, params)
 
         return (port_name, of_port)
 
         of_port = bridge.add_port(port_name, params)
 
         return (port_name, of_port)
 
+    def add_tunnel_port(self, switch_name, remote_ip, tunnel_type='vxlan', params=None):
+        """Creates tunneling port
+        """
+        bridge = self._bridges[switch_name]
+        pcount = str(self._get_port_count('type=' + tunnel_type))
+        port_name = tunnel_type + pcount
+        local_params = ['--', 'set', 'Interface', port_name,
+                        'type=' + tunnel_type,
+                        'options:remote_ip=' + remote_ip]
+
+        if params is not None:
+            local_params = local_params + params
+
+        of_port = bridge.add_port(port_name, local_params)
+        return (port_name, of_port)
+
     def get_ports(self, switch_name):
         """See IVswitch for general description
         """
     def get_ports(self, switch_name):
         """See IVswitch for general description
         """
@@ -129,11 +164,11 @@ class OvsDpdkVhost(IVSwitch):
         bridge = self._bridges[switch_name]
         bridge.del_port(port_name)
 
         bridge = self._bridges[switch_name]
         bridge.del_port(port_name)
 
-    def add_flow(self, switch_name, flow):
+    def add_flow(self, switch_name, flow, cache='off'):
         """See IVswitch for general description
         """
         bridge = self._bridges[switch_name]
         """See IVswitch for general description
         """
         bridge = self._bridges[switch_name]
-        bridge.add_flow(flow)
+        bridge.add_flow(flow, cache=cache)
 
     def del_flow(self, switch_name, flow=None):
         """See IVswitch for general description
 
     def del_flow(self, switch_name, flow=None):
         """See IVswitch for general description
@@ -142,14 +177,37 @@ class OvsDpdkVhost(IVSwitch):
         bridge = self._bridges[switch_name]
         bridge.del_flow(flow)
 
         bridge = self._bridges[switch_name]
         bridge.del_flow(flow)
 
-    @staticmethod
-    def _get_port_count(bridge, param):
+    def dump_flows(self, switch_name):
+        """See IVswitch for general description
+        """
+        bridge = self._bridges[switch_name]
+        bridge.dump_flows()
+
+    def add_route(self, switch_name, network, destination):
+        """See IVswitch for general description
+        """
+        bridge = self._bridges[switch_name]
+        bridge.add_route(network, destination)
+
+    def set_tunnel_arp(self, ip_addr, mac_addr, switch_name):
+        """See IVswitch for general description
+        """
+        bridge = self._bridges[switch_name]
+        bridge.set_tunnel_arp(ip_addr, mac_addr, switch_name)
+
+    def _get_port_count(self, param):
         """Returns the number of ports having a certain parameter
 
         :param bridge: The src.ovs.ofctl.OFBridge on which to operate
         :param param: The parameter to search for
         :returns: Count of matches
         """
         """Returns the number of ports having a certain parameter
 
         :param bridge: The src.ovs.ofctl.OFBridge on which to operate
         :param param: The parameter to search for
         :returns: Count of matches
         """
-        port_params = [c for (_, (_, c)) in list(bridge.get_ports().items())]
-        param_hits = [i for i in port_params if param in i]
-        return len(param_hits)
+        cnt = 0
+        for k in self._bridges:
+            pparams = [c for (_, (_, c)) in list(self._bridges[k].get_ports().items())]
+            phits = [i for i in pparams if param in i]
+            cnt += len(phits)
+
+        if cnt is None:
+            cnt = 0
+        return cnt