From f939f4eb05f55e7e4c81e1b5dc954c3fc06d2389 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 31 Oct 2026 11:53:23 +0100 Subject: T3871: bind interface names to hardware slots instead of hw-id (#2246) * docs: T3871: describe how interface names are assigned Names are no longer derived from the hw-id node. They are bound to the slot the hardware occupies and recorded in a mapping file, so document what decides a name, what happens when a card is replaced or added, and how to rename an interface. The troubleshooting page said to pin a MAC with hw-id when interfaces were renamed after a VM migration or a clone. That node no longer exists and the situation it describes no longer arises, so replace it with a pointer to the new section and a note on where to look when an interface really is missing. * docs: T3871: drop hw-id from the example output The node is gone from the CLI, so example configuration dumps which still show it no longer match what a reader sees on their own system. Remove it from the shown output only; no prose changes. The comparison shown on the testing page is rewritten rather than trimmed, as deleting the lines would have left an edit level behind with nothing under it. --- docs/automation/vyos-api.md | 3 - docs/cli.md | 14 +-- docs/configexamples/inter-vrf-routing-vrf-lite.md | 1 - docs/configexamples/zone-policy.md | 1 - docs/configuration/interfaces/ethernet.md | 135 ++++++++++++++++++++++ docs/configuration/interfaces/wireless.md | 2 - docs/contributing/testing.md | 6 - docs/troubleshooting/interfaces.md | 49 ++++---- 8 files changed, 159 insertions(+), 52 deletions(-) (limited to 'docs') diff --git a/docs/automation/vyos-api.md b/docs/automation/vyos-api.md index 19524d7f..ffbd92f3 100644 --- a/docs/automation/vyos-api.md +++ b/docs/automation/vyos-api.md @@ -172,12 +172,10 @@ response (shortened) "eth0": { "address": "dhcp", "duplex": "auto", - "hw-id": "50:00:00:01:00:00", "speed": "auto" }, "eth1": { "duplex": "auto", - "hw-id": "50:00:00:01:00:01", "speed": "auto" ... }, @@ -435,7 +433,6 @@ response (shortened): { "success": true, "data": "set interfaces ethernet eth0 address 'dhcp'\n - set interfaces ethernet eth0 hw-id '50:00:00:01:00:00'\n set system host-name 'vyos'\n ...", "error": null diff --git a/docs/cli.md b/docs/cli.md index da9993bc..0728ebae 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -253,7 +253,6 @@ vyos@vyos:~$ show configuration interfaces { ethernet eth0 { address dhcp - hw-id 00:53:00:00:aa:01 } loopback lo { } @@ -314,7 +313,6 @@ Get a collection of all the set commands required which led to the running confi :::{code-block} none vyos@vyos:~$ show configuration commands set interfaces ethernet eth0 address 'dhcp' -set interfaces ethernet eth0 hw-id '00:53:dd:44:3b:0f' set interfaces loopback 'lo' set service ssh port '22' set system config-management commit-revisions '20' @@ -343,7 +341,7 @@ Use the `show configuration commands | strip-private` command when you want to h View the current active configuration in JSON format. :::{code-block} none -{"interfaces": {"ethernet": {"eth0": {"address": ["192.0.2.11/24", "192.0.2.35/24"], "hw-id": "52:54:00:48:a0:c6"}, "eth1": {"address": ["203.0.113.1/24"], "hw-id": "52:54:00:fc:50:0b"}}, "loopback": {"lo": {}}}, "protocols": {"static": {"route": {"0.0.0.0/0": {"next-hop": {"192.0.2.254": {}}}}}}, "service": {"ssh": {"disable-host-validation": {}}}, "system": {"config-management": {"commit-revisions": "100"}, "console": {"device": {"ttyS0": {"speed": "115200"}}}, "host-name": "r11-vyos", "login": {"user": {"vyos": {"authentication": {"encrypted-password": "$6$Vt68...F0", "plaintext-password": "", "public-keys": {"vyos@vyos": {"key": "AAAAxxx=", "type": "ssh-rsa"}}}}}}, "name-server": ["203.0.113.254"], "ntp": {"server": {"time1.vyos.net": {}, "time2.vyos.net": {}, "time3.vyos.net": {}}}, "syslog": {"global": {"facility": {"all": {"level": "info"}, "protocols": {"level": "debug"}}}}, "time-zone": "America/New_York"}} +{"interfaces": {"ethernet": {"eth0": {"address": ["192.0.2.11/24", "192.0.2.35/24"]}, "eth1": {"address": ["203.0.113.1/24"]}}, "loopback": {"lo": {}}}, "protocols": {"static": {"route": {"0.0.0.0/0": {"next-hop": {"192.0.2.254": {}}}}}}, "service": {"ssh": {"disable-host-validation": {}}}, "system": {"config-management": {"commit-revisions": "100"}, "console": {"device": {"ttyS0": {"speed": "115200"}}}, "host-name": "r11-vyos", "login": {"user": {"vyos": {"authentication": {"encrypted-password": "$6$Vt68...F0", "plaintext-password": "", "public-keys": {"vyos@vyos": {"key": "AAAAxxx=", "type": "ssh-rsa"}}}}}}, "name-server": ["203.0.113.254"], "ntp": {"server": {"time1.vyos.net": {}, "time2.vyos.net": {}, "time3.vyos.net": {}}}, "syslog": {"global": {"facility": {"all": {"level": "info"}, "protocols": {"level": "debug"}}}}, "time-zone": "America/New_York"}} ::: ``` @@ -359,14 +357,12 @@ View the current active configuration in readable JSON format. "address": [ "192.0.2.11/24", "192.0.2.35/24" - ], - "hw-id": "52:54:00:48:a0:c6" + ] }, "eth1": { "address": [ "203.0.113.1/24" - ], - "hw-id": "52:54:00:fc:50:0b" + ] } }, "loopback": { @@ -496,7 +492,6 @@ vyos@vyos# show interfaces ethernet eth0 { description MY_OLD_DESCRIPTION disable - hw-id 00:53:dd:44:3b:03 } loopback lo { } @@ -512,7 +507,6 @@ vyos@vyos# show interfaces + address dhcp > description MY_NEW_DESCRIPTION - disable - hw-id 00:53:dd:44:3b:03 } loopback lo { } @@ -524,7 +518,6 @@ mode using {cfgcmd}`show | commands` ``` none vyos@vyos# show interfaces ethernet eth0 | commands set address dhcp -set hw-id 00:53:ad:44:3b:03 ``` These commands are also relative to the level you are inside and only relevant @@ -534,7 +527,6 @@ configuration blocks will be displayed when entering a sub-level. [edit interfaces ethernet eth0] vyos@vyos# show address dhcp - hw-id 00:53:ad:44:3b:03 ``` Exiting from the configuration mode is done via the {cfgcmd}`exit` command from diff --git a/docs/configexamples/inter-vrf-routing-vrf-lite.md b/docs/configexamples/inter-vrf-routing-vrf-lite.md index 2ac36904..31854b5d 100644 --- a/docs/configexamples/inter-vrf-routing-vrf-lite.md +++ b/docs/configexamples/inter-vrf-routing-vrf-lite.md @@ -670,7 +670,6 @@ set protocols static route6 ::/0 next-hop 2001:db8::1 ```none set interfaces dummy dum0 address '172.16.0.1/24' set interfaces dummy dum0 address '2001:db8:0:2::1/64' -set interfaces ethernet eth0 hw-id '50:00:00:03:00:00' set interfaces ethernet eth1 address '172.16.2.2/30' set interfaces ethernet eth1 address '2001:db8::3/127' set protocols static route 0.0.0.0/0 next-hop 172.16.2.1 diff --git a/docs/configexamples/zone-policy.md b/docs/configexamples/zone-policy.md index 2cd773a9..3f899927 100644 --- a/docs/configexamples/zone-policy.md +++ b/docs/configexamples/zone-policy.md @@ -54,7 +54,6 @@ It will look something like this: interfaces { ethernet eth0 { duplex auto - hw-id 00:53:ed:6e:2a:92 smp_affinity auto speed auto vif 10 { diff --git a/docs/configuration/interfaces/ethernet.md b/docs/configuration/interfaces/ethernet.md index eac0b443..6ca5dc6c 100644 --- a/docs/configuration/interfaces/ethernet.md +++ b/docs/configuration/interfaces/ethernet.md @@ -369,6 +369,141 @@ Uplink/core tracking. :var2: eth3 ``` +(interface-naming)= + +## Interface naming + +VyOS owns the `ethN` and `wlanN` namespace: the kernel command line carries +`net.ifnames=0`, which turns off the naming policy systemd would otherwise +apply. Which physical port gets which name is therefore decided by VyOS, and +that decision has to survive a reboot. + +### How names are assigned + +A name is bound to the **slot** the hardware sits in, not to its MAC address. +The bindings live in `/config/interface-mapping.json`: + +```{code-block} none +{ + "version": 1, + "interfaces": { + "eth0": "ID_NET_NAME_SLOT=ens18", + "eth1": "ID_PATH=pci-0000:00:13.0" + } +} +``` + +Each value is a single udev property. The most stable one the device can +offer is used, in this order: + +1. `ID_NET_NAME_ONBOARD` +2. `ID_NET_NAME_SLOT` +3. `ID_NET_NAME_PATH` +4. `ID_PATH` +5. `ID_NET_NAME_MAC` + +A firmware slot index survives PCI renumbering, a bus path does not — adding a +card can shift `pci-0000:00:13.0` but not the slot the firmware reports. The +last entry is a fallback for paravirtual buses which offer no usable topology. + +The store is rendered into one file per interface under +`/etc/systemd/network/`, named `10-vyos-.link`, so udev applies the +name as the device appears and nothing ever observes a probe-order name. + +:::{note} +The `.link` files are generated from the mapping file. Do not edit them, +they are regenerated on every boot. +::: + +A name stays reserved while its hardware is absent, so a NIC which appears +later can never inherit the name — and with it the addresses — of an +interface which is merely unplugged. Hardware the system has not seen before +is named at boot in canonical hardware order and then recorded. + +What a boot decided can be inspected in `/run/vyos-net-name-resolve.json`. + +### Replacing a network card + +Nothing needs to be done. The slot is the identity, so a replacement card in +the same slot is the same interface and keeps its configuration. This is the +case which used to require updating a `hw-id` value by hand. + +### Adding a network card + +A card which the system has not seen before is given the next free name, and +that name is appended after the ones already in use. Where the card sits has +no say in it: a card in a slot between two existing ones does **not** take a +name in the middle and push the others along, because every name already +recorded is reserved. Renumbering would move interfaces onto cables they were +never configured for. + +So on a system with `eth0` to `eth7`, a card added in any free slot becomes +`eth8`, and keeps that name once it is recorded. + +This applies to a card plugged into a running system as well. It is named as +soon as it appears, and a configuration node for it is added on the next +boot, after which it can be configured like any other interface. + +### Renaming an interface + +Renaming an interface means changing both the configuration and the mapping +file. Changing only one of them leaves the old name's settings orphaned and +the new name unconfigured. + +To rename `eth1` to `eth23`: + +```{code-block} none +vyos@vyos:~$ configure +vyos@vyos# rename interfaces ethernet eth1 to interfaces ethernet eth23 +vyos@vyos# commit +vyos@vyos# save +vyos@vyos# exit +``` + +Then change the key in the mapping file, leaving its value untouched: + +```{code-block} none +vyos@vyos:~$ sudo vi /config/interface-mapping.json +``` + +```{code-block} none +{ + "version": 1, + "interfaces": { + "eth0": "ID_NET_NAME_SLOT=ens18", + "eth23": "ID_PATH=pci-0000:00:13.0" + } +} +``` + +The new name is applied on the next boot: + +```{code-block} none +vyos@vyos:~$ reboot +``` + +:::{note} +The mapping file belongs to the `vyattacfg` group and is edited with +`sudo`. It lives on the config volume and therefore survives an image +upgrade. +::: + +### Migrating from hw-id + +`interfaces ethernet hw-id` and +`interfaces wireless hw-id` no longer exist. A name is a property +of the hardware, not of the configuration. + +Upgrading converts the existing bindings automatically: every `hw-id` is +matched against the permanent address of the hardware actually present and +the slot that card sits in is recorded. No interface changes its name across +the upgrade, including systems whose names never followed slot order. A +`hw-id` whose hardware is absent is skipped, as the configuration may well +originate from another machine. + +Setting a MAC address is unrelated to naming and is still done with +`set interfaces ethernet mac
`. + ## Operation ```{opcmd} show interfaces ethernet diff --git a/docs/configuration/interfaces/wireless.md b/docs/configuration/interfaces/wireless.md index 9e6b7c99..057ff9e1 100644 --- a/docs/configuration/interfaces/wireless.md +++ b/docs/configuration/interfaces/wireless.md @@ -803,7 +803,6 @@ interfaces { } channel 11 description "802.11ax 2.4GHz" - hw-id [...] mode ax physical-device phy0 security { @@ -884,7 +883,6 @@ interfaces { channel 5 description "802.11ax 6GHz" enable-bf-protection - hw-id [...] mgmt-frame-protection required mode ax physical-device phy0 diff --git a/docs/contributing/testing.md b/docs/contributing/testing.md index b68cad1b..46e6a881 100644 --- a/docs/contributing/testing.md +++ b/docs/contributing/testing.md @@ -178,16 +178,10 @@ Loading configuration from '/usr/libexec/vyos/tests/config/ospf-small' Load complete. Use 'commit' to make changes effective. [edit] vyos@vyos# compare -[edit interfaces ethernet eth0] --hw-id 00:50:56:bf:c5:6d [edit interfaces ethernet eth1] +duplex auto --hw-id 00:50:56:b3:38:c5 +speed auto [edit interfaces] --ethernet eth2 { -- hw-id 00:50:56:b3:9c:1d --} -vti vti1 { - address 192.0.2.1/30 -} diff --git a/docs/troubleshooting/interfaces.md b/docs/troubleshooting/interfaces.md index 553cbf90..5881842e 100644 --- a/docs/troubleshooting/interfaces.md +++ b/docs/troubleshooting/interfaces.md @@ -1,36 +1,29 @@ # Interface Names -If you find the names of your interfaces have changed, this could be because -your MAC addresses have changed. +Interface names no longer follow the MAC address of a network card. A name is +bound to the slot the hardware sits in, so the situations which used to rename +interfaces do not any more: -- For example, you have a VyOS VM with 4 Ethernet interfaces named - eth0, eth1, eth2 and eth3. Then, you migrate your VyOS VM to a different - host and find your interfaces now are eth4, eth5, eth6 and eth7. +- Migrating a VM to a different host, where the hypervisor hands out new MAC + addresses, keeps the interface names. +- Cloning a VM, for example in GNS3, keeps the interface names. +- Replacing a failed network card with a new one in the same slot keeps the + name and the configuration of that interface. - One way to fix this issue **taking control of the MAC addresses** is: +An interface whose card is removed keeps its name reserved, so a card added +later can never take over the name — and with it the addresses — of the +interface which went away. - Log into VyOS and run this command to display your interface settings. +See {ref}`interface-naming` for how names are assigned, and for the procedure +to rename an interface. - ```none - show interfaces detail - ``` +If an interface really is missing after a reboot, check which names were +resolved for this boot: - Take note of MAC addresses. +```none +cat /run/vyos-net-name-resolve.json +``` - Now, in order to update a MAC address in the configuration, run this command - specifying the interface name and MAC address you want. - - ```none - set interfaces ethernet eth0 hw-id 00:0c:29:da:a4:fe - ``` - - If it is a VM, go into the settings of the host and set the MAC address to - the settings found in the config.boot file. You can also set the MAC to - static if the host allows so. - -- Another example could be when cloning VyOS VMs in GNS3 and you get into the - same issue: interface names have changed. - - And **a more generic way to fix it** is just deleting every MAC address at - the configuration file of the cloned machine. They will be correctly - regenerated automatically. +An interface listed under `missing` has a name reserved in the mapping file, +but its hardware did not appear. That points at the card, its driver or the +slot it is plugged into, rather than at the naming. -- cgit v1.2.3