]>
Commit | Line | Data |
---|---|---|
e84e4e76 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 | ||
6b3f9c85 MT |
22 | function stp_init() { |
23 | module_load stp | |
24 | ||
25 | assert binary_exists brctl | |
26 | assert binary_exists rstpctl | |
27 | } | |
28 | ||
29 | init_register stp_init | |
30 | ||
feb76eaf MT |
31 | function __rstpctl_bridge_get() { |
32 | local bridge=${1} | |
33 | local param=${2} | |
34 | ||
35 | assert isset bridge | |
36 | assert isset param | |
e84e4e76 | 37 | |
e84e4e76 MT |
38 | local key |
39 | local val | |
feb76eaf MT |
40 | rstpctl dumpbridge ${bridge} | \ |
41 | while read bridge key val; do | |
42 | if [ "${key}" = "${param}" ]; then | |
43 | echo "${val}" | |
e84e4e76 MT |
44 | return ${EXIT_OK} |
45 | fi | |
46 | done | |
47 | ||
48 | return ${EXIT_ERROR} | |
49 | } | |
50 | ||
feb76eaf | 51 | function __rstpctl_port_get() { |
e84e4e76 MT |
52 | local bridge=${1} |
53 | local port=${2} | |
feb76eaf | 54 | local param=${3} |
e84e4e76 | 55 | |
feb76eaf MT |
56 | assert isset bridge |
57 | assert isset port | |
58 | assert isset param | |
59 | ||
60 | local key | |
61 | local val | |
62 | rstpctl dumpports ${bridge} | \ | |
63 | while read por key val; do | |
64 | if [ "${port}" = "${por}" -a "${key}" = "${param}" ]; then | |
65 | echo "${val}" | |
e84e4e76 MT |
66 | return ${EXIT_OK} |
67 | fi | |
68 | done | |
69 | ||
70 | return ${EXIT_ERROR} | |
71 | } | |
72 | ||
feb76eaf | 73 | function stp_enable() { |
e84e4e76 | 74 | local bridge=${1} |
e84e4e76 | 75 | |
feb76eaf MT |
76 | assert isset bridge |
77 | assert zone_exists ${bridge} | |
e84e4e76 | 78 | |
feb76eaf | 79 | brctl stp ${bridge} on |
e84e4e76 | 80 | |
feb76eaf MT |
81 | local mode=$(zone_config_get ${bridge} STP_MODE) |
82 | ||
83 | case "${mode}" in | |
84 | stp) | |
85 | rstpctl setforcevers ${bridge} slow | |
86 | ;; | |
87 | rstp) | |
88 | rstpctl setforcevers ${bridge} normal | |
89 | ;; | |
90 | *) | |
b816e04b MT |
91 | log WARNING "Unknown protocol version: ${mode}." |
92 | log WARNING "Using default mode." | |
feb76eaf MT |
93 | ;; |
94 | esac | |
e84e4e76 MT |
95 | } |
96 | ||
feb76eaf | 97 | function stp_disable() { |
e84e4e76 | 98 | local bridge=${1} |
e84e4e76 | 99 | |
feb76eaf MT |
100 | assert isset bridge |
101 | assert zone_exists ${bridge} | |
102 | ||
103 | brctl stp ${bridge} off | |
e84e4e76 MT |
104 | } |
105 | ||
feb76eaf | 106 | function stp_bridge_get_protocol() { |
e84e4e76 | 107 | local bridge=${1} |
e84e4e76 | 108 | |
feb76eaf MT |
109 | assert isset bridge |
110 | ||
36e3fd2f MT |
111 | local enabled=$(__device_get_file ${bridge} "bridge/stp_state") |
112 | if ! enabled ${enabled}; then | |
113 | return ${EXIT_OK} | |
114 | fi | |
115 | ||
feb76eaf MT |
116 | local mode=$(__rstpctl_bridge_get ${bridge} protocol_version) |
117 | ||
118 | case "${mode}" in | |
119 | 0) | |
120 | echo "stp" | |
121 | ;; | |
122 | 2) | |
123 | echo "rstp" | |
36e3fd2f MT |
124 | ;; |
125 | # When rstpctl has an error, we assume that rstpd is not running and | |
126 | # return the slow mode. | |
127 | "") | |
128 | echo "stp" | |
129 | ;; | |
feb76eaf | 130 | esac |
e84e4e76 MT |
131 | } |
132 | ||
feb76eaf MT |
133 | function stp_bridge_set_protocol() { |
134 | : XXX WANTED | |
135 | } | |
136 | ||
137 | function stp_bridge_get_id() { | |
e84e4e76 | 138 | local bridge=${1} |
e84e4e76 | 139 | |
feb76eaf MT |
140 | assert isset bridge |
141 | ||
142 | case "$(stp_bridge_get_protocol ${bridge})" in | |
143 | rstp) | |
144 | __rstpctl_bridge_get ${bridge} "id" | |
145 | return ${EXIT_OK} | |
146 | ;; | |
147 | stp) | |
148 | __device_get_file ${bridge} "bridge/bridge_id" | |
149 | return ${EXIT_OK} | |
150 | ;; | |
151 | esac | |
152 | ||
153 | return ${EXIT_ERROR} | |
e84e4e76 MT |
154 | } |
155 | ||
feb76eaf | 156 | function stp_bridge_get_forward_delay() { |
e84e4e76 | 157 | local bridge=${1} |
e84e4e76 | 158 | |
feb76eaf MT |
159 | assert isset bridge |
160 | ||
161 | case "$(stp_bridge_get_protocol ${bridge})" in | |
162 | rstp) | |
163 | __rstpctl_bridge_get ${bridge} "bridge_forward_delay" | |
164 | return ${EXIT_OK} | |
165 | ;; | |
166 | stp) | |
167 | __device_get_file ${bridge} "bridge/forward_delay" | |
168 | return ${EXIT_OK} | |
169 | ;; | |
170 | esac | |
171 | ||
172 | return ${EXIT_ERROR} | |
e84e4e76 MT |
173 | } |
174 | ||
feb76eaf | 175 | function stp_bridge_get_hello_time() { |
e84e4e76 MT |
176 | local bridge=${1} |
177 | ||
feb76eaf | 178 | assert isset bridge |
e84e4e76 | 179 | |
feb76eaf MT |
180 | case "$(stp_bridge_get_protocol ${bridge})" in |
181 | rstp) | |
182 | __rstpctl_bridge_get ${bridge} "bridge_hello_time" | |
e84e4e76 MT |
183 | return ${EXIT_OK} |
184 | ;; | |
feb76eaf MT |
185 | stp) |
186 | __device_get_file ${bridge} "bridge/hello_time" | |
187 | return ${EXIT_OK} | |
e84e4e76 MT |
188 | ;; |
189 | esac | |
feb76eaf MT |
190 | |
191 | return ${EXIT_ERROR} | |
e84e4e76 MT |
192 | } |
193 | ||
feb76eaf | 194 | function stp_bridge_get_max_age() { |
e84e4e76 MT |
195 | local bridge=${1} |
196 | ||
feb76eaf MT |
197 | assert isset bridge |
198 | ||
199 | case "$(stp_bridge_get_protocol ${bridge})" in | |
200 | rstp) | |
201 | __rstpctl_bridge_get ${bridge} "bridge_max_age" | |
202 | return ${EXIT_OK} | |
203 | ;; | |
204 | stp) | |
205 | __device_get_file ${bridge} "bridge/max_age" | |
206 | return ${EXIT_OK} | |
207 | ;; | |
208 | esac | |
209 | ||
210 | return ${EXIT_ERROR} | |
e84e4e76 MT |
211 | } |
212 | ||
feb76eaf | 213 | function stp_bridge_get_designated_root() { |
e84e4e76 | 214 | local bridge=${1} |
feb76eaf MT |
215 | local output |
216 | ||
217 | assert isset bridge | |
e84e4e76 | 218 | |
feb76eaf MT |
219 | case "$(stp_bridge_get_protocol ${bridge})" in |
220 | rstp) | |
221 | output=$(__rstpctl_bridge_get ${bridge} "designated_root") | |
222 | ;; | |
223 | stp) | |
224 | output=$(__device_get_file ${bridge} "bridge/root_id") | |
225 | ;; | |
226 | esac | |
227 | ||
228 | if ! isset output; then | |
229 | return ${EXIT_ERROR} | |
230 | fi | |
231 | ||
232 | mac_format "${output:5:12}" | |
233 | ||
234 | return ${EXIT_OK} | |
e84e4e76 MT |
235 | } |
236 | ||
feb76eaf | 237 | function stp_bridge_get_root_path_cost() { |
e84e4e76 MT |
238 | local bridge=${1} |
239 | ||
feb76eaf MT |
240 | assert isset bridge |
241 | ||
242 | case "$(stp_bridge_get_protocol ${bridge})" in | |
243 | rstp) | |
244 | __rstpctl_bridge_get ${bridge} "root_path_cost" | |
245 | return ${EXIT_OK} | |
246 | ;; | |
247 | stp) | |
248 | __device_get_file ${bridge} "bridge/root_path_cost" | |
249 | return ${EXIT_OK} | |
250 | ;; | |
251 | esac | |
e84e4e76 | 252 | |
feb76eaf | 253 | return ${EXIT_ERROR} |
e84e4e76 MT |
254 | } |
255 | ||
feb76eaf | 256 | function stp_bridge_get_root_port_id() { |
e84e4e76 MT |
257 | local bridge=${1} |
258 | ||
feb76eaf MT |
259 | assert isset bridge |
260 | ||
261 | case "$(stp_bridge_get_protocol ${bridge})" in | |
262 | rstp) | |
263 | __rstpctl_bridge_get ${bridge} "root_port" | |
264 | return ${EXIT_OK} | |
265 | ;; | |
266 | stp) | |
267 | __device_get_file ${bridge} "bridge/root_port" | |
268 | return ${EXIT_OK} | |
269 | ;; | |
270 | esac | |
e84e4e76 | 271 | |
feb76eaf | 272 | return ${EXIT_ERROR} |
e84e4e76 MT |
273 | } |
274 | ||
feb76eaf | 275 | function stp_bridge_get_root_port() { |
e84e4e76 MT |
276 | local bridge=${1} |
277 | ||
feb76eaf | 278 | assert isset bridge |
e84e4e76 | 279 | |
feb76eaf | 280 | local id=$(stp_bridge_get_root_port_id ${bridge}) |
e84e4e76 | 281 | |
feb76eaf MT |
282 | local member |
283 | local member_id | |
284 | for member in $(bridge_get_members ${bridge}); do | |
285 | member_id=$(stp_port_get_id ${bridge} ${member}) | |
e84e4e76 | 286 | |
feb76eaf MT |
287 | if [ "${id}" = "${member_id}" ]; then |
288 | echo "${member}" | |
289 | return ${EXIT_OK} | |
290 | fi | |
291 | done | |
e84e4e76 | 292 | |
feb76eaf | 293 | return ${EXIT_ERROR} |
e84e4e76 MT |
294 | } |
295 | ||
feb76eaf MT |
296 | function stp_bridge_is_root() { |
297 | local bridge=${1} | |
e84e4e76 | 298 | |
feb76eaf | 299 | assert isset bridge |
e84e4e76 | 300 | |
feb76eaf | 301 | [ -n "$(stp_bridge_get_root_port ${bridge})" ] |
e84e4e76 MT |
302 | } |
303 | ||
feb76eaf MT |
304 | function stp_bridge_get_priority() { |
305 | local bridge=${1} | |
e84e4e76 | 306 | |
feb76eaf | 307 | assert isset bridge |
e84e4e76 | 308 | |
feb76eaf MT |
309 | case "$(stp_bridge_get_protocol ${bridge})" in |
310 | rstp) | |
311 | local output=$(__rstpctl_bridge_get ${bridge} "root_path_cost") | |
312 | dec "${output:0:4}" | |
313 | return ${EXIT_OK} | |
314 | ;; | |
315 | stp) | |
316 | __device_get_file ${bridge} "bridge/priority" | |
317 | return ${EXIT_OK} | |
318 | ;; | |
319 | esac | |
e84e4e76 | 320 | |
feb76eaf | 321 | return ${EXIT_ERROR} |
e84e4e76 MT |
322 | } |
323 | ||
feb76eaf MT |
324 | function stp_bridge_get_topology_change_count() { |
325 | local bridge=${1} | |
e84e4e76 | 326 | |
feb76eaf | 327 | assert isset bridge |
e84e4e76 | 328 | |
feb76eaf MT |
329 | case "$(stp_bridge_get_protocol ${bridge})" in |
330 | rstp) | |
331 | __rstpctl_bridge_get ${bridge} "topology_change_count" | |
332 | return ${EXIT_OK} | |
333 | ;; | |
334 | stp) | |
335 | __device_get_file ${bridge} "bridge/topology_change" | |
336 | return ${EXIT_OK} | |
337 | ;; | |
338 | esac | |
e84e4e76 | 339 | |
feb76eaf | 340 | return ${EXIT_ERROR} |
e84e4e76 MT |
341 | } |
342 | ||
feb76eaf MT |
343 | function stp_bridge_get_topology_change_timer() { |
344 | local bridge=${1} | |
345 | ||
346 | assert isset bridge | |
347 | ||
348 | case "$(stp_bridge_get_protocol ${bridge})" in | |
349 | rstp) | |
350 | __rstpctl_bridge_get ${bridge} "time_since_topology_change" | |
351 | return ${EXIT_OK} | |
352 | ;; | |
353 | stp) | |
354 | __device_get_file ${bridge} "bridge/topology_change_timer" | |
355 | return ${EXIT_OK} | |
356 | ;; | |
357 | esac | |
e84e4e76 | 358 | |
feb76eaf | 359 | return ${EXIT_ERROR} |
e84e4e76 MT |
360 | } |
361 | ||
feb76eaf MT |
362 | function stp_bridge_get_topology_change_detected() { |
363 | local bridge=${1} | |
e84e4e76 | 364 | |
feb76eaf | 365 | assert isset bridge |
e84e4e76 | 366 | |
feb76eaf MT |
367 | case "$(stp_bridge_get_protocol ${bridge})" in |
368 | rstp) | |
369 | __rstpctl_bridge_get ${bridge} "topology_change" | |
370 | return ${EXIT_OK} | |
371 | ;; | |
372 | stp) | |
373 | __device_get_file ${bridge} "bridge/topology_change_detected" | |
374 | return ${EXIT_OK} | |
375 | ;; | |
376 | esac | |
6b3f9c85 | 377 | |
feb76eaf | 378 | return ${EXIT_ERROR} |
6b3f9c85 MT |
379 | } |
380 | ||
feb76eaf MT |
381 | # STP states |
382 | STP_STATE[0]="disabled" | |
383 | STP_STATE[1]="listening" | |
384 | STP_STATE[2]="learning" | |
385 | STP_STATE[3]="forwarding" | |
386 | STP_STATE[4]="blocking" | |
387 | ||
388 | function stp_port_get_state() { | |
6b3f9c85 | 389 | local bridge=${1} |
feb76eaf MT |
390 | local port=${2} |
391 | local output | |
6b3f9c85 MT |
392 | |
393 | assert isset bridge | |
feb76eaf | 394 | assert isset port |
6b3f9c85 | 395 | |
feb76eaf MT |
396 | case "$(stp_bridge_get_protocol ${bridge})" in |
397 | rstp) | |
398 | output=$(__rstpctl_port_get ${bridge} ${port} "state") | |
399 | ;; | |
400 | stp) | |
401 | output=$(__device_get_file ${bridge} "brif/${port}/state") | |
6b3f9c85 | 402 | |
feb76eaf MT |
403 | # Translate int to name |
404 | output="${STP_STATE[${output}]}" | |
405 | ;; | |
406 | esac | |
6b3f9c85 | 407 | |
feb76eaf MT |
408 | if ! isset output; then |
409 | return ${EXIT_ERROR} | |
410 | fi | |
411 | ||
412 | echo "${output^^}" | |
413 | ||
414 | return ${EXIT_OK} | |
415 | } | |
416 | ||
417 | function stp_port_get_id() { | |
418 | local bridge=${1} | |
419 | local port=${2} | |
420 | ||
421 | assert isset bridge | |
422 | assert isset port | |
423 | ||
424 | case "$(stp_bridge_get_protocol ${bridge})" in | |
425 | rstp) | |
426 | __rstpctl_port_get ${bridge} ${port} "id" | |
427 | return ${EXIT_OK} | |
428 | ;; | |
6b3f9c85 | 429 | stp) |
feb76eaf MT |
430 | dec $(__device_get_file ${bridge} "brif/${port}/port_no") |
431 | return ${EXIT_OK} | |
6b3f9c85 | 432 | ;; |
feb76eaf MT |
433 | esac |
434 | ||
435 | return ${EXIT_ERROR} | |
436 | } | |
437 | ||
438 | function stp_port_get_cost() { | |
439 | local bridge=${1} | |
440 | local port=${2} | |
441 | ||
442 | assert isset bridge | |
443 | assert isset port | |
444 | ||
445 | case "$(stp_bridge_get_protocol ${bridge})" in | |
6b3f9c85 | 446 | rstp) |
feb76eaf MT |
447 | __rstpctl_port_get ${bridge} ${port} "path_cost" |
448 | return ${EXIT_OK} | |
6b3f9c85 | 449 | ;; |
feb76eaf MT |
450 | stp) |
451 | __device_get_file ${bridge} "brif/${port}/path_cost" | |
452 | return ${EXIT_OK} | |
6b3f9c85 MT |
453 | ;; |
454 | esac | |
feb76eaf MT |
455 | |
456 | return ${EXIT_ERROR} | |
6b3f9c85 MT |
457 | } |
458 | ||
feb76eaf | 459 | function stp_port_get_designated_root() { |
6b3f9c85 | 460 | local bridge=${1} |
feb76eaf MT |
461 | local port=${2} |
462 | local output | |
6b3f9c85 MT |
463 | |
464 | assert isset bridge | |
feb76eaf | 465 | assert isset port |
6b3f9c85 | 466 | |
feb76eaf MT |
467 | case "$(stp_bridge_get_protocol ${bridge})" in |
468 | rstp) | |
469 | output=$(__rstpctl_port_get ${bridge} ${port} "designated_root") | |
470 | ;; | |
471 | stp) | |
472 | output=$(__device_get_file ${bridge} "brif/${port}/designated_root") | |
473 | ;; | |
474 | esac | |
475 | ||
36e3fd2f MT |
476 | if [ -n "${output}" ]; then |
477 | mac_format ${output:5:12} | |
478 | return ${EXIT_OK} | |
479 | fi | |
feb76eaf MT |
480 | |
481 | return ${EXIT_ERROR} | |
6b3f9c85 | 482 | } |