summaryrefslogtreecommitdiff
path: root/ironic_python_agent/hardware_managers
diff options
context:
space:
mode:
authorMoshe Levi <moshele@mellanox.com>2016-11-17 02:11:04 +0200
committerSzymon Borkowski <szymon.borkowski@intel.com>2016-11-22 15:46:12 +0100
commit1bdcd4449f6dc3c39cffcefa8efba243b7c00456 (patch)
tree7da005a297795141feb1859d0bbba4deba2cf8ac /ironic_python_agent/hardware_managers
parentf9236682f7bb7048e607bd9235cf14d2088806ff (diff)
downloadironic-python-agent-1bdcd4449f6dc3c39cffcefa8efba243b7c00456.tar.gz
Add a new Hardware Manager for Mellanox NICs
This patch add Mellanox Manager to support Mellanox InfiniBand NICs. It adds client_id to the NetworkInterface for the InfiniBand network interface. The Mellanox Manager provides it own implementation of get_interface_info. The mlnx get_interface_info generate InfiniBand MAC and client-id from the InfiniBand network interface address. Closes-Bug: #1532534 Change-Id: I4e7f7649a1bdeaa3ee99b2748037b0f37fea486c
Diffstat (limited to 'ironic_python_agent/hardware_managers')
-rw-r--r--ironic_python_agent/hardware_managers/__init__.py0
-rw-r--r--ironic_python_agent/hardware_managers/mlnx.py111
2 files changed, 111 insertions, 0 deletions
diff --git a/ironic_python_agent/hardware_managers/__init__.py b/ironic_python_agent/hardware_managers/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ironic_python_agent/hardware_managers/__init__.py
diff --git a/ironic_python_agent/hardware_managers/mlnx.py b/ironic_python_agent/hardware_managers/mlnx.py
new file mode 100644
index 00000000..63ef5b32
--- /dev/null
+++ b/ironic_python_agent/hardware_managers/mlnx.py
@@ -0,0 +1,111 @@
+# Copyright 2016 Mellanox Technologies, Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import os
+
+from ironic_python_agent import errors
+from ironic_python_agent import hardware
+from ironic_python_agent import netutils
+from oslo_log import log
+
+LOG = log.getLogger()
+# Mellanox NIC Vendor ID
+MLNX_VENDOR_ID = '0x15b3'
+# Mellanox Prefix to generate InfiniBand CLient-ID
+MLNX_INFINIBAND_CLIENT_ID_PREFIX = 'ff:00:00:00:00:00:02:00:00:02:c9:00:'
+
+
+def _infiniband_address_to_mac(address):
+ """Convert InfiniBand address to MAC
+
+ Convert InfiniBand address to MAC by Mellanox specific
+ translation. The InfiniBand address is 59 characters
+ composed from GID:GUID. The last 24 characters are the
+ GUID. The InfiniBand MAC is upper 10 characters and lower
+ 9 characters from the GUID
+ Example:
+ address - a0:00:00:27:fe:80:00:00:00:00:00:00:7c:fe:90:03:00:29:26:52
+ GUID - 7c:fe:90:03:00:29:26:52
+ InfiniBand MAC - 7c:fe:90:29:26:52
+
+ :param address: InfiniBand Address.
+ :returns: InfiniBand MAC.
+ """
+ return address[36:-14] + address[51:]
+
+
+def _generate_client_id(address):
+ """Generate client id from InfiniBand address
+
+ :param address: InfiniBand address.
+ :returns: client id.
+ """
+ return MLNX_INFINIBAND_CLIENT_ID_PREFIX + address[36:]
+
+
+def _detect_hardware():
+ """method for detection of Mellanox NICs
+
+ :return True/False
+ """
+ iface_names = os.listdir('/sys/class/net')
+ for ifname in iface_names:
+ if (hardware._get_device_info(ifname, 'net', 'vendor') ==
+ MLNX_VENDOR_ID):
+ return True
+ return False
+
+
+class MellanoxDeviceHardwareManager(hardware.HardwareManager):
+ """Mellanox hardware manager to support a single device"""
+
+ HARDWARE_MANAGER_NAME = 'MellanoxDeviceHardwareManager'
+ HARDWARE_MANAGER_VERSION = '1'
+
+ def evaluate_hardware_support(self):
+ """Declare level of hardware support provided."""
+
+ if _detect_hardware():
+ LOG.debug('Found Mellanox device')
+ return hardware.HardwareSupport.MAINLINE
+ else:
+ LOG.debug('No Mellanox devices found')
+ return hardware.HardwareSupport.NONE
+
+ def get_interface_info(self, interface_name):
+ """Return the interface information when its Mellanox and InfiniBand
+
+ In case of Mellanox and InfiniBand interface we do the following:
+ 1. Calculate the "InfiniBand MAC" according to InfiniBand GUID
+ 2. Calculate the client-id according to InfiniBand GUID
+ """
+
+ addr_path = '/sys/class/net/{0}/address'.format(interface_name)
+ with open(addr_path) as addr_file:
+ address = addr_file.read().strip()
+ vendor = hardware._get_device_info(interface_name, 'net', 'vendor')
+ if (len(address) != netutils.INFINIBAND_ADDR_LEN or
+ vendor != MLNX_VENDOR_ID):
+ raise errors.IncompatibleHardwareMethodError()
+
+ mac_addr = _infiniband_address_to_mac(address)
+ client_id = _generate_client_id(address)
+
+ return hardware.NetworkInterface(
+ interface_name, mac_addr,
+ ipv4_address=netutils.get_ipv4_addr(interface_name),
+ has_carrier=netutils.interface_has_carrier(interface_name),
+ lldp=None,
+ vendor=vendor,
+ product=hardware._get_device_info(interface_name, 'net', 'device'),
+ client_id=client_id)