]>
Commit | Line | Data |
---|---|---|
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 | } |