]> git.ipfire.org Git - people/arne_f/network.git/blame - functions.ipv6
network: Initialize the IPv6 stack.
[people/arne_f/network.git] / functions.ipv6
CommitLineData
4231f419
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
58fb41ee
MT
22function ipv6_init() {
23 log INFO "Initializing IPv6 networking."
24
25 # Enable forwarding on all devices
26 ipv6_device_forwarding_disable all
27 ipv6_device_forwarding_disable default
28
29 # Disable autoconfiguration on all devices per default
30 ipv6_device_autoconf_disable all
31 ipv6_device_autoconf_disable default
32
33 # XXX do we need this?
34 #local device
35 #for device in $(devices_get_all); do
36 # ipv6_device_forwarding_disable ${device}
37 # ipv6_device_autoconf_disable ${device}
38 #done
39}
40
41init_register ipv6_init
42
4231f419
MT
43function ipv6_device_autoconf_enable() {
44 local device=${1}
45
58fb41ee
MT
46 assert isset device
47
48 # Allow setting default and all settings
49 if ! isoneof device all default; then
50 assert device_exists ${device}
4231f419
MT
51 fi
52
58fb41ee
MT
53 local val
54 for val in accept_ra accept_redirects; do
55 echo 1 > /proc/sys/net/ipv6/conf/${device}/${val}
56 done
4231f419
MT
57}
58
59function ipv6_device_autoconf_disable() {
60 local device=${1}
61
58fb41ee
MT
62 assert isset device
63
64 # Allow setting default and all settings
65 if ! isoneof device all default; then
66 assert device_exists ${device}
67 fi
68
69 local val
70 for val in accept_ra accept_redirects; do
71 echo 0 > /proc/sys/net/ipv6/conf/${device}/${val}
72 done
73}
74
75function ipv6_device_forwarding_enable() {
76 local device=${1}
77
78 assert isset device
79
80 # Allow setting default and all settings
81 if ! isoneof device all default; then
82 assert device_exists ${device}
83 fi
84
85 echo 1 > /proc/sys/net/ipv6/conf/${device}/forwarding
86}
87
88function ipv6_device_forwarding_disable() {
89 local device=${1}
90
91 assert isset device
92
93 # Allow setting default and all settings
94 if ! isoneof device all default; then
95 assert device_exists ${device}
4231f419
MT
96 fi
97
58fb41ee
MT
98 echo 0 > /proc/sys/net/ipv6/conf/${device}/forwarding
99}
100
101# Enable IPv6 RFC3041 privacy extensions if desired
102function ipv6_device_privacy_extensions_enable() {
103 local device=${1}
104 local type=${2}
105
106 assert isset device
107 assert device_exists ${device}
108
109 # Default value is rfc3041
110 if [ -z "${type}" ]; then
111 type="rfc3041"
112 fi
113
114 assert isset type
115
116 case "${type}" in
117 rfc3041)
118 echo 2 > /proc/sys/net/ipv6/conf/${device}/use_tempaddr
119 ;;
120 *)
121 error_log "Given type '${type}' is not supported."
122 return ${EXIT_ERROR}
123 ;;
124 esac
125
126 return ${EXIT_OK}
127}
128
129function ipv6_device_privacy_extensions_disable() {
130 local device=${1}
131
132 assert isset device
133 assert device_exists ${device}
134
135 echo 0 > /proc/sys/net/ipv6/conf/${device}/use_tempaddr
4231f419
MT
136}
137
138function ipv6_is_valid() {
139 local address=${1}
140
58fb41ee
MT
141 assert isset address
142
4231f419
MT
143 # Check length
144 [ ${#address} -gt 39 ] && return ${EXIT_ERROR}
145
146 # XXX find :: twice?
147 # XXX check for documentation prefix?
148
149 # Check for bad characters
150 local char
151 for char in 0 1 2 3 4 5 6 7 8 9 a b c d e f :; do
152 address=${address//${char}/}
153 done
154 [ -n "${address}" ] && return ${EXIT_ERROR}
155
156 return ${EXIT_OK}
157}
158
159function ipv6_implode() {
160 local address=${1}
161
58fb41ee
MT
162 assert isset address
163
4231f419
MT
164 if ! ipv6_is_valid ${address}; then
165 error "IPv6 address is invalid: ${address}"
166 return ${EXIT_ERROR}
167 fi
168
169 # Make proper address in exploded format
170 address=$(ipv6_explode ${address})
171
172 local block
173 local char
174 local i
175
176 local address_new
177 local block_new
178
179 for block in ${address//:/\ }; do
180 block_new=
181 for i in $(seq 0 ${#block}); do
182 char="${block:${i}:1}"
183
184 [ -z "${char}" ] && continue
185
186 if [ -z "${block_new}" ] && [ "${char}" = "0" ]; then
187 continue
188 fi
189
190 block_new="${block_new}${char}"
191 done
192
193 [ -z "${block_new}" ] && block_new="0"
194
195 address_new="${address_new}:${block_new}"
196 done
197
198 # Cut first colon (:)
199 address="${address_new:1:${#address_new}}"
200
201 local match
202 local matches=()
203 local pattern
204 local pos_start
205 local pos_next
206 for pos_start in $(seq 0 ${#address}); do
207 matches["${pos_start}"]=0
208
209 for pos_next in $(seq ${pos_start} 2 ${#address}); do
210 case "${pos_start}" in
211 0)
212 match="${address:${pos_next}:2}"
213 pattern="0:"
214 ;;
215 *)
216 match="${address:${pos_next}:2}"
217 pattern=":0"
218 ;;
219 esac
220
221 [ -z "${match}" ] && continue
222
223 if [ "${match}" = "${pattern}" ]; then
224 matches[${pos_start}]=$(( matches[${pos_start}] + 1))
225 else
226 break
227 fi
228 done
229 done
230
231 local pos_best
232 local pos_best_val=0
233 for i in $(seq 0 ${#matches[@]}); do
234 [ -z "${matches[${i}]}" ] && continue
235
236 if [ ${matches[${i}]} -gt ${pos_best_val} ]; then
237 pos_best=${i}
238 pos_best_val=${matches[${i}]}
239 fi
240 done
241
242 if [ -n "${pos_best}" ]; then
243 address_new="${address:0:${pos_best}}::"
244
245 local pos_end=$(( ${pos_best_val} * 2 + ${pos_best} + 1))
246
247 if [ "${pos_best}" = "0" ]; then
248 pos_end=$(( ${pos_end} - 1 ))
249 fi
250
251 address="${address_new}${address:${pos_end}:${#address}}"
252 fi
253
254 assert ipv6_is_valid ${address}
255
256 echo "${address}"
257}
258
259function ipv6_explode() {
260 local address=${1}
261
58fb41ee
MT
262 assert isset address
263
4231f419
MT
264 if [ ${#address} -eq 39 ]; then
265 echo "${address}"
266 return ${EXIT_OK}
267 fi
268
269 address=${address//::/:X:}
270
271 local block
272 local block_count=0
273 local block_id
274 local block_max=8
275 local blocks=()
276
277 for block in ${address//:/\ }; do
278 blocks[${block_count}]=${block}
279
280 block_count=$(( ${block_count} + 1 ))
281 done
282
283 if [ ${#blocks[@]} -lt ${block_max} ]; then
284 for block_id in $(seq ${#blocks[@]} -1 0); do
285 block=${blocks[${block_id}]}
286
287 [ -z "${block}" ] && continue
288
289 if [ "${block}" = "X" ]; then
290 blocks[${block_id}]="0000"
291 break
292 fi
293
294 blocks[$(( ${block_max} - ${block_count} + ${block_id} ))]=${block}
295 blocks[${block_id}]="0000"
296 done
297 fi
298
299 for block_id in $(seq 0 ${#blocks[@]}); do
300 block=${blocks[${block_id}]}
301
302 [ -z "${block}" ] && block="0000"
303
304 while [ "${#block}" -lt 4 ]; do
305 block="0${block}"
306 done
307
308 blocks[${block_id}]=${block}
309 done
310
311 address=
312 for block in ${blocks[@]}; do
313 address="${address}:${block}"
314 done
315 address=${address:1:39}
316
317 assert ipv6_is_valid ${address}
318
319 echo "${address}"
320}
321
322function ipv6_hash() {
323 local address=${1}
324
58fb41ee
MT
325 assert isset address
326
4231f419
MT
327 # Explode address
328 address=$(ipv6_explode ${address})
329
330 echo "${address//:/}"
331}