2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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. #
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. #
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/>. #
20 ###############################################################################
23 # We default to RSTP, because it has the better user experience and
24 # faster convergence times. Despite of that, it completely downgradeable
26 STP_DEFAULT_MODE
="rstp"
28 # Allowed modes of the spanning tree protocol.
29 STP_ALLOWED_MODES
="rstp stp"
31 function __rstpctl_bridge_get
() {
40 rstpctl dumpbridge
${bridge} | \
41 while read bridge key val
; do
42 if [ "${key}" = "${param}" ]; then
51 function __rstpctl_port_get
() {
62 rstpctl dumpports
${bridge} | \
63 while read por key val
; do
64 if [ "${port}" = "${por}" -a "${key}" = "${param}" ]; then
73 function stp_enable
() {
78 assert zone_exists
${bridge}
80 # Tell the kernel to enable STP.
81 brctl stp
${bridge} on
83 # Set the correct protocol version.
84 if [ -z "${mode}" ]; then
85 mode
="${STP_DEFAULT_MODE}"
87 stp_bridge_set_protocol
${bridge} ${mode}
90 function stp_disable
() {
94 assert zone_exists
${bridge}
96 brctl stp
${bridge} off
99 function stp_bridge_set_protocol
() {
106 if ! listmatch
${mode} ${STP_ALLOWED_MODES}; then
107 log WARNING
"Unknown protocol version: ${mode}."
108 log WARNING
"Using default mode."
110 mode
="${STP_DEFAULT_MODE}"
113 mstpctl setforcevers
${bridge} ${mode}
117 function stp_bridge_get_protocol
() {
122 local enabled
=$
(__device_get_file
${bridge} "bridge/stp_state")
123 if ! enabled
${enabled}; then
127 local mode
=$
(__rstpctl_bridge_get
${bridge} protocol_version
)
136 # When rstpctl has an error, we assume that rstpd is not running and
137 # return the slow mode.
144 function stp_bridge_get_id
() {
149 case "$(stp_bridge_get_protocol ${bridge})" in
151 __rstpctl_bridge_get
${bridge} "id"
155 __device_get_file
${bridge} "bridge/bridge_id"
163 function stp_bridge_get_forward_delay
() {
168 case "$(stp_bridge_get_protocol ${bridge})" in
170 __rstpctl_bridge_get
${bridge} "bridge_forward_delay"
174 __device_get_file
${bridge} "bridge/forward_delay"
182 function stp_bridge_get_hello_time
() {
187 case "$(stp_bridge_get_protocol ${bridge})" in
189 __rstpctl_bridge_get
${bridge} "bridge_hello_time"
193 __device_get_file
${bridge} "bridge/hello_time"
201 function stp_bridge_get_max_age
() {
206 case "$(stp_bridge_get_protocol ${bridge})" in
208 __rstpctl_bridge_get
${bridge} "bridge_max_age"
212 __device_get_file
${bridge} "bridge/max_age"
220 function stp_bridge_get_designated_root
() {
226 case "$(stp_bridge_get_protocol ${bridge})" in
228 output
=$
(__rstpctl_bridge_get
${bridge} "designated_root")
231 output
=$
(__device_get_file
${bridge} "bridge/root_id")
235 if ! isset output
; then
239 mac_format
"${output:5:12}"
244 function stp_bridge_get_root_path_cost
() {
249 case "$(stp_bridge_get_protocol ${bridge})" in
251 __rstpctl_bridge_get
${bridge} "root_path_cost"
255 __device_get_file
${bridge} "bridge/root_path_cost"
263 function stp_bridge_get_root_port_id
() {
268 case "$(stp_bridge_get_protocol ${bridge})" in
270 __rstpctl_bridge_get
${bridge} "root_port"
274 __device_get_file
${bridge} "bridge/root_port"
282 function stp_bridge_get_root_port
() {
287 local id
=$
(stp_bridge_get_root_port_id
${bridge})
291 for member
in $
(bridge_get_members
${bridge}); do
292 member_id
=$
(stp_port_get_id
${bridge} ${member})
294 if [ "${id}" = "${member_id}" ]; then
303 function stp_bridge_is_root
() {
308 [ -n "$(stp_bridge_get_root_port ${bridge})" ]
311 function stp_bridge_get_priority
() {
316 case "$(stp_bridge_get_protocol ${bridge})" in
318 local output
=$
(__rstpctl_bridge_get
${bridge} "root_path_cost")
323 __device_get_file
${bridge} "bridge/priority"
331 function stp_bridge_get_topology_change_count
() {
336 case "$(stp_bridge_get_protocol ${bridge})" in
338 __rstpctl_bridge_get
${bridge} "topology_change_count"
342 __device_get_file
${bridge} "bridge/topology_change"
350 function stp_bridge_get_topology_change_timer
() {
355 case "$(stp_bridge_get_protocol ${bridge})" in
357 __rstpctl_bridge_get
${bridge} "time_since_topology_change"
361 __device_get_file
${bridge} "bridge/topology_change_timer"
369 function stp_bridge_get_topology_change_detected
() {
374 case "$(stp_bridge_get_protocol ${bridge})" in
376 __rstpctl_bridge_get
${bridge} "topology_change"
380 __device_get_file
${bridge} "bridge/topology_change_detected"
389 STP_STATE
[0]="disabled"
390 STP_STATE
[1]="listening"
391 STP_STATE
[2]="learning"
392 STP_STATE
[3]="forwarding"
393 STP_STATE
[4]="blocking"
395 function stp_port_get_state
() {
403 case "$(stp_bridge_get_protocol ${bridge})" in
405 output
=$
(__rstpctl_port_get
${bridge} ${port} "state")
408 output
=$
(__device_get_file
${bridge} "brif/${port}/state")
410 # Translate int to name
411 output
="${STP_STATE[${output}]}"
415 if ! isset output
; then
424 function stp_port_get_id
() {
431 case "$(stp_bridge_get_protocol ${bridge})" in
433 __rstpctl_port_get
${bridge} ${port} "id"
437 dec $
(__device_get_file
${bridge} "brif/${port}/port_no")
445 function stp_port_get_cost
() {
452 case "$(stp_bridge_get_protocol ${bridge})" in
454 __rstpctl_port_get
${bridge} ${port} "path_cost"
458 __device_get_file
${bridge} "brif/${port}/path_cost"
466 function stp_port_get_designated_root
() {
474 case "$(stp_bridge_get_protocol ${bridge})" in
476 output
=$
(__rstpctl_port_get
${bridge} ${port} "designated_root")
479 output
=$
(__device_get_file
${bridge} "brif/${port}/designated_root")
483 if [ -n "${output}" ]; then
484 mac_format
${output:5:12}