]> git.ipfire.org Git - people/arne_f/network.git/blame - functions.device
network: Remove deprecated function device_set_mac.
[people/arne_f/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
81ed640c
MT
104function device_is_bridge_attached() {
105 local device=${1}
106
107 [ -d "${SYS_CLASS_NET}/${device}/brport" ]
108}
109
1848564d
MT
110# Check if the device is a virtual device
111function device_is_virtual() {
112 local device=${1}
113
114 [ -e "/proc/net/vlan/${device}" ]
115}
116
117# Check if the device has virtual devices
118function device_has_virtuals() {
fb02e543
MT
119 local device=${1}
120
121 if device_is_virtual ${device}; then
122 return 1
123 fi
124
1848564d
MT
125 if [ ! -e "/proc/net/vlan/config" ]; then
126 return 1
127 fi
128 grep -q "${1}$" /proc/net/vlan/config
129}
130
131function device_is_vlan() { # XXX Compat function
132 log DEBUG "Deprecated function device_is_vlan() was used."
133
134 device_is_virtual $@
135}
136
137# Check if the device is a ppp device
138function device_is_ppp() {
139 local device=${1}
140
141 ip link show ${device} 2>/dev/null | grep -qE "<.*POINTOPOINT.*>"
142}
143
144# Check if the device is a loopback device
145function device_is_loopback() {
146 local device=$(devicify ${1})
147 [ "${device}" = "lo" ]
148}
149
150# Check if the device is a physical network interface
151function device_is_real() {
152 local device=${1}
153
154 device_is_loopback ${device} && \
155 return ${EXIT_ERROR}
156
157 device_is_bonding ${device} && \
158 return ${EXIT_ERROR}
159
160 device_is_bridge ${device} && \
161 return ${EXIT_ERROR}
162
163 device_is_ppp ${device} && \
164 return ${EXIT_ERROR}
165
166 device_is_virtual ${device} && \
167 return ${EXIT_ERROR}
168
169 return ${EXIT_OK}
170}
171
172# Get the device type
173function device_get_type() {
174 local device=$(devicify ${1})
175
176 if device_is_vlan ${device}; then
177 echo "vlan"
178
179 elif device_is_bonding ${device}; then
180 echo "bonding"
181
182 elif device_is_bridge ${device}; then
183 echo "bridge"
184
185 elif device_is_ppp ${device}; then
186 echo "ppp"
187
188 elif device_is_loopback ${device}; then
189 echo "loopback"
190
191 elif device_is_real ${device}; then
192 echo "real"
193
194 else
195 echo "unknown"
196 fi
197}
198
199function device_get_address() {
200 local device=${1}
201
202 cat ${SYS_CLASS_NET}/${device}/address 2>/dev/null
203}
204
205function device_set_address() {
1b7a1578
MT
206 local device=${1}
207 local addr=${2}
208
209 if ! device_exists ${device}; then
210 error "Device '${device}' does not exist."
211 return ${EXIT_ERROR}
212 fi
213
214 log INFO "Setting address of '${device}' to '${addr}' - was $(device_get_address ${device})."
215
216 local up
217 if device_is_up ${device}; then
218 device_set_down ${device}
219 up=1
220 fi
221
222 ip link set ${device} address ${addr}
223 local ret=$?
224
225 if [ "${up}" = "1" ]; then
226 device_set_up ${device}
227 fi
228
229 if [ "${ret}" != "0" ]; then
230 error_log "Could not set address '${addr}' on device '${device}'."
231 fi
232
233 return ${ret}
1848564d
MT
234}
235
236function devices_get_all() {
237 local device
238 for device in ${SYS_CLASS_NET}/*; do
239 echo "$(basename ${device})"
240 done | sort
241}
242
243# Check if a device has a cable plugged in
244function device_has_carrier() {
245 local device=$(devicify ${1})
246 [ "$(<${SYS_CLASS_NET}/${device}/carrier)" = "1" ]
247}
248
249# Check if the device is free
250function device_is_free() {
81ed640c 251 ! device_is_used $@
1848564d
MT
252}
253
254# Check if the device is used
255function device_is_used() {
256 local device=$(devicify ${1})
257
fb02e543
MT
258 device_has_virtuals ${device} && \
259 return ${EXIT_OK}
1848564d 260 device_is_bonded ${device} && \
fb02e543 261 return ${EXIT_OK}
81ed640c
MT
262 device_is_bridge_attached ${device} && \
263 return ${EXIT_OK}
1848564d 264
fb02e543 265 return ${EXIT_ERROR}
1848564d
MT
266}
267
268# XXX to be removed I think
269function device_get_free() {
270 local destination=${1}
271
272 # Replace + by a valid number
273 if grep -q "+$" <<<${destination}; then
274 local number=0
275 destination=$(sed -e "s/+//" <<<$destination)
276 while [ "${number}" -le "100" ]; do
277 if ! device_exists "${destination}${number}"; then
278 destination="${destination}${number}"
279 break
280 fi
281 number=$(($number + 1))
282 done
283 fi
284 echo "${destination}"
285}
286
1848564d 287function device_rename() {
1b7a1578
MT
288 warning_log "Called deprecated function 'device_rename'"
289
290 device_set_name $@
291}
292
293function device_hash() {
294 local device=${1}
295
296 macify ${device} | tr -d ':'
297}
298
299# Give the device a new name
300function device_set_name() {
1848564d
MT
301 local source=$1
302 local destination=$(device_get_free ${2})
303
304 # Check if devices exists
305 if ! device_exists ${source} || device_exists ${destination}; then
306 return 4
307 fi
308
309 local up
310 if device_is_up ${source}; then
311 ip link set ${source} down
312 up=1
313 fi
314
315 ip link set ${source} name ${destination}
316
317 if [ "${up}" = "1" ]; then
318 ip link set ${destination} up
319 fi
320}
321
1848564d
MT
322# Set device up
323function device_set_up() {
324 local device=$(devicify ${1})
325
326 # Do nothing if device is already up
327 device_is_up ${device} && return ${EXIT_OK}
328
81ed640c
MT
329 device_set_parent_up ${device}
330
331 log DEBUG "Setting up device '${device}'"
332
1848564d
MT
333 ip link set ${device} up
334}
335
81ed640c
MT
336function device_set_parent_up() {
337 local device=${1}
338 local parent
339
340 if device_is_virtual ${device}; then
341 parent=$(device_virtual_get_parent ${device})
342
343 device_is_up ${parent} && return ${EXIT_OK}
344
345 log DEBUG "Setting up parent device '${parent}' of '${device}'"
346
347 device_set_up ${parent}
348 return $?
349 fi
350
351 return ${EXIT_OK}
352}
353
1848564d
MT
354# Set device down
355function device_set_down() {
356 local device=$(devicify ${1})
357
81ed640c
MT
358 local ret=${EXIT_OK}
359
360 if device_is_up ${device}; then
361 log DEBUG "Tearing down device '${device}'"
362
363 ip link set ${device} down
364 ret=$?
365 fi
366
367 device_set_parent_down ${device}
1848564d 368
81ed640c
MT
369 return ${ret}
370}
371
372function device_set_parent_down() {
373 local device=${1}
374 local parent
375
376 if device_is_virtual ${device}; then
377 parent=$(device_virtual_get_parent ${device})
378
379 device_is_up ${parent} || return ${EXIT_OK}
380
381 if device_is_free ${parent}; then
382 log DEBUG "Tearing down parent device '${parent}' of '${device}'"
383
384 device_set_down ${parent}
385 fi
386 fi
387
388 return ${EXIT_OK}
1848564d
MT
389}
390
1848564d
MT
391function device_get_mtu() {
392 local device=${1}
393
394 if ! device_exists ${device}; then
395 error "Device '${device}' does not exist."
396 return ${EXIT_ERROR}
397 fi
398
399 cat ${SYS_CLASS_NET}/${device}/mtu
400}
401
402# Set mtu to a device
403function device_set_mtu() {
1b7a1578 404 local device=${1}
1848564d
MT
405 local mtu=${2}
406
1b7a1578
MT
407 if ! device_exists ${device}; then
408 error "Device '${device}' does not exist."
409 return ${EXIT_ERROR}
410 fi
411
412 local oldmtu=$(device_get_mtu ${device})
413
414 if [ "${oldmtu}" = "${mtu}" ]; then
415 # No need to set mtu.
416 return ${EXIT_OK}
417 fi
418
419 log INFO "Setting mtu of '${device}' to '${mtu}' - was ${oldmtu}."
420
1848564d 421 local up
1b7a1578
MT
422 if device_is_up ${device}; then
423 device_set_down ${device}
1848564d
MT
424 up=1
425 fi
426
1b7a1578 427 ip link set ${device} mtu ${mtu}
1848564d
MT
428 local ret=$?
429
430 if [ "${up}" = "1" ]; then
1b7a1578
MT
431 device_set_up ${device}
432 fi
433
434 if [ "${ret}" != "0" ]; then
435 error_log "Could not set mtu '${mtu}' on device '${device}'."
1848564d
MT
436 fi
437
438 return ${ret}
439}
440
441function device_discover() {
442 local device=${1}
443
1b7a1578
MT
444 log INFO "Running discovery process on device '${device}'."
445
1848564d
MT
446 local hook
447 for hook in $(hooks_get_all); do
448 hook_exec ${hook} discover ${device}
449 done
450}
451
452function device_create_virtual() {
453 log WARN "Called deprecated function device_create_virtual"
454 device_virtual_create $@
455}
456
457function device_virtual_create() {
458 local port=$(devicify ${1})
459 local vid=${2}
460 local mac=${3}
461 local newport=${port}v${vid}
462
463 if [ -z "${mac}" ]; then
464 mac=$(mac_generate)
465 fi
466
1b7a1578
MT
467 log INFO "Creating virtual device '${newport}' with address '${mac}'."
468
fb02e543 469 local oldport=$(device_virtual_get_by_parent_and_vid ${port} ${vid})
1848564d 470
fb02e543
MT
471 if device_exists ${oldport}; then
472 local differences
473
474 if [ "${oldport}" != "${newport}" ]; then
475 differences="${differences} name"
476 fi
477 if [ "$(device_get_address ${oldport})" != "${mac}" ]; then
478 differences="${differences} address"
479 fi
480
481 echo "differences: $differences"
482
483 if [ -n "${differences}" ]; then
484 if device_is_used ${oldport}; then
485 error_log "There was a device '${oldport}' set up with VID '${vid}' and parent '${port}' which is used somewhere else. Cannot go on."
486 return ${EXIT_ERROR}
487 else
488 log DEBUG "There is a device '${oldport}' but it not used, so we grab it to ourselves."
489 fi
490 else
491 log DEBUG "Device '${newport}' already exists and reflects our configuration. Go on."
492
493 device_set_up ${oldport}
494 return ${EXIT_OK}
495 fi
496
497 else
498 log DEBUG "Virtual device '${newport}' does not exist, yet."
499
500 vconfig set_name_type DEV_PLUS_VID_NO_PAD >/dev/null
501 vconfig add ${port} ${vid} >/dev/null
502
503 if [ $? -ne ${EXIT_OK} ]; then
504 error_log "Could not create virtual device '${newport}'."
505 return ${EXIT_ERROR}
506 fi
507
508 oldport=$(device_virtual_get_by_parent_and_vid ${port} ${vid})
509
510 fi
511
512 assert device_exists ${oldport}
513
514 if ! device_exists ${oldport}; then
515 error "Could not determine the created virtual device '${newport}'."
1b7a1578
MT
516 return ${EXIT_ERROR}
517 fi
1848564d
MT
518
519 # The device is expected to be named like ${port}.${vid}
520 # and will be renamed to the virtual schema
fb02e543 521 device_set_name ${oldport} ${newport}
1848564d 522
1b7a1578
MT
523 if [ $? -ne ${EXIT_OK} ]; then
524 error_log "Could not set name of virtual device '${newport}'."
525 return ${EXIT_ERROR}
526 fi
527
fb02e543
MT
528 assert device_exists ${newport}
529
1848564d
MT
530 # Setting new mac address
531 device_set_address ${newport} ${mac}
1b7a1578
MT
532
533 if [ $? -ne ${EXIT_OK} ]; then
534 error_log "Could not set address '${mac}' to virtual device '${newport}'."
535 return ${EXIT_ERROR}
536 fi
1848564d
MT
537
538 # Bring up the new device
539 device_set_up ${newport}
540
1848564d
MT
541 return ${EXIT_OK}
542}
543
544function device_virtual_remove() {
545 local device=$(devicify ${1})
546
81ed640c 547 log INFO "Removing virtual device '${device}' with address '$(macify ${device})'."
1b7a1578 548
1848564d
MT
549 device_set_down ${device}
550
551 vconfig rem ${device} >/dev/null
1848564d 552
1b7a1578
MT
553 if [ $? -ne ${EXIT_OK} ]; then
554 error_log "Could not remote virtual device '${newport}'."
555 return ${EXIT_ERROR}
556 fi
557
1848564d
MT
558 return ${EXIT_OK}
559}
560
81ed640c
MT
561function device_virtual_get_parent() {
562 local device=${1}
563
564 local parent=$(grep "^${device}" < /proc/net/vlan/config | awk '{ print $NF }')
565
566 if device_exists ${parent}; then
567 echo "${parent}"
568 return ${EXIT_OK}
569 fi
570
571 return ${EXIT_ERROR}
572}
573
fb02e543
MT
574function device_virtual_get_by_parent_and_vid() {
575 local parent=${1}
576 local vid=${2}
577
578 local v_port
579 local v_id
580 local v_parent
581
582 fgrep '|' < /proc/net/vlan/config | tr -d '|' | \
583 while read v_port v_id v_parent; do
584 if [ "${v_parent}" = "${parent}" ] && [ "${v_id}" = "${vid}" ]; then
585 echo "${v_port}"
586 return ${EXIT_OK}
587 fi
588 done
589
590 return ${EXIT_ERROR}
591}
592
1848564d
MT
593function device_bonding_create() {
594 local device=${1}
595 local mac=${2}
596
597 [ -z "${mac}" ] && mac=$(mac_generate)
598
1b7a1578
MT
599 log INFO "Creating bonding device '${device}' (${mac})."
600
1848564d 601 echo "+${device}" > /sys/class/net/bonding_masters
7cbea20d 602 device_set_address ${mac}
1848564d
MT
603 device_set_up ${device}
604}
605
606function device_bonding_remove() {
607 local device=$(devicify ${1})
608
1b7a1578
MT
609 log INFO "Remove bonding device '${device}'."
610
1848564d
MT
611 device_set_down ${device}
612 echo "-${device}" > /sys/class/net/bonding_masters
613}
614
615function bonding_set_mode() {
616 local device=${1}
617 local mode=${2}
618
1b7a1578
MT
619 log INFO "Setting bonding mode on '${device}' '${mode}'."
620
1848564d
MT
621 echo "${mode}" > /sys/class/net/${device}/bonding/mode
622}
623
624function bonding_enslave_device() {
625 local device=$(devicify ${1})
626 local slave=$(devicify ${2})
1b7a1578
MT
627 shift 2
628
629 log INFO "Enslaving slave '${slave}' to '${device}'."
1848564d
MT
630
631 device_set_down ${slave}
632 echo "+${slave}" > /sys/class/net/${device}/bonding/slaves
633}
634
635function bridge_attach_device() {
636 local bridge=${1}
637 local device=${2}
638
639 if ! device_exists ${bridge}; then
640 error "Bridge '${bridge}' does not exist."
641 return ${EXIT_ERROR}
642 fi
643
644 if ! device_exists ${device}; then
645 error "Device '${device}' does not exist."
646 return ${EXIT_ERROR}
647 fi
648
1b7a1578
MT
649 log INFO "Attaching device '${device}' to bridge '${bridge}'."
650
1848564d
MT
651 # XXX device_set_up ${device} # Do we need this here?
652
653 brctl addif ${bridge} ${device}
654}
655
656function bridge_detach_device() {
657 local bridge=${1}
658 local device=${2}
659
660 if ! device_exists ${bridge}; then
661 error "Bridge '${bridge}' does not exist."
662 return ${EXIT_ERROR}
663 fi
664
665 if ! device_exists ${device}; then
666 error "Device '${device}' does not exist."
667 return ${EXIT_ERROR}
668 fi
669
1b7a1578
MT
670 log INFO "Detaching device '${device}' from bridge '${bridge}'."
671
672 brctl delif ${bridge} ${device}
1848564d
MT
673
674 device_set_down ${device}
675}
676
677function bridge_is_forwarding() {
678 local seconds=45
679 local zone=${1}
680
681 bridge_has_carrier ${zone} || return ${EXIT_ERROR}
682
683 local device
684 while [ ${seconds} -gt 0 ]; do
685 for device in ${SYS_CLASS_NET}/${zone}/brif/*; do
686 [ -e "${device}/state" ] || continue
687 if [ "$(<${device}/state)" = "3" ]; then
688 return ${EXIT_OK}
689 fi
690 done
691 sleep 1
692 seconds=$((${seconds} - 1))
693 done
694
695 return ${EXIT_ERROR}
696}
697
698function bridge_has_carrier() {
699 local zone=${1}
700
701 local has_carrier=${EXIT_ERROR}
702
703 local device
704 for device in ${SYS_CLASS_NET}/${zone}/brif/*; do
705 device=$(basename ${device})
706 device_exists ${device} || continue
707
708 device_has_carrier ${device} && has_carrier=${EXIT_OK}
709 done
710
711 return ${has_carrier}
712}
713
714function device_has_ipv4() {
715 local device=${1}
716 local addr=${2}
717
718 if ! device_exists ${device}; then
719 error "Device '${device}' does not exist."
720 return ${EXIT_ERROR}
721 fi
722
723 ip addr show ${device} | grep -q -e "inet " -e "${addr}"
724}