#!/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 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 } if [ -z "$INTERFACE" ]; then echo "Missing \$INTERFACE." >&2 exit 1 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) fi if [ -z "$DRIVER" ] && [ -z "$ID" ] ; then 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 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 if [ "$MAC_ADDR" ] ; then match="DRIVERS==\"?*\", ATTR{address}==\"$MAC_ADDR\"" else match="DRIVERS==\"$DRIVER\", KERNELS==\"$ID\"" fi if [ $basename = "ath" -o $basename = "wlan" ]; then match="$match, ATTR{type}==\"1\"" # do not match the wifi* interfaces fi write_rule "$match" "$INTERFACE" "$COMMENT" unlock_rules_file exit 0