pkt_gen: Add IxNet support for GRE frames
[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             self._setup_decap()
59
60     def _setup_encap(self):
61         """ Sets up the switch for overlay P2P encapsulation test
62
63         Create 2 bridges br0 (integration bridge) and br-ext and a VXLAN port
64         for encapsulation.
65         """
66         self._logger.debug('Setup using ' + str(self._vswitch_class))
67
68         try:
69             self._vswitch.start()
70             bridge = settings.getValue('TUNNEL_INTEGRATION_BRIDGE')
71             bridge_ext = settings.getValue('TUNNEL_EXTERNAL_BRIDGE')
72             bridge_ext_ip = settings.getValue('TUNNEL_EXTERNAL_BRIDGE_IP')
73             tg_port2_mac = settings.getValue('TRAFFICGEN_PORT2_MAC')
74             vtep_ip2 = settings.getValue('VTEP_IP2')
75             self._vswitch.add_switch(bridge)
76
77             tasks.run_task(['sudo', 'ifconfig', bridge,
78                             settings.getValue('VTEP_IP1')],
79                            self._logger, 'Assign ' +
80                            settings.getValue('VTEP_IP1') + ' to ' + bridge,
81                            False)
82
83             tunnel_type = self._traffic['tunnel_type']
84
85             self._vswitch.add_switch(bridge_ext)
86             (_, phy1_number) = self._vswitch.add_phy_port(bridge)
87             (_, phy2_number) = self._vswitch.add_tunnel_port(bridge,
88                                                              vtep_ip2,
89                                                              tunnel_type)
90             self._vswitch.add_phy_port(bridge_ext)
91
92             tasks.run_task(['sudo', 'ip', 'addr', 'add',
93                             bridge_ext_ip,
94                             'dev', bridge_ext], self._logger, 'Assign ' +
95                            bridge_ext_ip + ' to ' + bridge_ext)
96
97             tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', bridge_ext,
98                             'up'], self._logger,
99                            'Set ' + bridge_ext + 'status to up')
100
101             self._vswitch.add_route(bridge,
102                                     settings.getValue('VTEP_IP2_SUBNET'),
103                                     bridge_ext)
104
105             if settings.getValue('VSWITCH').endswith('Vanilla'):
106                 tasks.run_task(['sudo', 'arp', '-s', vtep_ip2, tg_port2_mac],
107                                self._logger,
108                                'Set ' + bridge_ext + ' status to up')
109             else:
110                 self._vswitch.set_tunnel_arp(vtep_ip2,
111                                              tg_port2_mac,
112                                              bridge_ext)
113
114             # Test is unidirectional for now
115             self._vswitch.del_flow(bridge)
116             flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
117                                       phy2_number)
118             self._vswitch.add_flow(bridge, flow1)
119
120         except:
121             self._vswitch.stop()
122             raise
123
124     def _setup_decap(self):
125         """ Sets up the switch for overlay P2P decapsulation test
126         """
127         self._logger.debug('Setup using ' + str(self._vswitch_class))
128
129         try:
130             self._vswitch.start()
131             bridge = settings.getValue('TUNNEL_INTEGRATION_BRIDGE')
132             bridge_ext = settings.getValue('TUNNEL_EXTERNAL_BRIDGE')
133             bridge_ext_ip = settings.getValue('TUNNEL_EXTERNAL_BRIDGE_IP')
134             tgen_ip1 = settings.getValue('TRAFFICGEN_PORT1_IP')
135             self._vswitch.add_switch(bridge)
136
137             tasks.run_task(['sudo', 'ifconfig', bridge,
138                             settings.getValue('VTEP_IP1')],
139                            self._logger, 'Assign ' +
140                            settings.getValue('VTEP_IP1') + ' to ' + bridge, False)
141
142             tunnel_type = self._traffic['tunnel_type']
143
144             self._vswitch.add_switch(bridge_ext)
145             self._vswitch.add_phy_port(bridge)
146             (_, phy2_number) = self._vswitch.add_phy_port(bridge_ext)
147             if tunnel_type == "vxlan":
148                 vxlan_vni = 'options:key=' + settings.getValue('VXLAN_VNI')
149                 (_, phy3_number) = self._vswitch.add_tunnel_port(bridge_ext,
150                                                                  tgen_ip1,
151                                                                  tunnel_type,
152                                                                  params=[vxlan_vni])
153             else:
154                 (_, phy3_number) = self._vswitch.add_tunnel_port(bridge_ext,
155                                                                  tgen_ip1,
156                                                                  tunnel_type)
157             tasks.run_task(['sudo', 'ip', 'addr', 'add',
158                             bridge_ext_ip,
159                             'dev', bridge_ext],
160                            self._logger, 'Assign ' +
161                            bridge_ext_ip
162                            + ' to ' + bridge_ext)
163
164             tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', bridge_ext,
165                             'up'],
166                            self._logger,
167                            'Set ' + bridge_ext + ' status to up')
168
169             self._vswitch.set_tunnel_arp(tgen_ip1,
170                                          settings.getValue('TRAFFICGEN_PORT1_MAC'),
171                                          bridge)
172             self._vswitch.set_tunnel_arp(bridge_ext_ip.split('/')[0],
173                                          settings.getValue('DUT_NIC1_MAC'),
174                                          bridge_ext)
175
176             # Test is unidirectional for now
177             self._vswitch.del_flow(bridge_ext)
178             flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
179                                       phy2_number)
180             self._vswitch.add_flow(bridge_ext, flow1)
181
182         except:
183             self._vswitch.stop()
184             raise
185
186     def stop(self):
187         """Tears down the switch created in setup().
188         """
189         self._logger.debug('Stop using ' + str(self._vswitch_class))
190         self._vswitch.stop()
191
192     def __enter__(self):
193         self.setup()
194
195     def __exit__(self, type_, value, traceback):
196         self.stop()
197
198     def get_vswitch(self):
199         """See IVswitchController for description
200         """
201         return self._vswitch
202
203     def get_ports_info(self):
204         """See IVswitchController for description
205         """
206         self._logger.debug('get_ports_info  using ' + str(self._vswitch_class))
207         return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
208
209     def dump_vswitch_flows(self):
210         """See IVswitchController for description
211         """
212         self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))