使用 udev 自动重命名和编号网卡

发布于 2024-08-08 21:38:00 字数 1304 浏览 6 评论 0原文

我正在编写一个 udev 规则来自动重命名具有特定 MAC 地址的 NIC 并对其进行编号。

生成的规则应该执行与 75-persistent-net-generator.rules 几乎相同的操作(匹配卡的 MAC 地址的前 3 个字节,将其命名为“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 等。

提前致谢, 弗洛克拉

I'm writing on an udev-rule to automatically rename and number NICs with specific MAC addresses.

The resulting rule should do nearly the same 75-persistent-net-generator.rules does (match first 3 bytes of the MAC address of card, name it 'mycard*' depending on how much cards of this vendor are installed, write the renaming-rule into 70-persistent-net.rules).

This is how far I've come until now:

# 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

The task "THE PART I DON'T GET" should do is to rename a card (lets say it's eth3) to mycard0 or if it's the second card in the system with a matching MAC address mycard1 and so on.

Thanks in advance,
flokra

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〗斷ホ乔殘χμё〖 2024-08-15 21:38:00

如果你在调用write_net_rules之前将ENV{INTERFACE}设置为“mycard0”,它会为你找到第一个未使用的mycardN,并为其写出规则,并返回ENV{INTERFACE_NEW}中的名称。

If you set ENV{INTERFACE} to "mycard0" before calling write_net_rules, it will find the first unused mycardN for you, write out the rule for it, and return the name in ENV{INTERFACE_NEW}.

错々过的事 2024-08-15 21:38:00

好的,这是我的解决方案(我已经使用 Debian 5.0 和 Ubuntu 9.04 对其进行了测试,因此我不确定它是否适用于其他发行版的 udev 实现):

  1. 75-persistent-mycard-generator.rules< /p>

    ACTION!="add", GOTO="persistent_mycard_generator_end"
    子系统!=“net”,GOTO=“persistent_mycard_generator_end”
    
    # 如果已经设置了名称则忽略该接口
    NAME==“?*”,GOTO =“persistent_mycard_generator_end”
    
    # 设备名称白名单
    KERNEL!="eth*", GOTO="persistent_mycard_generator_end"
    
    # 默认匹配 MAC 地址和接口类型
    ENV{MATCHADDR}="$attr{地址}"
    ENV{MATCHIFTYPE}="$attr{类型}"
    
    # 匹配接口dev_id
    ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}"
    
    # 默认匹配 MAC 地址和接口类型
    ENV{MATCHADDR}="$attr{地址}"
    ENV{MATCHIFTYPE}="$attr{类型}"
    
    # 匹配接口dev_id
    ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}"
    
    # 如果卡不是 mycard,则终止处理
    ENV{MATCHADDR}!="AA:BB:CC:*", GOTO="persistent_mycard_generator_end"
    
    # 为生成的规则提供很好的注释
    SUBSYSTEMS=="pci", ENV{COMMENT}="PCI 设备 $attr{供应商}:$attr{设备}"
    SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA 设备 $attr{card_id}:$attr{manf_id}"
    SUBSYSTEMS=="usb", ENV{COMMENT}="USB 设备 0x$attr{idVendor}:0x$attr{idProduct}"
    ENV{COMMENT}=="", ENV{COMMENT}="未知 $env{SUBSYSTEM} 设备($env{DEVPATH})"
    ATTRS{driver}=="?*", ENV{COMMENT}="$env{COMMENT} ($attr{driver})"
    
    # 将我的卡添加到评论中
    ENV{COMMENT}="$env{COMMENT} (mycard)"
    
    # 将接口名称设置为 mycard0(初始)
    ENV{INTERFACE}="mycard0"
    
    # 生成并编写规则
    驱动程序==“?*”,导入{program} =“write_mycard_rules”
    
    # 如果需要重命名接口
    ENV{INTERFACE_NEW}=="?*",NAME="$env{INTERFACE_NEW}"
    
    标签=“persistent_mycard_generator_end”
    
  2. write_mycard_rules

    RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'
    
    。 /lib/udev/hotplug.functions
    
    接口名称_taken() {
        本地值=“$(find_all_rules'NAME='$INTERFACE)”
        如果[“$值”];然后
            返回0
        菲
        返回1
    
    }
    
    查找下一个可用(){
        raw_find_next_available "$(find_all_rules 'NAME=' "$1")"
    }
    
    写规则(){
        本地匹配=“$1”
        本地名称=“$2”
        本地评论=“$3”
    
        {
        如果[“$PRINT_HEADER”];然后
            打印头=
            echo "# 这个文件是由$0自动生成的"
            echo "# 由 permanent-mycard-generator.rules 规则文件运行的程序。"
            回显“#”
            echo "# 你可以修改它,只要你将每条规则放在一行上即可。"
        菲
    
        回声“”
        [“$comment”] &&回显“#$评论”
        echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\""
        }>> $RULES_FILE
    }
    
    如果[-z“$INTERFACE”];然后
        echo "缺少\$INTERFACE" >&2
        1号出口
    菲
    
    # 防止并发进程同时修改文件。
    锁定规则文件
    
    # 检查规则文件是否可写。
    选择规则文件
    
    # 需要 DRIVERS 密钥才能不匹配网桥和 VLAN 子接口
    如果[“$MATCHADDR”];然后
        match="$match, DRIVERS==\"?*\", ATTR{地址}==\"$MATCHADDR\""
    菲
    
    
    如果[“$MATCHHDRV”];然后
        匹配=“$匹配,驱动程序==\“$MATCHHDRV\””
    菲
    
    如果[“$MATCHDEVID”];然后
        match="$match, ATTR{dev_id}==\"$MATCHDEVID\""
    菲
    
    
    如果[“$MATCHID”];然后
        match="$match, KERNELS==\"$MATCHID\""
    菲        
    
    如果[“$MATCHIFTYPE”];然后
        match="$match, ATTR{type}==\"$MATCHIFTYPE\""
    菲
    
    
    if [ -z "$match" ];然后
        echo“缺少有效匹配”>&2
        解锁规则文件
        1号出口
    菲
    
    基本名称=${接口%%[0-9]*}
    match="$match, KERNEL==\"eth*\""
    如果[“$INTERFACE_NAME”];然后
        # 外部工具可能会请求自定义名称
        COMMENT="$COMMENT(外部工具提供的自定义名称)"
    
        if [ "$INTERFACE_NAME" != "$INTERFACE" ];然后
            接口=$INTERFACE_NAME;
            回显“INTERFACE_NEW=$INTERFACE”
        菲
    别的
        # 如果使用当前名称的规则已存在,则查找新名称
        如果接口名称被采用;然后
            INTERFACE="$basename$(find_next_available "$basename[0-9]*")"
            回显“INTERFACE_NEW=$INTERFACE”
        菲
    菲
    
    write_rule“$match”“$INTERFACE”“$COMMENT”
    解锁规则文件
    出口0
    

最重要的更改是 75-persistent-mycard-generator.rules 中的 ENV{INTERFACE}="mycard0",它设置卡应获取的名称和 match="$match, KERNEL==\"eth*\"" 强制 udev 不使用新名称覆盖已使用的内核子系统。

OK, here's my solution (I've tested it with Debian 5.0 and Ubuntu 9.04, so I'm not sure if it works with the udev-implementations of other distributions):

  1. 75-persistent-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
    

The most important changes are ENV{INTERFACE}="mycard0" in 75-persistent-mycard-generator.rules which sets the name the card should get and match="$match, KERNEL==\"eth*\"" in write_mycard_rules which forces udev to not override the used Kernel Subsystem with the new name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文