dbbe52cc8131ca0f0501bc9ae04fd8fbf4a0d6c3
[openwrt/svn-archive/archive.git] / ipv6 / radvd / files / radvd.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008 Alina Friedrichsen <x-alina@gmx.net>
3 START=50
4
5 RADVD_INTERFACE_STRING_OPTIONS='MaxRtrAdvInterval MinRtrAdvInterval MinDelayBetweenRAs AdvLinkMTU AdvReachableTime AdvRetransTimer AdvCurHopLimit AdvDefaultLifetime AdvDefaultPreference HomeAgentLifetime HomeAgentPreference'
6 RADVD_INTERFACE_BOOLEAN_OPTIONS='IgnoreIfMissing AdvSendAdvert UnicastOnly AdvManagedFlag AdvOtherConfigFlag AdvSourceLLAddress AdvHomeAgentFlag AdvHomeAgentInfo AdvMobRtrSupportFlag AdvIntervalOpt'
7
8 RADVD_PREFIX_STRING_OPTIONS='AdvValidLifetime AdvPreferredLifetime'
9 RADVD_PREFIX_BOOLEAN_OPTIONS='AdvOnLink AdvAutonomous AdvRouterAddr'
10
11 RADVD_ROUTE_STRING_OPTIONS='AdvRouteLifetime AdvRoutePreference'
12
13 RADVD_RDNSS_STRING_OPTIONS='AdvRDNSSLifetime'
14
15 RADVD_DNSSL_STRING_OPTIONS='AdvDNSSLLifetime'
16
17 validate_varname() {
18 local varname=$1
19 [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
20 return 0
21 }
22
23 validate_ifname() {
24 local ifname=$1
25 [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
26 return 0
27 }
28
29 validate_ip6addr() {
30 local ip6addr=$1
31 [ -z "$ip6addr" -o "$ip6addr" != "${ip6addr%%[!A-Fa-f0-9.:]*}" ] && return 1
32 return 0
33 }
34
35 validate_ip6prefix() {
36 local ip6prefix=$1
37 [ -z "$ip6prefix" -o "$ip6prefix" != "${ip6prefix%%[!A-Fa-f0-9./:]*}" ] && return 1
38 return 0
39 }
40
41 validate_radvd_string() {
42 local radvd_string=$1
43 [ -z "$radvd_string" -o "$radvd_string" != "${radvd_string%%[!a-z0-9.:_-]*}" ] && return 1
44 return 0
45 }
46
47 get_ifname() {
48 local interface=$1
49 validate_varname "$interface" || return 1
50 local cfgt
51 local ifname
52
53 scan_interfaces
54 config_get cfgt "$interface" TYPE
55 [ "$cfgt" != "interface" ] && return 1
56 config_get ifname "$interface" ifname
57 validate_ifname "$ifname" || return 1
58 printf '%s\n' "$ifname"
59
60 return 0
61 }
62
63 get_ip6addr() {
64 local ifname=$1
65 local scope=$2
66 local iproute2_scope
67 local ifconfig_scope
68 local ip6addr
69
70 case "$scope" in
71 host) iproute2_scope=host ifconfig_scope=Host;;
72 link) iproute2_scope=link ifconfig_scope=Link;;
73 site) iproute2_scope=site ifconfig_scope=Site;;
74 global) iproute2_scope=global ifconfig_scope=Global;;
75 "") get_ip6addr "$ifname" global || get_ip6addr "$ifname" site; return;;
76 *) return 1;;
77 esac
78
79 ip6addr=$(LANG=C ip -f inet6 -- addr show dev "$ifname" 2> /dev/null | sed -n -e 's/^ *inet6 \([A-Fa-f0-9.:]*[/][0-9]*\) scope '"$iproute2_scope"' $/\1/p' | head -n 1)
80 if [ -z "$ip6addr" ]; then
81 ip6addr=$(LANG=C ifconfig "$ifname" 2> /dev/null | sed -n -e 's/^ *inet6 addr: \([A-Fa-f0-9.:]*[/][0-9]*\) Scope:'"$ifconfig_scope"'$/\1/p' | tail -n 1)
82 [ -z "$ip6addr" ] && return 1
83 fi
84
85 printf '%s\n' "$ip6addr"
86
87 return 0
88 }
89
90 radvd_find_config_file() {
91 local cfg=$1
92 validate_varname "$cfg" || return 0
93
94 config_get_bool ignore "$cfg" ignore 0
95 [ "$ignore" -ne 0 ] && return 0
96 config_get RADVD_CONFIG_FILE "$cfg" config_file
97
98 return 0
99 }
100
101 radvd_add_interface() {
102 local cfg=$1
103 validate_varname "$cfg" || return 0
104 local ignore
105 local interfaces
106 local interface
107 local list_interface
108 local exist
109
110 config_get_bool ignore "$cfg" ignore 0
111 [ "$ignore" -ne 0 ] && return 0
112
113 config_get interfaces "$cfg" interface
114 for interface in $interfaces; do
115 validate_varname "$interface" || continue
116 exist=0
117 for list_interface in $RADVD_INTERFACES; do
118 [ "$interface" = "$list_interface" ] && exist=1
119 done
120 [ "$exist" -eq 0 ] && RADVD_INTERFACES="$RADVD_INTERFACES $interface"
121 done
122
123 return 0
124 }
125
126 radvd_write_interface() {
127 local cfg=$1
128 validate_varname "$cfg" || return 0
129 local ignore
130 local interfaces
131 local interface
132 local name
133 local value
134
135 config_get_bool ignore "$cfg" ignore 0
136 [ "$ignore" -ne 0 ] && return 0
137
138 config_get interfaces "$cfg" interface
139 exist=0
140 for interface in $interfaces; do
141 [ "$INTERFACE" = "$interface" ] && exist=1
142 done
143 [ "$exist" -eq 0 ] && return 0
144
145 for name in $RADVD_INTERFACE_STRING_OPTIONS; do
146 config_get value "$cfg" "$name"
147 validate_radvd_string "$value" || continue
148 printf '\t%s %s;\n' "$name" "$value"
149 done
150
151 for name in $RADVD_INTERFACE_BOOLEAN_OPTIONS; do
152 config_get value "$cfg" "$name"
153 [ -z "$value" ] && continue
154 config_get_bool value "$cfg" "$name" 0
155 if [ "$value" -ne 0 ]; then
156 printf '\t%s on;\n' "$name"
157 else
158 printf '\t%s off;\n' "$name"
159 fi
160 done
161
162 config_get clients "$cfg" client
163 if [ -n "$clients" ]; then
164 printf '\n\tclients\n\t{\n'
165
166 for client in $clients; do
167 validate_ip6addr "$client" || continue
168 printf '\t\t%s;\n' "$client"
169 done
170
171 printf '\t};\n'
172 fi
173
174 return 0
175 }
176
177 radvd_write_prefix() {
178 local cfg=$1
179 validate_varname "$cfg" || return 0
180 local ignore
181 local interfaces
182 local interface
183 local prefixes
184 local prefix
185 local name
186 local value
187 local cfgt
188
189 config_get_bool ignore "$cfg" ignore 0
190 [ "$ignore" -ne 0 ] && return 0
191
192 config_get interfaces "$cfg" interface
193 exist=0
194 for interface in $interfaces; do
195 [ "$INTERFACE" = "$interface" ] && exist=1
196 done
197 [ "$exist" -eq 0 ] && return 0
198
199 config_get prefixes "$cfg" prefix
200 if [ -z "$prefixes" ]; then
201 prefixes=$(get_ip6addr "$IFNAME") || return 0
202 fi
203
204 for prefix in $prefixes; do
205 validate_ip6prefix "$prefix" || continue
206 printf '\n\tprefix %s\n\t{\n' "$prefix"
207
208 for name in $RADVD_PREFIX_STRING_OPTIONS; do
209 config_get value "$cfg" "$name"
210 validate_radvd_string "$value" || continue
211 printf '\t\t%s %s;\n' "$name" "$value"
212 done
213
214 for name in $RADVD_PREFIX_BOOLEAN_OPTIONS; do
215 config_get value "$cfg" "$name"
216 [ -z "$value" ] && continue
217 config_get_bool value "$cfg" "$name" 0
218 if [ "$value" -ne 0 ]; then
219 printf '\t\t%s on;\n' "$name"
220 else
221 printf '\t\t%s off;\n' "$name"
222 fi
223 done
224
225 config_get value "$cfg" Base6to4Interface
226 if [ -n "$value" ]; then
227 if ifname=$(get_ifname "$value"); then
228 printf '\t\t%s %s;\n' "Base6to4Interface" "$ifname"
229 fi
230 fi
231
232 printf '\t};\n'
233 done
234
235 return 0
236 }
237
238 radvd_write_route() {
239 local cfg=$1
240 validate_varname "$cfg" || return 0
241 local ignore
242 local interfaces
243 local interface
244 local prefixes
245 local prefix
246 local name
247 local value
248
249 config_get_bool ignore "$cfg" ignore 0
250 [ "$ignore" -ne 0 ] && return 0
251
252 config_get interfaces "$cfg" interface
253 exist=0
254 for interface in $interfaces; do
255 [ "$INTERFACE" = "$interface" ] && exist=1
256 done
257 [ "$exist" -eq 0 ] && return 0
258
259 config_get prefixes "$cfg" prefix
260 for prefix in $prefixes; do
261 validate_ip6prefix "$prefix" || continue
262 printf '\n\troute %s\n\t{\n' "$prefix"
263
264 for name in $RADVD_ROUTE_STRING_OPTIONS; do
265 config_get value "$cfg" "$name"
266 validate_radvd_string "$value" || continue
267 printf '\t\t%s %s;\n' "$name" "$value"
268 done
269
270 printf '\t};\n'
271 done
272
273 return 0
274 }
275
276 radvd_write_rdnss() {
277 local cfg=$1
278 validate_varname "$cfg" || return 0
279 local ignore
280 local interfaces
281 local interface
282 local addrs
283 local addr
284 local addr_list
285 local name
286 local value
287 local i
288
289 config_get_bool ignore "$cfg" ignore 0
290 [ "$ignore" -ne 0 ] && return 0
291
292 config_get interfaces "$cfg" interface
293 exist=0
294 for interface in $interfaces; do
295 [ "$INTERFACE" = "$interface" ] && exist=1
296 done
297 [ "$exist" -eq 0 ] && return 0
298
299 config_get addrs "$cfg" addr
300 i=0
301 for addr in $addrs; do
302 [ "$i" -ge 3 ] && break
303 validate_ip6addr "$addr" || continue
304 addr_list="$addr_list $addr"
305 i=$(($i+1))
306 done
307
308 if [ -z "$addr_list" ]; then
309 addr=$(get_ip6addr "$IFNAME" link) || return 0
310 addr_list=" ${addr%%[/]*}"
311 fi
312
313 printf '\n\tRDNSS%s\n\t{\n' "$addr_list"
314
315 for name in $RADVD_RDNSS_STRING_OPTIONS; do
316 config_get value "$cfg" "$name"
317 validate_radvd_string "$value" || continue
318 printf '\t\t%s %s;\n' "$name" "$value"
319 done
320
321 printf '\t};\n'
322
323 return 0
324 }
325
326 radvd_write_dnssl() {
327 local cfg=$1
328 validate_varname "$cfg" || return 0
329 local ignore
330 local interfaces
331 local interface
332 local suffixes
333 local suffix
334 local suffix_list
335 local name
336 local value
337
338 config_get_bool ignore "$cfg" ignore 0
339 [ "$ignore" -ne 0 ] && return 0
340
341 config_get interfaces "$cfg" interface
342 exist=0
343 for interface in $interfaces; do
344 [ "$INTERFACE" = "$interface" ] && exist=1
345 done
346 [ "$exist" -eq 0 ] && return 0
347
348 config_get suffixes "$cfg" suffix
349 for suffix in $suffixes; do
350 validate_radvd_string "$suffix" || continue
351 suffix_list="$suffix_list $suffix"
352 done
353
354 printf '\n\tDNSSL%s\n\t{\n' "$suffix_list"
355
356 for name in $RADVD_DNSSL_STRING_OPTIONS; do
357 config_get value "$cfg" "$name"
358 validate_radvd_string "$value" || continue
359 printf '\t\t%s %s;\n' "$name" "$value"
360 done
361
362 printf '\t};\n'
363
364 return 0
365 }
366
367 radvd_write_config() {
368 include /lib/network
369
370 RADVD_INTERFACES=
371 config_foreach radvd_add_interface interface
372 config_foreach radvd_add_interface prefix
373 config_foreach radvd_add_interface route
374 config_foreach radvd_add_interface RDNSS
375 config_foreach radvd_add_interface DNSSL
376
377 for INTERFACE in $RADVD_INTERFACES; do
378 IFNAME=$(get_ifname "$INTERFACE") || continue
379 printf 'interface %s\n{\n' "$IFNAME"
380 config_foreach radvd_write_interface interface
381 config_foreach radvd_write_prefix prefix
382 config_foreach radvd_write_route route
383 config_foreach radvd_write_rdnss rdnss
384 config_foreach radvd_write_dnssl dnssl
385 printf '};\n\n'
386 done
387
388 return 0
389 }
390
391 start() {
392 config_load radvd
393
394 RADVD_CONFIG_FILE=
395 config_foreach radvd_find_config_file radvd
396
397 if [ -z "$RADVD_CONFIG_FILE" ]; then
398 mkdir -p -- /var/etc/
399 radvd_write_config > /var/etc/radvd.conf
400 if [ -s "/var/etc/radvd.conf" ]; then
401 RADVD_CONFIG_FILE=/var/etc/radvd.conf
402 fi
403 fi
404
405 [ -z "$RADVD_CONFIG_FILE" ] && return 1
406
407 sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null 2> /dev/null
408
409 radvd -C "$RADVD_CONFIG_FILE" -m stderr_syslog -p /var/run/radvd.pid
410 }
411
412 stop() {
413 killall radvd
414 }