+ When nic_slot and nic_ports are both supplied, the function will just return
+ the PCI addresses for them. The logic used is:
+ (1) Run "dmidecode -t slot"
+ (2) Grep for "SlotID:" with given nic_slot, and derive the bus address;
+ (3) Based on given nic_ports, generate the pci addresses based on above
+ base address;
+
+ When either nic_slot or nic_ports is not supplied, the function will
+ traverse all Intel NICs which use i40e or ixgbe driver, sorted by PCI
+ address, and return first two available ports which are not bonded
+ (802.11ad).
+ """
+
+ if nic_slot and nic_ports:
+ dmidecode = subprocess.check_output(['dmidecode', '-t', 'slot'])
+ regex = r"(?<=SlotID:{}).*?(....:..:..\..)".format(nic_slot)
+ match = re.search(regex, dmidecode.decode('utf-8'), flags=re.DOTALL)
+ if not match:
+ return None
+
+ pcis = []
+ # On some servers, the "Bus Address" returned by dmidecode is not the
+ # base pci address of the NIC. So only keeping the bus part of the
+ # address for better compability.
+ bus = match.group(1)[:match.group(1).rindex(':') + 1] + "00."
+ for port in nic_ports:
+ pcis.append(bus + str(port))
+
+ return pcis
+
+ hx = r'[0-9a-fA-F]'
+ regex = r'({hx}{{4}}:({hx}{{2}}:{hx}{{2}}\.{hx}{{1}})).*(drv={driver}|.*unused=.*{driver})'
+ pcis = []