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:
6 # http://www.apache.org/licenses/LICENSE-2.0
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.
14 """Memif interface library."""
17 from enum import IntEnum
18 from robot.api import logger
20 from resources.libraries.python.topology import NodeType, Topology
21 from resources.libraries.python.PapiExecutor import PapiExecutor
22 from resources.libraries.python.L2Util import L2Util
25 class MemifRole(IntEnum):
26 """Memif interface roles"""
32 """Memif interface class"""
38 def _memif_dump(node):
39 """Get the memif dump on the given node.
41 :param node: Given node to get Memif dump from.
43 :returns: List of memif interfaces extracted from Papi response.
46 with PapiExecutor(node) as papi_exec:
47 dump = papi_exec.add("memif_dump").get_dump()
50 for item in dump.reply[0]["api_reply"]:
51 item["memif_details"]["if_name"] = \
52 item["memif_details"]["if_name"].rstrip('\x00')
53 item["memif_details"]["hw_addr"] = \
54 L2Util.bin_to_mac(item["memif_details"]["hw_addr"])
57 logger.debug("MEMIF data:\n{data}".format(data=data))
62 def _memif_socket_filename_add_del(node, is_add, filename, sid):
63 """Create Memif socket on the given node.
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.
73 :returns: Verified data from PAPI response. In this case, the response
77 cmd = 'memif_socket_filename_add_del'
78 err_msg = 'Failed to create memif socket on host {host}'.format(
83 socket_filename=str('/tmp/' + filename)
85 with PapiExecutor(node) as papi_exec:
86 data = papi_exec.add(cmd, **args).get_replies(err_msg).\
87 verify_reply(err_msg=err_msg)
91 def _memif_create(node, mid, sid, rxq=1, txq=1, role=1):
92 """Create Memif interface on the given node.
94 :param node: Given node to create Memif interface on.
95 :param mid: Memif interface ID.
96 :param sid: Socket ID.
97 :param rxq: Number of RX queues; 0 means do not set.
98 :param txq: Number of TX queues; 0 means do not set.
99 :param role: Memif interface role [master=0|slave=1]. Default is slave.
106 :returns: Verified data from PAPI response.
110 err_msg = 'Failed to create memif interface on host {host}'.format(
119 with PapiExecutor(node) as papi_exec:
120 data = papi_exec.add(cmd, **args).get_replies(err_msg).\
121 verify_reply(err_msg=err_msg)
125 def create_memif_interface(node, filename, mid, sid, rxq=1, txq=1,
127 """Create Memif interface on the given node.
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.
143 :returns: SW interface index.
145 :raises ValueError: If command 'create memif' fails.
148 role = getattr(MemifRole, role.upper()).value
151 Memif._memif_socket_filename_add_del(node, True, filename, sid)
154 rsp = Memif._memif_create(node, mid, sid, rxq=rxq, txq=txq, role=role)
157 if_key = Topology.add_new_port(node, 'memif')
158 Topology.update_interface_sw_if_index(node, if_key, rsp["sw_if_index"])
160 ifc_name = Memif.vpp_get_memif_interface_name(node, rsp["sw_if_index"])
161 Topology.update_interface_name(node, if_key, ifc_name)
163 ifc_mac = Memif.vpp_get_memif_interface_mac(node, rsp["sw_if_index"])
164 Topology.update_interface_mac_address(node, if_key, ifc_mac)
166 Topology.update_interface_memif_socket(node, if_key, '/tmp/' + filename)
167 Topology.update_interface_memif_id(node, if_key, mid)
168 Topology.update_interface_memif_role(node, if_key, str(role))
170 return rsp["sw_if_index"]
173 def show_memif(node):
174 """Show Memif data for the given node.
176 :param node: Given node to show Memif data on.
180 Memif._memif_dump(node)
183 def show_memif_on_all_duts(nodes):
184 """Show Memif data on all DUTs.
186 :param nodes: Topology nodes.
189 for node in nodes.values():
190 if node['type'] == NodeType.DUT:
191 Memif.show_memif(node)
194 def vpp_get_memif_interface_name(node, sw_if_idx):
195 """Get Memif interface name from Memif interfaces dump.
197 :param node: DUT node.
198 :param sw_if_idx: DUT node.
201 :returns: Memif interface name, or None if not found.
205 dump = Memif._memif_dump(node)
208 if item["memif_details"]["sw_if_index"] == sw_if_idx:
209 return item["memif_details"]["if_name"]
213 def vpp_get_memif_interface_mac(node, sw_if_idx):
214 """Get Memif interface MAC address from Memif interfaces dump.
216 :param node: DUT node.
217 :param sw_if_idx: DUT node.
220 :returns: Memif interface MAC address, or None if not found.
224 dump = Memif._memif_dump(node)
227 if item["memif_details"]["sw_if_index"] == sw_if_idx:
228 return item["memif_details"]["hw_addr"]