]>
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 | ||
e266c18e MT |
22 | # The default mode. |
23 | # We default to RSTP, because it has the better user experience and | |
24 | # faster convergence times. Despite of that, it completely downgradeable | |
25 | # to plain STP. | |
26 | STP_DEFAULT_MODE="rstp" | |
6b3f9c85 | 27 | |
e266c18e MT |
28 | # Allowed modes of the spanning tree protocol. |
29 | STP_ALLOWED_MODES="rstp stp" | |
6b3f9c85 | 30 | |
feb76eaf | 31 | function stp_enable() { |
e84e4e76 | 32 | local bridge=${1} |
feb76eaf | 33 | assert isset bridge |
e84e4e76 | 34 | |
e266c18e | 35 | # Tell the kernel to enable STP. |
7d85603e | 36 | print 1 > ${SYS_CLASS_NET}/${bridge}/bridge/stp_state |
e84e4e76 MT |
37 | } |
38 | ||
feb76eaf | 39 | function stp_disable() { |
e84e4e76 | 40 | local bridge=${1} |
feb76eaf | 41 | assert isset bridge |
feb76eaf | 42 | |
7d85603e MT |
43 | # Tell the kernel to disable STP. |
44 | print 0 > ${SYS_CLASS_NET}/${bridge}/bridge/stp_state | |
e84e4e76 MT |
45 | } |
46 | ||
3cb2fc42 MT |
47 | function stp_is_enabled() { |
48 | local bridge=${1} | |
49 | assert isset bridge | |
50 | ||
51 | local state=$(__device_get_file ${bridge} bridge/stp_state) | |
52 | ||
53 | case "${state}" in | |
54 | 0) | |
55 | return ${EXIT_FALSE} | |
56 | ;; | |
57 | *) | |
58 | return ${EXIT_TRUE} | |
59 | ;; | |
60 | esac | |
61 | } | |
62 | ||
8d4f9311 MT |
63 | function stp_get_name() { |
64 | local proto=${1} | |
65 | ||
66 | case "${proto}" in | |
67 | stp) | |
68 | echo "Spanning Tree Protocol" | |
69 | ;; | |
70 | rstp) | |
71 | echo "Rapid Spanning Tree Protocol" | |
72 | ;; | |
73 | mstp) | |
74 | echo "Multiple Spanning Tree Protocol" | |
75 | ;; | |
76 | esac | |
77 | ||
78 | return ${EXIT_OK} | |
79 | } | |
80 | ||
feb76eaf | 81 | function stp_bridge_get_protocol() { |
e84e4e76 | 82 | local bridge=${1} |
e84e4e76 | 83 | |
feb76eaf MT |
84 | assert isset bridge |
85 | ||
8d4f9311 MT |
86 | # Let's check what the kernel is telling us about it's STP state. |
87 | local state=$(__device_get_file ${bridge} "bridge/stp_state") | |
feb76eaf | 88 | |
8d4f9311 | 89 | case "${state}" in |
feb76eaf | 90 | 0) |
8d4f9311 MT |
91 | # STP is disabled. |
92 | return ${EXIT_OK} | |
93 | ;; | |
94 | 1) | |
95 | # Kernel mode STP is running. | |
feb76eaf | 96 | echo "stp" |
8d4f9311 | 97 | return ${EXIT_OK} |
feb76eaf MT |
98 | ;; |
99 | 2) | |
8d4f9311 | 100 | # User-space STP is running. |
36e3fd2f | 101 | ;; |
8d4f9311 MT |
102 | *) |
103 | log ERROR "Kernel is running in an unknown STP state." | |
104 | return ${EXIT_ERROR} | |
36e3fd2f | 105 | ;; |
feb76eaf | 106 | esac |
e84e4e76 | 107 | |
8d4f9311 | 108 | # We get here, when STP is running in user-space mode. |
e84e4e76 | 109 | |
8d4f9311 | 110 | # Get the current protocol version. |
6cd354eb | 111 | mstpctl showbridge ${bridge} force-protocol-version |
feb76eaf | 112 | |
8d4f9311 | 113 | return ${EXIT_OK} |
e84e4e76 MT |
114 | } |
115 | ||
8d4f9311 | 116 | function stp_bridge_get_id() { |
e84e4e76 | 117 | local bridge=${1} |
feb76eaf | 118 | assert isset bridge |
e84e4e76 | 119 | |
8d4f9311 | 120 | __device_get_file ${bridge} "bridge/bridge_id" |
feb76eaf | 121 | |
8d4f9311 | 122 | return $? |
e84e4e76 MT |
123 | } |
124 | ||
8d4f9311 | 125 | function stp_bridge_get_forward_delay() { |
e84e4e76 MT |
126 | local bridge=${1} |
127 | ||
feb76eaf MT |
128 | assert isset bridge |
129 | ||
6cd354eb | 130 | mstpctl showbridge ${bridge} forward-delay |
8d4f9311 | 131 | } |
feb76eaf | 132 | |
8d4f9311 | 133 | function stp_bridge_set_forward_delay() { |
e2aa12b3 MT |
134 | local bridge=${1} |
135 | assert isset bridge | |
136 | ||
137 | local fdelay=${2} | |
138 | assert isinteger fdelay | |
139 | ||
140 | # Check if the setting we want is already set. | |
141 | local current_fdelay=$(stp_bridge_get_forward_delay ${bridge}) | |
142 | [ ${fdelay} -eq ${current_fdelay} ] && return ${EXIT_OK} | |
143 | ||
144 | # The smallest value that may be set is 2. | |
145 | if [ ${fdelay} -lt 2 ]; then | |
146 | fdelay=2 | |
147 | fi | |
148 | ||
149 | # Set the new value. | |
150 | log INFO "Changing forward delay for '${bridge}': ${current_fdelay} --> ${fdelay}." | |
151 | brctl setfd ${bridge} ${fdelay} | |
152 | ||
153 | return ${EXIT_OK} | |
154 | } | |
155 | ||
156 | function stp_bridge_get_hello_time() { | |
157 | local bridge=${1} | |
158 | assert isset bridge | |
159 | ||
160 | local ht=$(__device_get_file ${bridge} "bridge/hello_time") | |
161 | ||
162 | # ht is now in seconds * 100. | |
163 | local split=$((${#ht} - 2)) | |
164 | ht="${ht:0:${split}}.${ht:${split}:2}" | |
165 | ||
166 | # Round the output. | |
167 | printf "%.0f\n" "${ht}" | |
168 | } | |
169 | ||
170 | function stp_bridge_set_hello_time() { | |
171 | local bridge=${1} | |
172 | assert isset bridge | |
173 | ||
174 | local hello=${2} | |
175 | assert isinteger hello | |
176 | ||
177 | # Check if the setting we want is already set. | |
178 | local current_hello=$(stp_bridge_get_hello_time ${bridge}) | |
179 | [ ${hello} -eq ${current_hello} ] && return ${EXIT_OK} | |
180 | ||
181 | # Set the new value. | |
182 | log INFO "Changing hello time for '${bridge}': ${current_hello} --> ${hello}." | |
183 | brctl sethello ${bridge} ${hello} | |
184 | ||
185 | return ${EXIT_OK} | |
186 | } | |
187 | ||
188 | function stp_bridge_get_max_age() { | |
189 | local bridge=${1} | |
190 | assert isset bridge | |
191 | ||
192 | local maxage=$(__device_get_file ${bridge} "bridge/max_age") | |
193 | ||
194 | # maxage is now in seconds * 100. | |
195 | local split=$((${#maxage} - 2)) | |
196 | maxage="${maxage:0:${split}}.${maxage:${split}:2}" | |
197 | ||
198 | # Round the output. | |
199 | printf "%.0f\n" "${maxage}" | |
200 | } | |
201 | ||
202 | function stp_bridge_set_max_age() { | |
203 | local bridge=${1} | |
204 | assert isset bridge | |
205 | ||
206 | local maxage=${2} | |
207 | assert isinteger maxage | |
208 | ||
209 | # Check if the setting we want is already set. | |
210 | local current_maxage=$(stp_bridge_get_max_age ${bridge}) | |
211 | [ ${maxage} -eq ${current_maxage} ] && return ${EXIT_OK} | |
212 | ||
213 | # Set the new value. | |
214 | log INFO "Changing max age for '${bridge}': ${current_maxage} --> ${maxage}." | |
215 | brctl setmaxage ${bridge} ${maxage} | |
216 | ||
217 | return ${EXIT_OK} | |
218 | } | |
219 | ||
220 | function stp_bridge_get_priority() { | |
221 | local bridge=${1} | |
222 | assert isset bridge | |
223 | ||
224 | __device_get_file ${bridge} "bridge/priority" | |
225 | } | |
226 | ||
227 | function stp_bridge_set_priority() { | |
228 | local bridge=${1} | |
229 | assert isset bridge | |
230 | ||
231 | local priority=${2} | |
232 | assert isinteger priority | |
233 | ||
234 | # Check if the setting we want is already set. | |
235 | local current_priority=$(stp_bridge_get_priority ${bridge}) | |
236 | [ ${priority} -eq ${current_priority} ] && return ${EXIT_OK} | |
237 | ||
238 | # Set the new value. | |
239 | log INFO "Changing priority for '${bridge}': ${current_priority} --> ${priority}." | |
240 | brctl setbridgeprio ${bridge} ${priority} | |
241 | ||
242 | return ${EXIT_OK} | |
e84e4e76 MT |
243 | } |
244 | ||
feb76eaf | 245 | function stp_bridge_get_designated_root() { |
e84e4e76 | 246 | local bridge=${1} |
feb76eaf MT |
247 | local output |
248 | ||
249 | assert isset bridge | |
e84e4e76 | 250 | |
6cd354eb | 251 | local output=$(mstpctl showbridge ${bridge} designated-root) |
feb76eaf MT |
252 | |
253 | if ! isset output; then | |
254 | return ${EXIT_ERROR} | |
255 | fi | |
256 | ||
8d4f9311 | 257 | echo "${output,,}" |
feb76eaf | 258 | return ${EXIT_OK} |
e84e4e76 MT |
259 | } |
260 | ||
feb76eaf | 261 | function stp_bridge_get_root_path_cost() { |
e84e4e76 MT |
262 | local bridge=${1} |
263 | ||
feb76eaf MT |
264 | assert isset bridge |
265 | ||
6cd354eb | 266 | mstpctl showbridge ${bridge} path-cost |
e84e4e76 MT |
267 | } |
268 | ||
feb76eaf | 269 | function stp_bridge_get_root_port_id() { |
e84e4e76 MT |
270 | local bridge=${1} |
271 | ||
feb76eaf MT |
272 | assert isset bridge |
273 | ||
6cd354eb | 274 | local root_port=$(mstpctl showbridge ${bridge} root-port) |
e84e4e76 | 275 | |
8d4f9311 MT |
276 | # Return error, when there is no root port. |
277 | if [ "${root_port}" = "none" ]; then | |
278 | return ${EXIT_ERROR} | |
279 | fi | |
280 | ||
281 | echo "${root_port}" | |
282 | return ${EXIT_OK} | |
e84e4e76 MT |
283 | } |
284 | ||
feb76eaf | 285 | function stp_bridge_get_root_port() { |
e84e4e76 MT |
286 | local bridge=${1} |
287 | ||
feb76eaf | 288 | assert isset bridge |
e84e4e76 | 289 | |
feb76eaf | 290 | local id=$(stp_bridge_get_root_port_id ${bridge}) |
e84e4e76 | 291 | |
feb76eaf MT |
292 | local member |
293 | local member_id | |
294 | for member in $(bridge_get_members ${bridge}); do | |
295 | member_id=$(stp_port_get_id ${bridge} ${member}) | |
e84e4e76 | 296 | |
feb76eaf MT |
297 | if [ "${id}" = "${member_id}" ]; then |
298 | echo "${member}" | |
299 | return ${EXIT_OK} | |
300 | fi | |
301 | done | |
e84e4e76 | 302 | |
feb76eaf | 303 | return ${EXIT_ERROR} |
e84e4e76 MT |
304 | } |
305 | ||
feb76eaf | 306 | function stp_bridge_is_root() { |
8d4f9311 MT |
307 | stp_bridge_get_root_port_id $@ >/dev/null |
308 | local ret=$? | |
e84e4e76 | 309 | |
8d4f9311 MT |
310 | if [ ${ret} -eq ${EXIT_ERROR} ]; then |
311 | return ${EXIT_OK} | |
312 | fi | |
e84e4e76 | 313 | |
8d4f9311 | 314 | return ${EXIT_ERROR} |
e84e4e76 MT |
315 | } |
316 | ||
feb76eaf MT |
317 | function stp_bridge_get_priority() { |
318 | local bridge=${1} | |
e84e4e76 | 319 | |
feb76eaf | 320 | assert isset bridge |
e84e4e76 | 321 | |
8d4f9311 | 322 | local id=$(stp_bridge_get_id ${bridge}) |
e84e4e76 | 323 | |
8d4f9311 | 324 | dec "${id:0:4}" |
e84e4e76 MT |
325 | } |
326 | ||
feb76eaf MT |
327 | function stp_bridge_get_topology_change_count() { |
328 | local bridge=${1} | |
e84e4e76 | 329 | |
feb76eaf | 330 | assert isset bridge |
e84e4e76 | 331 | |
6cd354eb | 332 | mstpctl showbridge ${bridge} topology-change-count |
e84e4e76 MT |
333 | } |
334 | ||
feb76eaf MT |
335 | function stp_bridge_get_topology_change_timer() { |
336 | local bridge=${1} | |
337 | ||
338 | assert isset bridge | |
339 | ||
6cd354eb | 340 | mstpctl showbridge ${bridge} time-since-topology-change |
e84e4e76 MT |
341 | } |
342 | ||
feb76eaf MT |
343 | function stp_bridge_get_topology_change_detected() { |
344 | local bridge=${1} | |
e84e4e76 | 345 | |
feb76eaf | 346 | assert isset bridge |
e84e4e76 | 347 | |
6cd354eb | 348 | local change=$(mstpctl showbridge ${bridge} topology-change) |
8d4f9311 MT |
349 | |
350 | echo "${change}" | |
351 | case "${change}" in | |
352 | yes) | |
feb76eaf MT |
353 | return ${EXIT_OK} |
354 | ;; | |
8d4f9311 MT |
355 | *) |
356 | return ${EXIT_ERROR} | |
feb76eaf MT |
357 | ;; |
358 | esac | |
6b3f9c85 MT |
359 | } |
360 | ||
feb76eaf | 361 | function stp_port_get_state() { |
6b3f9c85 | 362 | local bridge=${1} |
feb76eaf | 363 | local port=${2} |
6b3f9c85 MT |
364 | |
365 | assert isset bridge | |
feb76eaf | 366 | assert isset port |
6b3f9c85 | 367 | |
6cd354eb | 368 | local state=$(mstpctl showportdetail ${bridge} ${port} state) |
feb76eaf | 369 | |
8d4f9311 | 370 | echo "${state^^}" |
feb76eaf MT |
371 | } |
372 | ||
373 | function stp_port_get_id() { | |
374 | local bridge=${1} | |
375 | local port=${2} | |
376 | ||
377 | assert isset bridge | |
378 | assert isset port | |
379 | ||
8d4f9311 | 380 | local id=$(__device_get_file ${bridge} "brif/${port}/port_no") |
feb76eaf | 381 | |
8d4f9311 MT |
382 | dec ${id} |
383 | ||
384 | return ${EXIT_OK} | |
feb76eaf MT |
385 | } |
386 | ||
387 | function stp_port_get_cost() { | |
388 | local bridge=${1} | |
389 | local port=${2} | |
390 | ||
391 | assert isset bridge | |
392 | assert isset port | |
393 | ||
6cd354eb | 394 | mstpctl showportdetail ${bridge} ${port} external-port-cost |
feb76eaf MT |
395 | |
396 | return ${EXIT_ERROR} | |
6b3f9c85 MT |
397 | } |
398 | ||
feb76eaf | 399 | function stp_port_get_designated_root() { |
6b3f9c85 | 400 | local bridge=${1} |
feb76eaf MT |
401 | local port=${2} |
402 | local output | |
6b3f9c85 MT |
403 | |
404 | assert isset bridge | |
feb76eaf | 405 | assert isset port |
6b3f9c85 | 406 | |
6cd354eb | 407 | output=$(mstpctl showportdetail ${bridge} ${port} designated-root) |
feb76eaf | 408 | |
36e3fd2f | 409 | if [ -n "${output}" ]; then |
8d4f9311 | 410 | echo "${output,,}" |
36e3fd2f MT |
411 | return ${EXIT_OK} |
412 | fi | |
feb76eaf MT |
413 | |
414 | return ${EXIT_ERROR} | |
6b3f9c85 | 415 | } |