إعادة التسمية والترقيم التلقائي لـ nics باستخدام udev

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

  •  10-07-2019
  •  | 
  •  

سؤال

أنا أكتب وفقًا لقاعدة udev لإعادة تسمية وترقيم بطاقات NIC تلقائيًا باستخدام عناوين MAC محددة.

يجب أن تفعل القاعدة الناتجة نفس الشيء تقريبًا 75-persistent-net-generator.rules يقوم بمطابقة البايتات الثلاثة الأولى من عنوان 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

المهمة "الجزء الذي لم أحصل عليه" التي يجب أن تقوم بها هي إعادة تسمية البطاقة (لنفترض أنها eth3) إلى mycard0 أو إذا كانت البطاقة الثانية في النظام التي لها عنوان MAC مطابق mycard1 وما إلى ذلك.

شكرا مقدما ، flokra

هل كانت مفيدة؟

المحلول

إذا قمت بتعيين ENV {INTERFACE} ل"mycard0" قبل استدعاء write_net_rules، وسوف تجد أول غير المستخدمة mycardN بالنسبة لك، الكتابة خارج قاعدة لذلك، وإرجاع اسم في ENV {INTERFACE_NEW}.

نصائح أخرى

حسنًا، هذا هو الحل (لقد اختبرته مع Debian 5.0 وUbuntu 9.04، لذا لست متأكدًا مما إذا كان يعمل مع تطبيقات udev للتوزيعات الأخرى):

  1. 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"
    
  2. 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 $0"
            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 عدم تجاوز نظام Kernel الفرعي المستخدم بالاسم الجديد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top