Update CRC list and support 21997/7
[csit.git] / resources / libraries / python / Memif.py
1 # Copyright (c) 2019 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
17 from enum import IntEnum
18 from robot.api import logger
19
20 from resources.libraries.python.topology import NodeType, Topology
21 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
22
23
24 class MemifRole(IntEnum):
25     """Memif interface roles"""
26     MASTER = 0
27     SLAVE = 1
28
29
30 class Memif(object):
31     """Memif interface class"""
32
33     def __init__(self):
34         pass
35
36     @staticmethod
37     def _memif_details(node):
38         """Get the memif dump details on the given node.
39
40         :param node: Given node to get Memif dump from.
41         :type node: dict
42         :returns: List of memif interfaces extracted from Papi response.
43         :rtype: list
44         """
45         cmd = "memif_dump"
46         with PapiSocketExecutor(node) as papi_exec:
47             details = papi_exec.add(cmd).get_details()
48
49         for memif in details:
50             memif["hw_addr"] = str(memif["hw_addr"])
51             memif["role"] = memif["role"].value
52             memif["mode"] = memif["mode"].value
53             memif["flags"] = memif["flags"].value \
54                 if hasattr(memif["flags"], 'value') else int(memif["flags"])
55
56         logger.debug("MEMIF details:\n{details}".format(details=details))
57
58         return details
59
60     @staticmethod
61     def _memif_socket_filename_add_del(node, is_add, filename, sid):
62         """Create Memif socket on the given node.
63
64         :param node: Given node to create Memif socket on.
65         :param is_add: If True, socket is added, otherwise deleted.
66         :param filename: Memif interface socket filename.
67         :param sid: Socket ID.
68         :type node: dict
69         :type is_add: bool
70         :type filename: str
71         :type sid: str
72         :returns: Verified data from PAPI response. In this case, the response
73             includes only retval.
74         :rtype: dict
75         """
76         cmd = 'memif_socket_filename_add_del'
77         err_msg = 'Failed to create memif socket on host {host}'.format(
78             host=node['host'])
79         args = dict(
80             is_add=is_add,
81             socket_id=int(sid),
82             socket_filename=str('/tmp/' + filename)
83         )
84         with PapiSocketExecutor(node) as papi_exec:
85             return papi_exec.add(cmd, **args).get_reply(err_msg)
86
87     @staticmethod
88     def _memif_create(node, mid, sid, rxq=1, txq=1, role=1):
89         """Create Memif interface on the given node, return its sw_if_index.
90
91         :param node: Given node to create Memif interface on.
92         :param mid: Memif interface ID.
93         :param sid: Socket ID.
94         :param rxq: Number of RX queues; 0 means do not set.
95         :param txq: Number of TX queues; 0 means do not set.
96         :param role: Memif interface role [master=0|slave=1]. Default is slave.
97         :type node: dict
98         :type mid: str
99         :type sid: str
100         :type rxq: int
101         :type txq: int
102         :type role: int
103         :returns: sw_if_index
104         :rtype: int
105         """
106         cmd = 'memif_create'
107         err_msg = 'Failed to create memif interface on host {host}'.format(
108             host=node['host'])
109         args = dict(
110             role=role,
111             rx_queues=int(rxq),
112             tx_queues=int(txq),
113             socket_id=int(sid),
114             id=int(mid),
115             secret=""
116         )
117         with PapiSocketExecutor(node) as papi_exec:
118             return papi_exec.add(cmd, **args).get_sw_if_index(err_msg)
119
120     @staticmethod
121     def create_memif_interface(node, filename, mid, sid, rxq=1, txq=1,
122                                role="SLAVE"):
123         """Create Memif interface on the given node.
124
125         :param node: Given node to create Memif interface on.
126         :param filename: Memif interface socket filename.
127         :param mid: Memif interface ID.
128         :param sid: Socket ID.
129         :param rxq: Number of RX queues; 0 means do not set.
130         :param txq: Number of TX queues; 0 means do not set.
131         :param role: Memif interface role [master=0|slave=1]. Default is master.
132         :type node: dict
133         :type filename: str
134         :type mid: str
135         :type sid: str
136         :type rxq: int
137         :type txq: int
138         :type role: str
139         :returns: SW interface index.
140         :rtype: int
141         :raises ValueError: If command 'create memif' fails.
142         """
143
144         role = getattr(MemifRole, role.upper()).value
145
146         # Create socket
147         Memif._memif_socket_filename_add_del(node, True, filename, sid)
148
149         # Create memif
150         sw_if_index = Memif._memif_create(
151             node, mid, sid, rxq=rxq, txq=txq, role=role)
152
153         # Update Topology
154         if_key = Topology.add_new_port(node, 'memif')
155         Topology.update_interface_sw_if_index(node, if_key, sw_if_index)
156
157         ifc_name = Memif.vpp_get_memif_interface_name(node, sw_if_index)
158         Topology.update_interface_name(node, if_key, ifc_name)
159
160         ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_index)
161         Topology.update_interface_mac_address(node, if_key, ifc_mac)
162
163         Topology.update_interface_memif_socket(node, if_key, '/tmp/' + filename)
164         Topology.update_interface_memif_id(node, if_key, mid)
165         Topology.update_interface_memif_role(node, if_key, str(role))
166
167         return sw_if_index
168
169     @staticmethod
170     def show_memif(node):
171         """Show Memif data for the given node.
172
173         :param node: Given node to show Memif data on.
174         :type node: dict
175         """
176
177         Memif._memif_details(node)
178
179     @staticmethod
180     def show_memif_on_all_duts(nodes):
181         """Show Memif data on all DUTs.
182
183         :param nodes: Topology nodes.
184         :type nodes: dict
185         """
186         for node in nodes.values():
187             if node['type'] == NodeType.DUT:
188                 Memif.show_memif(node)
189
190     @staticmethod
191     def vpp_get_memif_interface_name(node, sw_if_index):
192         """Get Memif interface name from Memif interfaces dump.
193
194         :param node: DUT node.
195         :param sw_if_index: DUT node.
196         :type node: dict
197         :type sw_if_index: int
198         :returns: Memif interface name, or None if not found.
199         :rtype: str
200         """
201
202         details = Memif._memif_details(node)
203
204         for memif in details:
205             if memif["sw_if_index"] == sw_if_index:
206                 return memif["if_name"]
207         return None
208
209     @staticmethod
210     def vpp_get_memif_interface_mac(node, sw_if_index):
211         """Get Memif interface MAC address from Memif interfaces dump.
212
213         :param node: DUT node.
214         :param sw_if_index: DUT node.
215         :type node: dict
216         :type sw_if_index: int
217         :returns: Memif interface MAC address, or None if not found.
218         :rtype: str
219         """
220
221         details = Memif._memif_details(node)
222
223         for memif in details:
224             if memif["sw_if_index"] == sw_if_index:
225                 return memif["hw_addr"]
226         return None