]> git.ipfire.org Git - people/stevee/network.git/blob - src/hooks/ports/bonding
f0572c3f5b496f45b3df8b33d55549bf412ae34b
[people/stevee/network.git] / src / hooks / ports / 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 . /usr/lib/network/header-port
23
24 HOOK_SETTINGS="ADDRESS MIIMON MODE OFFLOADING SLAVES"
25
26 DEFAULT_MIIMON=100
27 DEFAULT_MODE="balance-rr"
28
29 hook_check_settings() {
30 assert isset ADDRESS
31 assert ismac ADDRESS
32
33 #assert isset SLAVES
34 assert isinteger MIIMON
35 }
36
37 hook_parse_cmdline() {
38 while [ $# -gt 0 ]; do
39 case "${1}" in
40 --address=*)
41 ADDRESS="$(cli_get_val "${1}")"
42
43 if ! mac_is_valid "${ADDRESS}"; then
44 error "Invalid MAC address: ${ADDRESS}"
45 return ${EXIT_ERROR}
46 fi
47 ;;
48
49 --miimon=*)
50 MIIMON=$(cli_get_val "${1}")
51 ;;
52 --mode=*)
53 MODE=$(cli_get_val "${1}")
54 ;;
55 --offloading=*)
56 OFFLOADING="$(cli_get_val "${1}")"
57
58 if enabled OFFLOADING; then
59 OFFLOADING="on"
60 elif disabled OFFLOADING; then
61 OFFLOADING="off"
62 else
63 error "Invalid value for offloading: ${OFFLOADING}"
64 return ${EXIT_ERROR}
65 fi
66 ;;
67 +*)
68 local slave=$(cli_get_val "${1:1}")
69
70 if port_exists "${slave}"; then
71 if list_match "${slave}" ${SLAVES}; then
72 warning "Port ${slave} is already enslaved"
73 else
74 list_append SLAVES "${slave}"
75 fi
76 else
77 warning "Port ${slave} does not exist"
78 fi
79 ;;
80 -*)
81 local slave=$(cli_get_val "${1:1}")
82 if ! list_remove SLAVES "${slave}"; then
83 warning "Port ${slave} is not a slave of this bonding device"
84 fi
85 ;;
86 *)
87 warning "Unknown argument '${1}'"
88 ;;
89 esac
90 shift
91 done
92
93 if isset ADDRESS; then
94 if ! ismac ADDRESS; then
95 error "The given MAC address is invalid: ${ADDRESS}"
96 return ${EXIT_ERROR}
97 fi
98 else
99 ADDRESS=$(mac_generate)
100 fi
101 }
102
103 hook_new() {
104 if ! hook_parse_cmdline "$@"; then
105 return ${EXIT_ERROR}
106 fi
107
108 # Find a new name
109 local port=$(port_find_free ${BONDING_PORT_PATTERN})
110 assert isset port
111
112 # Save configuration
113 if port_settings_write "${port}" ${HOOK_SETTINGS}; then
114 log INFO "New port ${port} has been created"
115 else
116 error "Could not save configuration for ${port}"
117 return ${EXIT_ERROR}
118 fi
119
120 return ${EXIT_OK}
121 }
122
123 hook_edit() {
124 local port=${1}
125
126 if ! hook_default_edit "$@"; then
127 return ${EXIT_ERROR}
128 fi
129
130 # If the master device is up, make sure that all
131 # slaves are up, too
132 if device_exists "${port}"; then
133 # Setting the mode requires us to destroy the device
134 # and to recreate it again.
135 local mode=$(bonding_get_mode "${port}")
136 if [ "${mode}" != "${MODE}" ]; then
137 port_restart "${port}"
138 return ${EXIT_OK}
139 fi
140
141 # Set address
142 device_set_address "${port}" "${ADDRESS}"
143
144 # Set miimon
145 bonding_set_miimon "${port}" "${MIIMON}"
146
147 local slave
148 for slave in ${SLAVES}; do
149 if device_exists "${slave}"; then
150 bonding_enslave_device "${port}" "${slave}"
151 else
152 port_create "${slave}"
153 fi
154 done
155 fi
156 }
157
158 hook_create() {
159 local port="${1}"
160 assert isset port
161
162 # Exit silently if the device already exists
163 device_exists "${port}" && exit ${EXIT_OK}
164
165 port_settings_read "${port}" ${HOOK_SETTINGS}
166
167 # Create the bonding devices
168 bonding_create "${port}" \
169 --address="${ADDRESS}" \
170 --mode="${MODE}" || exit ${EXIT_ERROR}
171
172 bonding_set_miimon "${port}" "${MIIMON}"
173
174 exit ${EXIT_OK}
175 }
176
177 hook_remove() {
178 local port="${1}"
179 assert isset port
180
181 port_settings_read "${port}" ${HOOK_SETTINGS}
182
183 # Remove the bonding device
184 if device_exists "${port}"; then
185 bonding_remove "${port}"
186 fi
187 }
188
189 hook_up() {
190 local port="${1}"
191 assert isset port
192
193 port_settings_read "${port}" ${HOOK_SETTINGS}
194
195 # Auto-enable or disable hardware offloading
196 if ! isset OFFLOADING || enabled OFFLOADING; then
197 offloading_auto "${port}"
198 else
199 offloading_disable_all "${port}"
200 fi
201
202 # Execute the default action
203 hook_default_up "${port}"
204
205 # Bring up all slaves
206 local slave
207 for slave in $(unquote ${SLAVES}); do
208 port_up "${slave}"
209 done
210 }
211
212 hook_down() {
213 local port="${1}"
214 assert isset port
215
216 port_settings_read "${port}" ${HOOK_SETTINGS}
217
218 # Bring down all slaves
219 local slave
220 for slave in $(unquote ${SLAVES}); do
221 port_down "${slave}"
222 done
223
224 # Execute the default action
225 hook_default_down "${port}"
226 }
227
228 hook_hotplug() {
229 local port="${1}"
230 assert isset port
231
232 case "$(hotplug_action)" in
233 add)
234 # Handle events of the same interface
235 if hotplug_event_port_is_interface "${port}"; then
236 # Read configuration
237 port_settings_read "${port}" ${HOOK_SETTINGS}
238
239 # Bring up all slaves
240 # Attach those which already exist and try to create
241 # those which don't exist yet. They will be attached
242 # in their own hotplug event.
243 local slave
244 for slave in $(unquote ${SLAVES}); do
245 if device_exists "${slave}"; then
246 bonding_enslave_device "${port}" "${slave}"
247 else
248 port_create "${slave}"
249 fi
250 done
251
252 exit ${EXIT_OK}
253
254 # Handle slave devices that have just been created and
255 # attach them.
256 elif hotplug_event_interface_is_slave_of_port "${port}"; then
257 bonding_enslave_device "${port}" "${INTERFACE}"
258
259 # If the parent device has been set up, we will
260 # bring up the slave device as well.
261 if device_is_up "${port}"; then
262 port_up "${INTERFACE}"
263 fi
264 fi
265
266 exit ${EXIT_OK}
267 ;;
268
269 remove)
270 if hotplug_event_port_is_interface "${port}"; then
271 # Bring down all slaves after the parent device went away
272 local slave
273 for slave in $(port_get_slaves "${port}"); do
274 port_remove "${slave}"
275 done
276
277 exit ${EXIT_OK}
278 fi
279 ;;
280 esac
281
282 exit ${EXIT_NOT_HANDLED}
283 }