]> git.ipfire.org Git - people/stevee/network.git/blob - src/functions/functions.ports
Dropping port_dir()
[people/stevee/network.git] / src / functions / functions.ports
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 port_list() {
23 list_directory "${NETWORK_PORTS_DIR}"
24 }
25
26 port_list_in_use() {
27 local ports_in_use
28
29 # Collect all ports that are attached to a zone
30 local zone
31 for zone in $(zones_get_all); do
32 list_append ports_in_use $(zone_get_ports "${zone}")
33 done
34
35 # Collect all ports that are enslaved by an other port
36 local port
37 for port in $(port_list); do
38 list_append ports_in_use $(port_get_slaves "${port}")
39 done
40
41 list_sort ${ports_in_use}
42 }
43
44 port_list_free() {
45 local ports_in_use="$(port_list_in_use)"
46
47 local port
48 for port in $(port_list); do
49 if ! list_match "${port}" ${ports_in_use}; then
50 print "${port}"
51 fi
52 done
53
54 return ${EXIT_OK}
55 }
56
57 port_get_hook() {
58 local port=${1}
59 assert isset port
60
61 config_get_hook $(port_file ${port})
62 }
63
64 port_config_dir() {
65 local port=${1}
66
67 print "${RUN_DIR}/ports/${port}"
68 return ${EXIT_OK}
69 }
70
71 port_settings_read() {
72 local port="${1}"
73 assert isset port
74
75 # Save the HOOK variable.
76 local hook="${HOOK}"
77
78 settings_read "$(port_file "${port}")" ${HOOK_SETTINGS}
79
80 # Restore hook.
81 HOOK="${hook}"
82 }
83
84 port_settings_write() {
85 local port="${1}"
86 assert isset port
87 shift
88
89 local args
90 if function_exists "hook_check_settings"; then
91 list_append args "--check=\"hook_check_settings\""
92 fi
93 list_append args ${HOOK_SETTINGS}
94
95 settings_write "$(port_file "${port}")" ${args}
96 }
97
98 ports_get_all() {
99 port_list
100 }
101
102 port_file() {
103 local port="${1}"
104 assert isset port
105
106 echo "${NETWORK_PORTS_DIR}/${port}/settings"
107 }
108
109 port_exists() {
110 local port=${1}
111
112 [ -d "${NETWORK_CONFIG_DIR}/ports/${port}" ]
113 }
114
115 port_get_hook() {
116 local port=${1}
117
118 assert isset port
119
120 config_get_hook $(port_file ${port})
121 }
122
123 port_is_attached() {
124 local port=${1}
125 shift
126
127 assert isset port
128
129 local zone
130 for zone in $(zones_get_all); do
131 if list_match ${port} $(zone_get_ports ${zone}); then
132 echo "${zone}"
133 return ${EXIT_OK}
134 fi
135 done
136
137 return ${EXIT_ERROR}
138 }
139
140 port_is_up() {
141 device_is_up "$@"
142 }
143
144 port_new() {
145 local hook="${1}"
146 shift
147
148 if ! hook_exists port "${hook}"; then
149 error "Port hook '${hook}' does not exist."
150 return ${EXIT_ERROR}
151 fi
152
153 hook_exec port "${hook}" new "$@"
154 }
155
156 port_destroy() {
157 local port=${1}
158 assert isset port
159
160 # Cannot delete a port that does not exist
161 if ! port_exists ${port}; then
162 error "No such port: ${port}"
163 return ${EXIT_ERROR}
164 fi
165
166 local attached_zone=$(port_is_attached ${port})
167 if [ -n "${attached_zone}" ]; then
168 if ! zone_port_detach "${attached_zone}" "${port}"; then
169 error "Could not remove port ${port} from zone ${zone}"
170 return ${EXIT_ERROR}
171 fi
172 fi
173
174 # Check if the port is linked to any other port and don't allow the user
175 # to delete it.
176 local other_port
177 for other_port in $(ports_get); do
178 [ "${other_port}" = "${port}" ] && continue
179
180 if list_match ${port} $(port_get_children ${other_port}); then
181 log ERROR "Cannot destroy port '${port}' which is child of port '${other_port}'."
182 return ${EXIT_ERROR}
183 fi
184 done
185
186 # Shut down the port before destroying it
187 if ! port_remove "${port}"; then
188 return ${EXIT_ERROR}
189 fi
190
191 rm -rf "${NETWORK_PORTS_DIR}/${port}"
192 }
193
194 port_create() {
195 port_cmd "create" "$@"
196 }
197
198 port_remove() {
199 local port="${1}"
200 assert isset port
201
202 if ! port_exists "${port}"; then
203 log ERROR "Port ${port} does not exist"
204 return ${EXIT_ERROR}
205 fi
206
207 # If the device is still up, we need to bring it down first.
208 if device_is_up "${port}"; then
209 port_down "${port}"
210 fi
211
212 port_cmd "remove" "${port}"
213 }
214
215 # Restarts the port by removing it and then re-creating it
216 port_restart() {
217 local port="${1}"
218 assert isset port
219
220 port_remove "${port}"
221
222 port_create "${port}"
223 }
224
225 port_edit() {
226 port_cmd edit "$@"
227 }
228
229 port_up() {
230 assert [ $# -eq 1 ]
231
232 local port="${1}"
233
234 # Check if the port exists
235 if ! device_exists "${port}"; then
236 log ERROR "Could not bring up port ${port} which has not been created"
237 return ${EXIT_ERROR}
238 fi
239
240 port_cmd up "${port}"
241 }
242
243 port_down() {
244 port_cmd down "$@"
245 }
246
247 port_status() {
248 port_cmd status "$@"
249 }
250
251 port_cmd() {
252 local cmd=${1}
253 local port=${2}
254 shift 2
255
256 assert isset cmd
257 assert isset port
258
259 local hook=$(port_get_hook ${port})
260
261 # Abort if we could not find a hook
262 if ! isset hook; then
263 log CRITICAL "Port ${port} does not have a hook associated with it"
264 return ${EXIT_ERROR}
265 fi
266
267 hook_exec port ${hook} ${cmd} ${port} "$@"
268 }
269
270 ports_get() {
271 local port
272 for port in $(list_directory "${NETWORK_PORTS_DIR}"); do
273 if port_exists ${port}; then
274 echo "${port}"
275 fi
276 done
277 }
278
279 port_find_free() {
280 local pattern=${1}
281
282 assert isset pattern
283
284 local port
285 local i=0
286
287 while [ ${i} -lt 99 ]; do
288 port=${pattern//N/${i}}
289 if ! port_exists ${port} && ! device_exists ${port}; then
290 echo "${port}"
291 return ${EXIT_OK}
292 fi
293 i=$(( ${i} + 1 ))
294 done
295
296 return ${EXIT_ERROR}
297 }
298
299 port_get_children() {
300 local port=${1}
301
302 assert port_exists "${port}"
303
304 port_cmd "children" "${port}"
305 }
306
307 port_zone() {
308 # Get name of the zones, this port is configured in.
309 local port=${1}
310 shift
311
312 assert isset port
313
314 local zone
315 for zone in $(zones_get_all); do
316 if zone_has_port ${zone} ${port}; then
317 echo "${zone}"
318 return ${EXIT_OK}
319 fi
320 done
321
322 return ${EXIT_OK}
323 }
324
325 port_hotplug_event() {
326 local port="${1}"
327 assert isset port
328
329 hotplug_assert_in_hotplug_event
330
331 port_cmd "hotplug" "${port}"
332 }
333
334 port_get_slaves() {
335 local port="${1}"
336
337 port_settings_read "${port}" \
338 --ignore-superfluous-settings SLAVES
339 print "${SLAVES}"
340 }
341
342 port_device_is_slave() {
343 assert [ $# -eq 2 ]
344
345 local port="${1}"
346 local device="${2}"
347
348 # Get slaves of port
349 local slaves="$(port_get_slaves "${port}")"
350
351 # Returns true if device is in slaves
352 list_match "${device}" ${slaves}
353 }
354
355 port_get_phy() {
356 local port="${1}"
357
358 port_settings_read "${port}" \
359 --ignore-superfluous-settings PHY
360 print "${PHY}"
361 }
362
363 port_uses_phy() {
364 assert [ $# -eq 2 ]
365
366 local port="${1}"
367 local phy="${2}"
368
369 # Nothing to do if an empty argument is given
370 if ! isset phy; then
371 return ${EXIT_FALSE}
372 fi
373
374 phy="$(phy_get_address "${phy}")"
375
376 local port_phy="$(port_get_phy "${port}")"
377 [ "${port_phy}" = "${phy}" ]
378 }
379
380 ports_lowest_address() {
381 local address
382 local addresses
383
384 local port
385 for port in $(port_list); do
386 # Skip all ports that do not exist
387 # any more or are not plugged in
388 device_exists "${port}" || continue
389
390 # Skip all ports that are not proper ethernet devices
391 device_is_wireless "${port}" && continue
392 device_is_ethernet "${port}" || continue
393
394 list_append addresses "$(device_get_address "${port}")"
395 done
396
397 # Sort the list
398 addresses="$(list_sort ${addresses})"
399
400 # Get the first element which is the lowest MAC address
401 list_head ${addresses}
402 }
403
404 port_identify() {
405 device_identify "$@"
406 }
407
408 port_get_color() {
409 # This function return the color of a port
410 assert [ $# -eq 1 ]
411
412 local name=${1}
413 color_read "port" ${name}
414 }
415
416 port_get_description_title() {
417 assert [ $# -eq 1 ]
418
419 local name=${1}
420 description_title_read $(description_format_filename "port" "${name}")
421 }