Fix for shared NIC with the N3000 FPGA
An issue can occur when using an N3000 FPGA NIC with upper vlan interfaces (oam, mgmt, etc). Because the N3000 is reset after the networking initialization is complete, any IPv6 addresses, or (IPv4 / IPv6) default routes configured on the vlan interfaces will be removed. This commit fixes the issue by creating an FPGA resource for puppet containing the N3000 interface name and any of the 'used by' (upper) interfaces belonging to the interface. If these resources are present, puppet will restart the upper interfaces after the N3000 FPGA is reset, allowing any configured IP addresses and routes to be restored. Depends-On: https://review.opendev.org/c/starlingx/stx-puppet/+/795710 Partial-Bug: #1931461 Change-Id: Ie6725f572a32bfe649962a6eadca498bcc2c9e7c Signed-off-by: Steven Webster <steven.webster@windriver.com>
This commit is contained in:
parent
81051adf46
commit
ec8ff34ab1
|
@ -32,6 +32,7 @@ PCI_DEVICE_VENDOR_INTEL = "8086"
|
|||
# Device Ids
|
||||
PCI_DEVICE_ID_FPGA_INTEL_5GNR_FEC_PF = "0d8f"
|
||||
PCI_DEVICE_ID_FPGA_INTEL_5GNR_FEC_VF = "0d90"
|
||||
PCI_DEVICE_ID_FPGA_INTEL_I40_PF = "0d58"
|
||||
|
||||
PCI_DEVICE_ID_ACC100_INTEL_5GNR_FEC_PF = "0d5c"
|
||||
PCI_DEVICE_ID_ACC100_INTEL_5GNR_FEC_VF = "0d5d"
|
||||
|
|
|
@ -127,6 +127,22 @@ def get_lower_interface(context, iface):
|
|||
return context['interfaces'][lower_ifname]
|
||||
|
||||
|
||||
def get_pci_device_id(port):
|
||||
"""
|
||||
Determine the PCI device id of given port.
|
||||
"""
|
||||
# The device id can be found by inspecting the '[xxxx]' at the
|
||||
# end of the port's pdevice field
|
||||
if not port or not port.get('pdevice', None):
|
||||
return None
|
||||
device_id = re.search(r'\[([0-9a-fA-F]{1,4})\]$', port['pdevice'])
|
||||
if device_id:
|
||||
device_id = device_id.group(1)
|
||||
return str(device_id)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_sriov_interface_port(context, iface):
|
||||
"""
|
||||
Determine the underlying port of the SR-IOV interface.
|
||||
|
@ -143,15 +159,10 @@ def get_sriov_interface_device_id(context, iface):
|
|||
"""
|
||||
Determine the underlying PCI device id of the SR-IOV interface.
|
||||
"""
|
||||
# The device id can be found by inspecting the '[xxxx]' at the
|
||||
# end of the port's pdevice field
|
||||
device_id = None
|
||||
port = get_sriov_interface_port(context, iface)
|
||||
if port:
|
||||
device_id = re.search(r'\[([0-9a-fA-F]{1,4})\]$', port['pdevice'])
|
||||
if device_id:
|
||||
device_id = device_id.group(1)
|
||||
return device_id
|
||||
if not port:
|
||||
return None
|
||||
return get_pci_device_id(port)
|
||||
|
||||
|
||||
def get_sriov_interface_vf_addrs(context, iface, vf_addr_list):
|
||||
|
|
|
@ -14,6 +14,7 @@ from netaddr import IPNetwork
|
|||
from oslo_log import log
|
||||
from sysinv._i18n import _
|
||||
from sysinv.common import constants
|
||||
from sysinv.common import device as dconstants
|
||||
from sysinv.common import exception
|
||||
from sysinv.common import interface
|
||||
from sysinv.common import utils
|
||||
|
@ -53,6 +54,7 @@ DHCP_METHOD = 'dhcp'
|
|||
|
||||
NETWORK_CONFIG_RESOURCE = 'platform::interfaces::network_config'
|
||||
SRIOV_CONFIG_RESOURCE = 'platform::interfaces::sriov::sriov_config'
|
||||
FPGA_CONFIG_RESOURCE = 'platform::interfaces::fpga::fpga_config'
|
||||
ADDRESS_CONFIG_RESOURCE = 'platform::network::addresses::address_config'
|
||||
ROUTE_CONFIG_RESOURCE = 'platform::network::routes::route_config'
|
||||
|
||||
|
@ -89,6 +91,7 @@ class InterfacePuppet(base.BasePuppet):
|
|||
ROUTE_CONFIG_RESOURCE: {},
|
||||
ADDRESS_CONFIG_RESOURCE: {},
|
||||
SRIOV_CONFIG_RESOURCE: {},
|
||||
FPGA_CONFIG_RESOURCE: {},
|
||||
DATA_IFACE_LIST_RESOURCE: [],
|
||||
}
|
||||
|
||||
|
@ -457,6 +460,28 @@ def is_a_mellanox_cx3_device(context, iface):
|
|||
return False
|
||||
|
||||
|
||||
def is_an_n3000_i40_device(context, iface):
|
||||
"""
|
||||
Determine if the underlying device is onboard an N3000 FPGA.
|
||||
"""
|
||||
if iface['iftype'] != constants.INTERFACE_TYPE_ETHERNET:
|
||||
# We only care about configuring specific settings for related ethernet
|
||||
# devices.
|
||||
return False
|
||||
|
||||
port = get_interface_port(context, iface)
|
||||
if not port:
|
||||
return False
|
||||
|
||||
device_id = interface.get_pci_device_id(port)
|
||||
if not device_id:
|
||||
return False
|
||||
|
||||
if device_id == dconstants.PCI_DEVICE_ID_FPGA_INTEL_I40_PF:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_master_interface(context, iface):
|
||||
"""
|
||||
Get the interface name of the given interface's master (if any). The
|
||||
|
@ -1116,6 +1141,34 @@ def get_sriov_config(context, iface):
|
|||
return config
|
||||
|
||||
|
||||
def get_n3000_config(context, iface):
|
||||
config = {}
|
||||
if is_an_n3000_i40_device(context, iface):
|
||||
port = get_interface_port(context, iface)
|
||||
if not port:
|
||||
return {}
|
||||
|
||||
device_id = interface.get_pci_device_id(port)
|
||||
if not device_id:
|
||||
return {}
|
||||
|
||||
config = {
|
||||
'ifname': port['name'],
|
||||
'device_id': device_id,
|
||||
'used_by': iface['used_by'] or []
|
||||
}
|
||||
return config
|
||||
|
||||
|
||||
def get_fpga_config(context, iface):
|
||||
"""
|
||||
Returns an FPGA interface config dictionary.
|
||||
"""
|
||||
config = {}
|
||||
config.update(get_n3000_config(context, iface))
|
||||
return config
|
||||
|
||||
|
||||
def get_common_network_config(context, iface, config, network_id=None):
|
||||
"""
|
||||
Augments a basic config dictionary with the attributes specific to an upper
|
||||
|
@ -1253,6 +1306,12 @@ def generate_network_config(context, config, iface):
|
|||
sriov_config['ifname']: format_sriov_config(sriov_config)
|
||||
})
|
||||
|
||||
fpga_config = get_fpga_config(context, iface)
|
||||
if fpga_config:
|
||||
config[FPGA_CONFIG_RESOURCE].update({
|
||||
fpga_config['ifname']: format_fpga_config(fpga_config)
|
||||
})
|
||||
|
||||
|
||||
def find_network_by_pool_uuid(context, pool_uuid):
|
||||
for networktype, network in six.iteritems(context['networks']):
|
||||
|
@ -1489,3 +1548,13 @@ def format_sriov_config(config):
|
|||
sriov_config = copy.copy(config)
|
||||
del sriov_config['ifname']
|
||||
return sriov_config
|
||||
|
||||
|
||||
def format_fpga_config(config):
|
||||
"""
|
||||
Converts a fpga_config resource dictionary to the equivalent puppet
|
||||
resource definition parameters.
|
||||
"""
|
||||
fpga_config = copy.copy(config)
|
||||
del fpga_config['ifname']
|
||||
return fpga_config
|
||||
|
|
Loading…
Reference in New Issue