автоматическое переименование и нумерация nics с использованием udev

StackOverflow https://stackoverflow.com/questions/1644771

  •  10-07-2019
  •  | 
  •  

Вопрос

Я пишу правило udev для автоматического переименования и нумерации сетевых карт с определенными MAC-адресами.

Полученное правило должно выполнять почти то же самое, что и 75-persistent-net-generator.rules (совпадать с первыми 3 байтами MAC-адреса карты, назовите его «mycard *» в зависимости от того, сколько карты этого производителя установлены, напишите правило переименования в 70-persistent-net.rules ).

Вот как далеко я дошел до сих пор:

# udev rules to name rename cards to mycard

ACTION!="add", GOTO="persistent_mycard_generator_end"
SUBSYSTEM!="net", GOTO="persistent_mycard_generator_end"

# ignore the interface if a name has already been set
NAME=="mycard*", GOTO="persistent_mycard_generator_end"

# device name whitelist
KERNEL!="eth*", GOTO="persistent_mycard_generator_end"

# read MAC address
ENV{MATCHADDR}="$attr{address}"

# match interface type
ENV{MATCHIFTYPE}="$attr{type}"

# ignore non mycard MAC addresses
ENV{MATCHADDR}!="00:11:22:*", GOTO="persistent_mycard_generator_end"

# default comment
ENV{COMMENT}=="", ENV{COMMENT}="mycard connected through ($attr{driver})"

#### THIS IS THE PART I DON'T GET ####

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

# rename interface if needed
ENV{INTERFACE_NEW}=="?*", NAME="mycard*"

#### THIS IS THE END OF THE PART I DON'T GET ####

LABEL="persistent_mycard_generator_end

Задача "ЧАСТЬ I НЕ ПОЛУЧИТЬ" следует переименовать карту (скажем, eth3) в mycard0 или, если это вторая карта в системе с совпадающим MAC-адресом mycard1 и т. д.

Заранее спасибо, flokra

Это было полезно?

Решение

Если вы установите ENV {INTERFACE} на "mycard0" перед вызовом write_net_rules он найдет для вас первую неиспользованную mycardN, напишет для нее правило и вернет имя в ENV {INTERFACE_NEW}.

Другие советы

Хорошо, вот мое решение (я тестировал его с Debian 5.0 и Ubuntu 9.04, поэтому я не уверен, работает ли он с реализациями udev других дистрибутивов):

<Ол> <Литий> <р> 75-стойкие-mycard-generator.rules
ACTION!="add", GOTO="persistent_mycard_generator_end"
SUBSYSTEM!="net", GOTO="persistent_mycard_generator_end"

# ignore the interface if a name has already been set
NAME=="?*", GOTO="persistent_mycard_generator_end"

# device name whitelist
KERNEL!="eth*", GOTO="persistent_mycard_generator_end"

# by default match on the MAC address and interface type
ENV{MATCHADDR}="$attr{address}"
ENV{MATCHIFTYPE}="$attr{type}"

# match interface dev_id
ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}"

# by default match on the MAC address and interface type
ENV{MATCHADDR}="$attr{address}"
ENV{MATCHIFTYPE}="$attr{type}"

# match interface dev_id
ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}"

# terminate processing if card is not a mycard
ENV{MATCHADDR}!="AA:BB:CC:*", GOTO="persistent_mycard_generator_end"

# provide nice comments for the generated rules
SUBSYSTEMS=="pci", ENV{COMMENT}="PCI device $attr{vendor}:$attr{device}"
SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA device $attr{card_id}:$attr{manf_id}"
SUBSYSTEMS=="usb", ENV{COMMENT}="USB device 0x$attr{idVendor}:0x$attr{idProduct}"
ENV{COMMENT}=="", ENV{COMMENT}="Unknown $env{SUBSYSTEM} device($env{DEVPATH})"
ATTRS{driver}=="?*", ENV{COMMENT}="$env{COMMENT} ($attr{driver})"

# add mycard to comment
ENV{COMMENT}="$env{COMMENT} (mycard)"

# set interface name to mycard0 (initially)
ENV{INTERFACE}="mycard0"

# generate and write the rule
DRIVERS=="?*", IMPORT{program}="write_mycard_rules"

# rename the interface if requested
ENV{INTERFACE_NEW}=="?*",NAME="$env{INTERFACE_NEW}"

LABEL="persistent_mycard_generator_end"
  • <р> write_mycard_rules

    RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'
    
    . /lib/udev/hotplug.functions
    
    interface_name_taken() {
        local value="$(find_all_rules 'NAME=' $INTERFACE)"
        if [ "$value" ]; then
            return 0
        fi
        return 1
    
    }
    
    find_next_available() {
        raw_find_next_available "$(find_all_rules 'NAME=' "$1")"
    }
    
    write_rule() {
        local match="$1"
        local name="$2"
        local comment="$3"
    
        {
        if [ "$PRINT_HEADER" ]; then
            PRINT_HEADER=
            echo "# This file was automatically generated by the <*>"
            echo "# program run by the persistent-mycard-generator.rules rules file."
            echo "#"
            echo "# You can modify it, as long as you keep each rule on a single line."
        fi
    
        echo ""
        [ "$comment" ] && echo "# $comment"
        echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\""
        } >> $RULES_FILE
    }
    
    if [ -z "$INTERFACE" ]; then
        echo "missing \$INTERFACE" >&2
        exit 1
    fi
    
    # Prevent concurrent processes from modifying the file at the same time.
    lock_rules_file
    
    # Check if the rules file is writeable.
    choose_rules_file
    
    # the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
    if [ "$MATCHADDR" ]; then
        match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\""
    fi
    
    
    if [ "$MATCHDRV" ]; then
        match="$match, DRIVERS==\"$MATCHDRV\""
    fi
    
    if [ "$MATCHDEVID" ]; then
        match="$match, ATTR{dev_id}==\"$MATCHDEVID\""
    fi
    
    
    if [ "$MATCHID" ]; then
        match="$match, KERNELS==\"$MATCHID\""
    fi        
    
    if [ "$MATCHIFTYPE" ]; then
        match="$match, ATTR{type}==\"$MATCHIFTYPE\""
    fi
    
    
    if [ -z "$match" ]; then
        echo "missing valid match" >&2
        unlock_rules_file
        exit 1
    fi
    
    basename=${INTERFACE%%[0-9]*}
    match="$match, KERNEL==\"eth*\""
    if [ "$INTERFACE_NAME" ]; then
        # external tools may request a custom name
        COMMENT="$COMMENT (custom name provided by external tool)"
    
        if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then
            INTERFACE=$INTERFACE_NAME;
            echo "INTERFACE_NEW=$INTERFACE"
        fi
    else
        # if a rule using the current name already exists, find a new name
        if interface_name_taken; then
            INTERFACE="$basename$(find_next_available "$basename[0-9]*")"
            echo "INTERFACE_NEW=$INTERFACE"
        fi
    fi
    
    write_rule "$match" "$INTERFACE" "$COMMENT"
    unlock_rules_file
    exit 0
    
  • Наиболее важными изменениями являются ENV {INTERFACE} = " mycard0 " в 75-persistent-mycard-generator.rules, который задает имя, которое должна получить карта, и match = " $ match, KERNEL == \ " eth * \ " " в write_mycard_rules, которая заставляет udev не переопределять используемую подсистему ядра с новым именем.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top