Add support for multi port on the same phynet
Change-Id: I70db5d405d57430efa3d99034d75133287d7aa4a
This commit is contained in:
parent
1175563298
commit
71cfd3a094
|
@ -25,33 +25,31 @@ UNTAGGED_VLAN_ID = 4095
|
|||
|
||||
INVALID_MAC = '00:00:00:00:00:00'
|
||||
|
||||
# CX3
|
||||
ADMIN_GUID_PATH = "/sys/class/infiniband/%s/iov/ports/%s/admin_guids/%s"
|
||||
GUID_INDEX_PATH = "/sys/class/infiniband/%s/iov/%s/ports/%s/gid_idx/0"
|
||||
PKEY_INDEX_PATH = "/sys/class/infiniband/%s/iov/%s/ports/%s/pkey_idx/%s"
|
||||
# MLNX4
|
||||
MLNX4_ADMIN_GUID_PATH = "/sys/class/infiniband/%s/iov/ports/%s/admin_guids/%s"
|
||||
MLNX4_GUID_INDEX_PATH = "/sys/class/infiniband/%s/iov/%s/ports/%s/gid_idx/0"
|
||||
MLNX4_PKEY_INDEX_PATH = "/sys/class/infiniband/%s/iov/%s/ports/%s/pkey_idx/%s"
|
||||
|
||||
# CX4
|
||||
CX4_GUID_NODE_PATH = ('/sys/class/infiniband/%(module)s/device/sriov/'
|
||||
# MLNX5
|
||||
MLNX5_GUID_NODE_PATH = ('/sys/class/infiniband/%(module)s/device/sriov/'
|
||||
'%(vf_num)s/node')
|
||||
CX4_GUID_PORT_PATH = ('/sys/class/infiniband/%(module)s/device/sriov/'
|
||||
MLNX5_GUID_PORT_PATH = ('/sys/class/infiniband/%(module)s/device/sriov/'
|
||||
'%(vf_num)s/port')
|
||||
CX4_GUID_POLICY_PATH = ('/sys/class/infiniband/%(module)s/device/sriov/'
|
||||
MLNX5_GUID_POLICY_PATH = ('/sys/class/infiniband/%(module)s/device/sriov/'
|
||||
'%(vf_num)s/policy')
|
||||
UNBIND_PATH = '/sys/bus/pci/drivers/mlx5_core/unbind'
|
||||
BIND_PATH = '/sys/bus/pci/drivers/mlx5_core/bind'
|
||||
|
||||
INVALID_GUID_CX3 = 'ffffffffffffffff'
|
||||
INVALID_GUID_CX4 = 'ff:ff:ff:ff:ff:ff:ff:ff'
|
||||
MLNX4_INVALID_GUID = 'ffffffffffffffff'
|
||||
MLNX5_INVALID_GUID = 'ff:ff:ff:ff:ff:ff:ff:ff'
|
||||
|
||||
CONN_URL = '%(transport)s://%(addr)s:%(port)s'
|
||||
|
||||
CX3_VF_DEVICE_TYPE_LIST = ('0x1004', )
|
||||
CX4_VF_DEVICE_TYPE_LIST = ('0x1014', '0x1016')
|
||||
CX5_VF_DEVICE_TYPE_LIST = ('0x1018', )
|
||||
MLNX4_VF_DEVICE_TYPE_LIST = ('0x1004', )
|
||||
MLNX5_VF_DEVICE_TYPE_LIST = ('0x1014', '0x1016', '0x1018')
|
||||
|
||||
CX3_VF_DEVICE_TYPE = 'CX3'
|
||||
CX4_VF_DEVICE_TYPE = 'CX4'
|
||||
CX5_VF_DEVICE_TYPE = 'CX5'
|
||||
MLNX4_VF_DEVICE_TYPE = 'MLNX4'
|
||||
MLNX5_VF_DEVICE_TYPE = 'MLNX5'
|
||||
|
||||
SOCKET_OS_PORT = '60001'
|
||||
SOCKET_OS_TRANSPORT = 'tcp'
|
||||
|
|
|
@ -26,25 +26,31 @@ class DeviceDB(object):
|
|||
|
||||
def add_fabric(self, fabric, pf, pci_id, hca_port, fabric_type,
|
||||
pf_mlx_dev):
|
||||
details = {}
|
||||
details['vfs'] = {}
|
||||
details['pf'] = pf
|
||||
details['pf_device_type'] = None
|
||||
details['pci_id'] = pci_id
|
||||
details['hca_port'] = hca_port
|
||||
details['fabric_type'] = fabric_type
|
||||
details['pf_mlx_dev'] = pf_mlx_dev
|
||||
self.device_db[fabric] = details
|
||||
pf_details = {}
|
||||
pf_details['vfs'] = {}
|
||||
pf_details['pf_device_type'] = None
|
||||
pf_details['pci_id'] = pci_id
|
||||
pf_details['hca_port'] = hca_port
|
||||
pf_details['fabric_type'] = fabric_type
|
||||
pf_details['pf_mlx_dev'] = pf_mlx_dev
|
||||
if self.device_db.get(fabric) is None:
|
||||
self.device_db[fabric] = {pf: pf_details}
|
||||
else:
|
||||
self.device_db[fabric][pf] = pf_details
|
||||
|
||||
def get_fabric_details(self, fabric):
|
||||
return self.device_db[fabric]
|
||||
def get_fabric_details(self, fabric, pf=None):
|
||||
if pf is None:
|
||||
return self.device_db[fabric]
|
||||
else:
|
||||
return self.device_db[fabric][pf]
|
||||
|
||||
def set_fabric_devices(self, fabric, vfs):
|
||||
self.device_db[fabric]['vfs'] = vfs
|
||||
def set_fabric_devices(self, fabric, pf, vfs):
|
||||
self.device_db[fabric][pf]['vfs'] = vfs
|
||||
vf = six.next(six.itervalues(vfs))
|
||||
self.device_db[fabric]['pf_device_type'] = vf['vf_device_type']
|
||||
self.device_db[fabric][pf]['pf_device_type'] = vf['vf_device_type']
|
||||
|
||||
def get_dev_fabric(self, dev):
|
||||
for fabric in self.device_db:
|
||||
if dev in self.device_db[fabric]['vfs']:
|
||||
return fabric
|
||||
for pf in self.device_db[fabric]:
|
||||
if dev in self.device_db[fabric][pf]['vfs']:
|
||||
return fabric
|
||||
|
|
|
@ -23,9 +23,11 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
class eSwitchDB(object):
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, pf, vfs):
|
||||
self.port_table = {}
|
||||
self.port_policy = {}
|
||||
self.vfs = vfs
|
||||
self.pf = pf
|
||||
|
||||
def create_port(self, port_name, port_type):
|
||||
self.port_table.update({port_name: {'type': port_type,
|
||||
|
|
|
@ -67,7 +67,11 @@ class eSwitchHandler(object):
|
|||
sys.exit(1)
|
||||
|
||||
if fabric_type:
|
||||
self.eswitches[fabric] = eswitch_db.eSwitchDB()
|
||||
if self.eswitches.get(fabric) is None:
|
||||
self.eswitches[fabric] = []
|
||||
vfs = self.pci_utils.get_vfs_info(pf)
|
||||
self.eswitches[fabric].append(
|
||||
eswitch_db.eSwitchDB(pf=pf, vfs=vfs))
|
||||
self._add_fabric(fabric, pf, fabric_type)
|
||||
res_fabrics.append((fabric, pf, fabric_type))
|
||||
else:
|
||||
|
@ -88,19 +92,27 @@ class eSwitchHandler(object):
|
|||
def _add_fabric(self, fabric, pf, fabric_type):
|
||||
self.rm.add_fabric(fabric, pf, fabric_type)
|
||||
self._config_port_up(pf)
|
||||
fabric_details = self.rm.get_fabric_details(fabric)
|
||||
|
||||
for vf in fabric_details['vfs']:
|
||||
self.eswitches[fabric].create_port(vf, constants.VIF_TYPE_HOSTDEV)
|
||||
pf_fabric_details = self.rm.get_fabric_details(fabric, pf)
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
eswitch = None
|
||||
for esw in eswitches:
|
||||
if esw.pf == pf:
|
||||
eswitch = esw
|
||||
break
|
||||
for vf in pf_fabric_details['vfs']:
|
||||
eswitch.create_port(vf, constants.VIF_TYPE_HOSTDEV)
|
||||
|
||||
def _treat_added_devices(self, devices, vm_ids):
|
||||
for device in devices:
|
||||
dev, mac, fabric = device
|
||||
if fabric:
|
||||
self.eswitches[fabric].attach_vnic(
|
||||
port_name=dev, device_id=vm_ids[dev], vnic_mac=mac)
|
||||
if self.eswitches[fabric].vnic_exists(mac):
|
||||
self.eswitches[fabric].plug_nic(port_name=dev)
|
||||
for eswitch in self.eswitches[fabric]:
|
||||
if dev in eswitch.vfs:
|
||||
eswitch.attach_vnic(
|
||||
port_name=dev, device_id=vm_ids[dev], vnic_mac=mac)
|
||||
if eswitch.vnic_exists(mac):
|
||||
eswitch.plug_nic(port_name=dev)
|
||||
break
|
||||
else:
|
||||
LOG.info(_LI("No Fabric defined for device %s"), dev)
|
||||
|
||||
|
@ -108,17 +120,20 @@ class eSwitchHandler(object):
|
|||
for dev, mac in devices:
|
||||
fabric = self.rm.get_fabric_for_dev(dev)
|
||||
if fabric:
|
||||
self.eswitches[fabric].detach_vnic(vnic_mac=mac)
|
||||
for eswitch in self.eswitches[fabric]:
|
||||
if dev in eswitch.vfs:
|
||||
eswitch.detach_vnic(vnic_mac=mac)
|
||||
else:
|
||||
LOG.info(_LI("No Fabric defined for device %s"), dev)
|
||||
|
||||
def get_vnics(self, fabrics):
|
||||
vnics = {}
|
||||
for fabric in fabrics:
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
if eswitch:
|
||||
vnics_for_eswitch = eswitch.get_attached_vnics()
|
||||
vnics.update(vnics_for_eswitch)
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
if eswitches:
|
||||
for eswitch in eswitches:
|
||||
vnics_for_eswitch = eswitch.get_attached_vnics()
|
||||
vnics.update(vnics_for_eswitch)
|
||||
else:
|
||||
LOG.error(_LE("No eSwitch found for Fabric %s"), fabric)
|
||||
continue
|
||||
|
@ -126,7 +141,7 @@ class eSwitchHandler(object):
|
|||
return vnics
|
||||
|
||||
def create_port(self, fabric, vnic_type, device_id, vnic_mac, pci_slot):
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
eswitch = self._get_eswitch_for_fabric_and_pci(fabric, pci_slot)
|
||||
if eswitch:
|
||||
try:
|
||||
if eswitch.attach_vnic(
|
||||
|
@ -143,7 +158,7 @@ class eSwitchHandler(object):
|
|||
return pci_slot
|
||||
|
||||
def plug_nic(self, fabric, device_id, vnic_mac, pci_slot):
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
eswitch = self._get_eswitch_for_fabric_and_pci(fabric, pci_slot)
|
||||
if eswitch:
|
||||
eswitch.port_table[pci_slot]['vnic'] = vnic_mac
|
||||
eswitch.port_policy.update(
|
||||
|
@ -161,110 +176,129 @@ class eSwitchHandler(object):
|
|||
|
||||
def delete_port(self, fabric, vnic_mac):
|
||||
dev = None
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
if eswitch:
|
||||
dev = eswitch.detach_vnic(vnic_mac)
|
||||
if dev:
|
||||
self._config_vf_mac_address(fabric, dev)
|
||||
else:
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if eswitch and vnic_mac in eswitch.get_attached_vnics():
|
||||
dev = eswitch.detach_vnic(vnic_mac)
|
||||
if dev:
|
||||
self._config_vf_mac_address(fabric, dev)
|
||||
break
|
||||
|
||||
if dev is None:
|
||||
LOG.warning(_LW("No eSwitch found for Fabric %s"), fabric)
|
||||
return dev
|
||||
|
||||
def port_release(self, fabric, vnic_mac):
|
||||
ret = None
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
dev = None
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if eswitch and vnic_mac in eswitch.get_attached_vnics():
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
break
|
||||
if dev:
|
||||
if (eswitch.get_port_state(dev) ==
|
||||
constants.VPORT_STATE_UNPLUGGED):
|
||||
ret = self.set_vlan(
|
||||
fabric, vnic_mac, constants.UNTAGGED_VLAN_ID)
|
||||
self.port_down(fabric, vnic_mac)
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
eswitch.port_release(vnic_mac)
|
||||
eswitch.port_release(vnic_mac)
|
||||
return ret
|
||||
|
||||
def port_up(self, fabric, vnic_mac):
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
if eswitch:
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
if not dev:
|
||||
LOG.info(_LI("No device for MAC %s"), vnic_mac)
|
||||
dev = None
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if eswitch and vnic_mac in eswitch.get_attached_vnics():
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
break
|
||||
if not dev:
|
||||
LOG.info(_LI("No device for MAC %s"), vnic_mac)
|
||||
|
||||
def port_down(self, fabric, vnic_mac):
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
if eswitch:
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
if dev:
|
||||
LOG.info(_LI("IB port for MAC %s doen't support "
|
||||
"port down"), vnic_mac)
|
||||
else:
|
||||
LOG.info(_LI("No device for MAC %s"), vnic_mac)
|
||||
dev = None
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if eswitch and vnic_mac in eswitch.get_attached_vnics():
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
if dev:
|
||||
LOG.info(_LI("IB port for MAC %s doen't support "
|
||||
"port down"), vnic_mac)
|
||||
break
|
||||
if dev is None:
|
||||
LOG.info(_LI("No device for MAC %s"), vnic_mac)
|
||||
|
||||
def set_vlan(self, fabric, vnic_mac, vlan):
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
if eswitch:
|
||||
eswitch.set_vlan(vnic_mac, vlan)
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
state = eswitch.get_port_state(dev)
|
||||
if dev:
|
||||
if state in (constants.VPORT_STATE_ATTACHED,
|
||||
constants.VPORT_STATE_UNPLUGGED):
|
||||
if eswitch.get_port_table()[dev]['alias']:
|
||||
dev = eswitch.get_port_table()[dev]['alias']
|
||||
try:
|
||||
self._config_vlan_ib(fabric, dev, vlan)
|
||||
return True
|
||||
except RuntimeError:
|
||||
LOG.error(_LE('Set VLAN operation failed'))
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if eswitch and vnic_mac in eswitch.get_attached_vnics():
|
||||
eswitch.set_vlan(vnic_mac, vlan)
|
||||
dev = eswitch.get_dev_for_vnic(vnic_mac)
|
||||
state = eswitch.get_port_state(dev)
|
||||
if dev:
|
||||
if state in (constants.VPORT_STATE_ATTACHED,
|
||||
constants.VPORT_STATE_UNPLUGGED):
|
||||
if eswitch.get_port_table()[dev]['alias']:
|
||||
dev = eswitch.get_port_table()[dev]['alias']
|
||||
try:
|
||||
self._config_vlan_ib(fabric, dev, vlan)
|
||||
return True
|
||||
except RuntimeError:
|
||||
LOG.error(_LE('Set VLAN operation failed'))
|
||||
return False
|
||||
|
||||
def get_eswitch_tables(self, fabrics):
|
||||
tables = {}
|
||||
for fabric in fabrics:
|
||||
eswitch = self._get_vswitch_for_fabric(fabric)
|
||||
if eswitch:
|
||||
tables[fabric] = {
|
||||
'port_table': eswitch.get_port_table_matrix(),
|
||||
'port_policy': eswitch.get_port_policy_matrix()
|
||||
}
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if eswitch:
|
||||
tables[fabric] = {
|
||||
'port_table': eswitch.get_port_table_matrix(),
|
||||
'port_policy': eswitch.get_port_policy_matrix()
|
||||
}
|
||||
else:
|
||||
LOG.info(_LI("Get eswitch tables: No eswitch %s") % fabric)
|
||||
return tables
|
||||
|
||||
def _get_vswitch_for_fabric(self, fabric):
|
||||
def _get_eswitches_for_fabric(self, fabric):
|
||||
if fabric in self.eswitches:
|
||||
return self.eswitches[fabric]
|
||||
else:
|
||||
return
|
||||
|
||||
def _get_eswitch_for_fabric_and_pci(self, fabric, pci_slot):
|
||||
eswitches = self._get_eswitches_for_fabric(fabric)
|
||||
for eswitch in eswitches:
|
||||
if pci_slot in eswitch.vfs:
|
||||
return eswitch
|
||||
|
||||
def _config_vf_pkey(self, ppkey_idx, pkey_idx,
|
||||
pf_mlx_dev, vf_pci_id, hca_port):
|
||||
path = constants.PKEY_INDEX_PATH % (pf_mlx_dev, vf_pci_id,
|
||||
hca_port, pkey_idx)
|
||||
path = constants.MLNX4_PKEY_INDEX_PATH % (pf_mlx_dev, vf_pci_id,
|
||||
hca_port, pkey_idx)
|
||||
cmd = ['ebrctl', 'write-sys', path, ppkey_idx]
|
||||
command_utils.execute(*cmd)
|
||||
|
||||
def _get_guid_idx(self, pf_mlx_dev, dev, hca_port):
|
||||
path = constants.GUID_INDEX_PATH % (pf_mlx_dev, dev, hca_port)
|
||||
path = constants.MLNX4_ADMIN_GUID_PATH % (pf_mlx_dev, dev, hca_port)
|
||||
with open(path) as fd:
|
||||
idx = fd.readline().strip()
|
||||
return idx
|
||||
|
||||
def _get_guid_from_mac(self, mac, device_type):
|
||||
guid = None
|
||||
if device_type == constants.CX3_VF_DEVICE_TYPE:
|
||||
if device_type == constants.MLNX4_VF_DEVICE_TYPE:
|
||||
if mac is None:
|
||||
guid = constants.INVALID_GUID_CX3
|
||||
guid = constants.MLNX4_INVALID_GUID
|
||||
else:
|
||||
mac = mac.replace(':', '')
|
||||
prefix = mac[:6]
|
||||
suffix = mac[6:]
|
||||
guid = prefix + '0000' + suffix
|
||||
elif (device_type == constants.CX4_VF_DEVICE_TYPE or
|
||||
device_type == constants.CX5_VF_DEVICE_TYPE):
|
||||
elif (device_type == constants.MLNX5_VF_DEVICE_TYPE):
|
||||
if mac is None:
|
||||
guid = constants.INVALID_GUID_CX4
|
||||
guid = constants.MLNX5_INVALID_GUID
|
||||
else:
|
||||
prefix = mac[:9]
|
||||
suffix = mac[9:]
|
||||
|
@ -272,26 +306,26 @@ class eSwitchHandler(object):
|
|||
return guid
|
||||
|
||||
def _config_vf_mac_address(self, fabric, dev, vnic_mac=None):
|
||||
fabric_details = self.rm.get_fabric_details(fabric)
|
||||
vf_device_type = fabric_details['vfs'][dev]['vf_device_type']
|
||||
pf_fabric_details = self._get_pf_fabric(fabric, dev)
|
||||
vf_device_type = pf_fabric_details['vfs'][dev]['vf_device_type']
|
||||
vguid = self._get_guid_from_mac(vnic_mac, vf_device_type)
|
||||
if vf_device_type == constants.CX3_VF_DEVICE_TYPE:
|
||||
self._config_vf_mac_address_cx3(vguid, dev, fabric_details)
|
||||
elif (vf_device_type == constants.CX4_VF_DEVICE_TYPE or
|
||||
vf_device_type == constants.CX5_VF_DEVICE_TYPE):
|
||||
self._config_vf_mac_address_cx4(vguid, dev, fabric_details)
|
||||
if vf_device_type == constants.MLNX4_VF_DEVICE_TYPE:
|
||||
self._config_vf_mac_address_mlnx4(vguid, dev, pf_fabric_details)
|
||||
elif (vf_device_type == constants.MLNX5_VF_DEVICE_TYPE):
|
||||
self._config_vf_mac_address_mlnx5(vguid, dev, pf_fabric_details)
|
||||
else:
|
||||
LOG.error(_LE("Unsupported vf device type: %s "),
|
||||
vf_device_type)
|
||||
|
||||
def _config_vf_mac_address_cx3(self, vguid, dev, fabric_details):
|
||||
hca_port = fabric_details['hca_port']
|
||||
pf_mlx_dev = fabric_details['pf_mlx_dev']
|
||||
def _config_vf_mac_address_mlnx4(self, vguid, dev, pf_fabric_details):
|
||||
hca_port = pf_fabric_details['hca_port']
|
||||
pf_mlx_dev = pf_fabric_details['pf_mlx_dev']
|
||||
self._config_vf_pkey(
|
||||
INVALID_PKEY, DEFAULT_PKEY_IDX, pf_mlx_dev, dev, hca_port)
|
||||
|
||||
guid_idx = self._get_guid_idx(pf_mlx_dev, dev, hca_port)
|
||||
path = constants.ADMIN_GUID_PATH % (pf_mlx_dev, hca_port, guid_idx)
|
||||
path = constants.MLNX4_ADMIN_GUID_PATH % (
|
||||
pf_mlx_dev, hca_port, guid_idx)
|
||||
cmd = ['ebrctl', 'write-sys', path, vguid]
|
||||
command_utils.execute(*cmd)
|
||||
ppkey_idx = self._get_pkey_idx(
|
||||
|
@ -303,20 +337,20 @@ class eSwitchHandler(object):
|
|||
LOG.error(_LE("Can't find partial management pkey for"
|
||||
"%(pf)s:%(dev)s"), {'pf': pf_mlx_dev, 'dev': dev})
|
||||
|
||||
def _config_vf_mac_address_cx4(self, vguid, dev, fabric_details):
|
||||
vf_num = fabric_details['vfs'][dev]['vf_num']
|
||||
pf_mlx_dev = fabric_details['pf_mlx_dev']
|
||||
guid_node = constants.CX4_GUID_NODE_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
guid_port = constants.CX4_GUID_PORT_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
guid_poliy = constants.CX4_GUID_POLICY_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
def _config_vf_mac_address_mlnx5(self, vguid, dev, pf_fabric_details):
|
||||
vf_num = pf_fabric_details['vfs'][dev]['vf_num']
|
||||
pf_mlx_dev = pf_fabric_details['pf_mlx_dev']
|
||||
guid_node = constants.MLNX5_GUID_NODE_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
guid_port = constants.MLNX5_GUID_PORT_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
guid_poliy = constants.MLNX5_GUID_POLICY_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
for path in (guid_node, guid_port):
|
||||
cmd = ['ebrctl', 'write-sys', path, vguid]
|
||||
command_utils.execute(*cmd)
|
||||
|
||||
if vguid == constants.INVALID_GUID_CX4:
|
||||
if vguid == constants.MLNX5_INVALID_GUID:
|
||||
cmd = ['ebrctl', 'write-sys', guid_poliy, 'Down\n']
|
||||
command_utils.execute(*cmd)
|
||||
cmd = ['ebrctl', 'write-sys', constants.UNBIND_PATH, dev]
|
||||
|
@ -328,19 +362,19 @@ class eSwitchHandler(object):
|
|||
command_utils.execute(*cmd)
|
||||
|
||||
def _config_vlan_ib(self, fabric, dev, vlan):
|
||||
fabric_details = self.rm.get_fabric_details(fabric)
|
||||
hca_port = fabric_details['hca_port']
|
||||
pf_mlx_dev = fabric_details['pf_mlx_dev']
|
||||
vf_device_type = fabric_details['vfs'][dev]['vf_device_type']
|
||||
if vf_device_type == constants.CX3_VF_DEVICE_TYPE:
|
||||
self._config_vlan_ib_cx3(vlan, pf_mlx_dev, dev, hca_port)
|
||||
elif vf_device_type == constants.CX4_VF_DEVICE_TYPE:
|
||||
pf_fabric_details = self._get_pf_fabric(fabric, dev)
|
||||
hca_port = pf_fabric_details['hca_port']
|
||||
pf_mlx_dev = pf_fabric_details['pf_mlx_dev']
|
||||
vf_device_type = pf_fabric_details['vfs'][dev]['vf_device_type']
|
||||
if vf_device_type == constants.MLNX4_VF_DEVICE_TYPE:
|
||||
self._config_vlan_ib_mlnx4(vlan, pf_mlx_dev, dev, hca_port)
|
||||
elif vf_device_type == constants.MLNX5_VF_DEVICE_TYPE:
|
||||
pass
|
||||
else:
|
||||
LOG.error(_LE("Unsupported vf device type: %s "),
|
||||
vf_device_type)
|
||||
|
||||
def _config_vlan_ib_cx3(self, vlan, pf_mlx_dev, dev, hca_port):
|
||||
def _config_vlan_ib_mlnx4(self, vlan, pf_mlx_dev, dev, hca_port):
|
||||
if vlan == 0:
|
||||
ppkey_idx = self._get_pkey_idx(
|
||||
int(DEFAULT_PKEY, 16), pf_mlx_dev, hca_port)
|
||||
|
@ -372,3 +406,9 @@ class eSwitchHandler(object):
|
|||
def _config_port_up(self, dev):
|
||||
cmd = ['ip', 'link', 'set', dev, 'up']
|
||||
command_utils.execute(*cmd)
|
||||
|
||||
def _get_pf_fabric(self, fabric, dev):
|
||||
fabric_details = self.rm.get_fabric_details(fabric)
|
||||
for pf_fabric in fabric_details.values():
|
||||
if dev in pf_fabric['vfs']:
|
||||
return pf_fabric
|
||||
|
|
|
@ -38,7 +38,7 @@ class ResourceManager(object):
|
|||
pf_mlx_dev)
|
||||
vfs = self.discover_devices(pf)
|
||||
LOG.info(_LI("PF %(pf)s, vfs = %(vf)s"), {'pf': pf, 'vf': vfs})
|
||||
self.device_db.set_fabric_devices(fabric, vfs)
|
||||
self.device_db.set_fabric_devices(fabric, pf, vfs)
|
||||
|
||||
def scan_attached_devices(self):
|
||||
devices = []
|
||||
|
@ -68,8 +68,8 @@ class ResourceManager(object):
|
|||
vm_ids[dev[0]] = vm_id
|
||||
return devices, vm_ids
|
||||
|
||||
def get_fabric_details(self, fabric):
|
||||
return self.device_db.get_fabric_details(fabric)
|
||||
def get_fabric_details(self, fabric, pf=None):
|
||||
return self.device_db.get_fabric_details(fabric, pf)
|
||||
|
||||
def discover_devices(self, pf):
|
||||
return self.pci_utils.get_vfs_info(pf)
|
||||
|
@ -98,22 +98,25 @@ class ResourceManager(object):
|
|||
fabric = self.get_fabric_for_dev(dev)
|
||||
if fabric:
|
||||
fabric_details = self.get_fabric_details(fabric)
|
||||
if fabric_details['pf_device_type'] == \
|
||||
constants.CX3_VF_DEVICE_TYPE:
|
||||
hca_port = fabric_details['hca_port']
|
||||
pf_mlx_dev = fabric_details['pf_mlx_dev']
|
||||
vf_index = self.pci_utils.get_guid_index(pf_mlx_dev, dev,
|
||||
hca_port)
|
||||
elif fabric_details['pf_device_type'] in \
|
||||
[constants.CX4_VF_DEVICE_TYPE,
|
||||
constants.CX5_VF_DEVICE_TYPE]:
|
||||
vf_index = fabric_details['vfs'][dev]['vf_num']
|
||||
try:
|
||||
mac = self.macs_map[fabric][str(vf_index)]
|
||||
devs.append((dev, mac, fabric))
|
||||
except KeyError:
|
||||
LOG.warning(_LW("Failed to retrieve Hostdev MAC"
|
||||
"for dev %s"), dev)
|
||||
for pf_fabric_details in fabric_details.values():
|
||||
if (pf_fabric_details['pf_device_type'] ==
|
||||
constants.MLNX4_VF_DEVICE_TYPE):
|
||||
hca_port = pf_fabric_details['hca_port']
|
||||
pf_mlx_dev = pf_fabric_details['pf_mlx_dev']
|
||||
vf_index = self.pci_utils.get_guid_index(
|
||||
pf_mlx_dev, dev, hca_port)
|
||||
elif (pf_fabric_details['pf_device_type'] ==
|
||||
constants.MLNX5_VF_DEVICE_TYPE):
|
||||
if dev in pf_fabric_details['vfs']:
|
||||
vf_index = pf_fabric_details['vfs'][dev]['vf_num']
|
||||
else:
|
||||
continue
|
||||
try:
|
||||
mac = self.macs_map[fabric][str(vf_index)]
|
||||
devs.append((dev, mac, fabric))
|
||||
except KeyError:
|
||||
LOG.warning(_LW("Failed to retrieve Hostdev MAC"
|
||||
"for dev %s"), dev)
|
||||
else:
|
||||
LOG.info(_LI("No Fabric defined for device %s"), hostdev)
|
||||
return devs
|
||||
|
|
|
@ -79,12 +79,13 @@ class pciUtils(object):
|
|||
with open(device_type_file, 'r') as fd:
|
||||
device_type = fd.read()
|
||||
device_type = device_type.strip(os.linesep)
|
||||
if device_type in constants.CX3_VF_DEVICE_TYPE_LIST:
|
||||
device_vf_type = constants.CX3_VF_DEVICE_TYPE
|
||||
elif device_type in constants.CX4_VF_DEVICE_TYPE_LIST:
|
||||
device_vf_type = constants.CX4_VF_DEVICE_TYPE
|
||||
elif device_type in constants.CX5_VF_DEVICE_TYPE_LIST:
|
||||
device_vf_type = constants.CX5_VF_DEVICE_TYPE
|
||||
if device_type in constants.MLNX4_VF_DEVICE_TYPE_LIST:
|
||||
device_vf_type = constants.MLNX4_VF_DEVICE_TYPE
|
||||
elif device_type in constants.MLNX5_VF_DEVICE_TYPE_LIST:
|
||||
device_vf_type = constants.MLNX5_VF_DEVICE_TYPE
|
||||
else:
|
||||
raise Exception(_LE('device type %s is not '
|
||||
'supported'), device_type)
|
||||
except IOError:
|
||||
pass
|
||||
return device_vf_type
|
||||
|
@ -170,7 +171,7 @@ class pciUtils(object):
|
|||
|
||||
def get_guid_index(self, pf_mlx_dev, dev, hca_port):
|
||||
guid_index = None
|
||||
path = constants.GUID_INDEX_PATH % (pf_mlx_dev, dev, hca_port)
|
||||
path = constants.MLNX4_GUID_INDEX_PATH % (pf_mlx_dev, dev, hca_port)
|
||||
with open(path) as fd:
|
||||
guid_index = fd.readline().strip()
|
||||
return guid_index
|
||||
|
@ -185,23 +186,28 @@ class pciUtils(object):
|
|||
return
|
||||
|
||||
def get_vfs_macs_ib(self, fabric_details):
|
||||
if fabric_details['pf_device_type'] == constants.CX3_VF_DEVICE_TYPE:
|
||||
return self.get_vfs_macs_ib_cx3(fabric_details)
|
||||
elif fabric_details['pf_device_type'] == constants.CX4_VF_DEVICE_TYPE:
|
||||
return self.get_vfs_macs_ib_cx4(fabric_details)
|
||||
macs_map = {}
|
||||
for pf_fabric_details in fabric_details.values():
|
||||
if (pf_fabric_details['pf_device_type'] ==
|
||||
constants.MLNX4_VF_DEVICE_TYPE):
|
||||
macs_map.update(self.get_vfs_macs_ib_mlnx4(pf_fabric_details))
|
||||
elif (pf_fabric_details['pf_device_type'] ==
|
||||
constants.MLNX5_VF_DEVICE_TYPE):
|
||||
macs_map.update(self.get_vfs_macs_ib_mlnx5(pf_fabric_details))
|
||||
return macs_map
|
||||
|
||||
def get_vfs_macs_ib_cx3(self, fabric_details):
|
||||
def get_vfs_macs_ib_mlnx4(self, fabric_details):
|
||||
hca_port = fabric_details['hca_port']
|
||||
pf_mlx_dev = fabric_details['pf_mlx_dev']
|
||||
macs_map = {}
|
||||
guids_path = constants.ADMIN_GUID_PATH % (pf_mlx_dev, hca_port,
|
||||
guids_path = constants.MLNX4_ADMIN_GUID_PATH % (pf_mlx_dev, hca_port,
|
||||
'[1-9]*')
|
||||
paths = glob.glob(guids_path)
|
||||
for path in paths:
|
||||
vf_index = path.split('/')[-1]
|
||||
with open(path) as f:
|
||||
guid = f.readline().strip()
|
||||
if guid == constants.INVALID_GUID_CX3:
|
||||
if guid == constants.MLNX4_INVALID_GUID:
|
||||
mac = constants.INVALID_MAC
|
||||
else:
|
||||
head = guid[:6]
|
||||
|
@ -210,14 +216,15 @@ class pciUtils(object):
|
|||
macs_map[str(int(vf_index))] = mac
|
||||
return macs_map
|
||||
|
||||
def get_vfs_macs_ib_cx4(self, fabric_details):
|
||||
def get_vfs_macs_ib_mlnx5(self, fabric_details):
|
||||
vfs = fabric_details['vfs']
|
||||
macs_map = {}
|
||||
for vf in vfs.values():
|
||||
vf_num = vf['vf_num']
|
||||
pf_mlx_dev = fabric_details['pf_mlx_dev']
|
||||
guid_path = constants.CX4_GUID_NODE_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num}
|
||||
guid_path = (
|
||||
constants.MLNX5_GUID_NODE_PATH % {'module': pf_mlx_dev,
|
||||
'vf_num': vf_num})
|
||||
with open(guid_path) as f:
|
||||
guid = f.readline().strip()
|
||||
head = guid[:8]
|
||||
|
|
|
@ -404,7 +404,7 @@ def main():
|
|||
|
||||
try:
|
||||
interface_mappings = q_utils.parse_mappings(
|
||||
cfg.CONF.ESWITCH.physical_interface_mappings)
|
||||
cfg.CONF.ESWITCH.physical_interface_mappings, unique_keys=False)
|
||||
except ValueError as e:
|
||||
LOG.error(_LE("Parsing physical_interface_mappings failed: %s. "
|
||||
"Agent terminated!"), e)
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# 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.
|
||||
|
||||
from networking_mlnx.eswitchd.db import device_db
|
||||
from networking_mlnx.tests import base
|
||||
|
||||
|
||||
class TestDeviceDB(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDeviceDB, self).setUp()
|
||||
self.device_db_inst = device_db.DeviceDB()
|
||||
|
||||
def _add_fabric(self):
|
||||
fabric = "fabric"
|
||||
details = {}
|
||||
details['pf'] = "pf"
|
||||
details['pci_id'] = "0000:81:00"
|
||||
details['hca_port'] = 1
|
||||
details['fabric_type'] = "fabric_type"
|
||||
details['pf_mlx_dev'] = "mlx4_0"
|
||||
self.device_db_inst.add_fabric(fabric, details['pf'],
|
||||
details['pci_id'], details['hca_port'],
|
||||
details['fabric_type'], details['pf_mlx_dev'])
|
||||
|
||||
return {"fabric": fabric, "details": details}
|
||||
|
||||
def test_add_fabric(self):
|
||||
data = self._add_fabric()
|
||||
fabric = data["fabric"]
|
||||
details = data["details"]
|
||||
|
||||
self.assertIn(fabric, self.device_db_inst.device_db)
|
||||
for key in details:
|
||||
self.assertEqual(details[key],
|
||||
self.device_db_inst.device_db[fabric][key])
|
||||
|
||||
def test_get_fabric_details(self):
|
||||
data = self._add_fabric()
|
||||
fabric = data["fabric"]
|
||||
details = data["details"]
|
||||
|
||||
self.assertIn(fabric, self.device_db_inst.device_db)
|
||||
for key in details:
|
||||
self.assertEqual(details[key],
|
||||
self.device_db_inst.get_fabric_details(fabric)[key])
|
||||
|
||||
def test_set_fabric_devices(self):
|
||||
self._add_fabric()
|
||||
fabric = "fabric"
|
||||
vfs = {}
|
||||
pci_id = "0000:81:00.1"
|
||||
vf_num = 8
|
||||
vf_device_type = "CX3"
|
||||
vfs[pci_id] = {'vf_num': vf_num, 'vf_device_type': vf_device_type}
|
||||
self.device_db_inst.set_fabric_devices(fabric, vfs)
|
||||
|
||||
details = self.device_db_inst.get_fabric_details(fabric)
|
||||
self.assertIn(pci_id, details["vfs"])
|
||||
self.assertEqual(vf_num, details["vfs"][pci_id]["vf_num"])
|
||||
self.assertEqual(vf_device_type,
|
||||
details["vfs"][pci_id]["vf_device_type"])
|
||||
|
||||
def test_get_dev_fabric_existent(self):
|
||||
self._add_fabric()
|
||||
fabric = "fabric"
|
||||
vfs = {}
|
||||
pci_id = "0000:81:00.1"
|
||||
vf_num = 8
|
||||
vf_device_type = "CX3"
|
||||
vfs[pci_id] = {'vf_num': vf_num, 'vf_device_type': vf_device_type}
|
||||
self.device_db_inst.set_fabric_devices(fabric, vfs)
|
||||
|
||||
self.assertEqual(fabric, self.device_db_inst.get_dev_fabric(pci_id))
|
||||
|
||||
def test_get_dev_fabric_inexistent(self):
|
||||
self.assertIsNone(self.device_db_inst.get_dev_fabric("inexistent_dev"))
|
Loading…
Reference in New Issue