]> git.ipfire.org Git - people/ms/network.git/blame - functions.device
doc: Confused STP standards.
[people/ms/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
711ffac1
MT
25 assert isset device
26
1848564d
MT
27 if device_exists ${device}; then
28 echo "${device}"
29 return ${EXIT_OK}
30 fi
31
32 local d
33 for d in $(devices_get_all); do
34 if [ "$(device_get_address ${d})" = "${device}" ]; then
35 echo "${d}"
36 return ${EXIT_OK}
37 fi
38 done
39
40 return ${EXIT_ERROR}
41}
42
43function macify() {
44 local device=${1}
45
711ffac1
MT
46 assert isset device
47
1848564d
MT
48 if mac_is_valid ${device}; then
49 echo "${device}"
50 return ${EXIT_OK}
51 fi
52
53 if device_exists ${device}; then
54 device_get_address ${device}
55 return ${EXIT_OK}
56 fi
57
58 return ${EXIT_ERROR}
59}
60
61# Check if the device exists
62function device_exists() {
63 local device=${1}
64
65 # If device name was not found, exit.
66 [ -n "${device}" ] || return ${EXIT_ERROR}
67
68 [ -d "${SYS_CLASS_NET}/${device}" ]
69}
70
e369be1a
MT
71function device_has_flag() {
72 local device=${1}
73 local flag=${2}
74
75 local flags=$(__device_get_file ${device} flags)
76
77 if [[ "$(( ${flags} & ${flag} ))" -eq 0 ]]; then
78 return ${EXIT_FALSE}
79 else
80 return ${EXIT_TRUE}
81 fi
82}
83
1848564d
MT
84# Check if the device is up
85function device_is_up() {
86 local device=${1}
87
88 device_exists ${device} || return ${EXIT_ERROR}
89
e369be1a 90 device_has_flag ${device} 0x1
1848564d
MT
91}
92
93# Check if the device is a bonding device
94function device_is_bonding() {
95 [ -d "/sys/class/net/${1}/bonding" ]
96}
97
98# Check if the device bonded in a bonding device
99function device_is_bonded() {
711ffac1 100 local device=${1}
1848564d 101
711ffac1 102 [ -d "${SYS_CLASS_NET}/${device}/master" ]
1848564d
MT
103}
104
105# Check if the device is a bridge
106function device_is_bridge() {
107 [ -d "/sys/class/net/${1}/bridge" ]
108}
109
81ed640c
MT
110function device_is_bridge_attached() {
111 local device=${1}
112
113 [ -d "${SYS_CLASS_NET}/${device}/brport" ]
114}
115
1848564d
MT
116# Check if the device is a virtual device
117function device_is_virtual() {
118 local device=${1}
119
120 [ -e "/proc/net/vlan/${device}" ]
121}
122
123# Check if the device has virtual devices
124function device_has_virtuals() {
fb02e543
MT
125 local device=${1}
126
127 if device_is_virtual ${device}; then
ec63256a 128 return ${EXIT_FALSE}
fb02e543
MT
129 fi
130
ec63256a
MT
131 local virtuals=$(device_get_virtuals ${device})
132 [ -n "${virtuals}" ] && return ${EXIT_OK} || return ${EXIT_ERROR}
133}
134
135function device_get_virtuals() {
136 local device=${1}
137
138 local dev spacer1 id spacer2 parent
139 while read dev spacer1 id spacer2 parent; do
140 [ "${parent}" = "${device}" ] && echo "${dev}"
141 done < /proc/net/vlan/config | sort
1848564d
MT
142}
143
1848564d
MT
144# Check if the device is a ppp device
145function device_is_ppp() {
146 local device=${1}
147
55b802cc 148 local type=$(__device_get_file ${device} type)
28f0b4ab 149
e369be1a
MT
150 [ "${type}" = "512" ] && return ${EXIT_OK} || return ${EXIT_ERROR}
151}
55b802cc 152
e369be1a
MT
153# Check if the device is a pointopoint device.
154function device_is_ptp() {
155 local device=${1}
156
157 device_has_flag ${device} 0x10
1848564d
MT
158}
159
160# Check if the device is a loopback device
161function device_is_loopback() {
5bb2429a
MT
162 local device=${1}
163
1848564d
MT
164 [ "${device}" = "lo" ]
165}
166
a508c27e
MT
167# Check if the device is a wireless device
168function device_is_wireless() {
169 local device=${1}
170
171 [ -d "${SYS_CLASS_NET}/${device}/phy80211" ]
172}
173
1848564d 174# Check if the device is a physical network interface
ec63256a 175function device_is_ethernet() {
1848564d
MT
176 local device=${1}
177
178 device_is_loopback ${device} && \
179 return ${EXIT_ERROR}
180
181 device_is_bonding ${device} && \
182 return ${EXIT_ERROR}
183
184 device_is_bridge ${device} && \
185 return ${EXIT_ERROR}
186
187 device_is_ppp ${device} && \
188 return ${EXIT_ERROR}
189
190 device_is_virtual ${device} && \
191 return ${EXIT_ERROR}
192
419b4cd0
MT
193 [ "$(__device_get_file ${device} type)" != "1" ] && \
194 return ${EXIT_ERROR}
195
1848564d
MT
196 return ${EXIT_OK}
197}
198
199# Get the device type
200function device_get_type() {
5bb2429a 201 local device=${1}
1848564d 202
8c6a8966 203 if device_is_virtual ${device}; then
1848564d
MT
204 echo "vlan"
205
206 elif device_is_bonding ${device}; then
207 echo "bonding"
208
209 elif device_is_bridge ${device}; then
210 echo "bridge"
211
212 elif device_is_ppp ${device}; then
213 echo "ppp"
214
215 elif device_is_loopback ${device}; then
216 echo "loopback"
217
a508c27e
MT
218 elif device_is_wireless ${device}; then
219 echo "wireless"
220
ec63256a
MT
221 elif device_is_ethernet ${device}; then
222 echo "ethernet"
1848564d
MT
223
224 else
225 echo "unknown"
226 fi
227}
228
711ffac1
MT
229function device_get_status() {
230 local device=${1}
231
232 assert isset device
233
234 local status=${STATUS_UNKNOWN}
235
236 if ! device_has_carrier ${device}; then
237 status=${STATUS_NOCARRIER}
238 elif device_is_up ${device}; then
239 status=${STATUS_UP}
240 elif device_is_down ${device}; then
241 status=${STATUS_DOWN}
242 fi
243
244 assert isset status
245
246 echo "${status}"
247}
248
1848564d
MT
249function device_get_address() {
250 local device=${1}
251
252 cat ${SYS_CLASS_NET}/${device}/address 2>/dev/null
253}
254
255function device_set_address() {
1b7a1578
MT
256 local device=${1}
257 local addr=${2}
258
259 if ! device_exists ${device}; then
260 error "Device '${device}' does not exist."
261 return ${EXIT_ERROR}
262 fi
263
264 log INFO "Setting address of '${device}' to '${addr}' - was $(device_get_address ${device})."
265
266 local up
267 if device_is_up ${device}; then
268 device_set_down ${device}
269 up=1
270 fi
271
272 ip link set ${device} address ${addr}
273 local ret=$?
274
275 if [ "${up}" = "1" ]; then
276 device_set_up ${device}
277 fi
278
279 if [ "${ret}" != "0" ]; then
280 error_log "Could not set address '${addr}' on device '${device}'."
281 fi
282
283 return ${ret}
1848564d
MT
284}
285
711ffac1 286function device_get() {
2ae0fb8d 287 local device
711ffac1
MT
288 local devices
289
2ae0fb8d
MT
290 for device in ${SYS_CLASS_NET}/*; do
291 device=$(basename ${device})
711ffac1 292
2ae0fb8d
MT
293 # bonding_masters is no device
294 [ "${device}" = "bonding_masters" ] && continue
295
296 devices="${devices} ${device}"
297 done
711ffac1
MT
298
299 echo ${devices}
300 return ${EXIT_OK}
301}
302
1848564d 303function devices_get_all() {
711ffac1 304 device_get
1848564d
MT
305}
306
307# Check if a device has a cable plugged in
308function device_has_carrier() {
5bb2429a
MT
309 local device=${1}
310 assert isset device
311
ec63256a
MT
312 local carrier=$(__device_get_file ${device} carrier)
313 [ "${carrier}" = "1" ]
1848564d
MT
314}
315
1e4c26a4
MT
316function device_is_promisc() {
317 local device=${1}
318
e369be1a 319 device_has_flag ${device} 0x200
1e4c26a4
MT
320}
321
cf6e4606
MT
322function device_set_promisc() {
323 local device=${1}
324 local state=${2}
325
326 assert device_exists ${device}
327 assert isset state
328 assert isoneof state on off
329
330 ip link set ${device} promisc ${state}
331}
332
1848564d
MT
333# Check if the device is free
334function device_is_free() {
81ed640c 335 ! device_is_used $@
1848564d
MT
336}
337
338# Check if the device is used
339function device_is_used() {
5bb2429a 340 local device=${1}
1848564d 341
fb02e543
MT
342 device_has_virtuals ${device} && \
343 return ${EXIT_OK}
1848564d 344 device_is_bonded ${device} && \
fb02e543 345 return ${EXIT_OK}
81ed640c
MT
346 device_is_bridge_attached ${device} && \
347 return ${EXIT_OK}
1848564d 348
fb02e543 349 return ${EXIT_ERROR}
1848564d
MT
350}
351
1b7a1578
MT
352function device_hash() {
353 local device=${1}
354
37e4ec8b
MT
355 # Get mac address of device and remove all colons (:)
356 # that will result in a hash.
357 device=$(macify ${device})
358
359 echo "${device//:/}"
1b7a1578
MT
360}
361
362# Give the device a new name
363function device_set_name() {
1848564d 364 local source=$1
1578dae9 365 local destination=${2}
1848564d
MT
366
367 # Check if devices exists
368 if ! device_exists ${source} || device_exists ${destination}; then
369 return 4
370 fi
371
372 local up
373 if device_is_up ${source}; then
374 ip link set ${source} down
375 up=1
376 fi
377
378 ip link set ${source} name ${destination}
379
380 if [ "${up}" = "1" ]; then
381 ip link set ${destination} up
382 fi
383}
384
1848564d
MT
385# Set device up
386function device_set_up() {
5bb2429a 387 local device=${1}
1848564d 388
711ffac1
MT
389 # Silently fail if device was not found
390 [ -z "${device}" ] && return ${EXIT_ERROR}
391
1848564d
MT
392 # Do nothing if device is already up
393 device_is_up ${device} && return ${EXIT_OK}
394
81ed640c
MT
395 device_set_parent_up ${device}
396
397 log DEBUG "Setting up device '${device}'"
398
1848564d
MT
399 ip link set ${device} up
400}
401
81ed640c
MT
402function device_set_parent_up() {
403 local device=${1}
404 local parent
405
406 if device_is_virtual ${device}; then
8c6a8966 407 parent=$(virtual_get_parent ${device})
81ed640c
MT
408
409 device_is_up ${parent} && return ${EXIT_OK}
410
411 log DEBUG "Setting up parent device '${parent}' of '${device}'"
412
413 device_set_up ${parent}
414 return $?
415 fi
416
417 return ${EXIT_OK}
418}
419
1848564d
MT
420# Set device down
421function device_set_down() {
5bb2429a
MT
422 local device=${1}
423 assert isset device
1848564d 424
81ed640c
MT
425 local ret=${EXIT_OK}
426
427 if device_is_up ${device}; then
428 log DEBUG "Tearing down device '${device}'"
429
430 ip link set ${device} down
431 ret=$?
432 fi
433
434 device_set_parent_down ${device}
1848564d 435
81ed640c
MT
436 return ${ret}
437}
438
439function device_set_parent_down() {
440 local device=${1}
441 local parent
442
443 if device_is_virtual ${device}; then
8c6a8966 444 parent=$(virtual_get_parent ${device})
81ed640c
MT
445
446 device_is_up ${parent} || return ${EXIT_OK}
447
448 if device_is_free ${parent}; then
449 log DEBUG "Tearing down parent device '${parent}' of '${device}'"
450
451 device_set_down ${parent}
452 fi
453 fi
454
455 return ${EXIT_OK}
1848564d
MT
456}
457
1848564d
MT
458function device_get_mtu() {
459 local device=${1}
460
461 if ! device_exists ${device}; then
462 error "Device '${device}' does not exist."
463 return ${EXIT_ERROR}
464 fi
465
f3e6fe50 466 echo $(<${SYS_CLASS_NET}/${device}/mtu)
1848564d
MT
467}
468
469# Set mtu to a device
470function device_set_mtu() {
1b7a1578 471 local device=${1}
1848564d
MT
472 local mtu=${2}
473
1b7a1578
MT
474 if ! device_exists ${device}; then
475 error "Device '${device}' does not exist."
476 return ${EXIT_ERROR}
477 fi
478
479 local oldmtu=$(device_get_mtu ${device})
480
481 if [ "${oldmtu}" = "${mtu}" ]; then
482 # No need to set mtu.
483 return ${EXIT_OK}
484 fi
485
486 log INFO "Setting mtu of '${device}' to '${mtu}' - was ${oldmtu}."
487
1848564d 488 local up
1b7a1578
MT
489 if device_is_up ${device}; then
490 device_set_down ${device}
1848564d
MT
491 up=1
492 fi
493
1b7a1578 494 ip link set ${device} mtu ${mtu}
1848564d
MT
495 local ret=$?
496
497 if [ "${up}" = "1" ]; then
1b7a1578
MT
498 device_set_up ${device}
499 fi
500
501 if [ "${ret}" != "0" ]; then
502 error_log "Could not set mtu '${mtu}' on device '${device}'."
1848564d
MT
503 fi
504
505 return ${ret}
506}
507
508function device_discover() {
509 local device=${1}
510
1b7a1578
MT
511 log INFO "Running discovery process on device '${device}'."
512
1848564d 513 local hook
d61a01d4
MT
514 for hook in $(hook_zone_get_all); do
515 hook_zone_exec ${hook} discover ${device}
1848564d
MT
516 done
517}
518
38f61548 519function device_has_ip() {
1848564d
MT
520 local device=${1}
521 local addr=${2}
522
38f61548
MT
523 assert isset addr
524 assert device_exists ${device}
525
526 # IPv6 addresses must be fully imploded
527 local protocol=$(ip_detect_protocol ${addr})
528 case "${protocol}" in
529 ipv6)
530 addr=$(ipv6_implode ${addr})
531 ;;
532 esac
1848564d 533
38f61548 534 listmatch ${addr} $(device_get_addresses ${device})
1848564d 535}
4231f419 536
38f61548 537function device_get_addresses() {
4231f419 538 local device=${1}
4231f419 539
38f61548 540 assert device_exists ${device}
4231f419 541
38f61548
MT
542 local prot
543 local addr
544 local line
545 ip addr show ${device} | \
546 while read prot addr line; do
547 [ "${prot:0:4}" = "inet" ] && echo "${addr}"
548 done
4231f419 549}
711ffac1 550
711ffac1
MT
551function __device_get_file() {
552 local device=${1}
553 local file=${2}
554
555 assert isset device
556 assert isset file
557
e369be1a
MT
558 local path="${SYS_CLASS_NET}/${device}/${file}"
559 [ -r "${path}" ] || return ${EXIT_ERROR}
560
561 echo "$(<${path})"
711ffac1
MT
562}
563
564function device_get_rx_bytes() {
565 local device=${1}
566
567 __device_get_file ${device} statistics/rx_bytes
568}
569
570function device_get_tx_bytes() {
571 local device=${1}
572
573 __device_get_file ${device} statistics/tx_bytes
574}
575
576function device_get_rx_packets() {
577 local device=${1}
578
579 __device_get_file ${device} statistics/rx_packets
580}
581
582function device_get_tx_packets() {
583 local device=${1}
584
585 __device_get_file ${device} statistics/tx_packets
586}
587
588function device_get_rx_errors() {
589 local device=${1}
590
591 __device_get_file ${device} statistics/rx_errors
592}
593
594function device_get_tx_errors() {
595 local device=${1}
596
597 __device_get_file ${device} statistics/tx_errors
598}
ec63256a
MT
599
600function device_get_speed() {
601 local device=${1}
602
603 __device_get_file ${device} speed
604}
605
606function device_get_duplex() {
607 local device=${1}
608
609 __device_get_file ${device} duplex
610}