]> git.ipfire.org Git - people/stevee/network.git/blob - src/functions/functions.bonding
bonding: Major rewrite of the hook
[people/stevee/network.git] / src / functions / functions.bonding
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
22 BONDING_ALLOWED_MODES="balance-rr active-backup balance-xor broadcast 802.3ad \
23 balance-tlb balance-alb"
24 BONDING_MASTERS="/sys/class/net/bonding_masters"
25 BONDING_PORT_PATTERN="bN"
26
27 bonding_init() {
28 module_load "bonding"
29 }
30
31 bonding_create() {
32 local device=${1}
33 assert isset device
34 shift
35
36 local address
37 local mode="balance-rr"
38
39 while [ $# -gt 0 ]; do
40 case "${1}" in
41 --address=*)
42 address=$(cli_get_val ${1})
43 ;;
44 --mode=*)
45 mode=$(cli_get_val ${1})
46 ;;
47 *)
48 error "Unrecognized argument: ${1}"
49 return ${EXIT_ERROR}
50 ;;
51 esac
52 shift
53 done
54
55 if isset address; then
56 if ! ismac address; then
57 log ERROR "Invalid mac address: ${address}"
58 return ${EXIT_ERROR}
59 fi
60 fi
61
62 if ! list_match "${mode}" ${BONDING_ALLOWED_MODES}; then
63 log ERROR "Bonding mode is not supported: ${mode}"
64 log ERROR "Valid modes are: ${BONDING_ALLOWED_MODES}"
65 return ${EXIT_ERROR}
66 fi
67
68 # Initialize the bonding driver just
69 # when we need it.
70 bonding_init
71
72 # Create the bonding device
73 if cmd ip link add "${device}" address "${address}" \
74 type bond mode "${mode}"; then
75 log DEBUG "Successfully created bonding device '${device}'"
76 else
77 log ERROR "Could not create bonding device '${device}'"
78 return ${EXIT_ERROR}
79 fi
80
81 return ${EXIT_OK}
82 }
83
84 bonding_remove() {
85 local device=${1}
86 assert isset device
87
88 # Remove the device.
89 if device_delete "${device}"; then
90 log DEBUG "Successfully removed bonding device '${device}'"
91 else
92 log ERROR "Could not remove bonding device '${device}'"
93 return ${EXIT_ERROR}
94 fi
95
96 return ${EXIT_OK}
97 }
98
99 bonding_get_mode() {
100 local device=${1}
101 assert isset device
102
103 local mode mode_num
104 read mode mode_num < ${SYS_CLASS_NET}/${device}/bonding/mode
105 print "${mode}"
106 }
107
108 bonding_set_mode() {
109 assert [ $# -eq 2 ]
110
111 local device="${1}"
112 local mode="${2}"
113
114 if fappend "${SYS_CLASS_NET}/${device}/bonding/mode" "${mode}"; then
115 log DEBUG "Set mode of bond '${device}' to '${mode}'"
116 else
117 log ERROR "Could not set mode of bond '${device}' to '${mode}'"
118 return ${EXIT_ERROR}
119 fi
120
121 return ${EXIT_OK}
122 }
123
124 bonding_enslave_device() {
125 local device=${1}
126 assert isset device
127
128 local slave=${2}
129 assert isset slave
130
131 shift 2
132
133 local slaves="$(bonding_get_slaves "${device}")"
134 if list_match "${slave}" ${slaves}; then
135 log DEBUG "${slave} is already enslaved in ${device}"
136 return ${EXIT_OK}
137 fi
138
139 # Slave must be down to be enslaved.
140 if ! device_set_down "${slave}"; then
141 log ERROR "Cannot enslave '${slave}' because it cannot be set down."
142 return ${EXIT_ERROR}
143 fi
144
145 # Add it
146 cmd ip link set "${slave}" master "${device}"
147 local ret=$?
148
149 if [ ${ret} -eq ${EXIT_OK} ]; then
150 log DEBUG "Successfully enslaved '${slave}' to '${device}'"
151 else
152 log ERROR "Could not enslave '${slave}' to '${device}'"
153 return ${EXIT_ERROR}
154 fi
155
156 return ${EXIT_OK}
157 }
158
159 bonding_get_slaves() {
160 local device=${1}
161 assert isset device
162 shift
163
164 local file="slaves"
165 while [ $# -gt 0 ]; do
166 case "${1}" in
167 --active)
168 file="active_slave"
169 ;;
170 *)
171 error "Unrecognized argument: ${1}"
172 return ${EXIT_ERROR}
173 ;;
174 esac
175 shift
176 done
177
178 fread ${SYS_CLASS_NET}/${device}/bonding/${file}
179
180 return ${EXIT_OK}
181 }
182
183 bonding_get_lacp_rate() {
184 local device=${1}
185 assert isset device
186
187 local rate rateno
188 read -r rate rateno \
189 < ${SYS_CLASS_NET}/${device}/bonding/lacp_rate
190
191 print "${rate}"
192 return ${EXIT_OK}
193 }
194
195 bonding_get_miimon() {
196 local device=${1}
197 assert isset device
198
199 fread ${SYS_CLASS_NET}/${device}/bonding/miimon
200 }
201
202 bonding_set_miimon() {
203 local device=${1}
204 assert isset device
205
206 local miimon=${2}
207 assert isset miimon
208
209 print "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon
210 }
211
212 bonding_slave_get_master() {
213 local slave=${1}
214 assert isset slave
215
216 device_is_bonded ${slave} || return ${EXIT_ERROR}
217
218 local master=$(fread ${SYS_CLASS_NET}/${slave}/master/ifindex)
219 if isset master; then
220 device_ifindex_to_name ${master}
221 return ${EXIT_OK}
222 fi
223
224 return ${EXIT_ERROR}
225 }