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