src: add appropriate build flags for OVS dpdk
[vswitchperf.git] / vswitches / ovs_dpdk_vhost.py
1 # Copyright 2015 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 from conf import settings
20 from vswitches.vswitch import IVSwitch
21 from src.ovs import VSwitchd, OFBridge
22 from src.dpdk import dpdk
23
24 _VSWITCHD_CONST_ARGS = ['--', '--log-file']
25 _VHOST_METHOD = settings.getValue('VHOST_METHOD')
26
27 class OvsDpdkVhost(IVSwitch):
28     """VSwitch implementation using DPDK and vhost ports
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     _logger = logging.getLogger()
40
41     def __init__(self):
42         vswitchd_args = ['--dpdk']
43         vswitchd_args += settings.getValue('VSWITCHD_DPDK_ARGS')
44         vswitchd_args += _VSWITCHD_CONST_ARGS
45
46         if settings.getValue('VNF').endswith('Cuse'):
47             self._logger.info("Inserting VHOST Cuse modules into kernel...")
48             dpdk.insert_vhost_modules()
49
50         self._vswitchd = VSwitchd(vswitchd_args=vswitchd_args,
51                                   expected_cmd=
52                                   r'EAL: Master l*core \d+ is ready')
53         self._bridges = {}
54
55     def start(self):
56         """See IVswitch for general description
57
58         Activates DPDK kernel modules, ovsdb and vswitchd.
59         """
60         dpdk.init()
61         self._vswitchd.start()
62
63     def stop(self):
64         """See IVswitch for general description
65
66         Kills ovsdb and vswitchd and removes DPDK kernel modules.
67         """
68         self._vswitchd.kill()
69         dpdk.cleanup()
70         dpdk.remove_vhost_modules()
71
72     def add_switch(self, switch_name):
73         """See IVswitch for general description
74         """
75         bridge = OFBridge(switch_name)
76         bridge.create()
77         bridge.set_db_attribute('Open_vSwitch', '.',
78                                 'other_config:max-idle',
79                                 settings.getValue('VSWITCH_FLOW_TIMEOUT'))
80
81         if settings.getValue('VSWITCH_AFFINITIZATION_ON') == 1:
82             # Sets the PMD core mask to VSWITCH_PMD_CPU_MASK
83             # for CPU core affinitization
84             bridge.set_db_attribute('Open_vSwitch', '.',
85                                     'other_config:pmd-cpu-mask',
86                                     settings.getValue('VSWITCH_PMD_CPU_MASK'))
87
88         bridge.set_db_attribute('Bridge', bridge.br_name,
89                                 'datapath_type', 'netdev')
90         self._bridges[switch_name] = bridge
91
92     def del_switch(self, switch_name):
93         """See IVswitch for general description
94         """
95         bridge = self._bridges[switch_name]
96         self._bridges.pop(switch_name)
97         bridge.destroy()
98
99     def add_phy_port(self, switch_name):
100         """See IVswitch for general description
101
102         Creates a port of type dpdk.
103         The new port is named dpdk<n> where n is an integer starting from 0.
104         """
105         bridge = self._bridges[switch_name]
106         dpdk_count = self._get_port_count(bridge, 'type=dpdk')
107         port_name = 'dpdk' + str(dpdk_count)
108         params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
109         of_port = bridge.add_port(port_name, params)
110
111         return (port_name, of_port)
112
113     def add_vport(self, switch_name):
114         """See IVswitch for general description
115
116         Creates a port of type dpdkvhost
117         The new port is named dpdkvhost<n> where n is an integer starting
118         from 0
119         """
120         bridge = self._bridges[switch_name]
121         # Changed dpdkvhost to dpdkvhostuser to be able to run in Qemu 2.2
122         if settings.getValue('VNF').endswith('Cuse'):
123             vhost_count = self._get_port_count(bridge, 'type=dpdkvhostcuse')
124             port_name = 'dpdkvhostcuse' + str(vhost_count)
125             params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostcuse']
126         else:
127             vhost_count = self._get_port_count(bridge, 'type=dpdkvhostuser')
128             port_name = 'dpdkvhostuser' + str(vhost_count)
129             params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostuser']
130
131         of_port = bridge.add_port(port_name, params)
132
133         return (port_name, of_port)
134
135     def get_ports(self, switch_name):
136         """See IVswitch for general description
137         """
138         bridge = self._bridges[switch_name]
139         ports = list(bridge.get_ports().items())
140         return [(name, of_port) for (name, (of_port, _)) in ports]
141
142     def del_port(self, switch_name, port_name):
143         """See IVswitch for general description
144         """
145         bridge = self._bridges[switch_name]
146         bridge.del_port(port_name)
147
148     def add_flow(self, switch_name, flow):
149         """See IVswitch for general description
150         """
151         bridge = self._bridges[switch_name]
152         bridge.add_flow(flow)
153
154     def del_flow(self, switch_name, flow=None):
155         """See IVswitch for general description
156         """
157         flow = flow or {}
158         bridge = self._bridges[switch_name]
159         bridge.del_flow(flow)
160
161     @staticmethod
162     def _get_port_count(bridge, param):
163         """Returns the number of ports having a certain parameter
164
165         :param bridge: The src.ovs.ofctl.OFBridge on which to operate
166         :param param: The parameter to search for
167         :returns: Count of matches
168         """
169         port_params = [c for (_, (_, c)) in list(bridge.get_ports().items())]
170         param_hits = [i for i in port_params if param in i]
171         return len(param_hits)