77797b8f9591d5dec33ef4108680b08444d9a88d
[vswitchperf.git] / core / vswitch_controller_op2p.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 """VSwitch controller for Physical to Tunnel Endpoint to Physical deployment
16 """
17
18 import logging
19
20 from core.vswitch_controller import IVswitchController
21 from vswitches.utils import add_ports_to_flow
22 from conf import settings
23 from tools import tasks
24
25 _FLOW_TEMPLATE = {
26     'idle_timeout': '0'
27 }
28
29 class VswitchControllerOP2P(IVswitchController):
30     """VSwitch controller for OP2P deployment scenario.
31
32     Attributes:
33         _vswitch_class: The vSwitch class to be used.
34         _vswitch: The vSwitch object controlled by this controller
35         _deployment_scenario: A string describing the scenario to set-up in the
36             constructor.
37     """
38     def __init__(self, vswitch_class, traffic, tunnel_operation=None):
39         """Initializes up the prerequisites for the OP2P deployment scenario.
40
41         :vswitch_class: the vSwitch class to be used.
42         """
43         self._logger = logging.getLogger(__name__)
44         self._vswitch_class = vswitch_class
45         self._vswitch = vswitch_class()
46         self._deployment_scenario = "OP2P"
47         self._traffic = traffic.copy()
48         self._tunnel_operation = tunnel_operation
49         self._logger.debug('Creation using ' + str(self._vswitch_class))
50
51     def setup(self):
52         """ Sets up the switch for overlay P2P (tunnel encap or decap)
53         """
54         self._logger.debug('Setting up ' + str(self._tunnel_operation))
55         if self._tunnel_operation == "encapsulation":
56             self._setup_encap()
57         else:
58             if settings.getValue('VSWITCH').endswith('Vanilla'):
59                 self._setup_decap_vanilla()
60             else:
61                 self._setup_decap()
62
63     def _setup_encap(self):
64         """ Sets up the switch for overlay P2P encapsulation test
65
66         Create 2 bridges br0 (integration bridge) and br-ext and a VXLAN port
67         for encapsulation.
68         """
69         self._logger.debug('Setup using ' + str(self._vswitch_class))
70
71         try:
72             self._vswitch.start()
73             bridge = settings.getValue('TUNNEL_INTEGRATION_BRIDGE')
74             bridge_ext = settings.getValue('TUNNEL_EXTERNAL_BRIDGE')
75             bridge_ext_ip = settings.getValue('TUNNEL_EXTERNAL_BRIDGE_IP')
76             tg_port2_mac = settings.getValue('TRAFFICGEN_PORT2_MAC')
77             vtep_ip2 = settings.getValue('VTEP_IP2')
78             self._vswitch.add_switch(bridge)
79
80             tasks.run_task(['sudo', 'ifconfig', bridge,
81                             settings.getValue('VTEP_IP1')],
82                            self._logger, 'Assign ' +
83                            settings.getValue('VTEP_IP1') + ' to ' + bridge,
84                            False)
85
86             tunnel_type = self._traffic['tunnel_type']
87
88             self._vswitch.add_switch(bridge_ext)
89             (_, phy1_number) = self._vswitch.add_phy_port(bridge)
90             (_, phy2_number) = self._vswitch.add_tunnel_port(bridge,
91                                                              vtep_ip2,
92                                                              tunnel_type)
93             self._vswitch.add_phy_port(bridge_ext)
94
95             tasks.run_task(['sudo', 'ip', 'addr', 'add',
96                             bridge_ext_ip,
97                             'dev', bridge_ext], self._logger, 'Assign ' +
98                            bridge_ext_ip + ' to ' + bridge_ext)
99
100             tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', bridge_ext,
101                             'up'], self._logger,
102                            'Set ' + bridge_ext + 'status to up')
103
104             self._vswitch.add_route(bridge,
105                                     settings.getValue('VTEP_IP2_SUBNET'),
106                                     bridge_ext)
107
108             if settings.getValue('VSWITCH').endswith('Vanilla'):
109                 tasks.run_task(['sudo', 'arp', '-s', vtep_ip2, tg_port2_mac],
110                                self._logger,
111                                'Set ' + bridge_ext + ' status to up')
112             else:
113                 self._vswitch.set_tunnel_arp(vtep_ip2,
114                                              tg_port2_mac,
115                                              bridge_ext)
116
117             # Test is unidirectional for now
118             self._vswitch.del_flow(bridge)
119             flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
120                                       phy2_number)
121             self._vswitch.add_flow(bridge, flow1)
122
123         except:
124             self._vswitch.stop()
125             raise
126
127     def _setup_decap(self):
128         """ Sets up the switch for overlay P2P decapsulation test
129         """
130         self._logger.debug('Setup using ' + str(self._vswitch_class))
131
132         try:
133             self._vswitch.start()
134             bridge = settings.getValue('TUNNEL_INTEGRATION_BRIDGE')
135             bridge_ext = settings.getValue('TUNNEL_EXTERNAL_BRIDGE')
136             bridge_ext_ip = settings.getValue('TUNNEL_EXTERNAL_BRIDGE_IP')
137             tgen_ip1 = settings.getValue('TRAFFICGEN_PORT1_IP')
138             self._vswitch.add_switch(bridge)
139
140             tasks.run_task(['sudo', 'ifconfig', bridge,
141                             settings.getValue('VTEP_IP1')],
142                            self._logger, 'Assign ' +
143                            settings.getValue('VTEP_IP1') + ' to ' + bridge, False)
144
145             tunnel_type = self._traffic['tunnel_type']
146
147             self._vswitch.add_switch(bridge_ext)
148             self._vswitch.add_phy_port(bridge)
149             (_, phy2_number) = self._vswitch.add_phy_port(bridge_ext)
150             if tunnel_type == "vxlan":
151                 vxlan_vni = 'options:key=' + settings.getValue('VXLAN_VNI')
152                 (_, phy3_number) = self._vswitch.add_tunnel_port(bridge_ext,
153                                                                  tgen_ip1,
154                                                                  tunnel_type,
155                                                                  params=[vxlan_vni])
156             else:
157                 (_, phy3_number) = self._vswitch.add_tunnel_port(bridge_ext,
158                                                                  tgen_ip1,
159                                                                  tunnel_type)
160             tasks.run_task(['sudo', 'ip', 'addr', 'add',
161                             bridge_ext_ip,
162                             'dev', bridge_ext],
163                            self._logger, 'Assign ' +
164                            bridge_ext_ip
165                            + ' to ' + bridge_ext)
166
167             tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', bridge_ext,
168                             'up'],
169                            self._logger,
170                            'Set ' + bridge_ext + ' status to up')
171
172             self._vswitch.set_tunnel_arp(tgen_ip1,
173                                          settings.getValue('TRAFFICGEN_PORT1_MAC'),
174                                          bridge)
175             # Test is unidirectional for now
176             self._vswitch.del_flow(bridge_ext)
177             flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
178                                       phy2_number)
179             self._vswitch.add_flow(bridge_ext, flow1)
180
181         except:
182             self._vswitch.stop()
183             raise
184
185     def _setup_decap_vanilla(self):
186         """ Sets up the switch for overlay P2P decapsulation test
187         """
188         self._logger.debug('Setup decap vanilla ' + str(self._vswitch_class))
189
190         try:
191             self._vswitch.start()
192             bridge = settings.getValue('TUNNEL_INTEGRATION_BRIDGE')
193             bridge_ext = settings.getValue('TUNNEL_EXTERNAL_BRIDGE')
194             bridge_ext_ip = settings.getValue('TUNNEL_EXTERNAL_BRIDGE_IP')
195             tgen_ip1 = settings.getValue('TRAFFICGEN_PORT1_IP')
196             self._vswitch.add_switch(bridge)
197
198             tasks.run_task(['sudo', 'ifconfig', bridge,
199                             settings.getValue('TUNNEL_INT_BRIDGE_IP')],
200                            self._logger, 'Assign ' +
201                            settings.getValue('TUNNEL_INT_BRIDGE_IP') + ' to ' + bridge, False)
202
203             tunnel_type = self._traffic['tunnel_type']
204
205             self._vswitch.add_switch(bridge_ext)
206             self._vswitch.add_phy_port(bridge_ext)
207             (_, phy2_number) = self._vswitch.add_phy_port(bridge)
208
209             if tunnel_type == "vxlan":
210                 vxlan_vni = 'options:key=' + settings.getValue('VXLAN_VNI')
211                 self._vswitch.add_tunnel_port(bridge, tgen_ip1, tunnel_type,
212                                               params=[vxlan_vni])
213             else:
214                 self._vswitch.add_tunnel_port(bridge, tgen_ip1, tunnel_type)
215
216             tasks.run_task(['sudo', 'ip', 'addr', 'add',
217                             bridge_ext_ip,
218                             'dev', bridge_ext],
219                            self._logger, 'Assign ' +
220                            bridge_ext_ip
221                            + ' to ' + bridge_ext)
222
223             tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', bridge_ext,
224                             'up'],
225                            self._logger,
226                            'Set ' + bridge_ext + ' status to up')
227
228             tg_port2_mac = settings.getValue('TRAFFICGEN_PORT2_MAC')
229             vtep_ip2 = settings.getValue('TRAFFICGEN_PORT2_IP')
230
231             self._vswitch.set_tunnel_arp(vtep_ip2,
232                                          tg_port2_mac,
233                                          bridge_ext)
234
235             self._vswitch.add_route(bridge,
236                                     settings.getValue('VTEP_IP2_SUBNET'),
237                                     bridge)
238
239
240             tasks.run_task(['sudo', 'arp', '-s', vtep_ip2, tg_port2_mac],
241                            self._logger,
242                            'Set ' + bridge_ext + ' status to up')
243
244
245             # Test is unidirectional for now
246             self._vswitch.del_flow(bridge_ext)
247
248             flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number, 'LOCAL')
249             self._vswitch.add_flow(bridge_ext, flow1)
250
251         except:
252             self._vswitch.stop()
253             raise
254
255     def stop(self):
256         """Tears down the switch created in setup().
257         """
258         self._logger.debug('Stop using ' + str(self._vswitch_class))
259         self._vswitch.stop()
260
261     def __enter__(self):
262         self.setup()
263
264     def __exit__(self, type_, value, traceback):
265         self.stop()
266
267     def get_vswitch(self):
268         """See IVswitchController for description
269         """
270         return self._vswitch
271
272     def get_ports_info(self):
273         """See IVswitchController for description
274         """
275         self._logger.debug('get_ports_info  using ' + str(self._vswitch_class))
276         return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
277
278     def dump_vswitch_flows(self):
279         """See IVswitchController for description
280         """
281         self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))