#!/bin/sh -e
+
+# This script is run to create persistent network device naming rules
+# based on properties of the device.
+# If the interface needs to be renamed, INTERFACE_NEW=<name> will be printed
+# on stdout to allow udev to IMPORT it.
+
+# variables used to communicate:
+# MATCHADDR MAC address used for the match
+# MATCHID bus_id used for the match
+# MATCHDEVID dev_id used for the match
+# MATCHDRV driver name used for the match
+# MATCHIFTYPE interface type match
+# COMMENT comment to add to the generated rule
+# INTERFACE_NAME requested name supplied by external tool
+# INTERFACE_NEW new interface name returned by rule writer
+
+# Copyright (C) 2006 Marco d'Itri <md@Linux.IT>
+# Copyright (C) 2007 Kay Sievers <kay.sievers@vrfy.org>
#
-# This script is run if the interface (recognized by its MAC address) lacks
-# a rule for persistent naming.
-#
-# If there is already a persistent rule with that interface name then the
-# current interface needs to be renamed.
-#
-# If the interface needs to be renamed, a NAME=value pair will be printed
-# on stdout to allow udev to IMPORT it. Then a rule for the MAC address and
-# interface name is written.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
#
-# (C) 2006 Marco d'Itri <md@Linux.IT>
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation version 2 of the License.
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# debug, if UDEV_LOG=<debug>
+if [ -n "$UDEV_LOG" ]; then
+ if [ "$UDEV_LOG" -ge 7 ]; then
+ set -x
+ fi
+fi
RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'
if [ "$PRINT_HEADER" ]; then
PRINT_HEADER=
echo "# This file was automatically generated by the $0"
- echo "# program, probably run by the persistent-net-generator.rules rules file."
+ echo "# program, run by the persistent-net-generator.rules rules file."
echo "#"
- echo "# You can modify it, as long as you keep each rule on a single line."
+ echo "# You can modify it, as long as you keep each rule on a single"
+ echo "# line, and change only the value of the NAME= key."
fi
echo ""
[ "$comment" ] && echo "# $comment"
- echo "SUBSYSTEM==\"net\", $match, NAME=\"$name\""
+ echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\""
} >> $RULES_FILE
}
-# used only if $RULES_FILE is empty, like on installation
-if [ "$1" = "all_interfaces" ]; then
- if [ -e $RULES_FILE ]; then
- printf "$RULES_FILE exists, persistent interface names\nnot saved.\n" >&2
- exit 0
- fi
+if [ -z "$INTERFACE" ]; then
+ echo "missing \$INTERFACE" >&2
+ exit 1
+fi
- if [ ! -e /sys/class/net/ ]; then
- echo "/sys/class/net/ is not available, persistent interface names not saved." >&2
- exit 0
- fi
+# Prevent concurrent processes from modifying the file at the same time.
+lock_rules_file
- cd /sys/class/net/ || return 0
+# Check if the rules file is writeable.
+choose_rules_file
- for INTERFACE in *; do
- case $INTERFACE in
- eth*|ath*|wlan*|ra*|sta*|ctc*|hsi*) ;;
- *) continue ;;
- esac
+# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
+if [ "$MATCHADDR" ]; then
+ match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\""
+fi
- INTERFACE="$INTERFACE" DEVPATH="/class/net/$INTERFACE" \
- /lib/udev/write_net_rules || true
- done
+if [ "$MATCHDRV" ]; then
+ match="$match, DRIVERS==\"$MATCHDRV\""
+fi
- exit 0
+if [ "$MATCHDEVID" ]; then
+ match="$match, ATTR{dev_id}==\"$MATCHDEVID\""
fi
-if [ -z "$INTERFACE" ]; then
- echo "Missing \$INTERFACE." >&2
- exit 1
+if [ "$MATCHID" ]; then
+ match="$match, KERNELS==\"$MATCHID\""
fi
-if [ "$1" ]; then
- while [ "$*" ] ; do
- case $1 in
- --mac)
- shift
- MAC_ADDR=$1
- shift
- ;;
- --driver)
- shift
- DRIVER=$1
- shift
- ;;
- --id)
- shift
- ID=$1
- shift
- ;;
- *)
- MAC_ADDR=$1
- shift
- ;;
- esac
- done
-else
- MAC_ADDR=$(sysread address)
+if [ "$MATCHIFTYPE" ]; then
+ match="$match, ATTR{type}==\"$MATCHIFTYPE\""
fi
-if [ -z "$DRIVER" ] && [ -z "$ID" ] ; then
- if [ -z "$MAC_ADDR" ]; then
- echo "No MAC address for $INTERFACE." >&2
+if [ -z "$match" ]; then
+ echo "missing valid match" >&2
+ unlock_rules_file
exit 1
- fi
- if [ "$MAC_ADDR" = "00:00:00:00:00:00" ]; then
- echo "NULL MAC address for $INTERFACE." >&2
- exit 1
- fi
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
-
-# If a rule using the current name already exists then find a new name and
-# report it to udev which will rename the interface.
basename=${INTERFACE%%[0-9]*}
-if interface_name_taken; then
- INTERFACE="$basename$(find_next_available "$basename[0-9]*")"
- if [ ! -t 1 ]; then
+match="$match, KERNEL==\"$basename*\""
+
+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
-fi
-
-# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
-if [ "$MAC_ADDR" ] ; then
- match="DRIVERS==\"?*\", ATTRS{address}==\"$MAC_ADDR\""
else
- match="DRIVERS==\"$DRIVER\", KERNELS==\"$ID\""
-fi
-if [ $basename = "ath" -o $basename = "wlan" ]; then
- match="$match, ATTRS{type}==\"1\"" # do not match the wifi* interfaces
+ # 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]*")"
+ # prevent INTERFACE from being "eth" instead of "eth0"
+ [ "$INTERFACE" = "${INTERFACE%%[ \[\]0-9]*}" ] && INTERFACE=${INTERFACE}0
+ echo "INTERFACE_NEW=$INTERFACE"
+ fi
fi
write_rule "$match" "$INTERFACE" "$COMMENT"
unlock_rules_file
exit 0
-