3 # This script is run if the interface (recognized by its MAC address) lacks
4 # a rule for persistent naming.
6 # If there is already a persistent rule with that interface name then the
7 # current interface needs to be renamed.
9 # If the interface needs to be renamed, a NAME=value pair will be printed
10 # on stdout to allow udev to IMPORT it. Then a rule for the MAC address and
11 # interface name is written.
13 # (C) 2006 Marco d'Itri <md@Linux.IT>
15 # This program is free software; you can redistribute it and/or modify it
16 # under the terms of the GNU General Public License as published by the
17 # Free Software Foundation version 2 of the License.
19 RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'
21 . /lib/udev/rule_generator.functions
23 interface_name_taken() {
24 local value="$(find_all_rules 'NAME=' $INTERFACE)"
32 find_next_available() {
33 raw_find_next_available "$(find_all_rules 'NAME=' "$1")"
42 if [ "$PRINT_HEADER" ]; then
44 echo "# This file was automatically generated by the $0"
45 echo "# program, probably run by the persistent-net-generator.rules rules file."
47 echo "# You can modify it, as long as you keep each rule on a single line."
51 [ "$comment" ] && echo "# $comment"
52 echo "SUBSYSTEM==\"net\", $match, NAME=\"$name\""
56 # used only if $RULES_FILE is empty, like on installation
57 if [ "$1" = "all_interfaces" ]; then
58 if [ -e $RULES_FILE ]; then
59 printf "$RULES_FILE exists, persistent interface names\nnot saved.\n" >&2
63 if [ ! -e /sys/class/net/ ]; then
64 echo "/sys/class/net/ is not available, persistent interface names not saved." >&2
68 cd /sys/class/net/ || return 0
70 for INTERFACE in *; do
72 eth*|ath*|wlan*|ra*|sta*) ;;
76 INTERFACE="$INTERFACE" DEVPATH="/class/net/$INTERFACE" \
77 /lib/udev/write_net_rules || true
83 if [ -z "$INTERFACE" ]; then
84 echo "Missing \$INTERFACE." >&2
91 MAC_ADDR=$(sysread address)
94 if [ -z "$MAC_ADDR" ]; then
95 echo "No MAC address for $INTERFACE." >&2
98 if [ "$MAC_ADDR" = "00:00:00:00:00:00" ]; then
99 echo "NULL MAC address for $INTERFACE." >&2
103 # Prevent concurrent processes from modifying the file at the same time.
106 # Check if the rules file is writeable.
109 # If a rule using the current name already exists then find a new name and
110 # report it to udev which will rename the interface.
111 basename=${INTERFACE%%[0-9]*}
112 if interface_name_taken; then
113 INTERFACE="$basename$(find_next_available "$basename[0-9]*")"
115 echo "INTERFACE_NEW=$INTERFACE"
119 # the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
120 match="DRIVERS==\"?*\", ATTRS{address}==\"$MAC_ADDR\""
121 if [ $basename = "ath" -o $basename = "wlan" ]; then
122 match="$match, ATTRS{type}==\"1\"" # do not match the wifi* interfaces
125 write_rule "$match" "$INTERFACE" "$COMMENT"