#!/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 # # 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