]> git.ipfire.org Git - people/stevee/network.git/blame - functions.device
network: Log assertion errors.
[people/stevee/network.git] / functions.device
CommitLineData
1848564d
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
1b7a1578 22function devicify() {
1848564d
MT
23 local device=${1}
24
25 if device_exists ${device}; then
26 echo "${device}"
27 return ${EXIT_OK}
28 fi
29
30 local d
31 for d in $(devices_get_all); do
32 if [ "$(device_get_address ${d})" = "${device}" ]; then
33 echo "${d}"
34 return ${EXIT_OK}
35 fi
36 done
37
38 return ${EXIT_ERROR}
39}
40
41function macify() {
42 local device=${1}
43
44 if mac_is_valid ${device}; then
45 echo "${device}"
46 return ${EXIT_OK}
47 fi
48
49 if device_exists ${device}; then
50 device_get_address ${device}
51 return ${EXIT_OK}
52 fi
53
54 return ${EXIT_ERROR}
55}
56
57# Check if the device exists
58function device_exists() {
59 local device=${1}
60
61 # If device name was not found, exit.
62 [ -n "${device}" ] || return ${EXIT_ERROR}
63
64 [ -d "${SYS_CLASS_NET}/${device}" ]
65}
66
67# Check if the device is up
68function device_is_up() {
69 local device=${1}
70
71 device_exists ${device} || return ${EXIT_ERROR}
72
73 ip link show ${device} 2>/dev/null | grep -qE "<.*UP.*>"
74}
75
76# Check if the device is a bonding device
77function device_is_bonding() {
78 [ -d "/sys/class/net/${1}/bonding" ]
79}
80
81# Check if the device bonded in a bonding device
82function device_is_bonded() {
83 local dev
84 for dev in /sys/class/net/*; do
85 # Skip crappy files
86 [ -d "${dev}" ] || continue
87
88 # Continue if not a bonding device
89 device_is_bonding "${dev##*/}" || continue
90
91 if grep -q "\<${1}\>" ${dev}/bonding/slaves; then
92 return 0
93 fi
94 done
95
96 return 1
97}
98
99# Check if the device is a bridge
100function device_is_bridge() {
101 [ -d "/sys/class/net/${1}/bridge" ]
102}
103
104# Check if the device is a virtual device
105function device_is_virtual() {
106 local device=${1}
107
108 [ -e "/proc/net/vlan/${device}" ]
109}
110
111# Check if the device has virtual devices
112function device_has_virtuals() {
113 if [ ! -e "/proc/net/vlan/config" ]; then
114 return 1
115 fi
116 grep -q "${1}$" /proc/net/vlan/config
117}
118
119function device_is_vlan() { # XXX Compat function
120 log DEBUG "Deprecated function device_is_vlan() was used."
121
122 device_is_virtual $@
123}
124
125# Check if the device is a ppp device
126function device_is_ppp() {
127 local device=${1}
128
129 ip link show ${device} 2>/dev/null | grep -qE "<.*POINTOPOINT.*>"
130}
131
132# Check if the device is a loopback device
133function device_is_loopback() {
134 local device=$(devicify ${1})
135 [ "${device}" = "lo" ]
136}
137
138# Check if the device is a physical network interface
139function device_is_real() {
140 local device=${1}
141
142 device_is_loopback ${device} && \
143 return ${EXIT_ERROR}
144
145 device_is_bonding ${device} && \
146 return ${EXIT_ERROR}
147
148 device_is_bridge ${device} && \
149 return ${EXIT_ERROR}
150
151 device_is_ppp ${device} && \
152 return ${EXIT_ERROR}
153
154 device_is_virtual ${device} && \
155 return ${EXIT_ERROR}
156
157 return ${EXIT_OK}
158}
159
160# Get the device type
161function device_get_type() {
162 local device=$(devicify ${1})
163
164 if device_is_vlan ${device}; then
165 echo "vlan"
166
167 elif device_is_bonding ${device}; then
168 echo "bonding"
169
170 elif device_is_bridge ${device}; then
171 echo "bridge"
172
173 elif device_is_ppp ${device}; then
174 echo "ppp"
175
176 elif device_is_loopback ${device}; then
177 echo "loopback"
178
179 elif device_is_real ${device}; then
180 echo "real"
181
182 else
183 echo "unknown"
184 fi
185}
186
187function device_get_address() {
188 local device=${1}
189
190 cat ${SYS_CLASS_NET}/${device}/address 2>/dev/null
191}
192
193function device_set_address() {
1b7a1578
MT
194 local device=${1}
195 local addr=${2}
196
197 if ! device_exists ${device}; then
198 error "Device '${device}' does not exist."
199 return ${EXIT_ERROR}
200 fi
201
202 log INFO "Setting address of '${device}' to '${addr}' - was $(device_get_address ${device})."
203
204 local up
205 if device_is_up ${device}; then
206 device_set_down ${device}
207 up=1
208 fi
209
210 ip link set ${device} address ${addr}
211 local ret=$?
212
213 if [ "${up}" = "1" ]; then
214 device_set_up ${device}
215 fi
216
217 if [ "${ret}" != "0" ]; then
218 error_log "Could not set address '${addr}' on device '${device}'."
219 fi
220
221 return ${ret}
1848564d
MT
222}
223
224function devices_get_all() {
225 local device
226 for device in ${SYS_CLASS_NET}/*; do
227 echo "$(basename ${device})"
228 done | sort
229}
230
231# Check if a device has a cable plugged in
232function device_has_carrier() {
233 local device=$(devicify ${1})
234 [ "$(<${SYS_CLASS_NET}/${device}/carrier)" = "1" ]
235}
236
237# Check if the device is free
238function device_is_free() {
239 local device=${1}
240
241 device_is_used ${device} && \
242 return ${EXIT_ERROR}
243
244 return ${EXIT_OK}
245}
246
247# Check if the device is used
248function device_is_used() {
249 local device=$(devicify ${1})
250
251 device_has_vlans ${device} && \
252 return ${EXIT_ERROR}
253 device_is_bonded ${device} && \
254 return ${EXIT_ERROR}
255
256 return ${EXIT_OK}
257}
258
259# XXX to be removed I think
260function device_get_free() {
261 local destination=${1}
262
263 # Replace + by a valid number
264 if grep -q "+$" <<<${destination}; then
265 local number=0
266 destination=$(sed -e "s/+//" <<<$destination)
267 while [ "${number}" -le "100" ]; do
268 if ! device_exists "${destination}${number}"; then
269 destination="${destination}${number}"
270 break
271 fi
272 number=$(($number + 1))
273 done
274 fi
275 echo "${destination}"
276}
277
1848564d 278function device_rename() {
1b7a1578
MT
279 warning_log "Called deprecated function 'device_rename'"
280
281 device_set_name $@
282}
283
284function device_hash() {
285 local device=${1}
286
287 macify ${device} | tr -d ':'
288}
289
290# Give the device a new name
291function device_set_name() {
1848564d
MT
292 local source=$1
293 local destination=$(device_get_free ${2})
294
295 # Check if devices exists
296 if ! device_exists ${source} || device_exists ${destination}; then
297 return 4
298 fi
299
300 local up
301 if device_is_up ${source}; then
302 ip link set ${source} down
303 up=1
304 fi
305
306 ip link set ${source} name ${destination}
307
308 if [ "${up}" = "1" ]; then
309 ip link set ${destination} up
310 fi
311}
312
1848564d
MT
313# Set device up
314function device_set_up() {
315 local device=$(devicify ${1})
316
317 # Do nothing if device is already up
318 device_is_up ${device} && return ${EXIT_OK}
319
320 log DEBUG "Setting up device $@"
321 ip link set ${device} up
322}
323
324# Set device down
325function device_set_down() {
326 local device=$(devicify ${1})
327
328 # Do nothing if device is not up
329 device_is_up ${device} || return ${EXIT_OK}
330
331 log DEBUG "Tearing down device $@"
332 ip link set ${device} down
333}
334
335# Set new address to a device
336function device_set_mac() {
1b7a1578 337 warning_log "Called deprecated function 'device_set_mac'"
1848564d 338
1b7a1578 339 device_set_address $@
1848564d
MT
340}
341
342function device_get_mtu() {
343 local device=${1}
344
345 if ! device_exists ${device}; then
346 error "Device '${device}' does not exist."
347 return ${EXIT_ERROR}
348 fi
349
350 cat ${SYS_CLASS_NET}/${device}/mtu
351}
352
353# Set mtu to a device
354function device_set_mtu() {
1b7a1578 355 local device=${1}
1848564d
MT
356 local mtu=${2}
357
1b7a1578
MT
358 if ! device_exists ${device}; then
359 error "Device '${device}' does not exist."
360 return ${EXIT_ERROR}
361 fi
362
363 local oldmtu=$(device_get_mtu ${device})
364
365 if [ "${oldmtu}" = "${mtu}" ]; then
366 # No need to set mtu.
367 return ${EXIT_OK}
368 fi
369
370 log INFO "Setting mtu of '${device}' to '${mtu}' - was ${oldmtu}."
371
1848564d 372 local up
1b7a1578
MT
373 if device_is_up ${device}; then
374 device_set_down ${device}
1848564d
MT
375 up=1
376 fi
377
1b7a1578 378 ip link set ${device} mtu ${mtu}
1848564d
MT
379 local ret=$?
380
381 if [ "${up}" = "1" ]; then
1b7a1578
MT
382 device_set_up ${device}
383 fi
384
385 if [ "${ret}" != "0" ]; then
386 error_log "Could not set mtu '${mtu}' on device '${device}'."
1848564d
MT
387 fi
388
389 return ${ret}
390}
391
392function device_discover() {
393 local device=${1}
394
1b7a1578
MT
395 log INFO "Running discovery process on device '${device}'."
396
1848564d
MT
397 local hook
398 for hook in $(hooks_get_all); do
399 hook_exec ${hook} discover ${device}
400 done
401}
402
403function device_create_virtual() {
404 log WARN "Called deprecated function device_create_virtual"
405 device_virtual_create $@
406}
407
408function device_virtual_create() {
409 local port=$(devicify ${1})
410 local vid=${2}
411 local mac=${3}
412 local newport=${port}v${vid}
413
414 if [ -z "${mac}" ]; then
415 mac=$(mac_generate)
416 fi
417
1b7a1578
MT
418 log INFO "Creating virtual device '${newport}' with address '${mac}'."
419
1848564d
MT
420 # Bring up the parent device
421 # XXX Do we need this here?
422 #device_set_up ${port}
423
424 vconfig set_name_type DEV_PLUS_VID_NO_PAD >/dev/null
425 vconfig add ${port} ${vid} >/dev/null
1b7a1578
MT
426
427 if [ $? -ne ${EXIT_OK} ]; then
428 error_log "Could not create virtual device '${newport}'."
429 return ${EXIT_ERROR}
430 fi
1848564d
MT
431
432 # The device is expected to be named like ${port}.${vid}
433 # and will be renamed to the virtual schema
434 device_set_name ${port}.${vid} ${newport}
435
1b7a1578
MT
436 if [ $? -ne ${EXIT_OK} ]; then
437 error_log "Could not set name of virtual device '${newport}'."
438 return ${EXIT_ERROR}
439 fi
440
1848564d
MT
441 # Setting new mac address
442 device_set_address ${newport} ${mac}
1b7a1578
MT
443
444 if [ $? -ne ${EXIT_OK} ]; then
445 error_log "Could not set address '${mac}' to virtual device '${newport}'."
446 return ${EXIT_ERROR}
447 fi
1848564d
MT
448
449 # Bring up the new device
450 device_set_up ${newport}
451
1848564d
MT
452 return ${EXIT_OK}
453}
454
455function device_virtual_remove() {
456 local device=$(devicify ${1})
457
1b7a1578
MT
458 log INFO "Removing virtual device '${device}' with address '$(macify ${devive})'."
459
1848564d
MT
460 device_set_down ${device}
461
462 vconfig rem ${device} >/dev/null
1848564d 463
1b7a1578
MT
464 if [ $? -ne ${EXIT_OK} ]; then
465 error_log "Could not remote virtual device '${newport}'."
466 return ${EXIT_ERROR}
467 fi
468
1848564d
MT
469 return ${EXIT_OK}
470}
471
472function device_bonding_create() {
473 local device=${1}
474 local mac=${2}
475
476 [ -z "${mac}" ] && mac=$(mac_generate)
477
1b7a1578
MT
478 log INFO "Creating bonding device '${device}' (${mac})."
479
1848564d
MT
480 echo "+${device}" > /sys/class/net/bonding_masters
481 device_set_mac ${mac}
482 device_set_up ${device}
483}
484
485function device_bonding_remove() {
486 local device=$(devicify ${1})
487
1b7a1578
MT
488 log INFO "Remove bonding device '${device}'."
489
1848564d
MT
490 device_set_down ${device}
491 echo "-${device}" > /sys/class/net/bonding_masters
492}
493
494function bonding_set_mode() {
495 local device=${1}
496 local mode=${2}
497
1b7a1578
MT
498 log INFO "Setting bonding mode on '${device}' '${mode}'."
499
1848564d
MT
500 echo "${mode}" > /sys/class/net/${device}/bonding/mode
501}
502
503function bonding_enslave_device() {
504 local device=$(devicify ${1})
505 local slave=$(devicify ${2})
1b7a1578
MT
506 shift 2
507
508 log INFO "Enslaving slave '${slave}' to '${device}'."
1848564d
MT
509
510 device_set_down ${slave}
511 echo "+${slave}" > /sys/class/net/${device}/bonding/slaves
512}
513
514function bridge_attach_device() {
515 local bridge=${1}
516 local device=${2}
517
518 if ! device_exists ${bridge}; then
519 error "Bridge '${bridge}' does not exist."
520 return ${EXIT_ERROR}
521 fi
522
523 if ! device_exists ${device}; then
524 error "Device '${device}' does not exist."
525 return ${EXIT_ERROR}
526 fi
527
1b7a1578
MT
528 log INFO "Attaching device '${device}' to bridge '${bridge}'."
529
1848564d
MT
530 # XXX device_set_up ${device} # Do we need this here?
531
532 brctl addif ${bridge} ${device}
533}
534
535function bridge_detach_device() {
536 local bridge=${1}
537 local device=${2}
538
539 if ! device_exists ${bridge}; then
540 error "Bridge '${bridge}' does not exist."
541 return ${EXIT_ERROR}
542 fi
543
544 if ! device_exists ${device}; then
545 error "Device '${device}' does not exist."
546 return ${EXIT_ERROR}
547 fi
548
1b7a1578
MT
549 log INFO "Detaching device '${device}' from bridge '${bridge}'."
550
551 brctl delif ${bridge} ${device}
1848564d
MT
552
553 device_set_down ${device}
554}
555
556function bridge_is_forwarding() {
557 local seconds=45
558 local zone=${1}
559
560 bridge_has_carrier ${zone} || return ${EXIT_ERROR}
561
562 local device
563 while [ ${seconds} -gt 0 ]; do
564 for device in ${SYS_CLASS_NET}/${zone}/brif/*; do
565 [ -e "${device}/state" ] || continue
566 if [ "$(<${device}/state)" = "3" ]; then
567 return ${EXIT_OK}
568 fi
569 done
570 sleep 1
571 seconds=$((${seconds} - 1))
572 done
573
574 return ${EXIT_ERROR}
575}
576
577function bridge_has_carrier() {
578 local zone=${1}
579
580 local has_carrier=${EXIT_ERROR}
581
582 local device
583 for device in ${SYS_CLASS_NET}/${zone}/brif/*; do
584 device=$(basename ${device})
585 device_exists ${device} || continue
586
587 device_has_carrier ${device} && has_carrier=${EXIT_OK}
588 done
589
590 return ${has_carrier}
591}
592
593function device_has_ipv4() {
594 local device=${1}
595 local addr=${2}
596
597 if ! device_exists ${device}; then
598 error "Device '${device}' does not exist."
599 return ${EXIT_ERROR}
600 fi
601
602 ip addr show ${device} | grep -q -e "inet " -e "${addr}"
603}