The poorly documented and understood udev system on Ubuntu now generates persistent device names for network hardware, which is a step up from the old system where device names would be reassigned at boot and hardware changes could make assosciating a name with a physical insterface very frustrating. I wanted to take this a step further and generate meaningful custom names for different classes of hardware.
Specifically, much of the work I do involves USB 4G modems that appear as an emulated ethernet device. I want specific modems to recieve device names other than eth(x) to refect the networks they run on and the hardware they use. For example, I want Pantech UML 295s to appear as vz(x) instead of eth(x). Previously, I had been doing this the manual way that gets recommended any time this question is asked on the internet and modifying the /etc/udev/rules.d/70-persistent-net.rules
file to change the name of a device after it had been plugged in. For example:
This would change the name of the card with this specific MAC address to be vz0. This method was non ideal though, because it required manual intervention each time a card was plugged in. I wanted to use udev to fully automate the process of generating better names for cards.
Rule generation is handled by the file /lib/udev/rules.d/75-persistent-net-generator.rules
which invokes the shell script /lib/udev/write_net_rules
to actually create the persistent rules file (this is all on Ubuntu and may be slightly different on other distributions).
The write_net_rules
script operates based on the values the environment variables that are set before execution and helpfully includes the variable INTERFACE_NAME
which allows “external tools” (whatever that means) to choose a name for the interface. This actually means that we won’t even need to modify the 75-persistent-net-generator.rules
file at all and can simply create our own file that will execute before it in the udev rule chain to set the INTERFACE_NAME
variable. To do this, I created /etc/udev/rules.d/71-cell-card-naming.rules
which looks like this:
The file contains two rules which provide interface names for different classes of 4G card. The match information at the beginning of each command was found using the udevadm command to print info about the device. To print all information on the Pantech card the command looked like this: udevadm info -q all --path /sys/class/net/eth2 | less
. It prints a lot of information, but the important stuff is this:
Those variables can be matched on using the ENV{} syntax, for my purposes the ID_MODEL_ID
and ID_VENDOR_ID
variables were plenty to create the 71-cell-card-naming.rules
file.
There is one last piece of the puzzle which is more messy and less fun to deal with. The write_net_rules
script has poorly thought out control flow for the section that handles custom names, which means that it doesn’t check for duplicate devices when creating custom ones and as a result you will end up with a file full of devices named vz0 if you don’t fix it. This section specifically needed to be changed:
I reworked the control flow so that the check for duplicate interface names would not get skipped if custom names were in use. Simply replace the above lines with the code shown here:
With this change you can get properly increasing persistent network names for every new piece of hardware you plug in.