1#!/bin/sh -e 2 3# This script is run to create persistent network device naming rules 4# based on properties of the device. 5# If the interface needs to be renamed, INTERFACE_NEW=<name> will be printed 6# on stdout to allow udev to IMPORT it. 7 8# variables used to communicate: 9# MATCHADDR MAC address used for the match 10# MATCHID bus_id used for the match 11# MATCHDEVID dev_id used for the match 12# MATCHDRV driver name used for the match 13# MATCHIFTYPE interface type match 14# COMMENT comment to add to the generated rule 15# INTERFACE_NAME requested name supplied by external tool 16# INTERFACE_NEW new interface name returned by rule writer 17 18# Copyright (C) 2006 Marco d'Itri <md@Linux.IT> 19# Copyright (C) 2007 Kay Sievers <kay.sievers@vrfy.org> 20# 21# This program is free software: you can redistribute it and/or modify 22# it under the terms of the GNU General Public License as published by 23# the Free Software Foundation, either version 2 of the License, or 24# (at your option) any later version. 25# 26# This program is distributed in the hope that it will be useful, 27# but WITHOUT ANY WARRANTY; without even the implied warranty of 28# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29# GNU General Public License for more details. 30# 31# You should have received a copy of the GNU General Public License 32# along with this program. If not, see <http://www.gnu.org/licenses/>. 33 34RULES_FILE='@udevconfdir@/rules.d/70-persistent-net.rules' 35 36. @udevlibexecdir@/rule_generator.functions 37 38interface_name_taken() { 39 local value="$(find_all_rules 'NAME=' $INTERFACE)" 40 if [ "$value" ]; then 41 return 0 42 else 43 return 1 44 fi 45} 46 47find_next_available() { 48 raw_find_next_available "$(find_all_rules 'NAME=' "$1")" 49} 50 51write_rule() { 52 local match="$1" 53 local name="$2" 54 local comment="$3" 55 56 { 57 if [ "$PRINT_HEADER" ]; then 58 PRINT_HEADER= 59 echo "# This file was automatically generated by the $0" 60 echo "# program, run by the persistent-net-generator.rules rules file." 61 echo "#" 62 echo "# You can modify it, as long as you keep each rule on a single" 63 echo "# line, and change only the value of the NAME= key." 64 fi 65 66 echo "" 67 [ "$comment" ] && echo "# $comment" 68 echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\"" 69 } >> $RULES_FILE 70} 71 72if [ -z "$INTERFACE" ]; then 73 echo "missing \$INTERFACE" >&2 74 exit 1 75fi 76 77# Prevent concurrent processes from modifying the file at the same time. 78lock_rules_file 79 80# Check if the rules file is writeable. 81choose_rules_file 82 83# the DRIVERS key is needed to not match bridges and VLAN sub-interfaces 84if [ "$MATCHADDR" ]; then 85 match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\"" 86fi 87 88if [ "$MATCHDRV" ]; then 89 match="$match, DRIVERS==\"$MATCHDRV\"" 90fi 91 92if [ "$MATCHDEVID" ]; then 93 match="$match, ATTR{dev_id}==\"$MATCHDEVID\"" 94fi 95 96if [ "$MATCHID" ]; then 97 match="$match, KERNELS==\"$MATCHID\"" 98fi 99 100if [ "$MATCHIFTYPE" ]; then 101 match="$match, ATTR{type}==\"$MATCHIFTYPE\"" 102fi 103 104if [ -z "$match" ]; then 105 echo "missing valid match" >&2 106 unlock_rules_file 107 exit 1 108fi 109 110basename=${INTERFACE%%[0-9]*} 111match="$match, KERNEL==\"$basename*\"" 112 113if [ "$INTERFACE_NAME" ]; then 114 # external tools may request a custom name 115 COMMENT="$COMMENT (custom name provided by external tool)" 116 if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then 117 INTERFACE=$INTERFACE_NAME; 118 echo "INTERFACE_NEW=$INTERFACE" 119 fi 120else 121 # if a rule using the current name already exists, find a new name 122 if interface_name_taken; then 123 INTERFACE="$basename$(find_next_available "$basename[0-9]*")" 124 # prevent INTERFACE from being "eth" instead of "eth0" 125 [ "$INTERFACE" = "${INTERFACE%%[ \[\]0-9]*}" ] && INTERFACE=${INTERFACE}0 126 echo "INTERFACE_NEW=$INTERFACE" 127 fi 128fi 129 130write_rule "$match" "$INTERFACE" "$COMMENT" 131 132unlock_rules_file 133 134exit 0 135