diff options
| author | Christian Breunig <christian@breunig.cc> | 2026-10-07 19:56:39 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2026-10-31 09:58:29 +0000 |
| commit | e12776075f2dde8026f523e0d86f327bac7d398c (patch) | |
| tree | 9f4f94e22d7aa752cef60536680077ce4591a7db /python | |
| parent | c73faac7f95ec837da6f964d15cc05ff9ffd2de6 (diff) | |
| download | vyos-1x-e12776075f2dde8026f523e0d86f327bac7d398c.tar.gz vyos-1x-e12776075f2dde8026f523e0d86f327bac7d398c.zip | |
interfaces: T3871: remove the hw-id node and migrate its bindings
The node decides nothing now that the mapping store owns naming, and keeping
it would leave two sources of truth free to disagree.
Existing bindings are carried into the store by matching each hw-id against
the permanent address of the hardware present, so a box named by an older
release keeps exactly the names it had. Entries whose hardware is absent are
skipped - the configuration may well originate from another machine. The
hardware address of an interface is now read off the device rather than from
the configuration.
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/ifconfig/ethernet.py | 1 | ||||
| -rw-r--r-- | python/vyos/ifconfig/ifname_store.py | 7 | ||||
| -rw-r--r-- | python/vyos/ifconfig/interface.py | 21 | ||||
| -rw-r--r-- | python/vyos/vpp/config_filter.py | 1 |
4 files changed, 20 insertions, 10 deletions
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index ab5c8a0b8..41fd6a0b9 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -114,7 +114,6 @@ class EthernetIf(Interface): 'ring_buffer.rx', 'ring_buffer.tx', 'speed', - 'hw_id', ] return bond_allowed_sections diff --git a/python/vyos/ifconfig/ifname_store.py b/python/vyos/ifconfig/ifname_store.py index 0d10fd1ef..e6a0876fd 100644 --- a/python/vyos/ifconfig/ifname_store.py +++ b/python/vyos/ifconfig/ifname_store.py @@ -121,6 +121,13 @@ def permanent_mac(ifname: str, sys_class_net: str = '/sys/class/net') -> str: return '' +def recorded_mac(ifname: str) -> str: + """The address naming recorded for this name. It outlives a dataplane + taking the port over, which leaves nothing in sysfs to read it from. + """ + return load_store().get('hardware', {}).get(ifname, '') + + def is_wireless(ifname: str, sys_class_net: str = '/sys/class/net') -> bool: """Checked via sysfs, not via the - possibly still probe-order - name.""" return (Path(sys_class_net) / ifname / 'phy80211').exists() diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 692875491..b00bbc18a 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -30,6 +30,8 @@ from vyos.configdict import list_diff from vyos.configdict import dict_merge from vyos.configdict import get_vlan_ids from vyos.defaults import directories +from vyos.ifconfig.ifname_store import permanent_mac +from vyos.ifconfig.ifname_store import recorded_mac from vyos.template import is_ipv4 from vyos.template import is_ipv6 from vyos.template import render @@ -1823,9 +1825,8 @@ class Interface(Control): from vyos.pki import load_certificate from vyos.pki import wrap_private_key - # The default is a fallback to hw_id which is not present for any interface - # other then an ethernet interface. Thus we emulate hw_id by reading back the - # Kernel assigned MAC address + # T3871: the template keys the identity off a MAC, which is no + # longer a configuration node - read it off the device if 'hw_id' not in self.config: self.config['hw_id'] = read_file(f'/sys/class/net/{self.ifname}/address') render(wpa_supplicant_conf, 'ethernet/wpa_supplicant.conf.j2', self.config) @@ -1884,12 +1885,16 @@ class Interface(Control): # method to apply()? self.config = config - # Change interface MAC address - re-set to real hardware address (hw-id) - # if custom mac is removed. Skip if bond member. + # A custom MAC wins; removing it restores the hardware address, which + # T3871 takes from what naming recorded rather than from a + # configuration node. A dataplane which has taken the port over leaves + # no device to read it from, so the record is what is left. Neither is + # there for a bridge or a tunnel, which is what keeps this a no-op for + # them. Skip if bond member. if 'is_bond_member' not in config: - mac = config.get('hw_id') - if 'mac' in config: - mac = config.get('mac') + mac = config.get('mac') or recorded_mac(self.ifname) + if not mac and os.path.exists(f'/sys/class/net/{self.ifname}/device'): + mac = permanent_mac(self.ifname) if mac: self.set_mac(mac) diff --git a/python/vyos/vpp/config_filter.py b/python/vyos/vpp/config_filter.py index f6b4aaff2..71c85cce1 100644 --- a/python/vyos/vpp/config_filter.py +++ b/python/vyos/vpp/config_filter.py @@ -33,7 +33,6 @@ def iface_filter_eth(config: Config, iface: str) -> None: 'dhcpv6-options', 'disable', 'eapol', - 'hw-id', 'ip', 'ipv6', 'mac', |
