paths: Support binary packages
[vswitchperf.git] / vswitches / ovs_dpdk_vhost.py
1 # Copyright 2015-2016 Intel Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #   http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """VSPERF VSwitch implementation using DPDK and vhost ports
16 """
17
18 import logging
19 import subprocess
20 import os
21
22 from src.ovs import OFBridge
23 from src.dpdk import dpdk
24 from conf import settings
25 from vswitches.ovs import IVSwitchOvs
26
27 class OvsDpdkVhost(IVSwitchOvs):
28     """ Open vSwitch with DPDK support
29
30     Generic OVS wrapper functionality in src.ovs is maximally used. This
31     class wraps DPDK system configuration along with DPDK specific OVS
32     parameters
33
34     The method docstrings document only considerations specific to this
35     implementation. For generic information of the nature of the methods,
36     see the interface.
37     """
38
39     def __init__(self):
40         super(OvsDpdkVhost, self).__init__()
41         self._logger = logging.getLogger(__name__)
42
43         vswitchd_args = []
44
45         # legacy DPDK configuration through --dpdk option of vswitchd
46         if self.old_dpdk_config():
47             vswitchd_args = ['--dpdk'] + settings.getValue('VSWITCHD_DPDK_ARGS')
48             if self._vswitchd_args:
49                 self._vswitchd_args = vswitchd_args + ['--'] + self._vswitchd_args
50             else:
51                 self._vswitchd_args = vswitchd_args
52
53     def configure(self):
54         """ Configure vswitchd DPDK options through ovsdb if needed
55         """
56         dpdk_config = settings.getValue('VSWITCHD_DPDK_CONFIG')
57         if dpdk_config and not self.old_dpdk_config():
58             # enforce calls to ovs-vsctl with --no-wait
59             tmp_br = OFBridge(timeout=-1)
60             for option in dpdk_config:
61                 tmp_br.set_db_attribute('Open_vSwitch', '.',
62                                         'other_config:' + option, dpdk_config[option])
63
64     def start(self):
65         """See IVswitch for general description
66
67         Activates DPDK kernel modules, ovsdb and vswitchd.
68         """
69         dpdk.init()
70         super(OvsDpdkVhost, self).start()
71         # old style OVS <= 2.5.0 multi-queue enable
72         if settings.getValue('OVS_OLD_STYLE_MQ') and \
73                 int(settings.getValue('VSWITCH_DPDK_MULTI_QUEUES')):
74             tmp_br = OFBridge(timeout=-1)
75             tmp_br.set_db_attribute(
76                 'Open_vSwitch', '.', 'other_config:' +
77                 'n-dpdk-rxqs', settings.getValue('VSWITCH_DPDK_MULTI_QUEUES'))
78
79     def stop(self):
80         """See IVswitch for general description
81
82         Kills ovsdb and vswitchd and removes DPDK kernel modules.
83         """
84
85         super(OvsDpdkVhost, self).stop()
86         dpdk.cleanup()
87
88     def add_switch(self, switch_name, params=None):
89         """See IVswitch for general description
90         """
91         switch_params = ['--', 'set', 'bridge', switch_name, 'datapath_type=netdev']
92         if params:
93             switch_params = switch_params + params
94
95         super(OvsDpdkVhost, self).add_switch(switch_name, switch_params)
96         if settings.getValue('VSWITCH_AFFINITIZATION_ON') == 1:
97             # Sets the PMD core mask to VSWITCH_PMD_CPU_MASK
98             # for CPU core affinitization
99             self._bridges[switch_name].set_db_attribute('Open_vSwitch', '.',
100                                                         'other_config:pmd-cpu-mask',
101                                                         settings.getValue('VSWITCH_PMD_CPU_MASK'))
102
103     def add_phy_port(self, switch_name):
104         """See IVswitch for general description
105
106         Creates a port of type dpdk.
107         The new port is named dpdk<n> where n is an integer starting from 0.
108         """
109         bridge = self._bridges[switch_name]
110         dpdk_count = self._get_port_count('type=dpdk')
111         port_name = 'dpdk' + str(dpdk_count)
112         params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
113         # multi-queue enable
114
115         if int(settings.getValue('VSWITCH_DPDK_MULTI_QUEUES')) and \
116                 not settings.getValue('OVS_OLD_STYLE_MQ'):
117                 params += ['options:n_rxq={}'.format(
118                     settings.getValue('VSWITCH_DPDK_MULTI_QUEUES'))]
119         of_port = bridge.add_port(port_name, params)
120         return (port_name, of_port)
121
122     def add_vport(self, switch_name):
123         """See IVswitch for general description
124
125         Creates a port of type dpdkvhost
126         The new port is named dpdkvhost<n> where n is an integer starting
127         from 0
128         """
129         bridge = self._bridges[switch_name]
130         vhost_count = self._get_port_count('type=dpdkvhostuser')
131         port_name = 'dpdkvhostuser' + str(vhost_count)
132         params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostuser']
133         # multi queue enable
134         if int(settings.getValue('VSWITCH_DPDK_MULTI_QUEUES')) and \
135                 not settings.getValue('OVS_OLD_STYLE_MQ'):
136             params += ['options:n_rxq={}'.format(
137                 settings.getValue('VSWITCH_DPDK_MULTI_QUEUES'))]
138         of_port = bridge.add_port(port_name, params)
139
140         return (port_name, of_port)
141
142     @staticmethod
143     def old_dpdk_config():
144         """Checks if ovs-vswitchd uses legacy dpdk configuration via --dpdk option
145
146         :returns: True if legacy --dpdk option is supported, otherwise it returns False
147         """
148
149         ovs_vswitchd_bin = settings.getValue('TOOLS')['ovs-vswitchd']
150         try:
151             subprocess.check_output(ovs_vswitchd_bin + r' --help | grep "\-\-dpdk"', shell=True)
152             return True
153         except subprocess.CalledProcessError:
154             return False