chiark / gitweb /
b873b5bf8c5d68e2b9e351f41fad2a7089519917
[elogind.git] / extras / rule_generator / write_net_rules
1 #!/bin/sh -e
2 #
3 # This script is run if the interface (recognized by its MAC address) lacks
4 # a rule for persistent naming.
5 #
6 # If there is already a persistent rule with that interface name then the
7 # current interface needs to be renamed.
8 #
9 # If the interface needs to be renamed, a NAME=value pair will be printed
10 # on stdout to allow udev to IMPORT it. Then a rule for the MAC address and
11 # interface name is written.
12 #
13 # (C) 2006 Marco d'Itri <md@Linux.IT>
14 #
15 # This program is free software; you can redistribute it and/or modify it
16 # under the terms of the GNU General Public License as published by the
17 # Free Software Foundation version 2 of the License.
18
19 RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules'
20
21 . /lib/udev/rule_generator.functions
22
23 interface_name_taken() {
24         local value="$(find_all_rules 'NAME=' $INTERFACE)"
25         if [ "$value" ]; then
26                 return 0
27         else
28                 return 1
29         fi
30 }
31
32 find_next_available() {
33         raw_find_next_available "$(find_all_rules 'NAME=' "$1")"
34 }
35
36 write_rule() {
37         local match="$1"
38         local name="$2"
39         local comment="$3"
40
41         {
42         if [ "$PRINT_HEADER" ]; then
43                 PRINT_HEADER=
44                 echo "# This file was automatically generated by the $0"
45                 echo "# program run by the persistent-net-generator.rules rules file."
46                 echo "#"
47                 echo "# You can modify it, as long as you keep each rule on a single line."
48         fi
49
50         echo ""
51         [ "$comment" ] && echo "# $comment"
52         echo "SUBSYSTEM==\"net\", $match, NAME=\"$name\""
53         } >> $RULES_FILE
54 }
55
56 if [ -z "$INTERFACE" ]; then
57         echo "Missing \$INTERFACE." >&2
58         exit 1
59 fi
60
61 if [ "$1" ]; then
62     while [ "$*" ] ; do
63         case $1 in
64             --mac)
65                 shift
66                 MAC_ADDR=$1
67                 shift
68                 ;;
69             --driver)
70                 shift
71                 DRIVER=$1
72                 shift
73                 ;;
74             --id)
75                 shift
76                 ID=$1
77                 shift
78                 ;;
79             *)
80                 MAC_ADDR=$1
81                 shift
82                 ;;
83         esac
84     done
85 else
86     MAC_ADDR=$(sysread address)
87 fi
88
89 if [ -z "$DRIVER" ] && [ -z "$ID" ] ; then
90     if [ -z "$MAC_ADDR" ]; then
91         echo "No MAC address for $INTERFACE." >&2
92         exit 1
93     fi
94     if [ "$MAC_ADDR" = "00:00:00:00:00:00" ]; then
95         echo "NULL MAC address for $INTERFACE." >&2
96         exit 1
97     fi
98 fi
99
100 # Prevent concurrent processes from modifying the file at the same time.
101 lock_rules_file
102
103 # Check if the rules file is writeable.
104 choose_rules_file
105
106 # If a rule using the current name already exists then find a new name and
107 # report it to udev which will rename the interface.
108 basename=${INTERFACE%%[0-9]*}
109 if interface_name_taken; then
110         INTERFACE="$basename$(find_next_available "$basename[0-9]*")"
111         if [ ! -t 1 ]; then
112                 echo "INTERFACE_NEW=$INTERFACE"
113         fi
114 fi
115
116 # the DRIVERS key is needed to not match bridges and VLAN sub-interfaces
117 if [ "$MAC_ADDR" ] ; then
118     match="DRIVERS==\"?*\", ATTRS{address}==\"$MAC_ADDR\""
119 else
120     match="DRIVERS==\"$DRIVER\", KERNELS==\"$ID\""
121 fi
122 if [ $basename = "ath" -o $basename = "wlan" ]; then
123         match="$match, ATTRS{type}==\"1\"" # do not match the wifi* interfaces
124 fi
125
126 write_rule "$match" "$INTERFACE" "$COMMENT"
127
128 unlock_rules_file
129
130 exit 0
131