From 0af1c0660d2aded9cbc2867555b7d94f281fdc09 Mon Sep 17 00:00:00 2001 From: Michal Opala Date: Wed, 25 Feb 2026 16:23:03 +0100 Subject: [PATCH 1/3] M #-: Guard against accidental PCI manipulation of primary NICs Signed-off-by: Michal Opala --- roles/helper/pci/tasks/query.yml | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/roles/helper/pci/tasks/query.yml b/roles/helper/pci/tasks/query.yml index 83be18b..a8a44ef 100644 --- a/roles/helper/pci/tasks/query.yml +++ b/roles/helper/pci/tasks/query.yml @@ -141,3 +141,41 @@ {%- endif -%} {%- endfor -%} {{- output -}} + +- when: + - pci_forbidden_addresses is undefined + - ansible_facts.default_ipv4.interface is defined + - _interfaces | count > 0 + vars: + _interfaces: >- + {{ ansible_facts[ansible_facts.default_ipv4.interface].interfaces | d([ansible_facts.default_ipv4.interface]) }} + _paths: >- + {{ _interfaces | map('regex_replace', '^(.*)$', "-p '/sys/class/net/\g<1>'") }} + block: + - name: Query udev for device info + ansible.builtin.command: + cmd: "udevadm info --json=short {{ _paths | join(' ') }}" + register: command_udevadm_info + changed_when: false + + - name: Gather forbidden PCI addresses + ansible.builtin.set_fact: + pci_forbidden_addresses: >- + {{ command_udevadm_info.stdout_lines | map('from_json') + | selectattr('ID_PATH', 'defined') + | map(attribute='ID_PATH') + | map('regex_replace', '^pci-', '') }} + +- name: Assert 'lspci_devices' contains no forbidden PCI addresses + ansible.builtin.assert: + that: (pci_forbidden_addresses is undefined) + or + (pci_forbidden_addresses | count == 0) + or + (_detected | count == 0) + fail_msg: >- + Forbidden PCI addresses {{ _detected }} detected, aborting! + Please adjust 'pci_devices' to exclude forbidden PCI addresses. + vars: + _detected: >- + {{ lspci_devices | map(attribute='Slot') | intersect(pci_forbidden_addresses) }} From b7d25f95bd138f167448d900fc973f99e2c13c55 Mon Sep 17 00:00:00 2001 From: Michal Opala Date: Thu, 26 Feb 2026 10:32:55 +0100 Subject: [PATCH 2/3] M #-: Additionally handle bond interfaces Signed-off-by: Michal Opala --- roles/helper/pci/tasks/query.yml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/roles/helper/pci/tasks/query.yml b/roles/helper/pci/tasks/query.yml index a8a44ef..c342b6b 100644 --- a/roles/helper/pci/tasks/query.yml +++ b/roles/helper/pci/tasks/query.yml @@ -144,17 +144,27 @@ - when: - pci_forbidden_addresses is undefined - - ansible_facts.default_ipv4.interface is defined + - _default is defined - _interfaces | count > 0 vars: + _facts: >- + {{ ansible_facts }} + _default: >- + {{ _facts.default_ipv4.interface }} + # NOTE: It also handles nested bridge/bond interfaces.. _interfaces: >- - {{ ansible_facts[ansible_facts.default_ipv4.interface].interfaces | d([ansible_facts.default_ipv4.interface]) }} - _paths: >- - {{ _interfaces | map('regex_replace', '^(.*)$', "-p '/sys/class/net/\g<1>'") }} + {%- set output = [] -%} + {%- for v in _facts[_default].interfaces | d(_facts[_default].slaves) | d([_facts[_default].device | d(omit)]) -%} + {{- output.append(_facts[v].slaves | d([_facts[v].device | d(omit)])) -}} + {%- endfor -%} + {{- output | flatten -}} block: - name: Query udev for device info ansible.builtin.command: cmd: "udevadm info --json=short {{ _paths | join(' ') }}" + vars: + _paths: >- + {{ _interfaces | map('regex_replace', '^(.*)$', "-p '/sys/class/net/\g<1>'") }} register: command_udevadm_info changed_when: false From 491c86d7bce8d0921a4c53cb22e7a5620bee0a27 Mon Sep 17 00:00:00 2001 From: Michal Opala Date: Thu, 26 Feb 2026 11:26:43 +0100 Subject: [PATCH 3/3] M #-: Use udevadm info --query instead of --json (fix) Signed-off-by: Michal Opala --- roles/helper/pci/tasks/query.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/roles/helper/pci/tasks/query.yml b/roles/helper/pci/tasks/query.yml index c342b6b..7ca7d52 100644 --- a/roles/helper/pci/tasks/query.yml +++ b/roles/helper/pci/tasks/query.yml @@ -161,7 +161,7 @@ block: - name: Query udev for device info ansible.builtin.command: - cmd: "udevadm info --json=short {{ _paths | join(' ') }}" + cmd: "udevadm info --query=property --property=ID_PATH --value {{ _paths | join(' ') }}" vars: _paths: >- {{ _interfaces | map('regex_replace', '^(.*)$', "-p '/sys/class/net/\g<1>'") }} @@ -171,9 +171,7 @@ - name: Gather forbidden PCI addresses ansible.builtin.set_fact: pci_forbidden_addresses: >- - {{ command_udevadm_info.stdout_lines | map('from_json') - | selectattr('ID_PATH', 'defined') - | map(attribute='ID_PATH') + {{ command_udevadm_info.stdout_lines | select | map('regex_replace', '^pci-', '') }} - name: Assert 'lspci_devices' contains no forbidden PCI addresses