CSIT-1081 Container VPP configuration refactor
[csit.git] / resources / libraries / python / Memif.py
1 # Copyright (c) 2018 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """Memif interface library."""
15
16 from resources.libraries.python.ssh import SSH
17 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
18 from resources.libraries.python.topology import NodeType, Topology
19
20
21 class Memif(object):
22     """Memif interface class."""
23
24     def __init__(self):
25         pass
26
27     @staticmethod
28     def create_memif_interface(node, filename, mid, sid, rxq=1, txq=1,
29                                role='slave'):
30         """Create Memif interface on the given node.
31
32         :param node: Given node to create Memif interface on.
33         :param filename: Memif interface socket filename.
34         :param mid: Memif interface ID.
35         :param sid: Socket ID.
36         :param rxq: Number of RX queues.
37         :param txq: Number of TX queues.
38         :param role: Memif interface role [master|slave]. Default is master.
39         :type node: dict
40         :type filename: str
41         :type mid: str
42         :type sid: str
43         :type rxq: int
44         :type txq: int
45         :type role: str
46         :returns: SW interface index.
47         :rtype: int
48         :raises ValueError: If command 'create memif' fails.
49         """
50
51         with VatTerminal(node, json_param=False) as vat:
52             vat.vat_terminal_exec_cmd_from_template(
53                 'memif_socket_filename_add_del.vat',
54                 add_del='add', id=sid, filename='/tmp/'+filename)
55             vat.vat_terminal_exec_cmd_from_template(
56                 'memif_create.vat', id=mid, socket=sid, rxq=rxq, txq=txq,
57                 role=role)
58             if 'sw_if_index' in vat.vat_stdout:
59                 try:
60                     sw_if_idx = int(vat.vat_stdout.split()[4])
61                     if_key = Topology.add_new_port(node, 'memif')
62                     Topology.update_interface_sw_if_index(
63                         node, if_key, sw_if_idx)
64                     ifc_name = Memif.vpp_get_memif_interface_name(
65                         node, sw_if_idx)
66                     Topology.update_interface_name(node, if_key, ifc_name)
67                     ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_idx)
68                     Topology.update_interface_mac_address(node, if_key, ifc_mac)
69                     Topology.update_interface_memif_socket(node, if_key,
70                                                            '/tmp/'+filename)
71                     Topology.update_interface_memif_id(node, if_key, mid)
72                     Topology.update_interface_memif_role(node, if_key, role)
73                     return sw_if_idx
74                 except KeyError:
75                     raise ValueError('Create Memif interface failed on node '
76                                      '{}'.format(node['host']))
77             else:
78                 raise ValueError('Create Memif interface failed on node '
79                                  '{}'.format(node['host']))
80
81     @staticmethod
82     def dump_memif(node):
83         """Dump Memif data for the given node.
84
85         :param node: Given node to show Memif data on.
86         :type node: dict
87         """
88         vat = VatExecutor()
89         vat.execute_script("memif_dump.vat", node, json_out=False)
90
91     @staticmethod
92     def show_memif(node):
93         """Show Memif data for the given node.
94
95         :param node: Given node to show Memif data on.
96         :type node: dict
97         """
98         vat = VatExecutor()
99         vat.execute_script("show_memif.vat", node, json_out=False)
100
101     @staticmethod
102     def show_memif_on_all_duts(nodes):
103         """Show Memif data on all DUTs.
104
105         :param nodes: Topology nodes.
106         :type nodes: dict
107         """
108         for node in nodes.values():
109             if node['type'] == NodeType.DUT:
110                 Memif.show_memif(node)
111
112     @staticmethod
113     def clear_memif_socks(node, *socks):
114         """Clear Memif sockets for the given node.
115
116         :param node: Given node to clear Memif sockets on.
117         :param socks: Memif sockets.
118         :type node: dict
119         :type socks: list
120         """
121         ssh = SSH()
122         ssh.connect(node)
123
124         for sock in socks:
125             ssh.exec_command_sudo('rm -f {}'.format(sock))
126
127     @staticmethod
128     def parse_memif_dump_data(memif_data):
129         """Convert Memif data to dictionary.
130
131         :param memif_data: Dump of Memif interfaces data.
132         :type memif_data: str
133         :returns: Memif interfaces data in dictionary.
134         :rtype: dict
135         :raises RuntimeError: If there is no memif interface name found in
136             provided data.
137         """
138         memif_name = None
139         memif_dict = dict()
140         memif_data = str(memif_data)
141         values = dict()
142
143         clutter = ['vat#']
144         for garbage in clutter:
145             memif_data = memif_data.replace(garbage, '')
146
147         for line in memif_data.splitlines():
148             if line.startswith('Sending') or len(line) == 0:
149                 continue
150             elif line.startswith('memif'):
151                 if memif_name:
152                     memif_dict[memif_name] = values
153                 line_split = line.split(':', 1)
154                 memif_name = str(line_split[0])
155                 values = dict()
156                 line = line_split[1]
157             line_split = line.split()
158             for i in range(0, len(line_split), 2):
159                 key = str(line_split[i])
160                 try:
161                     value = line_split[i+1]
162                 except IndexError:
163                     value = None
164                 values[key] = value
165         if memif_name:
166             memif_dict[memif_name] = values
167         else:
168             raise RuntimeError('No memif interface name found')
169
170         return memif_dict
171
172     @staticmethod
173     def vpp_get_memif_interface_name(node, sw_if_idx):
174         """Get Memif interface name from Memif interfaces dump.
175
176         :param node: DUT node.
177         :param sw_if_idx: DUT node.
178         :type node: dict
179         :type sw_if_idx: int
180         :returns: Memif interface name.
181         :rtype: str
182         """
183         with VatTerminal(node, json_param=False) as vat:
184             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
185             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
186             for item in memif_data:
187                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
188                     return item
189         return None
190
191     @staticmethod
192     def vpp_get_memif_interface_mac(node, sw_if_idx):
193         """Get Memif interface MAC address from Memif interfaces dump.
194
195         :param node: DUT node.
196         :param sw_if_idx: DUT node.
197         :type node: dict
198         :type sw_if_idx: int
199         :returns: Memif interface MAC address.
200         :rtype: str
201         """
202         with VatTerminal(node, json_param=False) as vat:
203             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
204             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
205             for item in memif_data:
206                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
207                     return memif_data[item].get('mac', None)
208
209     @staticmethod
210     def vpp_get_memif_interface_socket(node, sw_if_idx):
211         """Get Memif interface socket path from Memif interfaces dump.
212
213         :param node: DUT node.
214         :param sw_if_idx: DUT node.
215         :type node: dict
216         :type sw_if_idx: int
217         :returns: Memif interface socket path.
218         :rtype: str
219         """
220         with VatTerminal(node, json_param=False) as vat:
221             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
222             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
223             for item in memif_data:
224                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
225                     return memif_data[item].get('socket', None)
226
227     @staticmethod
228     def vpp_get_memif_interface_id(node, sw_if_idx):
229         """Get Memif interface ID from Memif interfaces dump.
230
231         :param node: DUT node.
232         :param sw_if_idx: DUT node.
233         :type node: dict
234         :type sw_if_idx: int
235         :returns: Memif interface ID.
236         :rtype: int
237         """
238         with VatTerminal(node, json_param=False) as vat:
239             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
240             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
241             for item in memif_data:
242                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
243                     return int(memif_data[item].get('id', None))
244
245     @staticmethod
246     def vpp_get_memif_interface_role(node, sw_if_idx):
247         """Get Memif interface role from Memif interfaces dump.
248
249         :param node: DUT node.
250         :param sw_if_idx: DUT node.
251         :type node: dict
252         :type sw_if_idx: int
253         :returns: Memif interface role.
254         :rtype: int
255         """
256         with VatTerminal(node, json_param=False) as vat:
257             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
258             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
259             for item in memif_data:
260                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
261                     return memif_data[item].get('role', None)