+#!/bin/sh -e
+#
+# 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.
+#
+# (C) 2006 Marco d'Itri <md@Linux.IT>
+#
+# 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.
+
+RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'
+
+. /lib/udev/rule_generator.functions
+
+interface_name_taken() {
+ local value="$(find_all_rules 'NAME=' $INTERFACE)"
+ if [ "$value" ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+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, probably 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."
+ fi
+
+ echo ""
+ [ "$comment" ] && echo "# $comment"
+ echo "SUBSYSTEM==\"net\", $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 [ ! -e /sys/class/net/ ]; then
+ echo "/sys/class/net/ is not available, persistent interface names not saved." >&2
+ exit 0
+ fi
+
+ cd /sys/class/net/ || return 0
+
+ for INTERFACE in *; do
+ case $INTERFACE in
+ eth*|ath*|wlan*|ra*|sta*) ;;
+ *) continue ;;
+ esac
+
+ INTERFACE="$INTERFACE" DEVPATH="/class/net/$INTERFACE" \
+ /lib/udev/write_net_rules || true
+ done
+
+ exit 0
+fi
+
+if [ -z "$INTERFACE" ]; then
+ echo "Missing \$INTERFACE." >&2
+ exit 1
+fi
+
+if [ "$1" ]; then
+ MAC_ADDR="$1"
+else
+ MAC_ADDR=$(sysread address)
+fi
+
+if [ -z "$MAC_ADDR" ]; then
+ echo "No MAC address for $INTERFACE." >&2
+ exit 1
+fi
+if [ "$MAC_ADDR" = "00:00:00:00:00:00" ]; then
+ echo "NULL MAC address for $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
+
+# 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
+ echo "INTERFACE_NEW=$INTERFACE"
+ fi
+fi
+
+# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
+match="DRIVERS==\"?*\", ATTRS{address}==\"$MAC_ADDR\""
+if [ $basename = "ath" -o $basename = "wlan" ]; then
+ match="$match, ATTRS{type}==\"1\"" # do not match the wifi* interfaces
+fi
+
+write_rule "$match" "$INTERFACE" "$COMMENT"
+
+unlock_rules_file
+
+exit 0
+