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