From 581baa7a1ea6b8e6fa22a45d939a15fca9541012 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Tue, 24 Mar 2026 15:29:13 -0700 Subject: [PATCH 1/4] fix: add fallback to lspci when udevadm doesn't include NIC model name Signed-off-by: Harper, Jason M --- internal/script/scripts.go | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/internal/script/scripts.go b/internal/script/scripts.go index f764d8c5..b1e5c0ce 100644 --- a/internal/script/scripts.go +++ b/internal/script/scripts.go @@ -845,8 +845,34 @@ rdmsr 0x2FFE udevadm_out=$(udevadm info --query=all --path=/sys/class/net/"$ifc") echo "Vendor ID: $(echo "$udevadm_out" | grep ID_VENDOR_ID= | cut -d'=' -f2)" echo "Model ID: $(echo "$udevadm_out" | grep ID_MODEL_ID= | cut -d'=' -f2)" - echo "Vendor: $(echo "$udevadm_out" | grep ID_VENDOR_FROM_DATABASE= | cut -d'=' -f2)" - echo "Model: $(echo "$udevadm_out" | grep ID_MODEL_FROM_DATABASE= | cut -d'=' -f2)" + vendor=$(echo "$udevadm_out" | grep ID_VENDOR_FROM_DATABASE= | cut -d'=' -f2) + echo "Vendor: $vendor" + model=$(echo "$udevadm_out" | grep ID_MODEL_FROM_DATABASE= | cut -d'=' -f2) + # fall back to lspci if model is not available from udevadm, and trim vendor prefix if present (e.g. "Intel Ethernet Controller" -> "Ethernet Controller") + if [ -z "$model" ]; then + id_path=$(echo "$udevadm_out" | grep ID_PATH= | cut -d'=' -f2) + bdf=${id_path##*-} + # ID_PATH may include the domain (0000:49:00.0); lspci typically prints 49:00.0. + if [[ "$bdf" == *:*:* ]]; then + bdf=${bdf#*:} + fi + if [ -n "$bdf" ] && command -v lspci >/dev/null 2>&1; then + model=$(lspci -i pci.ids.gz | awk -v bdf="$bdf" 'tolower($0) ~ /ethernet/ && $1 == bdf { pos = index($0, ": "); if (pos > 0) print substr($0, pos + 2); exit }') + if [ -n "$model" ] && [ -n "$vendor" ]; then + model=$(awk -v vendor="$vendor" -v model="$model" 'BEGIN { + v = tolower(vendor) + m = tolower(model) + out = model + if (v != "" && substr(m, 1, length(v)) == v) { + out = substr(model, length(v) + 1) + sub(/^[[:space:]]+/, "", out) + } + print out + }') + fi + fi + fi + echo "Model: $model" echo "MTU: $(cat /sys/class/net/"$ifc"/mtu 2>/dev/null)" echo "$ethtool_out" echo "$ethtool_i_out" @@ -883,7 +909,7 @@ rdmsr 0x2FFE echo "----------------------------------------" done `, - Depends: []string{"ethtool"}, + Depends: []string{"ethtool", "lspci", "pci.ids.gz"}, Superuser: true, }, IRQBalanceScriptName: { From 310e7540fc35e79ab53b99745149afc1011acaaf Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Tue, 24 Mar 2026 15:29:34 -0700 Subject: [PATCH 2/4] don't include virtual interfaces in summary Signed-off-by: Harper, Jason M --- internal/extract/nic.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/extract/nic.go b/internal/extract/nic.go index faecfae9..8e2f1451 100644 --- a/internal/extract/nic.go +++ b/internal/extract/nic.go @@ -229,18 +229,22 @@ func NICIrqMappingsFromOutput(outputs map[string]script.ScriptOutput) [][]string // NICSummaryFromOutput returns a summary of installed NICs. func NICSummaryFromOutput(outputs map[string]script.ScriptOutput) string { nics := ParseNicInfo(outputs[script.NicInfoScriptName].Stdout) - if len(nics) == 0 { - return "N/A" - } modelCount := make(map[string]int) for _, nic := range nics { + // don't include virtual functions or bridge devices in the summary as they are not physical NICs, and we want the summary to reflect physical hardware + if strings.Contains(nic.Name, "(virtual)") || nic.Driver == "bridge" { + continue + } + if nic.Model == "" { + nic.Model = nic.Vendor + " Unknown Model" + } modelCount[nic.Model]++ } + if len(modelCount) == 0 { + return "N/A" + } var summary []string for model, count := range modelCount { - if model == "" { - model = "Unknown NIC" - } summary = append(summary, fmt.Sprintf("%dx %s", count, model)) } return strings.Join(summary, ", ") From 6cabcedde85278574b3e78d8a73077dfbf0df510 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Tue, 24 Mar 2026 16:01:23 -0700 Subject: [PATCH 3/4] improve check for virtual interface Signed-off-by: Harper, Jason M --- internal/extract/nic.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/extract/nic.go b/internal/extract/nic.go index 8e2f1451..3a634802 100644 --- a/internal/extract/nic.go +++ b/internal/extract/nic.go @@ -232,11 +232,16 @@ func NICSummaryFromOutput(outputs map[string]script.ScriptOutput) string { modelCount := make(map[string]int) for _, nic := range nics { // don't include virtual functions or bridge devices in the summary as they are not physical NICs, and we want the summary to reflect physical hardware - if strings.Contains(nic.Name, "(virtual)") || nic.Driver == "bridge" { + if nic.IsVirtual || strings.Contains(nic.Name, "(virtual)") || nic.Driver == "bridge" { continue } - if nic.Model == "" { - nic.Model = nic.Vendor + " Unknown Model" + if strings.TrimSpace(nic.Model) == "" { + vendor := strings.TrimSpace(nic.Vendor) + if vendor == "" { + nic.Model = "Unknown Vendor and Model" + } else { + nic.Model = vendor + " Unknown Model" + } } modelCount[nic.Model]++ } From 7bc5e4ddd7e5d22b8d197db4051c4b348de17a25 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Tue, 24 Mar 2026 16:01:38 -0700 Subject: [PATCH 4/4] more efficient extraction of model Signed-off-by: Harper, Jason M --- internal/script/scripts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/script/scripts.go b/internal/script/scripts.go index b1e5c0ce..55e7a68e 100644 --- a/internal/script/scripts.go +++ b/internal/script/scripts.go @@ -857,7 +857,7 @@ rdmsr 0x2FFE bdf=${bdf#*:} fi if [ -n "$bdf" ] && command -v lspci >/dev/null 2>&1; then - model=$(lspci -i pci.ids.gz | awk -v bdf="$bdf" 'tolower($0) ~ /ethernet/ && $1 == bdf { pos = index($0, ": "); if (pos > 0) print substr($0, pos + 2); exit }') + model=$(lspci -s "$bdf" -i pci.ids.gz | awk 'NR == 1 { pos = index($0, ": "); if (pos > 0) print substr($0, pos + 2); exit }') if [ -n "$model" ] && [ -n "$vendor" ]; then model=$(awk -v vendor="$vendor" -v model="$model" 'BEGIN { v = tolower(vendor)