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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
|
#!/bin/bash
# Copyright (c) 2004-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Contributed by Roy Marples (uberlord@gentoo.org)
# Fix any potential localisation problems
# Note that LC_ALL trumps LC_anything_else according to locale(7)
ip() {
LC_ALL=C /sbin/ip "$@"
}
iproute2_tunnel() {
LC_ALL=C /sbin/ip tunnel "$@"
}
# void iproute2_depend(void)
#
# Sets up the dependancies for the module
iproute2_depend() {
provide interface
functions interface_device
variables config routes fallback metric ipaddr ipaddr_fallback iproute inet6
}
# bool iproute2_check_installed(void)
#
# Returns 1 if iproute2 is installed, otherwise 0
iproute2_check_installed() {
local report="${1:-false}" installed="0"
if [[ ! -x /sbin/ip ]] ; then
installed="1"
${report} && eerror "For iproute2 support, emerge sys-apps/iproute2"
fi
if [[ ! -e /proc/net/netlink ]] ; then
installed="1"
${report} && eerror "iproute2 requires NetLink enabled in the kernel"
fi
return "${installed}"
}
# bool iproute2_exists(char *interface, bool report)
#
# Returns 1 if the interface exists, otherwise 0
iproute2_exists() {
local e="$( ip addr show label "$1" )" report="${2:-false}"
[[ -n ${e} ]] && return 0
if ${report} ; then
eerror "network interface $1 does not exist"
eerror "Please verify hardware or kernel module (driver)"
fi
return 1
}
# void iproute2_up(char *interface)
#
# provides a generic interface for bringing interfaces up
iproute2_up() {
ip link set up dev "$1"
}
# void iproute2_down(char *interface)
#
# provides a generic interface for bringing interfaces up
iproute2_down() {
ip link set down dev "$1"
}
# bool ifproute2_is_up(char *iface, bool withaddress)
#
# Returns 0 if the interface is up, otherwise 1
# If withaddress is true then the interface has to have an IPv4 address
# assigned as well
iproute2_is_up() {
local check="\<UP\>" addr="${2:-false}"
${addr} && check="${check}.*inet "
ip addr show "$1" | xargs | grep -Eq "${check}" && return 0
return 1
}
# void iproute2_set_flag(char *iface, char *flag, bool enabled)
#
# Sets or disables the interface flag
iproute2_set_flag() {
local enable="$3" opt="on"
${enable} || opt="off"
ip link set "$1" "$2" "${opt}"
}
# void iproute2_get_address(char *interface)
#
# Fetch the address retrieved by DHCP. If successful, echoes the
# address on stdout, otherwise echoes nothing.
iproute2_get_address() {
ip -family inet addr show "$1" | sed -n -e 's/.*inet \([^ ]*\).*/\1/p'
}
# bool iproute2_is_ethernet(char *interface)
#
# Return 0 if the link is ethernet, otherwise 1.
iproute2_is_ethernet() {
ip link show "$1" | grep -q "^[[:space:]]*link/ether[[:space:]]*"
}
# void iproute2_get_mac_address(char *interface)
#
# Fetch the mac address assingned to the network card
iproute2_get_mac_address() {
local mac="$( ip link show "$1" | sed -n -e \
'/link\// s/^.*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' )"
[[ ${mac} != '00:00:00:00:00:00' \
&& ${mac} != '44:44:44:44:44:44' \
&& ${mac} != 'FF:FF:FF:FF:FF:FF' ]] \
&& echo "${mac}"
}
# void iproute2_set_mac_address(char *interface, char *mac)
#
# Assigned the mac address to the network card
iproute2_set_mac_address() {
ip link set address "$2" dev "$1"
}
# int iproute2_set_name(char *interface, char *new_name)
#
# Renames the interface
# This will not work if the interface is setup!
iproute2_set_name() {
ip link set name "$2" dev "$1"
}
# void iproute2_get_aliases_rev(char *interface)
#
# Fetch the list of aliases for an interface.
# Outputs a space-separated list on stdout, in reverse order, for
# example "eth0:2 eth0:1"
iproute2_get_aliases_rev() {
local iface="$( interface_device "$1" )"
ip addr show dev "${iface}" | grep -o "${iface}:[0-9].*" | tac
}
# bool iproute2_del_addresses(char *interface, bool onlyinet)
#
# Remove addresses from interface.
# If onlyinet is true, then we only remove IPv4 / inet addresses.
iproute2_del_addresses() {
local pre=""
${2:-false} && pre="-f inet"
ip ${pre} addr flush label "$1" scope global &>/dev/null
ip ${pre} addr flush label "$1" scope site &>/dev/null
ip ${pre} addr flush label "$1" scope host &>/dev/null
return 0
}
# bool iproute2_get_old_config(char *iface)
#
# Returns config and config_fallback for the given interface
iproute2_get_old_config() {
local ifvar="$( bash_variable "$1" )" inet6="" t=""
# iproute2-style config vars
t="ipaddr_${ifvar}[@]"
config=( "${!t}" )
t="config_fallback_${ifvar}[@]"
config_fallback=( "${!t}" )
t="inet6_${ifvar}[@]"
inet6=( "${!t}" )
# BACKWARD COMPATIBILITY: check for space-separated inet6 addresses
[[ ${#inet6[@]} == "1" && ${inet6} == *" "* ]] && inet6=( ${inet6} )
# Add inet6 addresses to our config if required
[[ -n ${inet6} ]] && config=( "${config[@]}" "${inet6[@]}" )
# Support old style iface_xxx syntax
if [[ -z ${config} ]] ; then
if is_function ifconfig_get_old_config ; then
ifconfig_get_old_config "${iface}"
fi
fi
return 0
}
# bool iproute2_iface_stop(char *interface)
#
# Do final shutdown for an interface or alias.
#
# Returns 0 (true) when successful, non-zero (false) on failure
iproute2_iface_stop() {
local label="$1" iface="$( interface_device "$1" )"
# Shut down the link if this isn't an alias or vlan
if [[ ${label} == "${iface}" ]] ; then
iproute2_down "${iface}"
return $?
fi
return 0
}
# bool iproute2_add_address(char *interface, char *options ...)
#
# Adds an the specified address to the interface
# returns 0 on success and non-zero on failure
iproute2_add_address() {
local iface="$1" x=""
iproute2_exists "${iface}" true || return 1
# Extract the config
local -a config=( "$@" )
config=( ${config[@]:1} )
# Convert an ifconfig line to iproute2
local n="${#config[@]}"
for (( x=0; x<n; x++ )); do
case "${config[x]}" in
netmask)
config[0]="${config[0]}/$( netmask2cidr "${config[x+1]}" )"
unset config[x] config[x+1]
;;
mtu)
ip link set mtu "${config[x+1]}" dev "${iface}"
unset config[x] config[x+1]
;;
esac
done
config=( "${config[@]//pointopoint/peer}" )
# Always scope lo addresses as host unless specified otherwise
[[ ${iface} == "lo" && " ${config[@]} " != *" scope "* ]] \
&& config=( "${config[@]}" "scope host" )
# IPv4 specifics
if [[ ${config[@]} == *.*.*.* ]] ; then
# Work out a broadcast if none supplied
[[ ${config[@]} != *" brd "* && ${config[@]} != *" broadcast "* ]] \
&& config=( "${config[@]}" "brd +" )
fi
# Ensure that the interface is up so we can add IPv6 addresses
interface_up "${iface}"
# Some kernels like to apply lo with an address when they are brought up
if [[ ${iface} == "lo" \
&& ${config[@]} == "127.0.0.1/8 brd 127.255.255.255 scope host" ]] ; then
ip addr del dev "${iface}" 127.0.0.1/8 2>/dev/null
fi
ip addr add dev "${iface}" ${config[@]}
local r="$?"
[[ ${r} != "0" ]] && return "${r}"
local ifvar="$( bash_variable "${iface}" )"
# Remove the newly added route and replace with our metric
local metric="metric_${ifvar}"
[[ ${!metric:-0} == "0" ]] && return "${r}"
local network="$( ip_network "${config[0]}" )"
[[ -z ${network} ]] && return "${r}"
local cidr="${config[0]##*/}"
if ip route del "${network}/${cidr}" metric 0 dev "${iface}" \
2>/dev/null ; then
ip route add "${network}/${cidr}" metric "${!metric:-0}" dev "${iface}"
fi
return "${r}"
}
# bool iproute2_pre_start(char *interface)
#
# Runs any pre_start stuff on our interface - just the MTU atm
# We set MTU twice as it may be needed for DHCP - a dhcp client could
# change it in error, so we set MTU in post start too
iproute2_pre_start() {
local iface="$1"
interface_exists "${iface}" || return 0
local ifvar="$( bash_variable "$1" )"
# MTU support
local mtu="mtu_${ifvar}"
[[ -n ${!mtu} ]] && ip link set mtu "${!mtu}" dev "${iface}"
return 0
}
# bool iproute2_post_start(char *interface)
#
# Runs any post_start stuff on our interface and adds routes
# Always returns 0
iproute2_post_start() {
local iface="$1" ifvar="$( bash_variable "$1" )" x=""
iproute2_exists "${iface}" || return 0
# Make sure interface is marked UP
iproute2_up "${iface}"
# MTU support
local mtu="mtu_${ifvar}"
[[ -n ${!mtu} ]] && ip link set mtu "${!mtu}" dev "${iface}"
local x="routes_${ifvar}[@]"
local -a routes=( "${!x}" )
local metric="metric_${ifvar}"
# Test for old style ipaddr variable
if [[ -z ${routes} ]] ; then
t="iproute_${ifvar}[@]"
routes=( "${!t}" )
fi
# Set routes with ip route -- this might also include default route
if [[ -n ${routes} ]] ; then
einfo "Adding routes"
eindent
for x in "${routes[@]}"; do
ebegin "${x}"
# Support net-tools routing too
x="${x//gw/via}"
x="${x//-A inet6/}"
x="${x//-net/}"
[[ " ${x} " == *" -host "* ]] && x="${x//-host/} scope host"
# Attempt to support net-tools route netmask option
netmask="${x##* netmask }"
if [[ -n ${netmask} && ${x} != "${netmask}" ]] ; then
netmask="${netmask%% *}"
x="${x// netmask ${netmask} / }"
local -a a=( ${x} )
a[0]="${a[0]}/$( netmask2cidr "${netmask}")"
x="${a[@]}"
fi
# Add a metric if we don't have one
[[ " ${x} " != *" metric "* ]] && x="${x} metric ${!metric}"
ip route append ${x} dev "${iface}"
eend $?
done
eoutdent
fi
# Flush the route cache
ip route flush cache dev "${iface}"
return 0
}
# void iproute2_route_metric(char* interface, int metric)
#
# Change all routes for an interface to a given metric
iproute2_route_metric() {
local route=""
ip route | grep " dev $1" | {
while read route ; do
ip route del ${route}
ip route add ${route} metric "$2"
done
}
}
# void iproute2_default_route(char* interface, char* gateway_ip, int metric)
#
# Force default route to the specified gateway, optionally on
# the given interface
iproute2_default_route() {
local metric="${3:-0}"
ip route change default via "$2" metric "${metric}" dev "$1" 2>/dev/null \
|| ip route append default via "$2" metric "${metric}" dev "$1" 2>/dev/null
}
# void iproute2_post_stop(char* interface)
iproute2_post_stop() {
local iface="$1" rule=""
iproute2_exists "${iface}" || return
# Flush the route cache
ip route flush cache dev "${iface}"
}
# vim:ts=4
|