{"action":"created","issue":{"url":"https://api.github.com/repos/systemd/systemd/issues/3715","repository_url":"https://api.github.com/repos/systemd/systemd","labels_url":"https://api.github.com/repos/systemd/systemd/issues/3715/labels{/name}","comments_url":"https://api.github.com/repos/systemd/systemd/issues/3715/comments","events_url":"https://api.github.com/repos/systemd/systemd/issues/3715/events","html_url":"https://github.com/systemd/systemd/issues/3715","id":165347602,"number":3715,"title":"Predictable interface naming is flawed","user":{"login":"zrm","id":3430718,"avatar_url":"https://avatars.githubusercontent.com/u/3430718?v=3","gravatar_id":"","url":"https://api.github.com/users/zrm","html_url":"https://github.com/zrm","followers_url":"https://api.github.com/users/zrm/followers","following_url":"https://api.github.com/users/zrm/following{/other_user}","gists_url":"https://api.github.com/users/zrm/gists{/gist_id}","starred_url":"https://api.github.com/users/zrm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zrm/subscriptions","organizations_url":"https://api.github.com/users/zrm/orgs","repos_url":"https://api.github.com/users/zrm/repos","events_url":"https://api.github.com/users/zrm/events{/privacy}","received_events_url":"https://api.github.com/users/zrm/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/systemd/systemd/labels/needs-reporter-feedback","name":"needs-reporter-feedback","color":"eb6420"},{"url":"https://api.github.com/repos/systemd/systemd/labels/udev","name":"udev","color":"f7c6c7"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":14,"created_at":"2016-07-13T15:17:26Z","updated_at":"2016-07-16T19:56:50Z","closed_at":"2016-07-15T17:10:58Z","body":"### Submission type\r\n\r\n  - [X] Bug report\r\n  - [X] Request for enhancement (RFE)\r\n\r\n### Used distribution\r\n\r\n> Debian/Ubuntu\r\n\r\n### Predictable interface naming is flawed\r\n\r\nThis bug describes a design flaw. It can be summarized as \"network interface names should be names, not addresses.\"\r\n\r\nNaming interfaces with physical addresses causes trouble.\r\n\r\nIt makes the simple case complicated. A majority of machines previously had eth0, maybe also wlan0, and no other physical interface. Now they have enp3s5 or enp4s0 or enxbadbadbadbad, all different names. But the admin needs the interface name when configuring services and firewall rules. It was a lot easier to remember and type eth0 than, and I swear this is the actual name it gave, enP2p32s15f0.\r\n\r\nExisting scripts and documentation reference the default names. They have to be adjusted if your specific machine has any other interface name, only now a different name is the rule rather than the exception.\r\n\r\nPeople often suggest manually renaming the interfaces back to something sensible. This has always been a common practice for firewalls and routers, where historically you had an entry in /etc/udev/rules.d/70-persistent-net.rules and could just change the 'NAME=' entry from \"eth1\" to \"outside0\" to have meaningful names. But that file is not generated by default anymore, so the user has to create an equivalent file from scratch, read more documentation, find the interface hardware address, debug more typos and formatting errors and so on. Setting interface names manually is effectively turning off the \"feature\" though, and that is now harder than before.\r\n\r\n\r\nIt also gets the less simple cases wrong.\r\n\r\nSuppose I have used the builtin network interface for a while and now upgrade by adding a faster one. If the old name was eth0 then I give the new interface the old name and I'm done. But if the old name was enp2s0 then I have an ugly choice. Either I update firewall rules and daemon configs and every other reference on the system from enp2s0 to enp4s0 and hope I don't miss anything, or now I disable \"predictable naming\" and confuse everything by renaming enp4s0 to enp2s0 even though that name would both indicate the wrong device and imply the device is using \"predictable naming\" when it isn't. \r\n\r\nUsing topology as part of an interface name also makes the names less consistent. Put a laptop in a dock, plug in a thunderbolt PCIe cage, remove a GPU https://github.com/systemd/systemd/issues/2811, change a BIOS setting https://github.com/systemd/systemd/issues/563 and you can change the PCI topology and thus the name of all or none or some of your interfaces. When udev was using hardware MAC, non-network interface changes would rarely change network interface names and could rarely if ever silently cause an interface to use the name previously held by a different interface.\r\n\r\nAnything that could unexpectedly change the name of a firewall outside interface to that of a firewall inside interface is problematic.\r\n\r\nSo here is a suggested alternative (not altogether unlike the old way).\r\n\r\nAfter all network interfaces present at boot are discovered, consult the filesystem for the names of known interfaces and assign them. If a known interface is not found but an interface with the same MAC and a different slot exists, keep the name and update the slot. If there is no interface with that MAC but there is a new interface in the same slot, keep the name and update the MAC. Then deterministically order all the unmatched physical interfaces using the firmware index or PCI bus location, name them in order ethN, ethN+1, ..., wlanN, wlanN+1 and so on and write the new interfaces to the filesystem. An interface added after boot becomes ethN+2 etc.\r\n\r\nWith deterministic reordering after detection, machines that cannot write rules to the filesystem still use deterministic names for everything present at boot. But writing the interfaces to file when possible ensures that previously seen devices always get the same names even if PCI topology changes. And makes it easier for the user to set names by updating the name in a file that already exists and describes every existing interface. Matching known interfaces first by MAC then by slot means that an interface will keep its name when moved to a different slot or when PCI is renumbered, but if a NIC is altogether removed and another is put in the same slot (i.e. replacing a bad NIC or in a VM that randomly generates the MAC) then that works too. Then the user setting a custom interface name doesn't break the system's ability to update it in those cases.\r\n\r\nAnd every device with only one ethernet/wifi interface will still default to eth0/wlan0.\r\n\r\nThis doesn't guarantee consistent names on a device without a writable filesystem after interfaces are added or removed, but neither does the current method. Firmware will commonly change PCI enumeration order based on which devices are present at POST. At least this way interface names are only based on the order of network interfaces relative to each other and not the entire universe of things that could cause any PCI renumbering.\r\n\r\nA possible variant on this is to use different names than the kernel uses to avoid the rename race. So the kernel will set interface names eth0, eth1 and we rename them to enet0, enet1. In which case the default interface becomes enet0. Or do it the other way around and have the kernel assign enetN and then rename to the traditional ethN."},"comment":{"url":"https://api.github.com/repos/systemd/systemd/issues/comments/233148089","html_url":"https://github.com/systemd/systemd/issues/3715#issuecomment-233148089","issue_url":"https://api.github.com/repos/systemd/systemd/issues/3715","id":233148089,"user":{"login":"zrm","id":3430718,"avatar_url":"https://avatars.githubusercontent.com/u/3430718?v=3","gravatar_id":"","url":"https://api.github.com/users/zrm","html_url":"https://github.com/zrm","followers_url":"https://api.github.com/users/zrm/followers","following_url":"https://api.github.com/users/zrm/following{/other_user}","gists_url":"https://api.github.com/users/zrm/gists{/gist_id}","starred_url":"https://api.github.com/users/zrm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zrm/subscriptions","organizations_url":"https://api.github.com/users/zrm/orgs","repos_url":"https://api.github.com/users/zrm/repos","events_url":"https://api.github.com/users/zrm/events{/privacy}","received_events_url":"https://api.github.com/users/zrm/received_events","type":"User","site_admin":false},"created_at":"2016-07-16T19:56:49Z","updated_at":"2016-07-16T19:56:49Z","body":"> I disagree; this was one of the biggest issues with the old 75-persistent-net generator. This breaks important use cases like building an image which then gets deployed to a lot of boards, read-only root, race conditions, you have to remember to copy it to the initrd, etc.\r\n\r\nIt's possible to use state when available and still do something reasonable when it isn't.\r\n\r\nAnd the race with the kernel can be solved by using any different name prefix than the kernel does.\r\n\r\n> And how would you programmatically determine that? If it was a \"decisive\" property and it changes, then this is to be considered a new interface. And if it was an \"unimportant\" property then you shouldn't match on it in the first place.\r\n\r\nYou've listed the main important properties. The MAC and the topology.\r\n\r\n> The problems is that none of these is unanimously better\r\n\r\nAnd if you keep state then you know both.\r\n\r\nThe problem with using only the MAC is the case where it changes, but in that case there will be no interface with that MAC. So if there *is* an interface with that MAC, it's \"that\" interface regardless of port.\r\n\r\nThen after you match every name you can on MAC, match the remaining names on port. (Though MAC-only for USB may still be right.)\r\n\r\nWhich will even DTRT when the state is \"wrong\" like an image deployed to a different board of the same model, because the MAC won't match but the port will.\r\n\r\nAnd am I missing a specific problem with the read-only root case? If the image expects any particular interface to exist then it can be in the state file even if the file can't be modified anymore, but if it doesn't then what does it matter if hardware changes could change the interface names when nothing references them?\r\n"}}
{"actor":{"display_login":"zrm"}}