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