2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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. #
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. #
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/>. #
20 ###############################################################################
25 if device_exists
${device}; then
31 for d
in $
(devices_get_all
); do
32 if [ "$(device_get_address ${d})" = "${device}" ]; then
44 if mac_is_valid
${device}; then
49 if device_exists
${device}; then
50 device_get_address
${device}
57 # Check if the device exists
58 function device_exists
() {
61 # If device name was not found, exit.
62 [ -n "${device}" ] ||
return ${EXIT_ERROR}
64 [ -d "${SYS_CLASS_NET}/${device}" ]
67 # Check if the device is up
68 function device_is_up
() {
71 device_exists
${device} ||
return ${EXIT_ERROR}
73 ip link show
${device} 2>/dev
/null |
grep -qE "<.*UP.*>"
76 # Check if the device is a bonding device
77 function device_is_bonding
() {
78 [ -d "/sys/class/net/${1}/bonding" ]
81 # Check if the device bonded in a bonding device
82 function device_is_bonded
() {
84 for dev
in /sys
/class
/net
/*; do
86 [ -d "${dev}" ] ||
continue
88 # Continue if not a bonding device
89 device_is_bonding
"${dev##*/}" ||
continue
91 if grep -q "\<${1}\>" ${dev}/bonding
/slaves
; then
99 # Check if the device is a bridge
100 function device_is_bridge
() {
101 [ -d "/sys/class/net/${1}/bridge" ]
104 # Check if the device is a virtual device
105 function device_is_virtual
() {
108 [ -e "/proc/net/vlan/${device}" ]
111 # Check if the device has virtual devices
112 function device_has_virtuals
() {
113 if [ ! -e "/proc/net/vlan/config" ]; then
116 grep -q "${1}$" /proc
/net
/vlan
/config
119 function device_is_vlan
() { # XXX Compat function
120 log DEBUG
"Deprecated function device_is_vlan() was used."
125 # Check if the device is a ppp device
126 function device_is_ppp
() {
129 ip link show
${device} 2>/dev
/null |
grep -qE "<.*POINTOPOINT.*>"
132 # Check if the device is a loopback device
133 function device_is_loopback
() {
134 local device
=$
(devicify
${1})
135 [ "${device}" = "lo" ]
138 # Check if the device is a physical network interface
139 function device_is_real
() {
142 device_is_loopback
${device} && \
145 device_is_bonding
${device} && \
148 device_is_bridge
${device} && \
151 device_is_ppp
${device} && \
154 device_is_virtual
${device} && \
160 # Get the device type
161 function device_get_type
() {
162 local device
=$
(devicify
${1})
164 if device_is_vlan
${device}; then
167 elif device_is_bonding
${device}; then
170 elif device_is_bridge
${device}; then
173 elif device_is_ppp
${device}; then
176 elif device_is_loopback
${device}; then
179 elif device_is_real
${device}; then
187 function device_get_address
() {
190 cat ${SYS_CLASS_NET}/${device}/address
2>/dev
/null
193 function device_set_address
() {
197 function devices_get_all
() {
199 for device
in ${SYS_CLASS_NET}/*; do
200 echo "$(basename ${device})"
204 # Check if a device has a cable plugged in
205 function device_has_carrier
() {
206 local device
=$
(devicify
${1})
207 [ "$(<${SYS_CLASS_NET}/${device}/carrier)" = "1" ]
210 # Check if the device is free
211 function device_is_free
() {
214 device_is_used
${device} && \
220 # Check if the device is used
221 function device_is_used
() {
222 local device
=$
(devicify
${1})
224 device_has_vlans
${device} && \
226 device_is_bonded
${device} && \
232 # XXX to be removed I think
233 function device_get_free
() {
234 local destination
=${1}
236 # Replace + by a valid number
237 if grep -q "+$" <<<${destination}; then
239 destination
=$
(sed -e "s/+//" <<<$destination)
240 while [ "${number}" -le "100" ]; do
241 if ! device_exists
"${destination}${number}"; then
242 destination
="${destination}${number}"
245 number
=$
(($number + 1))
248 echo "${destination}"
251 # Should be renamed to device_set_name at some time
252 function device_rename
() {
254 local destination
=$
(device_get_free
${2})
256 # Check if devices exists
257 if ! device_exists
${source} || device_exists
${destination}; then
262 if device_is_up
${source}; then
263 ip link
set ${source} down
267 ip link
set ${source} name
${destination}
269 if [ "${up}" = "1" ]; then
270 ip link
set ${destination} up
274 function device_hash
() {
277 macify
${device} |
tr -d ':'
280 # Give the device a new name
281 function device_set_name
() {
286 function device_set_up
() {
287 local device
=$
(devicify
${1})
289 # Do nothing if device is already up
290 device_is_up
${device} && return ${EXIT_OK}
292 log DEBUG
"Setting up device $@"
293 ip link
set ${device} up
297 function device_set_down
() {
298 local device
=$
(devicify
${1})
300 # Do nothing if device is not up
301 device_is_up
${device} ||
return ${EXIT_OK}
303 log DEBUG
"Tearing down device $@"
304 ip link
set ${device} down
307 # Set new address to a device
308 function device_set_mac
() {
313 if device_is_up
${port}; then
314 device_set_down
${port}
318 ip link
set ${port} address
${mac}
321 if [ "${up}" = "1" ]; then
322 device_set_up
${port}
328 function device_get_mtu
() {
331 if ! device_exists
${device}; then
332 error
"Device '${device}' does not exist."
336 cat ${SYS_CLASS_NET}/${device}/mtu
339 # Set mtu to a device
340 function device_set_mtu
() {
345 if device_is_up
${port}; then
346 device_set_down
${port}
350 ip link
set ${port} mtu
${mtu}
353 if [ "${up}" = "1" ]; then
354 device_set_up
${port}
360 function device_discover
() {
364 for hook
in $
(hooks_get_all
); do
365 hook_exec
${hook} discover
${device}
369 function device_create_virtual
() {
370 log WARN
"Called deprecated function device_create_virtual"
371 device_virtual_create $@
374 function device_virtual_create
() {
375 local port
=$
(devicify
${1})
378 local newport
=${port}v
${vid}
380 if [ -z "${mac}" ]; then
384 # Bring up the parent device
385 # XXX Do we need this here?
386 #device_set_up ${port}
388 vconfig set_name_type DEV_PLUS_VID_NO_PAD
>/dev
/null
389 vconfig add
${port} ${vid} >/dev
/null
390 [ $?
-ne 0 ] && return ${EXIT_ERROR}
392 # The device is expected to be named like ${port}.${vid}
393 # and will be renamed to the virtual schema
394 device_set_name
${port}.${vid} ${newport}
396 # Setting new mac address
397 device_set_address
${newport} ${mac}
399 # Bring up the new device
400 device_set_up
${newport}
402 log DEBUG
"Created virtual device ${newport} (${mac})"
406 function device_virtual_remove
() {
407 local device
=$
(devicify
${1})
409 device_set_down
${device}
411 vconfig rem
${device} >/dev
/null
412 [ $?
-ne 0 ] && return ${EXIT_ERROR}
414 log DEBUG
"Removed virtual device ${device}"
418 function device_bonding_create
() {
422 [ -z "${mac}" ] && mac
=$
(mac_generate
)
424 echo "+${device}" > /sys
/class
/net
/bonding_masters
425 device_set_mac
${mac}
426 device_set_up
${device}
429 function device_bonding_remove
() {
430 local device
=$
(devicify
${1})
432 device_set_down
${device}
433 echo "-${device}" > /sys
/class
/net
/bonding_masters
436 function bonding_set_mode
() {
440 echo "${mode}" > /sys
/class
/net
/${device}/bonding
/mode
443 function bonding_enslave_device
() {
444 local device
=$
(devicify
${1})
445 local slave
=$
(devicify
${2})
447 device_set_down
${slave}
448 echo "+${slave}" > /sys
/class
/net
/${device}/bonding
/slaves
451 function bridge_attach_device
() {
455 if ! device_exists
${bridge}; then
456 error
"Bridge '${bridge}' does not exist."
460 if ! device_exists
${device}; then
461 error
"Device '${device}' does not exist."
465 # XXX device_set_up ${device} # Do we need this here?
467 brctl addif
${bridge} ${device}
470 function bridge_detach_device
() {
474 if ! device_exists
${bridge}; then
475 error
"Bridge '${bridge}' does not exist."
479 if ! device_exists
${device}; then
480 error
"Device '${device}' does not exist."
484 brctl delif
${zone} ${device}
486 device_set_down
${device}
489 function bridge_is_forwarding
() {
493 bridge_has_carrier
${zone} ||
return ${EXIT_ERROR}
496 while [ ${seconds} -gt 0 ]; do
497 for device
in ${SYS_CLASS_NET}/${zone}/brif
/*; do
498 [ -e "${device}/state" ] ||
continue
499 if [ "$(<${device}/state)" = "3" ]; then
504 seconds
=$
((${seconds} - 1))
510 function bridge_has_carrier
() {
513 local has_carrier
=${EXIT_ERROR}
516 for device
in ${SYS_CLASS_NET}/${zone}/brif
/*; do
517 device
=$
(basename ${device})
518 device_exists
${device} ||
continue
520 device_has_carrier
${device} && has_carrier
=${EXIT_OK}
523 return ${has_carrier}
526 function device_has_ipv4
() {
530 if ! device_exists
${device}; then
531 error
"Device '${device}' does not exist."
535 ip addr show
${device} |
grep -q -e "inet " -e "${addr}"