]> git.ipfire.org Git - network.git/blame - functions.stp
bridge-stp: Use internal service functions for controlling mstpd.
[network.git] / functions.stp
CommitLineData
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
22function stp_init() {
23 module_load stp
24
25 assert binary_exists brctl
26 assert binary_exists rstpctl
27}
28
29init_register stp_init
30
feb76eaf
MT
31function __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 51function __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 73function 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 97function 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 106function 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
133function stp_bridge_set_protocol() {
134 : XXX WANTED
135}
136
137function 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 156function 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 175function 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 194function 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 213function 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 237function 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 256function 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 275function 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
296function 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
304function 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
324function 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
343function 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
362function 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
382STP_STATE[0]="disabled"
383STP_STATE[1]="listening"
384STP_STATE[2]="learning"
385STP_STATE[3]="forwarding"
386STP_STATE[4]="blocking"
387
388function 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
417function 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
438function 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 459function 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}