-
Notifications
You must be signed in to change notification settings - Fork 14
/
ifname.sh
executable file
·252 lines (179 loc) · 5.18 KB
/
ifname.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#!/bin/dash
# rename interfaces to have persistnet names, according to the rules in $VDEV_IFNAMES_PATH
# the format of this file should be lines of:
# $IFNAME $ID_TYPE $ID_ARG
# where $IFNAME is the persistent name; $ID_TYPE is either "mac" or "devpath", and
# $ID_ARG is either the MAC address (formatted xx:xx:xx:xx:xx:xx) if $ID_TYPE is "mac", or
# $ID_ARG is the device path (starting with /devices)
. "$VDEV_HELPERS/subr.sh"
# go find the ifnames file from our config
IFNAMES_VAR="$(/bin/fgrep "ifnames=" "$VDEV_CONFIG_FILE")"
VDEV_IFNAMES_PATH=
if [ -n "$IFNAMES_VAR" ]; then
eval "$IFNAMES_VAR"
VDEV_IFNAMES_PATH="$ifnames"
fi
# make sure the file exists
if ! [ -e "$VDEV_IFNAMES_PATH" ]; then
exit 0
fi
if ! [ -f "$VDEV_IFNAMES_PATH" ]; then
vdev_error "Could not find ifnames file $VDEV_IFNAMES_PATH"
exit 1
fi
IP=
if [ -x /sbin/ip ]; then
IP=/sbin/ip
elif [ -x /bin/ip ]; then
IP=/bin/ip
fi
if [ -z "$IP" ]; then
vdev_error "Could not find iproute2. Network interfaces will not be configured."
exit 1
fi
# rename an interface
# $1 desired interface name
# $2 original interface name
rename_if() {
local _IFNAME
local _IFNAME_ORIG
local _IF_IS_DOWN
local _RC
_IFNAME="$1"
_IFNAME_ORIG="$2"
_IF_IS_DOWN=0
# is the interface up?
if [ -n "$($IP link show $_IFNAME_ORIG | /bin/grep "state UP")" ]; then
_IF_IS_DOWN=1
fi
# bring the interface down, if we must
if [ $_IF_IS_DOWN -ne 0 ]; then
$IP link set $_IFNAME_ORIG down
_RC=$?
if [ $_RC -ne 0 ]; then
return $_RC
fi
fi
$IP link set $_IFNAME_ORIG name $_IFNAME
_RC=$?
if [ $_RC -ne 0 ]; then
# try to recover: bring it back up, if it was up originally
if [ $_IF_IS_DOWN -ne 0 ]; then
$IP link set $_IFNAME_ORIG up
fi
return $_RC
fi
# bring the link back up, if it was up originally
if [ $_IF_IS_DOWN -ne 0 ]; then
$IP link set $_IFNAME up
_RC=$?
if [ $_RC -ne 0 ]; then
# try to recover
$IP link set $_IFNAME name $_IFNAME_ORIG
$IP link set $_IFNAME_ORIG up
return $_RC
fi
fi
return 0
}
# which interface has the given MAC?
# $1 MAC address
# print out the name of the interface
if_mac() {
local _MAC
local _IFNAME
_MAC="$1"
$IP link | /bin/grep -B 1 -i "$_MAC" | \
while read -r _IGNORED1 _IFNAME _IGNORED2; do
echo $_IFNAME | /bin/sed 's/://g'
break
done
return
}
# which interface has the given sysfs device path?
# $1 device path (starts with /devices)
# print out the name of the interface, if found
if_devpath() {
local _DEVPATH
local _IF_DEVPATH
local _SYSFS_IFNAME
_DEVPATH="$1"
while read -r _SYSFS_IFNAME; do
_IF_DEVPATH=$(/bin/readlink "$VDEV_OS_SYSFS_MOUNTPOINT/class/net/$_SYSFS_IFNAME" | /bin/sed 's/^\(..\/\)\+//g')
_IF_DEVPATH="/$_IF_DEVPATH"
if [ "$_IF_DEVPATH" = "$_DEVPATH/net/$_SYSFS_IFNAME" ]; then
# found!
echo "$_SYSFS_IFNAME"
break
fi
done <<EOF
$(/bin/ls "$VDEV_OS_SYSFS_MOUNTPOINT/class/net/")
EOF
return
}
# entry point
main() {
local LINECNT IFNAME ID_TYPE ID_ARG IFNAME_ORIG RC
LINECNT=0
# only bother with adding
if [ "$VDEV_ACTION" = "remove" ]; then
return 0
fi
# process ifnames
while read -r IFNAME ID_TYPE ID_ARG; do
IFNAME_ORIG=
LINECNT=$((LINECNT+1))
# skip comments
if [ -n "$(echo "$IFNAME" | /bin/egrep "^#")" ]; then
continue
fi
# skip blank lines
if [ -z "$IFNAME" ]; then
continue
fi
# skip invalid
if [ -z "$IFNAME" -o -z "$ID_TYPE" -o -z "$ID_ARG" ]; then
vdev_warn "Failed to parse line $LINECNT of $VDEV_IFNAMES_PATH"
continue
fi
# match identifier type
case "$ID_TYPE" in
mac)
# find the interface with this MAC address
IFNAME_ORIG="$(if_mac "$ID_ARG")"
;;
devpath)
# find the interface with this sysfs device path
IFNAME_ORIG="$(if_devpath "$ID_ARG")"
;;
*)
# unsupported
vdev_error "Unsupported interface identifier '$ID_TYPE'"
continue
;;
esac
if [ -z "$IFNAME_ORIG" ]; then
# couldn't match ID_ARG to an existing interface
continue
fi
if [ "$IFNAME_ORIG" != "$VDEV_OS_INTERFACE" ]; then
# the existing interface is not the one we're interested in
continue
fi
# do the rename
if [ "$IFNAME" != "$IFNAME_ORIG" ]; then
rename_if "$IFNAME" "$IFNAME_ORIG"
RC=$?
if [ $RC -ne 0 ]; then
# failed to rename
vdev_warn "Failed to rename '$IFNAME_ORIG' to '$IFNAME' ($IP exit code $RC)"
continue
fi
fi
done < "$VDEV_IFNAMES_PATH"
return 0
}
if [ $VDEV_DAEMONLET -eq 0 ]; then
main
exit $?
fi