]> git.ipfire.org Git - people/ms/network.git/blob - src/functions/functions.stp
Makefile: Fix typo in localstatedir
[people/ms/network.git] / src / functions / functions.stp
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
22 stp_enable() {
23 local bridge=${1}
24 assert isset bridge
25
26 # Tell the kernel to enable STP.
27 print 1 > ${SYS_CLASS_NET}/${bridge}/bridge/stp_state
28 }
29
30 stp_disable() {
31 local bridge=${1}
32 assert isset bridge
33
34 # Tell the kernel to disable STP.
35 print 0 > ${SYS_CLASS_NET}/${bridge}/bridge/stp_state
36 }
37
38 stp_is_enabled() {
39 local bridge=${1}
40 assert isset bridge
41
42 local state=$(__device_get_file ${bridge} bridge/stp_state)
43
44 case "${state}" in
45 0)
46 return ${EXIT_FALSE}
47 ;;
48 *)
49 return ${EXIT_TRUE}
50 ;;
51 esac
52 }
53
54 stp_bridge_get_id() {
55 local bridge=${1}
56 assert isset bridge
57
58 __device_get_file ${bridge} "bridge/bridge_id"
59
60 return $?
61 }
62
63 stp_bridge_get_forward_delay() {
64 local bridge=${1}
65 assert isset bridge
66
67 local output=$(__device_get_file ${bridge} bridge/forward_delay)
68 __stp_div_100 ${output}
69
70 return ${EXIT_OK}
71 }
72
73 stp_bridge_set_forward_delay() {
74 local bridge=${1}
75 assert isset bridge
76
77 local fdelay=${2}
78 assert isinteger fdelay
79
80 # The smallest value that may be set is 2.
81 if [ ${fdelay} -lt 2 ]; then
82 fdelay=2
83 fi
84
85 # Check if the setting we want is already set.
86 local current_fdelay=$(stp_bridge_get_forward_delay ${bridge})
87 [ ${fdelay} -eq ${current_fdelay} ] && return ${EXIT_OK}
88
89 # Set the new value.
90 log DEBUG "Setting forward delay on bridge '${bridge}' from '${current_fdelay}' to '${fdelay}'"
91 fappend "${SYS_CLASS_NET}/${bridge}/bridge/forward_delay" "$(( ${fdelay} * 100 ))"
92
93 return ${EXIT_OK}
94 }
95
96 stp_bridge_get_hello_time() {
97 local bridge=${1}
98 assert isset bridge
99
100 local ht=$(__device_get_file ${bridge} bridge/hello_time)
101 __stp_div_100 ${ht}
102
103 return ${EXIT_OK}
104 }
105
106 stp_bridge_set_hello_time() {
107 local bridge=${1}
108 assert isset bridge
109
110 local hello=${2}
111 assert isinteger hello
112
113 # Check if the setting we want is already set.
114 local current_hello=$(stp_bridge_get_hello_time ${bridge})
115 [ ${hello} -eq ${current_hello} ] && return ${EXIT_OK}
116
117 # Set the new value.
118 log INFO "Changing hello time for '${bridge}': ${current_hello} --> ${hello}"
119 print "$(( ${hello} * 100 ))" > ${SYS_CLASS_NET}/${bridge}/bridge/hellow_time
120
121 return ${EXIT_OK}
122 }
123
124 stp_bridge_get_max_age() {
125 local bridge=${1}
126 assert isset bridge
127
128 local maxage=$(__device_get_file ${bridge} "bridge/max_age")
129 __stp_div_100 ${maxage}
130
131 return ${EXIT_OK}
132 }
133
134 stp_bridge_set_max_age() {
135 local bridge=${1}
136 assert isset bridge
137
138 local maxage=${2}
139 assert isinteger maxage
140
141 # Check if the setting we want is already set.
142 local current_maxage=$(stp_bridge_get_max_age ${bridge})
143 [ ${maxage} -eq ${current_maxage} ] && return ${EXIT_OK}
144
145 # Set the new value.
146 log INFO "Changing max age for '${bridge}': ${current_maxage} --> ${maxage}"
147 print "$(( ${maxage} * 100 ))" > ${SYS_CLASS_NET}/${bridge}/bridge/max_age
148
149 return ${EXIT_OK}
150 }
151
152 stp_bridge_get_priority() {
153 local bridge=${1}
154 assert isset bridge
155
156 __device_get_file ${bridge} "bridge/priority"
157 return ${EXIT_OK}
158 }
159
160 stp_bridge_set_priority() {
161 local bridge=${1}
162 assert isset bridge
163
164 local priority=${2}
165 assert isinteger priority
166
167 # Check if the setting we want is already set.
168 local current_priority=$(stp_bridge_get_priority ${bridge})
169 [ ${priority} -eq ${current_priority} ] && return ${EXIT_OK}
170
171 # Set the new value.
172 log INFO "Changing priority for '${bridge}': ${current_priority} --> ${priority}"
173 print "${priority}" > ${SYS_CLASS_NET}/${bridge}/bridge/priority
174
175 return ${EXIT_OK}
176 }
177
178 stp_bridge_get_designated_root() {
179 local bridge=${1}
180 assert isset bridge
181
182 local output
183
184 output=$(__device_get_file ${bridge} bridge/root_id)
185 output=${output:6}
186
187 # Print output (lowercase).
188 print "${output,,}"
189
190 if isset output; then
191 return ${EXIT_OK}
192 else
193 return ${EXIT_ERROR}
194 fi
195 }
196
197 stp_bridge_get_root_path_cost() {
198 local bridge=${1}
199 assert isset bridge
200
201 __device_get_file ${bridge} bridge/root_path_cost
202 }
203
204 stp_bridge_get_root_port_id() {
205 local bridge=${1}
206 assert isset bridge
207
208 __device_get_file ${bridge} bridge/root_port_id
209 }
210
211 stp_bridge_get_root_port() {
212 local bridge=${1}
213 assert isset bridge
214
215 local id=$(stp_bridge_get_root_port_id ${bridge})
216
217 local member member_id
218 for member in $(bridge_get_members ${bridge}); do
219 member_id=$(stp_port_get_id ${bridge} ${member})
220
221 if [ "${id}" = "${member_id}" ]; then
222 print "${member}"
223 return ${EXIT_OK}
224 fi
225 done
226
227 return ${EXIT_ERROR}
228 }
229
230 stp_bridge_is_root() {
231 local bridge=${1}
232 assert isset bridge
233
234 local root_path_cost=$(stp_bridge_get_root_path_cost ${bridge})
235
236 if [ "${root_path_cost}" = "0" ]; then
237 return ${EXIT_TRUE}
238 fi
239
240 return ${EXIT_FALSE}
241 }
242
243 stp_bridge_get_topology_change_count() {
244 local bridge=${1}
245 assert isset bridge
246
247 __device_get_file ${bridge} bridge/topology_change
248 }
249
250 stp_bridge_get_topology_change_timer() {
251 local bridge=${1}
252 assert isset bridge
253
254 __device_get_file ${bridge} bridge/topology_change_timer
255 }
256
257 stp_bridge_get_topology_change_detected() {
258 local bridge=${1}
259 assert isset bridge
260
261 local change
262
263 change=$(__device_get_file ${bridge} bridge/topology_change_detected)
264
265 if enabled change; then
266 print "yes"
267 return ${EXIT_TRUE}
268 else
269 print "no"
270 return ${EXIT_FALSE}
271 fi
272 }
273
274 stp_port_get_state() {
275 local bridge=${1}
276 assert isset bridge
277
278 local port=${2}
279 assert isset port
280
281 local state=$(__device_get_file ${bridge} brif/${port}/state)
282
283 case "${state}" in
284 0)
285 print "DISABLED"
286 ;;
287 1)
288 print "LISTENING"
289 ;;
290 2)
291 print "LEARNING"
292 ;;
293 3)
294 print "FORWARDING"
295 ;;
296 4)
297 print "BLOCKING"
298 ;;
299 *)
300 return ${EXIT_ERROR}
301 ;;
302 esac
303
304 return ${EXIT_OK}
305 }
306
307 stp_port_get_id() {
308 local bridge=${1}
309 assert isset bridge
310
311 local port=${2}
312 assert isset port
313
314 dec $(__device_get_file ${bridge} "brif/${port}/port_no")
315 return ${EXIT_OK}
316 }
317
318 stp_port_get_cost() {
319 local bridge=${1}
320 assert isset bridge
321
322 local port=${2}
323 assert isset port
324
325 __device_get_file ${bridge} brif/${port}/path_cost
326 }
327
328 stp_port_set_cost() {
329 assert [ $# -eq 3 ]
330
331 local bridge="${1}"
332 local port="${2}"
333 local cost="${3}"
334
335 local old_cost="$(stp_port_get_cost "${bridge}" "${port}")"
336 if [ "${cost}" = "${old_cost}" ]; then
337 return ${EXIT_OK}
338 fi
339
340 log DEBUG "Setting STP path costs of port '${port}' (bridge '${bridge}') to '${cost}'"
341
342 __device_set_file "${bridge}" "brif/${port}/path_cost" "${cost}"
343 }
344
345 stp_port_get_priority() {
346 local bridge=${1}
347 assert isset bridge
348
349 local port=${2}
350 assert isset port
351
352 __device_get_file "${bridge}" "brif/${port}/priority"
353 }
354
355 stp_port_set_priority() {
356 assert [ $# -eq 3 ]
357
358 local bridge="${1}"
359 local port="${2}"
360 local priority="${3}"
361
362 # Nothing to do if the priority already matches
363 local old_priority="$(stp_port_get_priority "${bridge}" "${port}")"
364 if [ ${priority} -eq ${old_priority} ]; then
365 return ${EXIT_OK}
366 fi
367
368 log DEBUG "Setting STP priority to ${priority} on ${port}"
369
370 __device_set_file "${bridge}" "brif/${port}/priority" "${priority}"
371 }
372
373 stp_port_get_designated_root() {
374 local bridge=${1}
375 assert isset bridge
376
377 local port=${2}
378 assert isset port
379
380 local output=$(__device_get_file ${bridge} brif/${port}/designated_root)
381
382 if isset output; then
383 mac_format ${output:5}
384 return ${EXIT_OK}
385 fi
386
387 return ${EXIT_ERROR}
388 }
389
390 __stp_div_100() {
391 local val=${1}
392
393 local split=$((${#val} - 2))
394 val="${val:0:${split}}.${val:${split}:2}"
395
396 # Round the output.
397 print "%.0f" "${val}"
398 }