Custom names for network interfaces using udev PDF Print E-mail
Thursday, 14 January 2010 10:14

Recent versions of Linux use udev to automatically identify & assign names to network interfaces so that they are persistent across reboots, regardless of whether they are hot-swappable or not.  This is an excellent idea and works really well.............unless you want to (a) clone the disk image and roll it out as a standard image to other machines and (b) use custom network interface names.

Either of these things on their own is a simple workaround:

  • Cloning:  The problem with udev & cloning is that the cloned machines will have an entry for the master machine's NIC as well as their own NIC, so if the primary interface on the master was eth0 theirs will be eth1.  This can play havoc with any custom configuration scripts you may have.  To sidestep this simply delete /etc/udev/rules.d/70-persistent-net.rules before taking your clone image.  It will be recreated on bootup by each cloned machine, and each will hence only have a record of its own NIC.
  • Custom interface Name:  For standalone machines changing the name from eth0 to a custom name like mynet0 is very straightforward.  Simply edit /etc/udev/rules.d/70-persistent-net.rules (as root) and change the NAME="eth0" field for the interface you wish to change.  (Note:  If you are not using Ubuntu the leading number in that filename may be different)


When you want to use custom interface names and clone images the first workaround still applies, but the second one doesn't because you'd have to do it all by hand.  Hence we need the interfaces to be automatically named with our custom name.

In the case of my company we wanted to use ixp0, ixp1 etc. for NICs as our other products use that convention and we want to be able to use all our custom configuration scripts.  The solution (inspired by an article on stackoverflow.com, though I did it differently) is to edit both /lib/udev/rules.d/75-persistent-net-generator.rules and /lib/udev/write_net_rules.


Changes to /lib/udev/rules.d/75-persistent-net-generator.rules:

Since we wanted all eth interfaces to use ixp0 - but don't want to alter other network interface types - I added a section just before write_net_rule is invoked which sets INTERFACE_NAME to our desired value for all ethernet devices.  I just set INTERFACE_NAME and not INTERFACE because if you set INTERFACE udev changes the kernel module used from eth* to ixp*, which clearly won't work.

    # default comment
    ENV{COMMENT}=="", ENV{COMMENT}="net device ($attr{driver})"

    # Force use of ixp for eth devices so custom scripts can be applied directly
    #   - Cian 13/01/10
    KERNEL!="eth*", GOTO="force_ixp0_naming_end"
    ENV{INTERFACE_NAME}="ixp0"
    LABEL="force_ixp0_naming_end"

    # write rule
    DRIVERS=="?*", IMPORT{program}="write_net_rules_klas"


Changes to /lib/udev/write_net_rules:

The changes to the file above result in *all* network interfaces being labelled ixp0 (thanks for catching that, Hannes) which breaks everything.  Firstly I needed to add a subroutine to detect if the ixp0 interface already exists.  There is a subroutine that does something very similar but it is hardcoded to check for $INTERFACE so I simply copied it, thus:

    # Added this function to detect whether custom name is already in use
    #   - Cian 13/01/10
    custom_interface_name_taken() {
            local value="$(find_all_rules 'NAME=' $INTERFACE_NAME)"
            if [ "$value" ]; then
                    return 0
            else
                    return 1
            fi
    }

Secondly I had to modify the code which sets the custom INTERFACE_NAME, and tell it to get the next available interface number.  Again this was copy-n-pasted from elsewhere in the code.

    if [ "$INTERFACE_NAME" ]; then
            # external tools may request a custom name
            COMMENT="$COMMENT (custom name provided by external tool)"

            # if a rule using current custom name already exists, find a new name
            #   - Cian 13/01/10
            if custom_interface_name_taken; then
                    basename=${INTERFACE_NAME%%[0-9]*}
                    INTERFACE_NAME="$basename$(find_next_available "$basename[0-9]*")"
            fi

            if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then
                    INTERFACE=$INTERFACE_NAME;
                    echo "INTERFACE_NEW=$INTERFACE"
            fi
    else


Note:  As stated at the top of 75-persistent-net-generator.rules this solution will not survive an update.  I've uploaded both files in their entirety so I don't have to recreate them next time I want to do this:  75-persistent-net-generator.rules and write_net_rules.

Note 2:  If cloning you will still need to delete /etc/udev/rules.d/70-persistent-net.rules before creating your clone image, but it will be recreated with the custom interface name.

 
Joomla Templates by Joomlashack